High performance VoIP SDK for .Net developers

VoIP SIP SDK

How to manage multiple phone lines at the same time

Explanation

Prerequisities

Download: MultiplePhoneLines.zip

This article is a detailed guide about how to manage multiple phone lines when you use Ozeki VoIP SIP SDK. After reading through this page you will be fully familiar with all the essential terms concerning multiple phone lines and what you will need for creating your own solution using Ozeki VoIP SIP SDK.

Introduction

Advanced VoIP communication has to include the support of multiple phone lines. It means that a company can be called by more than one clients at the same time and the calls are dedicated to more than one phone line (Figure 1).

Using multiple phone lines does not necessarily means that the company has more than one public phone number but they can use a dispatcher point where the incoming calls are transferred to separate phone lines. This support is essential when you need to implement a call center where the customers can contact more than one company employees at the same time.


Figure 1 - Multiple phone lines

The following program code uses the background support of Ozeki VoIP SIP SDK, therefore you will need to download and install the SDK on your computer before starting to use the program code. You will also need to have Visual Studio 2010 or compatible IDE and .NET Framework installed on your system, as the program code below is written in C# language.

The phone line is directly connected to the SIP account you register to the PBX system. You can register more SIP accounts in your PBX and change them during the softphone runtime. In this case you can choose which line you wish to use for phone calls.

This example program handles two SIP accounts, therefore two phone lines can be used in it. You can register and unregister the lines and change between them with the "Line 1" and "Line 2" buttons on the GUI (Figure 2).


Figure 2 - A softphone example with multiple line support

The example project contains two classes. A PhoneLineInfo class that stores the SIP account information that is needed for the registration. As this example program only handles two lines, two PhoneLineInfo objects are stored as properties in the main Softphone class of the project.

The PhoneLineInfo class' constructor only sets the info properties that cannot be modified after the setting (Code 1).

public PhoneLineInfo(
            string displayName,
            string userName,
            string registerName,
            string password,
            string domain,
            int port,
            bool regReq,
           NatTraversalMethod traversal)
        {
            this.displayname= displayName;
            this.username = userName;
            this.registername = registerName;
            this.regpass = password;
            this.domainhost = domain;
            this.port = port;
            this.IsRegRequired = regReq;
            this.natTraversal = traversal;
        }

Code 1 - The constructor of the PhoneLineInfo class

The softphone function is similar in this example to the basic softphones, but there are some differences. The Softphone class stores the two registered phone line objects in phoneLine1 and phoneLine2 properties and the actually selected line in the actualPhoneLine object (Code 2). This is important as the call will always be made with the actually selected line.

IPhoneLine actualPhoneLine;
IPhoneLine phoneLine1;
IPhoneLine phoneLine2;

Code 2 - The phone line objects

Pressing the Register button will register a new phone line to the PBX with the information that is set in the form on the GUI. The event handler for this purpose can be seen in Code 3.

As the program can only handle two lines at the same time, if the number of lines exceeds two, it will pop up a message box about the fact that you cannot register more lines.

The registration data can be read from the textboxes of the registration form, the actual registration is made. The program tries to register the SIP account in the first available object. This can be the phoneLine1 or phoneLine 2 as well. You can any time unregister any of the phone lines by pressing the Unregister button. You can see which line is selected on the GUI as the username label below the line button is red for the selected line.

if (numberOfLines == 2)
            {
                MessageBox.Show("You cannot register more phone lines!", "Phone Line Number Limit Exceeded", MessageBoxButtons.OK,
            MessageBoxIcon.Information);
                return;
            }
            numberOfLines++;
            displayname = DisplayNameTB.Text;
            username = UserNameTB.Text;
            registername = RegNameTB.Text;
            regpass = RegPwdTB.Text;

            domainhost = string.Empty;
            domainhost = IPTB.Text;
            try
            {
                port = Int32.Parse(PortNo.Text);
            }
            catch (Exception ex)
            {

               ...
            }
            switch (NAT.SelectedIndex)
            {
                case -1:
                case 0:
                    natTraversal = NatTraversalMethod.None;
                    break;
                case 1:
                    natTraversal = NatTraversalMethod.STUN;
                    break;
                case 2:
                    natTraversal = NatTraversalMethod.TURN;
                    break;
            }
            IsRegRequired = checkBox1.Checked;

            if (line1 == null)
            {
                line1 = new PhoneLineInfo(displayname, username, registername, regpass, domainhost, port, IsRegRequired, natTraversal);
                Line1Button.Enabled = true;
                Line1Label.Text = username;

                registerPhoneLine(line1, 1);
                Line1Button.PerformClick();
            }
            else
            {
                line2 = new PhoneLineInfo(displayname, username, registername, regpass, domainhost, port, IsRegRequired, natTraversal);
                Line2Button.Enabled = true;
                Line2Label.Text = username;

                registerPhoneLine(line2, 2);
                Line2Button.PerformClick();
            }

Code 3 - The event handler method for the register button press

The actual registration process is made in the registerPhoneLine method (Code 4) that is parameterized by the phone line info and the number of the line to be registered. This specifies the program which phone line object is needed to be registered with the given data.

At the first time the softphone object needs to be initialized. This is exactly the same process as in case of any softphones. Then the registration is made according to the actual parameters.

if (softPhone == null)
                InitializeSoftPhone();
try
{
   SIPAccount sa = new SIPAccount(info.IsRegRequired, info.displayname, info.username, info.registername, info.regpass, info.domainhost, info.port);
   NatConfiguration nc = new NatConfiguration(info.natTraversal);
   if (num == 1)
   {

            phoneLine1 = softPhone.CreatePhoneLine(sa, nc);
            phoneLine1.PhoneLineStateChanged += new EventHandler<VoIPEventArgs<PhoneLineState>>(phoneLine_PhoneLineInformation);
            softPhone.RegisterPhoneLine(phoneLine1);
   }
   else
   {
            phoneLine2 = softPhone.CreatePhoneLine(sa, nc);
            phoneLine2.PhoneLineStateChanged += new EventHandler<VoIPEventArgs<PhoneLineState>>(phoneLine_PhoneLineInformation);
            softPhone.RegisterPhoneLine(phoneLine2);
   }
   DialedNumber.Text = string.Empty;

}
catch (Exception ex)
{
...

Code 4 - The method for phone line registration

In the registration process, the program performs a press event for the button of registered line. This will set the labels and textboxes on the GUI and the value of the actually selected phone line. Code 5 shows the event handler for the "Line 1" button. The "Line 2" button has a very similar event handler method.

if (line1 == null)
        return;
Username.Text = line1.username;
Line1Label.ForeColor = Color.Red;
Line2Label.ForeColor = Color.Black;
selectedLine = 1;
checkBox1.Checked = line1.IsRegRequired;
DisplayNameTB.Text = line1.displayname;
UserNameTB.Text = line1.username;
RegNameTB.Text = line1.registername;
RegPwdTB.Text = line1.regpass;
IPTB.Text = line1.domainhost;
PortNo.Text = line1.port.ToString();
switch (line1.natTraversal)
{
case NatTraversalMethod.None:
    NAT.SelectedIndex = 0;
    break;
case NatTraversalMethod.STUN:
    NAT.SelectedIndex = 1;
    break;
case NatTraversalMethod.TURN:
    NAT.SelectedIndex = 2;
    break;
}
actualPhoneLine = phoneLine1;

Code 5 - You can change the actually selected line by pressing one of the Line buttons

Setting the actualLine object is important as the calls will be made with this object like it can be seen in Code 6.

...
call = softPhone.CreateCallObject(actualPhoneLine, DialedNumber.Text);
WireUpCallEvents();
call.Start();
...

Code 6 - Making a call with the selected phone line

You can not only register, but unregister a selected phone line from the softphone. In this case you need to select the line to be unregistered by pressing the proper line button; the label below the button will turn to red. Then you need to press the unregister button and the line will be unregistered (Code 7).

private void UnregisterButton_Click(object sender, EventArgs e)
{
    if (selectedLine == 0)
        return;
    if (selectedLine == 1)
        unRegisterLine1();
    else
        unRegisterLine2();
}

Code 7 - Pressing the Unregister button will invoke this method

The actual unregistering process is made in two separate methods, one for each line. Code 8 shows the unregister method for the first line, the other is very similar to this one.

When you unregister the first line, the program tries to select an other one in case it is possible. This is done by performing a press event on the second line's button. This will fill the registration form with the line2 information and set the actual line to the phoneLine2 object. If there is no other registered line, the form will be set to empty and you will need to register a new line if you want to use the softphone for calls.

As for the unregistration, the line is unregistered from the softphone and both the line and the line info objects are set to null. The number of registered lines also reduces by one.

if (line1 == null)
        return;
Line1Label.Text = string.Empty;
Line1Button.Enabled = false;
numberOfLines--;
if (numberOfLines == 0)
Username.Text = "Username";
if (line2 != null)
   Line2Button.PerformClick();
else
{
        checkBox1.Checked = true;
        DisplayNameTB.Text = string.Empty;
        UserNameTB.Text = string.Empty;
        RegNameTB.Text = string.Empty;
        RegPwdTB.Text = string.Empty;
        IPTB.Text = string.Empty;
        PortNo.Text = "5060";
        NAT.SelectedIndex = -1;
}
softPhone.UnregisterPhoneLine(phoneLine1);
line1 = null;
phoneLine1 = null;

Code 8 - Unregistering the first line

The other methods in the example program are not explained in this article as they are exactly the same as in the case of any other softphone application. If you are not familiar with them, please check How to develop a softphone with Ozeki SIP SDK.

This article explains how you can manage multiple phone lines with the outstanding Ozeki VoIP SIP SDK. It can help you to fulfill your goals regarding this topic.

If you have any questions or need assistance, please contact us at info@voip-sip-sdk.com

You can select a suitable Ozeki VoIP SIP SDK license for multiple line management on Pricing and licensing information page

Related Pages

Operating system: Windows 8, Windows 7, Vista, 200x, XP
Development environment: Visual Studio 2010 (Recommended), Visual Studio 2008, Visual Studio 2005
Programming language: C#.NET
Supported .NET framework: .NET Framework 4.5, .NET Framework 4.0, .NET Framework 3.5 SP1
Software development kit: OZEKI VoIP SIP SDK (Download)
VoIP connection: 1 SIP account
System memory: 512 MB+
Free disk space: 100 MB+