#2 how to develop a voip softphone in c# by using ozeki voip sip sdk - part 2
DESCRIPTION
Dig deeper: http://www.voip-sip-sdk.com This presentation describes what you should do – having done the SIP registration – to develop a fully-functional softphone in C# in the most simplest way - by using the previously written components of Ozeki VoIP SIP SDK. This guide presents how to reaching the media handlers, handling the devices and attachning them to the call object. Now you also know how to make and accept calls, and how to handle the call states and events. This is the 1. part of the 3-part great softphone development turtorial series. Let's check the 2. part, too that explains how to make and receive call using your softphone. Get more information: http://www.voip-sip-sdk.com ... or ask for help via e-mail: [email protected]TRANSCRIPT
How to develop a
VoIP softphone in C# by using OZEKI VoIP SIP SDK
This presentation describes what you should do – having
done the SIP registration – to develop a fully-functional
softphone in C# in the most simplest way - by using the
previously written components of Ozeki VoIP SIP SDK.
Part 1: SIP registration
Part 2: Making and receiving calls Part 3: Controlling the calls
1/19
Previously on this series
Windows PC .NET compatible
development kit (e.g. MS Visual Studio)
installed on your PC
.NET Framework
installed on your PC
Ozeki VoIP SIP SDK
installed on your PC
In order to build a VoIP softphone application in C# you will need the followings:
2/19
Download free example source code for this project (Part 1) from
http://voip-sip-sdk.com/p_539-sip-registration-voip.html ! After studying the previous tutorial, you need be
familiar with adding VoIP components to your
references and creating a Softphone class that
provides a softphone object to the user using the
input setups. Now you have a console window
which interacts with the user and handles your
softphone with the provided opportunities.
Download free example source code for this project (Part 2) from
http://voip-sip-sdk.com/p_540-making-and-accepting-calls-voip.html !
In the ‘using section’ you need to add some extra lines, as well as:
Without these lines you would have to use
the namespace information as a label for all tools of the SDK.
Source code analysis
using Ozeki.Media; using Ozeki.Media.MediaHandlers; using Ozeki.Network.Nat; using Ozeki.VoIP; using Ozeki.VoIP.SDK;
3/19
Classes:
• Softphone.cs is used to introduce how to declare, define and initialize a softphone, how to handle
some of the Ozeki VoIP SIP SDK's events and how to use some features. So the aim is creating a
‘telephone software’, which has the same functionalities (or much more), as an ordinary phone’s.
• You will use the Program.cs class to create a new softphone, so you can use the functions and
listen to the events placed here.
The microphone will be connected to the mediaSender, and the speaker will be connected to
themediaReceiver with the help of the connector object. The mediaSender and
the mediaReceiver media handlers will be attached to the call object, this step is necessary if
you would like to send and receive media data (for example: voice) during the communication.
This sender and receiver object can be connected to different devices, media handlers as well.
You also need a variable to indicate the incoming call:
Objects (1)
IPhoneCall call; Microphone microphone; Speaker speaker; MediaConnector connector; PhoneCallAudioSender mediaSender; PhoneCallAudioReceiver mediaReceiver;
bool incomingCall;
In the guide you have created a softphone and a phone line object from the ISoftPhone and
the IPhoneLine interfaces. Now, you need to create some new objects:
4/19
In a constructor, you need to initialize the following new objects, variables:
Since your softphone has no any incoming call yet, you need to set the variable to ‘false’.
Objects (2)
microphone = Microphone.GetDefaultDevice(); speaker = Speaker.GetDefaultDevice(); connector = new MediaConnector(); mediaSender = new PhoneCallAudioSender(); mediaReceiver = new PhoneCallAudioReceiver(); incomingCall = false;
5/19
There are some methods to help your later work, for example the methods designed to
start and stop the devices, to connect them with the other media handlers, etc.
Let's start with the device starter/stopper ones. In this example microphone and a speaker
were used, but you can also use many other devices as objects, e.g. a webCamera.
As you can see, this method checks first if there is a device to be started or not. After that,
it starts the existing device with a single command. The method which stops them works
on a similar way, with the Stop() command of the device's object.
Starting and stopping the devices
if (microphone != null) { microphone.Start(); }
6/19
Connecting the media handlers (1)
if (microphone != null) { connector.Connect(microphone, mediaSender); }
In order to send voice through the microphone to the other client's speaker, you need
to connect the correct devices. Please note that it is possible to use several different
kind of media handlers with the Ozeki VoIP SIP SDK, for example there is a similar way
to connect a WaveStreamPlayback or anMP3Playback object to
the mediaSender object, to play a .wav or an .mp3 file into the call, as voice (and you
can receive and record voices, videos as well, and there is much more).
To connect the microphone object to the mediaSender object with the help of
the connector object, use the following lines:
7/19
The first parameter of the connector is the source, and the second is the destination of
the data stream. So, in case of speaker, it looks like:
As it shows, the mediaReceiver sends the voice to the speaker. (There is method called
‘disconnector’, which closes the connection between the two media handlers with
the Disconnect() method.) There is a way to close all of the connections with only one
command:
This line closes every connection.
Connecting the media handlers (2)
if (speaker != null) { connector.Connect(mediaReceiver, speaker); }
8/19
connector.Dispose();
In the source code, you can find two methods to help in subscribtion and
unsubscribtion. Subscribe to the events:
The first line: if the call state changes
The second line: if an error occurs during the call.
The method to unsubscribe from the events works similar to the subscriber
(with the ‘-=‘ operator).
Subscribing for the call events
call.CallStateChanged += (call_CallStateChanged); call.CallErrorOccured += (call_CallErrorOccured);
9/19
If you would like to be notified when there is an incoming call, you need to set an event
at the initialization of the softphone:
When the event notifies that there is a call waiting to be accepted, it sets the call object,
and subscribes to the events of the call with the help of the previously written method.
It also sets the value of the incomingCall variable to ‘false’ to indicate: there is no other
call waiting.
Listening to the incoming calls
softphone.IncomingCall += softphone_IncomingCall;
10/19
Maybe this is the main part of your softphone within the Softphone class. If the call
state changes, an event occurs. You can handle these events within the Softphone.cs
and the Program.cs file as well.
In this example two states has been used by their name:
Handling the call states (1)
CallState.Answered CallState.InCall
11/19
The ‘Answered’ state occurs, when the call is being answered, and the ‘InCall’ state occurs
during the call, so if there is an active communication. To understand the difference between
the two cases: the ‘Answered’ state can occur only once per call, but we can enter into the
same call again and again (for example if we put the call on hold, and then take the call off
hold).
In the ‘Answered’ state, we need to:
• Start the devices, with the help of the previously written method
• Attach the media handlers to the call
• Please note that we need the devices to be connected to the media sender and receiver
objects, but it's already done at the initializationof the softphone.
In this example you need these lines in order to attach the media handlers to the call:
Handling the call states (2)
12/19
mediaReceiver.AttachToCall(call); mediaSender.AttachToCall(call);
In the ‘InCall’ state, you need to:
• Start the devices with the help of the previously written method
• Please note that the media handlers are already set to the call
In both cases, you subscribes to the call events when the call is made or received.
More states can be used when the call ends:
If the call ends, you can be notified about it as the IsCallEnded() method returns with a
true value. For example it can occur, when an error occurs or the call enters into
‘Completed’ state, but we can handle them all in once.
When the call ends, you need to:
• Stop the devices with the help of the previously written method.
• Detach the media handlers from the call
• Unsubscribe from the call events
• Finally, set the call objects to ‘null’
Handling the call states (3)
13/19
Making a call means creating a call object, subscribing to the call events and then
call the Start() method of the call object. In the example the softphone checks first, if
there is an already active call or not.
If there is no active call, the you need to call the correct methods, illustrated above. To
hang up the call, you can use the call object's HangUp() method.
Making a call
if (call == null) { call = softphone.CreateCallObject(phoneLine, numberToDial); WireUpCallEvents(); call.Start(); }
14/19
As you could see, when the variable, which indicates the incoming call, has been set to
‘true’, then there is a call to accept (so, your phone is ‘ringing’). In this example there is
only text to notify if the phone is ringing. In order to let it ring with voice, you have a lot of
options provided by the SDK or just by most of the programming languages.
When you would like to accept a call, you need to set the value of the variable to ‘false’.
In order to indicate that there are no incoming calls anymore, you need to accept the call
with the Accept() method of the call object:
To hang up the call, You can use the call object's HangUp() method.
Accepting a call
if (incomingCall == true) { incomingCall = false; call.Accept(); }
15/19
You can find a method, called ‘DispatchAsync(Action action)’ in the source file. This
method is used to solve the thread blockings, because the ReadLine() methods would
block the thread.
Program.cs
This class will introduce the usage of a softphone object, handles the console events,
interacts with the user and uses the opportunities provided by the Softphone class. In
this example, the softphone can accept calls automatically, and can call the number,
given by the user. You can handle everything with separated methods. These methods
are communicating with each other, and making the source code more understandable
and reusable.
Solving the Thread blockings
16/19
The first step is the initialization the softphone you have created. To do this, you need
to call an initializer method. You also need to subscribe to the call events. For this
purpose you need the following lines:
Now you are listening to the phone line and the call states or errors and to the incoming
calls. This method will be called in the Main() method.
Initialization (1)
mySoftphone = new Softphone(); mySoftphone.PhoneLineStateChanged += mySoftphone_PhoneLineStateChanged; mySoftphone.CallStateChanged += mySoftphone_CallStateChanged; mySoftphone.IncomingCall += mySoftphone_IncomingCall; mySoftphone.CallErrorOccurred += mySoftphone_CallErrorOccurred;
17/19
Handling an error, occurred during the call By subscribing to listening to the call errors, you can notify the user about the occurred errors
with a simple message in this example.
Handling if there is an incoming call If there is an incoming call, your softphone notifies the user about that and automatically
accepts the call with the help of the previously written method of the softphone.
Handling the call's states You can reach the call states, since you are listening them. When the call ends, you calls the
method that is asking the user about a number to be dialled. There are more call states, but
in this tutorial you will need only this one.
Handling if the registration succeeded In the previous example (that introduces how to register to a PBX with a SIP account), you could
learn how to handle the states of the phone line. You've notified the user about the success, and
now you are telling the user to dial a number by calling a method to ask about it.
Asking the user about a number to be dialled In this example, the phone asks the user about a number to be dialled and then stores that
number as a string. You need to store the number as a string value, since it can contain special
characters as well.
Initialization (2)
18/19
Check the 3. part of the ‘How to develop a VoIP softphone in C# by using OZEKI VoIP SIP SDK’ tutorial series
and get to know how to control the calls using such useful features as call holding, redialing, call transferring, etc.!
After studying this tutorial, you need be familiar with reaching the media
handlers, handling the devices and attachning them to the call object. Now
you also know how to make and accept calls, and how to handle the call
states and events.
Thank you for your attention!
For more information please visit
www.voip-sip-sdk.com
or send an e-mail to
19/19