Getting Started with IPPhone

Requirements: IPWorks VoIP


The IPPhone component provides access to simple and intuitive operations designed to implement standard softphone features. This guide will cover the basics of activating the component, setting up audio devices for the component to use, establishing outgoing calls, handling incoming calls, and more.



To use the component, one of the first steps is to activate the softphone. This can be done by using the Activate method. The following properties are required before calling this method:

  • User
  • Password
  • Server
  • Port

The User and Password properties contain the credentials required to log in to the SIP provider you are using. Server contains the hostname or IP of the SIP provider. Port contains the port number the component will connect to, with a default value of 5060. The Activated event will fire once activation is successful. This could look like this:

ipphone.User = "username"; ipphone.Password = "password"; ipphone.Server = "HostnameOrIP"; ipphone.Port = 5060; ipphone.Activate();

Audio Setup

While not required, you may want to set up the audio devices the component will use. To view devices recognized by the component, you must call the ListSpeakers and ListMicrophones methods. Calling these methods will populate their respective collections, accessible through the Speakers and Microphones properties. Various information, such as the device name, will be available for each entry in the collection. The SetSpeaker and SetMicrophone methods can then be called with the name of the device, as it appears in the collections. For example, this process would look like this:

// Populate respective collections ipphone.ListSpeakers(); ipphone.ListMicrophones(); // Examine device names foreach (Speaker s in ipphone.Speakers) { Console.WriteLine(s.Name); } foreach (Microphone m in ipphone.Microphones) { Console.WriteLine(m.Name); } // Set devices for use by the component ipphone.SetSpeaker(ipphone.Speakers[0].Name); ipphone.SetMicrophone(ipphone.Microphones[0].Name);

Establish Outgoing Calls

After successful activation and setup of the audio devices, the component is now ready to make and receive calls. To do so, you must call the Dial method. This method takes three parameters: the number you wish to call, the caller ID, and a boolean that determines whether the method will connect synchronously (True) or asynchronously (False). The second parameter, specifying the caller ID, is completely optional. If set, the P-Asserted-Identity header (RFC 3325) will be sent in requests to the SIP Server. If left as an empty string, this header will not be sent. Dial will return a call identification string (CallId) unique to that particular call. After the method returns successfully, this call will be added to the collection of ongoing calls, located in the Calls property.

Synchronous Dial Example

If the third parameter of Dial is specified as true, the method will not return until the call has either been answered, declined, or ignored. Typically, three events will fire in the given order: OutgoingCall, DialCompleted, and CallReady. First, OutgoingCall will fire as soon as the invite process for the call has begun. After this process has completed and the call has been answered, declined, or ignored, DialCompleted and CallReady will fire. At this point, audio can be transmitted. In the below example, we assume the call has been answered:

string callId = ""; bool connected = false; ipphone.OnCallReady += (sender, e) => { connected = true; } try { callId = ipphone.Dial("123456789", "", true); } catch (IPWorksVoIPException e) { MessageBox.Show(e.Code + ": " + e.Message); } if (connected) { ipphone.PlayText(callId, "Hello"); }

Asynchronous Dial Example

If the third parameter of Dial is specified as false, the method will immediately return with the call's CallId. Typically, three events will fire in the given order: OutgoingCall, DialCompleted, and CallReady. First, OutgoingCall will fire as soon as the invite, or dial, process for the call has begun. Before the remaining two events fire, it is possible for the CallId of this call to change. This can occur if call forwarding, or redirection, occurs. In this case, when wait is false, the value returned by Dial (and present in OutgoingCall) will be incorrect.

This above issue is taken care of in DialCompleted event parameters. The OriginalCallId parameter will contain the original CallId returned by Dial. The CallId parameter will contain the updated and correct CallId. Along with this, other call details are specified within the event and can be used to determine if there were any issues within the dial process. It is important to note that when wait is true, this method will return the correct CallId.

Lastly, if DialCompleted has fired with no errors (indicated by an ErrorCode of 0), CallReady will fire containing the updated CallId. It is important to note that this event will fire after the call has either been answered, declined, or ignored. If the call has been declined or ignored, this event will still fire, but the component will attempt to leave a voicemail. You can end the voicemail at any time using the Hangup (or HangupAll) method. In the below example, we assume the call has been answered and take care to update the returned value of Dial in case redirection occurs:

bool connected = false; string callId = ""; ipphone.OnDialCompleted += (sender, e) => { if (e.ErrorCode != 0) { MessageBox.Show(e.ErrorCode + ": " + e.Description); // Handle error } if (e.OriginalCallId != e.CallId) { callId = e.CallId; // Update callId if redirect occurred } } ipphone.OnCallReady += (sender, e) => { connected = true; // If fired, we are ready to talk } string callId = ipphone.Dial("123456789", "", false); ... ... ... // Somewhere else... if (connected) { ipphone.PlayText(callId, "Hello"); }

Handle Incoming Calls

Incoming calls can be handled using the IncomingCall event. You can use the Answer, Decline, or Forward methods within this event to appropriately handle incoming calls. For example:

phone.OnIncomingCall += (sender, e) => { phone.Answer(e.CallId); // or phone.Decline(e.CallId); // or phone.Forward(e.CallId); }

Note that incoming calls will also appear in the Calls Collection. The Outgoing field (boolean) will determine if a call is outgoing (true) or incoming (false). You may want query this field, along with the corresponding CallId field, to answer or decline these calls.

Transfer Ongoing Calls

Ongoing calls can be transferred using the Transfer method. This method takes three parameters: the first contains the CallId of the call you wish to transfer, the second containing the number you would like to transfer the call to, and the third is a boolean parameter identical to the one present in the previously mentioned Dial method. This method will remove the call from the current collection specified in Calls. Using this method is almost identical to the steps above.

Ending Calls

Ongoing calls are terminated by passing the CallId to the Hangup method, or by calling HangupAll, which will terminate all ongoing calls. When a call has ended (by either party), the CallTerminated event will fire. It's important to note that in the case where an outgoing call is never answered, the component will attempt to leave a voicemail. The call will still be able to terminate via Hangup at any point during the voicemail procedure.

Other Functionality

In addition to the basic operations described above, the component also supports a variety of other features including:

  • Placing calls on hold
  • Playing audio from files/streams
  • Recording call audio to files/streams
  • Managing conference calls
  • DTMF signaling
  • Phone extensions

We appreciate your feedback.  If you have any questions, comments, or suggestions about this article please contact our support team at