How to send a Contact ID alert in C#

This article is a detailed guide on how to send a Contact ID alert using Ozeki VoIP SIP SDK. After studying the code example below, you will be able to send out any alarm or notification towards the Central Station through your VoIP network from your own C# application.

To use this example, you need to have Ozeki VoIP SIP SDK installed, and a reference to ozeki.dll should be added to your visual studio project. It is also recommended to visit the How to register to a SIP PBX and How to make a SIP voice call using C#? articles before studying this functionality.

What is the Contact ID? When is it needed?

In order to implement any alarm functionality, there is a need for a protocol that enables communication between the alarm systems and the Central Station. The Ademco Contact ID protocol is the most popular one of them.

Before getting to know the Contact ID sender functionality, it is worth to study the tutorial that describes how to receive a Contact ID alert in C#. You can find a detailed guide about the Contact ID protocol at the Contact ID protocol page. Its official documentation can be also found here: Contact ID standards.

The communication process is shown below:

the communication process of contact id protocol
Figure 1 - The communication process of Contact ID protocol

As it can be seen on Figure 2, you can send alarms through a VoIP call by using the following C# example. In this case, this example program operates as an alarm system.

the process of sending a contact id alert in c
Figure 2 - The process of sending a Contact ID alert in C#

How to implement a Contact ID alarm sender in C#?

If you do not use a codec applying lossless compression, the DTMF frequencies may be distorted during the communication with the Contact ID protocol. Therefore, you need to use PCMA or PCMU codecs. You can learn more about this in lines 28-32.

To implement the sender side it is required to be able to make a call. For more information about this, please study how to make a SIP voice call. The sender side implementation is almost the same that is discussed in case of the receiver side (How to receive a Contact ID alert in C#), since both of the sides need to play the role of the sender and receiver as well.

As in case of the receiver, here it is also needed to create a ContactIdHandler type object that needs to subscribe to the ContactIdSendFailed and ContactIdSendSuccessful events.

  • When the ContactIdSendFailed event occurs, it means that the sending of the alarm (that is, the contact ID) is failed. For instance, the kissoff signal is not received.
  • When the ContactIdSendSuccessful event occurs, it means that the sending of the alarm has been successful.

In this example program, the call will be finished and the current call state will be printed in both of the previous cases.

Similarly to the receiver side, the contactIdHandler object should be connected to the phoneCallAudioSender and phoneCallAudioReceiver objects with the help of the mediaConnector when the call is established. After this you need to call the Start() method.

When the call is finished, you need to disconnect the established connections, and stop the contactIdHandler by calling the Stop() method.

A Contact ID alarm sender example in C#

using System;
using Ozeki.Media;
using Ozeki.VoIP;

namespace ContactIdSender
{
    class Program
    {
        static ISoftPhone softphone;   // softphone object
        static IPhoneLine phoneLine;   // phoneline object
        static IPhoneCall call;  // call object

        static PhoneCallAudioSender phoneCallAudioSender;
        static PhoneCallAudioReceiver phoneCallAudioReceiver;

        static MediaConnector mediaConnector;
        static ContactIdHandler contactIdHandler; // Contact ID Handler object

        private static void Main(string[] args)
        {
            // Create a softphone object with RTP port range 5000-10000
            softphone = SoftPhoneFactory.CreateSoftPhone(5000, 10000);

            foreach (var s in softphone.Codecs)
            {
                softphone.DisableCodec(s.PayloadType);
            }
            softphone.EnableCodec(8); //only PCMA codec enabled

            // SIP account registration data, (supplied by your VoIP service provider)
            var registrationRequired = true;
            var userName = "sipusername"; //1000
            var displayName = "sipdisplayname"; //1000
            var authenticationId = "authenticationid"; //1000
            var registerPassword = "Password"; //1000
            var domainHost = "pbxip.voipprovider.com";
            var domainPort = 5060;
            
            var account = new SIPAccount(registrationRequired, displayName, userName, authenticationId, registerPassword, domainHost, domainPort);

            // Send SIP regitration request
            RegisterAccount(account);

            mediaConnector = new MediaConnector();
            phoneCallAudioSender = new PhoneCallAudioSender();
            phoneCallAudioReceiver = new PhoneCallAudioReceiver();
            contactIdHandler = new ContactIdHandler();

            contactIdHandler.SendNotification(1506, ContactIdEventQualifier.NewEvent, 110, 1, 22); // send the Contact ID alarm notification

            contactIdHandler.ContactIdSendSuccessful += contactIdHandler_ContactIdSendSuccessfull;
            contactIdHandler.ContactIdSendFailed += contactIdHandler_ContactIdSendFailed;

            // Prevents the termination of the application
            Console.ReadLine();
        }

        static void contactIdHandler_ContactIdSendFailed(object sender, EventArgs e)
        {
            call.HangUp();
            Console.WriteLine("Failed!");
        }

        static void contactIdHandler_ContactIdSendSuccessfull(object sender, EventArgs e)
        {
            call.HangUp();
            Console.WriteLine("Success!");
        }

        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);
            }
        }

        private 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!");
                CreateCall();
            }
        }

        static void CreateCall()
        {
            var numberToDial = "1001";
            call = softphone.CreateCallObject(phoneLine, numberToDial);
            call.CallStateChanged += call_CallStateChanged;
            call.Start();   // SIP INVITE request is being sent
        }

        static void call_CallStateChanged(object sender, CallStateChangedArgs e)
        {
            Console.WriteLine("Call state: {0}.", e.State);

            if (e.State == CallState.Answered)
                SetupDevices(); // set up the devices by calling the proper method

            if (e.State == CallState.Completed)
                StopDevices(); // detach and disconnect the devices by calling the proper method
        }

        static void SetupDevices()
        {
            // attach the phoneCallAudioSender and the phoneCallAudioReceiver to the call
            phoneCallAudioReceiver.AttachToCall(call);
            phoneCallAudioSender.AttachToCall(call);

            mediaConnector.Connect(contactIdHandler, phoneCallAudioSender); // connect the contactIdHandler to the phoneCallAudioSender object
            mediaConnector.Connect(phoneCallAudioReceiver, contactIdHandler); // connect the phoneCallAudioReceiver to the contactIdHandler object

            contactIdHandler.Start(); // start the contactIdHandler
        }

        static void StopDevices()
        {
            phoneCallAudioReceiver.Detach();
            phoneCallAudioSender.Detach();

            mediaConnector.Disconnect(contactIdHandler, phoneCallAudioSender);
            mediaConnector.Disconnect(phoneCallAudioReceiver, contactIdHandler);

            contactIdHandler.Stop(); // stop the contactIdHandler
        }
    }
}

Related Pages

More information