Tuesday, April 28, 2015

How to create a basic SIP softphone application in C#

Hi all, 

In this post I am going to introduce how to implement the basic softphone functionality. I will show how to create a console application that functions as a SIP softphone. It will be able to register to a phone system. (In the first tutorials I will focus on the background behaviour of the program, I will implement the GUI elements later.) 

Are you ready? Okay, let's get it started!



Prologue:


Although this softphone can not be used for making and receiving calls, but the SIP registration presented below is probably the most important part of the softphone development. Namely, to be able to make VoIP phone calls, the softphone should be connected to a PBX.

For this purpose, I used the freely available Asterisk phone system. After implementing the necessary functions, it will enable free internal VoIP telephony and it will make it possible to initiate external phone calls as well after connecting to a VoIP service provider. Considering that Asterisk is Linux-based, I installed it on my Raspberry Pi. If you do not want to use IoT (Internet of Things) devices, you can install it on a Linux-based computer of course, or you can use a Windows-based PBX (e.g. 3CX).

Prerequisites:




The following figure shows that I used the VoIP SDK dll provided by Ozeki along with Microsoft Visual Studio 2012 to accomplish my Great C# Softphone Project. It provides the necessary VoIP tools for the softphone development. (It requires at least .NET Framework 4.0 SP1 installed on your PC.)

The figure also shows that my project consists of the one class: this is the Program.cs.


C# source code for SIP softphone registration:


Okay, let's start the development by creating a new console application in the Visual Studio! First of all, I show you the whole source code, thereafter I will introduce it block-by-block. Feel free to copy and paste this source code into your Visual Studio:

using System;
using Ozeki.VoIP;
using Ozeki.VoIP.SDK;

namespace SIP_Register
{
    class Program
    {
        private static ISoftPhone softphone;
        private static IPhoneLine phoneLine;

        private static void Main(string[] args)
        {
            softphone = SoftPhoneFactory.CreateSoftPhone(5000, 10000);

            var registrationRequired = true;
            var userName = "995";
            var displayName = "995";
            var authenticationId = "995";
            var registerPassword = "995";
            var domainHost = "192.168.115.100";
            var domainPort = 5060;

            var account = new SIPAccount(registrationRequired, displayName, userName, authenticationId, registerPassword, domainHost, domainPort);

            RegisterAccount(account);

            Console.ReadLine();
        }

        static void RegisterAccount(SIPAccount account)
        {
            try
            {
                phoneLine = softphone.CreatePhoneLine(account);
                phoneLine.RegistrationStateChanged += sipAccount_RegStateChanged;
                softphone.RegisterPhoneLine(phoneLine);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error during SIP registration: " + ex);
            }
        }

        static void sipAccount_RegStateChanged(object sender, RegistrationStateChangedArgs e)
        {
            if (e.State == RegState.Error || e.State == RegState.NotRegistered)
                Console.WriteLine("Registration failed!");

            if (e.State == RegState.RegistrationSucceeded)
                Console.WriteLine("Registration succeeded - Online!");
        }
    }
}

Detailed explanation:


First of all, insert the necessary using lines:

using System;
using Ozeki.VoIP;
using Ozeki.VoIP.SDK;


Thereafter, you need to create the necessary objects (softPhone, phoneLine):

private static ISoftPhone softphone;
private static IPhoneLine phoneLine;


And the most exciting part is the following. To be able to register your softphone to your phone system, you need to assign a SIP account to your application. The following code snippet presents the Main() method that is used to registers this SIP account to the PBX. First, create a softphone object (5000-10000 refers to the RTP port range.). After this you need to set the following parameters:

  • Set the registrationRequired variable to "true"
  • Provide a username
  • Enter a display name
  • Give the authentication ID
  • Define the register password
  • Provide the IP address and the port number of your PBX

(Please note that it is necessary to create a new SIP account within your PBX as well by using the same SIP account details.)

At the end of the following code snippet you can see the RegisterAccount(account) that is used to send SIP registration request and the Console.ReadLine() prevents the termination of the application.

private static void Main(string[] args)
{
    softphone = SoftPhoneFactory.CreateSoftPhone(5000, 10000);

    var registrationRequired = true;
    var userName = "995";
    var displayName = "995";
    var authenticationId = "995";
    var registerPassword = "995";
    var domainHost = "192.168.115.100";
    var domainPort = 5060;

    var account = new SIPAccount(registrationRequired, displayName, userName, authenticationId, registerPassword, domainHost, domainPort);

    RegisterAccount(account);

    Console.ReadLine();
}


Below the RegisterAccount() method can be seen that is used to accomplish the registration procedure in the background.

static void RegisterAccount(SIPAccount account)
{
    try
    {
        phoneLine = softphone.CreatePhoneLine(account);
        phoneLine.RegistrationStateChanged += sipAccount_RegStateChanged;
        softphone.RegisterPhoneLine(phoneLine);
    }
    catch (Exception ex)
    {
        Console.WriteLine("Error during SIP registration: " + ex);
    }
}


By subscribing to the necessary events, you will be notified whether the SIP registration was successful or not. The corresponding code snippet can be seen below:

static void sipAccount_RegStateChanged(object sender, RegistrationStateChangedArgs e)
{
    if (e.State == RegState.Error || e.State == RegState.NotRegistered)
        Console.WriteLine("Registration failed!");

    if (e.State == RegState.RegistrationSucceeded)
        Console.WriteLine("Registration succeeded - Online!");
}


Summary


This post presented the first step of VoIP SIP softphone development. You could see step-by-step how to develop a console application in C# that functions as a virtual softphone. This softphone is able to register to a PBX.


In the next post I am going to present how to control the speakers and the microphone to be able to transmit your voice and listen to the other party. It is a very important step to be able to make VoIP phone calls. It's gonna be awesome! ;)

Please do not hesitate to leave a comment!



No comments:

Post a Comment