Thursday 30 May 2013

TAPI : A gateway to VOiP in .net

As I have promised earlier, here I'm going to present the VOiP enhancements in .net framework. To implement Voice and Video services you need to incorporate TAPI dll in your application. TAPI is Telephony Application Programming Interface and in this post I am quoting TAPI v3.0. Here is a C# program which will exemplify the procedure which needs to be followed while doing TAPI programming using TAPI 3.0. The program shows you how you can use the TAPI 3.0 functions to create a TAPI application of your own. Microsoft provides more than 100 functions as part of the TAPI library. TAPI 2.1 was more difficult to use as it was a set of API functions but TAPI 3.0 which comes as part of Windows 2000 has ActiveX controls that make the TAPI application creation much easier. The TAPI SDK that can be downloaded from the Microsoft site. Learning to use different TAPI functions require lot of time investment but once you create some applications using these TAPI functions, it becomes easier for you to use the TAPI functions more efficiently.

First of all develop a basic design with all necessary stuffs for our application.




Adding a Reference
The first thing you need to start working on TAPI 3.0 API is to add the references to your project. To do that first create a new project or open an existing project, then right click on the solution file in Solution Explorer. This will open "Add Reference" dialog box as below:



Then loacte the tapi3.dll by clicking on "Browse" and select the tapi3.dll file from your windows\system32 or windows\system directory and click OK. Then press OK in the preceeding dialog box.

Add Code To Your Program
Next you need to do is create the TAPI objects to initialize the TAPI 3.0 TSP (TAPI Service Providers - For documentation refer to MSDN). The code below is a declaration of the TAPI object and addresses the interfaces that will hold the addresses which are responsible for call handling, and basic call control interface which will hold the reference to the object that will be responsible for handling basic operations of the call.

private TAPIClass tapiObj;
private ITAddress[] ia=new TAPI3Lib.ITAddress[10];
private ITBasicCallControl bcc;

The code below is meant for initializing a TAPI object to use it with our application. The main functions are:
  • Initialize() will initialize TAPI.
  • EnumerateAddresses() will give the list of available TSPs.


void initializetapi3()
{
    try
    {
        tapiObj = new TAPIClass();
        tapiObj.Initialize();
        IEnumAddress ea=tapiObj.EnumerateAddresses();
        ITAddress ln;
        uint arg3=0;
        lines=0;
    
        cn=new callnotification();
        cn.addtolist=new callnotification.listshow(this.status);
        tapiObj.ITTAPIEventNotification_Event_Event+= new 
           TAPI3Lib.ITTAPIEventNotification_EventEventHandler(cn.Event);
        tapiObj.EventFilter=(int)(TAPI_EVENT.TE_CALLNOTIFICATION|
            TAPI_EVENT.TE_DIGITEVENT|
            TAPI_EVENT.TE_PHONEEVENT|
            TAPI_EVENT.TE_CALLSTATE|
            TAPI_EVENT.TE_GENERATEEVENT|
            TAPI_EVENT.TE_GATHERDIGITS|
            TAPI_EVENT.TE_REQUEST);
    
        for(int i=0;i<10;i++)
        {
            ea.Next(1,out ln,ref arg3);
            ia[i]=ln;
            if(ln!=null)
            {
                comboBox1.Items.Add(ia[i].AddressName);
                lines++;
            }
            else
                break;
        }
    }
    catch(Exception e)
    {
        MessageBox.Show(e.ToString());
    }
}

The code below is responsible for registering incoming calls so that these calls can be handled by the application. For that you need to select the line on which you want to receive calls and press the "Register" button.

try
{
    registertoken[line]=tapiObj.RegisterCallNotifications(ia[line],
                 true,true,TapiConstants.TAPIMEDIATYPE_AUDIO,2);    
    MessageBox.Show("Registration token : "+ 
                 registertoken[line], 
                 "Registration Succeed for line "+line);
}
catch(Exception ein)
{
    MessageBox.Show("Failed to register on line "+line,"Registration for calls");
}

The class given below is to be added depending upon your TAPI event handling requirements. This is specially designed according to the requirements of the application.

class callnotification:TAPI3Lib.ITTAPIEventNotification
{
    public delegate void listshow(string str);
    public listshow addtolist;
    
    public void Event(TAPI3Lib.TAPI_EVENT te,object eobj)
    {
        switch(te)
        {
            case TAPI3Lib.TAPI_EVENT.TE_CALLNOTIFICATION:
                addtolist("call notification event has occured");
                break;
            case TAPI3Lib.TAPI_EVENT.TE_DIGITEVENT:
                TAPI3Lib.ITDigitDetectionEvent dd = 
                   (TAPI3Lib.ITDigitDetectionEvent)eobj;
                addtolist("Dialed digit"+dd.ToString());
                break;
            case TAPI3Lib.TAPI_EVENT.TE_GENERATEEVENT:
                TAPI3Lib.ITDigitGenerationEvent dg = 
                     (TAPI3Lib.ITDigitGenerationEvent)eobj;
                MessageBox.Show("Digit dialed...!");
                addtolist("Dialed digit"+dg.ToString());
                break;
            case TAPI3Lib.TAPI_EVENT.TE_PHONEEVENT:
                addtolist("A phone event occured!");
                break;
            case TAPI3Lib.TAPI_EVENT.TE_GATHERDIGITS:
                addtolist("Gather digit event!");
                break;
            case TAPI3Lib.TAPI_EVENT.TE_CALLSTATE:
                TAPI3Lib.ITCallStateEvent a= 
                     (TAPI3Lib.ITCallStateEvent)eobj;
                TAPI3Lib.ITCallInfo b=a.Call;
            switch(b.CallState)
            {
                case TAPI3Lib.CALL_STATE.CS_INPROGRESS:
                    addtolist("Dialing...");
                    break;
                case TAPI3Lib.CALL_STATE.CS_CONNECTED:
                    addtolist("Connected");
                    break;
                case TAPI3Lib.CALL_STATE.CS_DISCONNECTED:
                    addtolist("Disconnected");
                    break;
                case TAPI3Lib.CALL_STATE.CS_OFFERING:
                    addtolist("Here's a call for you!");
                    break;
                case TAPI3Lib.CALL_STATE.CS_IDLE:
                    addtolist("Call is made!");
                    break;
            }
            break;
        }
    }
}

How to handle IP calls or "Technically" H.323 calls?
To do IP calls or H.323 calls, I have given a checkbox named IP call enabled. Enter the IP address of the destination and press the Call button. Otherwise it will not succeed in calling to the remote destination. To receive H.323 calls or IP calls, you need to first register on the line on which you want to receive IP calls and check the above mentioned checkbox.

Transferring a call
To transfer a call, first there should be one active call existing. Then you can specify the address to which the call is to be transferred to, as shown in the figure:




Here IP of the machine has been given since the call was an IP call. To provide this functionality, there is a function in IBasicCallControl named BlindTransfer(String TransferAddress).

My next post would be about developing a complete PHONE DIALER by using this API. So keep checking for updates or subscribe for RSS feeds.

Hope to have feedback from all the readers. :)...enjoy coding...