a step by step guide for building an ozeki voip sip softphone€¦ · ozeki informatics ltd. ozeki...

14
Ozeki Informatics Ltd. Ozeki VoIP Training Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone Lesson 3 A Step by Step Guide for Building an Ozeki VoIP SIP Softphone 2012. 01. 20. Abstract The third lesson of Ozeki VoIP Training is a detailed step by step guide that will show you everything you need to implement for an accurately working softphone for making voice calls. You will learn about all the necessary methods and settings that need to be done in the right order. Introduction Softphone is one of the most essential VoIP applications that can be used for communication. It is basically a software model of a traditional telephone set. The softphone that will build up in this lesson implements the most basic telephone functions and it can only be used for voice calling, but it can be extended for video calling and other special functions any time. This course material contains all the needed source code, but you can also download the Visual Studio project from our website. A blank Windows Forms Project When you create a Windows Forms application in Visual Studio, you get a blank form and some background code. The starting class code will look like the following: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace MyFirstSoftphone { public partial class Softphone : Form { public Softphone() 1.

Upload: others

Post on 31-Jul-2020

12 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: A Step by Step Guide for Building an Ozeki VoIP SIP Softphone€¦ · Ozeki Informatics Ltd. Ozeki VoIP Training Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

Ozeki Informatics Ltd. Ozeki VoIP Training

Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

Lesson 3

A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

2012. 01. 20.

AbstractThe third lesson of Ozeki VoIP Training is a detailed step by step guide that will show you everything you need to implement for an accurately working softphone for making voice calls. You will learn about all the necessary methods and settings that need to be done in the right order.

IntroductionSoftphone is one of the most essential VoIP applications that can be used for communication. It is basically a software model of a traditional telephone set. The softphone that will build up in this lesson implements the most basic telephone functions and it can only be used for voice calling, but it can be extended for video calling and other special functions any time. This course material contains all the needed source code, but you can also download the Visual Studio project from our website.

A blank Windows Forms ProjectWhen you create a Windows Forms application in Visual Studio, you get a blank form and some background code. The starting class code will look like the following: using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

namespace MyFirstSoftphone

{

public partial class Softphone : Form

{

public Softphone()

1.

Page 2: A Step by Step Guide for Building an Ozeki VoIP SIP Softphone€¦ · Ozeki Informatics Ltd. Ozeki VoIP Training Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

Ozeki Informatics Ltd. Ozeki VoIP Training

Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

{

InitializeComponent();

}

}

}

This is your main class that will contain the basic softphone functionality. If you want to get all the support Ozeki VoIP SIP SDK provides for implementing VoIP solutions, you need to register your SDK to the project. If you do not know how you can perform this, please check Ozeki VoIP Training Lesson 2.

Getting StartedIf you want to use the Ozeki VoIP SIP SDK provided tools without namespace labeling, you will need to add some precompilation directives to the using section of your class: using Ozeki.Media;

using Ozeki.Media.MediaHandlers;

using Ozeki.Network.Nat;

using Ozeki.VoIP;

using Ozeki.VoIP.Media;

using Ozeki.VoIP.SDK;

using Ozeki.Common;

These instruction will make sure that you can use all the tools needed in this simple softphone application like they were in the same namespace as your project. Now you will need to create the Graphical User Interface for your softphone. This needs some mouse work as well as some intuition. A basic Softphone GUI looks similar to the one shown in Figure 1.

2.

Page 3: A Step by Step Guide for Building an Ozeki VoIP SIP Softphone€¦ · Ozeki Informatics Ltd. Ozeki VoIP Training Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

Ozeki Informatics Ltd. Ozeki VoIP Training

Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

Figure 1 - A basic softphone GUI This GUI basically contains two panels, one for the telephone display that will show some information and the other for the keypad that contains the numeric keys, the * and # keys and two function keys for picking up and hanging up the phone. You will need 4 labels on the display: RegistrationState, ConnectionState, Username and DialedNumber. If you want to make a bit more sophisticated application, you can have some settings put onto your GUI too. In case of this example, the PBX settings are also on the GUI like it can be seen in Figure 2. This solution seems to be a bit advanced but it solves lot of your problems that can occur if you write your PBX settings directly in your code.

3.

Page 4: A Step by Step Guide for Building an Ozeki VoIP SIP Softphone€¦ · Ozeki Informatics Ltd. Ozeki VoIP Training Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

Ozeki Informatics Ltd. Ozeki VoIP Training

Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

Figure 2 - Softphone GUI with PBX registration data settings The PBX registration data is gained from the GUI elements on the “PBX registration data” groupbox. A PBX registration needs some basic information about the PBX itself, like the IP address and the listening port number of the PBX. These can be set in textboxes those values needs to be validated before the actual registration process starts. The labels indicate the purposes of the textboxes that are next to them. You can also specify if the registration is needed. For this purpose the simplest solution is to use a checkbox element. At the registration phase the SIP account is needed to set, this means you need to provide space to set the user name, the registration name, the registration password and the name to be displayed on the GUI. For this purpose you can also use labels and textboxes. The registration process will start when the user presses the OK button. If the format of the IP address or the port number is not valid, the user will get a notification about it in a message box and they can set the right data. Once the registration succeeded, the softphone is ready to make calls.

Setting Registration Data for the PBXThe basic data for the PBX registration needs to be stored, therefore you will need some variables that will be used for this purpose:

4.

Page 5: A Step by Step Guide for Building an Ozeki VoIP SIP Softphone€¦ · Ozeki Informatics Ltd. Ozeki VoIP Training Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

Ozeki Informatics Ltd. Ozeki VoIP Training

Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

public bool IsRegRequired = false;

public String displayname;

public String username;

public String registername;

public String regpass;

public String domainhost;

public int port;

public NatTraversalMethod natTraversal = 0;

These variables will get their values when the OK button is pressed. This functionality is implemented in the default event handler of the OK button. private void OKButton_Click(object sender, EventArgs e)

{

displayname = DisplayNameTB.Text;

username = UserNameTB.Text;

registername = RegNameTB.Text;

regpass = RegPwdTB.Text;

try

{

int i;

i = Int32.Parse(IP1.Text);

if (! (i >= 0 && i <=255))

throw new Exception();

i = Int32.Parse(IP2.Text);

if (! (i >= 0 && i <=255))

throw new Exception();

i = Int32.Parse(IP3.Text);

if (! (i >= 0 && i <=255))

throw new Exception();

i = Int32.Parse(IP4.Text);

if (! (i >= 0 && i <=255))

throw new Exception();

}

catch (Exception ex)

{

MessageBox.Show(String.Format("The IP address you set

is invalid, please set a valid IP address.\n {0}", ex.Message),

string.Empty, MessageBoxButtons.OK,

MessageBoxIcon.Error);

}

domainhost = IP1.Text + "." + IP2.Text + "." + IP3.Text + "." +

IP4.Text;

try

{

port = Int32.Parse(PortNo.Text);

5.

Page 6: A Step by Step Guide for Building an Ozeki VoIP SIP Softphone€¦ · Ozeki Informatics Ltd. Ozeki VoIP Training Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

Ozeki Informatics Ltd. Ozeki VoIP Training

Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

}

catch (Exception ex)

{

MessageBox.Show(String.Format("The port number you set

is invalid, please set a valid port number.\n {0}", ex.Message),

string.Empty, MessageBoxButtons.OK,

MessageBoxIcon.Error);

}

switch (NAT.SelectedIndex)

{

case -1:

case 0:

natTraversal = NatTraversalMethod.None;

break;

case 1:

natTraversal = NatTraversalMethod.STUN;

break;

case 2:

natTraversal = NatTraversalMethod.TURN;

break;

}

InitializeSoftPhone();

}

Implementing the Softphone FunctionalityAfter having all the PBX registration information, you can start implementing the softphone itself. For the softphone functions, there will be some other variables that need to be declared: ISoftPhone softPhone;

IPhoneLine phoneLine;

PhoneLineState phoneLineInformation;

IPhoneCall call;

Microphone microphone = Microphone.GetDefaultDevice();

Speaker speaker = Speaker.GetDefaultDevice();

MediaConnector connector = new MediaConnector();

PhoneCallAudioSender mediaSender = new PhoneCallAudioSender();

PhoneCallAudioReceiver mediaReceiver = new PhoneCallAudioReceiver();

bool inComingCall;

These tools are essential for the VoIP communication. Now, you will need to write the InitializeSoftPhone method that performs the actual PBX registration.

6.

Page 7: A Step by Step Guide for Building an Ozeki VoIP SIP Softphone€¦ · Ozeki Informatics Ltd. Ozeki VoIP Training Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

Ozeki Informatics Ltd. Ozeki VoIP Training

Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

private void InitializeSoftPhone()

{

try

{ softPhone =

SoftPhoneFactory.CreateSoftPhone(SoftPhoneFactory.GetLocalIP(), 5700,

5750, 5700); softPhone.IncomingCall += new

EventHandler<VoIPEventArgs<IPhoneCall>>(softPhone_IncomingCall);

SIPAccount sa = new SIPAccount(IsRegRequired,

displayname, username, registername, regpass, domainhost, port); NatConfiguration nc = new NatConfiguration(natTraversal);

phoneLine = softPhone.CreatePhoneLine(sa, nc); phoneLine.PhoneLineStateChanged += new

EventHandler<VoIPEventArgs<PhoneLineState>>(phoneLine_PhoneLineInform

ation);

softPhone.RegisterPhoneLine(phoneLine);

DialedNumber.Text = string.Empty;

}

catch (Exception ex)

{

MessageBox.Show(String.Format("You didn't set the

right IP address. Please set your IP address and try again.\n {0}",

ex.Message), string.Empty, MessageBoxButtons.OK,

MessageBoxIcon.Error);

}

}

This method actually creates a softphone object and registers it to the specified PBX with the SIP account you have set on the GUI. There is two event handler subscription in this method. The softphone is subscribed for the IncomingCall event and the phone line is subscribed for the PhoneLineInformation event. The event handler methods for these has to be implemented too. The registration needed checkbox also needs an event handler the notifies the softphone if it was checked: private void checkBox1_CheckedChanged(object sender, EventArgs e)

{

IsRegRequired = !IsRegRequired;

}

Before you implement the event handler methods, you will need a simple method for thread invocation:

7.

Page 8: A Step by Step Guide for Building an Ozeki VoIP SIP Softphone€¦ · Ozeki Informatics Ltd. Ozeki VoIP Training Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

Ozeki Informatics Ltd. Ozeki VoIP Training

Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

private void InvokeGUIThread(Action action)

{

Invoke(action);

}

This method will be used in some of the following methods that need to be implemented. Now you can write the event handler methods mentioned before. The PhoneLineInformation method is mainly for notification purposes, it sets the username, the connection state and the registration state labels on the GUI according to the PBX registration. private void phoneLine_PhoneLineInformation(object sender,

VoIPEventArgs<PhoneLineState> e)

{

phoneLineInformation = e.Item;

InvokeGUIThread(() =>

{ Username.Text = ((IPhoneLine)sender).SIPAccount.RegisterName;

if (e.Item == PhoneLineState.RegistrationSucceeded)

{

ConnectionState.Text = "Online";

RegistrationState.Text = "Registration succeeded";

}

else

RegistrationState.Text = e.Item.ToString();

});

}

The IncomingCall event notifies the softphone about an incoming call request. When there is an incoming call, the GUI needs to show the information about the caller as in case of a traditional telephone that has a display. private void softPhone_IncomingCall(object sender,

VoIPEventArgs<IPhoneCall> e)

{

InvokeGUIThread(() =>

{

RegistrationState.Text = "Incoming call";

DialedNumber.Text = String.Format("from {0}",

e.Item.DialInfo);

call = e.Item;

WireUpCallEvents();

inComingCall = true;

});

8.

Page 9: A Step by Step Guide for Building an Ozeki VoIP SIP Softphone€¦ · Ozeki Informatics Ltd. Ozeki VoIP Training Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

Ozeki Informatics Ltd. Ozeki VoIP Training

Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

}

The WireUpCallEvents method is a simple one that subscribes the call for the possible events. It has a sibling that unsubscribes the call from these events. private void WireUpCallEvents()

{ call.CallStateChanged += new

EventHandler<VoIPEventArgs<CallState>>(call_CallStateChanged); call.CallErrorOccured += new

EventHandler<VoIPEventArgs<CallError>>(call_CallErrorOccured);

}

private void WireDownCallEvents()

{

if (call != null)

{

call.CallStateChanged -= (call_CallStateChanged); ;

call.CallErrorOccured -= (call_CallErrorOccured);

}

}

These methods operate with the events of the call. The event handler methods for these events also need to be written in your program. The CallErrorOccured method is one of the simplest ones in this class. It only notifies the user about that some error occurred during the call. This purpose is simply done by writing the error message onto the GUI by changing the registration state label. private void call_CallErrorOccured(object sender,

VoIPEventArgs<CallError> e)

{

InvokeGUIThread(() =>

{

RegistrationState.Text = e.Item.ToString();

);

}

The CallStateChange is probably the most important method in case of a VoIP communication application. This will perform the actual work according to the actual call state. Foe example, in case of an established call it starts the audio input and output devices and connects the properAudioHandlers to the devices. private void call_CallStateChanged(object sender,

VoIPEventArgs<CallState> e)

9.

Page 10: A Step by Step Guide for Building an Ozeki VoIP SIP Softphone€¦ · Ozeki Informatics Ltd. Ozeki VoIP Training Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

Ozeki Informatics Ltd. Ozeki VoIP Training

Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

{ InvokeGUIThread(() => { RegistrationState.Text = e.Item.ToString(); }

);

switch (e.Item)

{

case CallState.InCall:

microphone.Start();

connector.Connect(microphone, mediaSender);

speaker.Start();

connector.Connect(mediaReceiver, speaker);

mediaSender.AttachToCall(call);

mediaReceiver.AttachToCall(call);

break;

case CallState.Completed:

microphone.Stop();

connector.Disconnect(microphone, mediaSender);

speaker.Stop();

connector.Disconnect(mediaReceiver, speaker);

mediaSender.Detach();

mediaReceiver.Detach();

WireDownCallEvents();

call = null;

InvokeGUIThread(() => { DialedNumber.Text = string.Empty; });

break;

case CallState.Cancelled:

WireDownCallEvents();

call = null;

break;

}

}

At this point all of the softphone functions are implemented. Now it is time to make the softphone keypad work properly by writing some event handler methods. The Pick Up button has double functionality. In case of an incoming call you can accept the call by pressing the Pick Up button, but the Pick Up button can also be used for starting an outgoing call. In this case the softphone will try to dial the number that is set on the GUI (DialedNumber panel). private void PickUp_Click(object sender, EventArgs e)

10.

Page 11: A Step by Step Guide for Building an Ozeki VoIP SIP Softphone€¦ · Ozeki Informatics Ltd. Ozeki VoIP Training Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

Ozeki Informatics Ltd. Ozeki VoIP Training

Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

{

if (inComingCall)

{

inComingCall = false;

call.Accept();

return;

}

if (call != null)

return;

if (string.IsNullOrEmpty(DialedNumber.Text))

return;

if (phoneLineInformation != PhoneLineState.RegistrationSucceeded &&

phoneLineInformation != PhoneLineState.NoRegNeeded)

{

MessageBox.Show("Phone line state is not valid!");

return;

}

call = softPhone.CreateCallObject(phoneLine, DialedNumber.Text);

WireUpCallEvents();

call.Start();

}

If there is no number set to dial and there is no incoming call, pressing the Pick Up button will do nothing at all. The Hang Up button also has double functionality. In case of an existing call, pressing the Hang Up button will end the call while in case of an incoming call, you can reject the call with it. private void HangUp_Click(object sender, EventArgs e)

{

if (call != null)

{ if (inComingCall && call.CallState == CallState.Ringing)

call.Reject();

else

call.HangUp();

inComingCall = false;

call = null;

}

DialedNumber.Text = string.Empty;

}

There is only one essential method left to implement that is the one for the numeric keypad

11.

Page 12: A Step by Step Guide for Building an Ozeki VoIP SIP Softphone€¦ · Ozeki Informatics Ltd. Ozeki VoIP Training Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

Ozeki Informatics Ltd. Ozeki VoIP Training

Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

buttons. These buttons’ click events can be handled with the same method, therefore you will not need to write 12 event handler. You can easily attach the following method to every numeric keypad button’s click event. private void KeyPadButton_Click(object sender, EventArgs e)

{

var btn = sender as Button;

if (btn != null)

{

if (btn.Text == "0/+")

{

DialedNumber.Text += "0";

}

else

DialedNumber.Text += btn.Text.Trim();

}

}

To attach the same event handler to more than one buttons, you will need to use the Properties panel on the Design view of your softphone application like it can be seen in Figure 3.

Figure 3 - You can set one event handler method to more GUI elements If you have registered the KeyPadButton_Click method to every numeric keypad button and to the * and # buttons, your softphone solution is finally ready to work. You can run the program, set the PBX registration data and use your brand new softphone.

12.

Page 13: A Step by Step Guide for Building an Ozeki VoIP SIP Softphone€¦ · Ozeki Informatics Ltd. Ozeki VoIP Training Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

Ozeki Informatics Ltd. Ozeki VoIP Training

Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

SummaryThis course material introduced all the necessary tools and methods that need to be implemented for a softphone application. The example program can be downloaded from the Ozeki VoIP SIP SDK website or you can copy and paste the code snippets into your Visual Studio Project. Do not forget to attach the event handlers with the proper GUI elements. Please answer the knowledge check questions foe making sure you have understood this lesson.

Knowledge Check Questions1. What are the basic data needed for a PBX registration?2. What are the basic events for a call?3. What purposes a Hang Up button is used for?4. How can you attach an event handler method to more than one buttons?

13.

Page 14: A Step by Step Guide for Building an Ozeki VoIP SIP Softphone€¦ · Ozeki Informatics Ltd. Ozeki VoIP Training Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

Ozeki Informatics Ltd. Ozeki VoIP Training

Lesson 3 - A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

Correct Answers for Knowledge Check Questions1. For the PBX registartion you will need a SIP account (display name, user name,

registration name, registration password) and the IP address and listening port number of the PBX. The NAT traversal policy can also be set to be able to make calls through firewalls.

2.The two most essential events for a call is the CallErrorOccured and the CallStateChanged. The call always needs to be subscribed for these.

3. A Hang Up button can be used for ending or rejecting a call according to the actual call state. If there is an existing call, the Hang Up button will end it, in case of an incoming call, you can reject it with pressing the Hang Up button.

4. You can use the Properties window for attaching an event handler to any GUI elements. You choose the lightning icon that indicates the Events tab, choose the event you want to handle and choose the proper event handler method from the list that appears.

14.