Friday, July 11, 2014

How to send a Contact ID alarm to the Central Station from a C# application over VoIP

Background of the problem

Before describing the implementation of my solution, I am going to explain the most important terms you need to know for better understanding.
First of all, let’s take a look at the operation of the traditional alarm systems in a nutshell. You have an alarm system installed and configured in your office or home. This alarm system is connected to the Central Station. In case of emergency (e.g. fire, burglary, theft or any other intrusion) the alarm system sends an alert to the Central Station that will take the appropriate action to avert the emergency.
But using my solution, you (more specifically: your C# application) can behave as an alarm system. That is, you can send out any alarm in case of emergency to the Central Station. Let’s see a drastic example that illustrates how my application can improve your security system: Due to a protracted work, you are sitting in the office late night. Since you are in the building, the alarm system is not activated yet. But in the meantime you experience something unusual and there is a suspicion of emergency. In this case you can use this C# application in order to send out a Contact ID alarm to the Central Station. The following figure illustrates this process:
Figure 1: How to send a Contact ID alarm to the Central Station in C#
Mini glossary:
  • Alarm System: It is a system designed to detect intrusion (unauthorized entry), fire, gas leak, Carbon Monoxide leakage, high or low temperature, system trouble, communication trouble or any other emergency event.
  • Central Station: It refers to a company providing services to monitor burglar, fire and residental alarm systems.
  • Contact ID protocol: It is the most popular protocol that is used to establish communication between the alarm systems and the Central Station.

Implementation of the alarm sender application in C#

Getting started

Before starting the development, let's see what you need for this project. Considering that my application has been written in C#, you need a development environment that supports C# (such as Microsoft Visual Studio). Please do not forget to install .NET Framework on your PC as well. There is also a need for some VoIP components added to your references to be able to implement the VoIP functionality (such as Ozeki VoIP SIP SDK). Since I have used the Ozeki SDK for this project, you need to install this SDK on your PC, too.
  1. For creating a new Console Application, open your Visual Studio, click File > New project. Now select the Visual C# Console Application menu item and provide a name for your project. Finally click OK.
  2. For adding the VoIP components provided by the SDK, right-click on References and select the Add references menu item. Browse and select the VoIPSDK.dll file then click OK.

Code explanation

In order to make the communication possible between the alarm system and the Central Station I used the Contact ID protocol. The essence of the Contact ID procotol is that the receiver side sends a Handshake firstly. When the sender side receives that, it will start to send the message. That is both of the sides need to play the role of the sender and receiver as well. Therefore, in addition to the sender side, it is needed to talk a little about the receiver side as well. This is the reason why both of the sides has been built in one project.
Figure 2 illustrates the communication process using the Contact ID protocol:
Figure 2: The communication process using the Contact ID protocol
As you can see above, the alarm signal is a DTMF signal. However, the DTMF frequencies may be distorted during the communication with the Contact ID protocol, if you do not use a codec applying lossless compression. Therefore, you need to use PCMA or PCMU codecs.
In my project 2 classes have been used: Softphone.cs and Program.cs. Now it’s time to study the implementation of the two classes!

The implementation of the Softphone.cs class

First of all, you need to create a softphone (a software-based telephone that has the same features as an ordinary phone). It is required, because the transmission of the alarm will be carried out through a VoIP call. So the alarm sending will be managed with the help of this softphone. The Softphone.cs class is used to declare, define and initialize a softphone, how to handle the necessary events and how to use its functions. The Softphone.cs will be used to create a new softphone in the Program.cs class.
Code 1 shows that the first step is the addition of some using lines:
using System;
using Ozeki.Media;
using Ozeki.Media.MediaHandlers;
using Ozeki.VoIP;
using Ozeki.VoIP.SDK;
Code 1: Add some using lines
As you can see below, you need to create 3 objects (softphone, phone line and call) from the ISoftphone,IPhoneLine and IPhoneCall interfaces:
ISoftPhone softphone; // softphone object
IPhoneLine phoneLine; // phoneline object
IPhoneCall call; // call object
Code 2: Creating the softphone, phone line and call objects
You also need to initialize the softphone in the constructor using the default parameters. You need to set the port range indicated by the first parameter (minPortRange) and the second parameter (maxPortRange). This is called the port’s interval. It can be seen in Code 3 that it also contains a third parameter: this is the listening port. As you can see, this is 5060 that is the port of the SIP.
softphone = SoftPhoneFactory.CreateSoftPhone(5000, 10000, 5060);
Code 3: Initializing the softphone in the constructor
By subscribing to the IncomingCall event, incoming calls will be monitored continuously (Code 4).
softphone.IncomingCall += softphone_IncomingCall;
Code 4: Subscribing to the IncomingCall event
In order to be able to communicate, you need to register your softphone to a PBX by using the Register()method (Code 5). This method gets all of the values required for the registration as parameters that are used to create a SIP account with the constructor of the SIPAccount class:
  • RegistrationRequired: Is the registration required or not? To be able to receive incoming calls, this field needs to be set to ’true’.
  • DisplayName: A name to be displayed at the called client.
  • UserName: If an other client dials this name (number), this user is getting called.
  • AuthenticationId: An identifier (like a login name) to the PBX.
  • RegisterPassword: The password for registering to the PBX. It works in pair with the authentication ID.
  • DomainHost: A domain name, e.g. an IP address.
  • DomainPort: Port number.
After that the system will be able to create the phone line (CreatePhoneLine() method) by using the account. By subscribing to the PhoneLineStateChanged, you can track the changes of the phone line. When the phone line has been created, you need to register this phone line by calling the RegisterPhoneLine() method.
// Send SIP regitration request
        public void Register(bool registrationRequired, string displayName, string userName, string authenticationId, string registerPassword, string domainHost, int domainPort)
        {
            try
            {
                var account = new SIPAccount(registrationRequired, displayName, userName, authenticationId, registerPassword, domainHost, domainPort);
                Console.WriteLine("\n Creating SIP account {0}", account);

                phoneLine = softphone.CreatePhoneLine(account);
                Console.WriteLine("Phoneline created.");

                phoneLine.PhoneLineStateChanged += phoneLine_PhoneLineStateChanged;

                softphone.RegisterPhoneLine(phoneLine);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error during SIP registration" + ex.ToString());
            }
        }
Code 5: Subscribing to the IncomingCall event
You have already subscribed to get notified if the state of the phone line has been changed. With thephoneLine_PhoneLineStateChanged() method you can set what to do for each state. If the state of the phone line is RegistrationSucceeded, the system will examine whether the call has been started or not. You need to setup the numberToDial (a telephone number to be dialed) and the call object as well. As you can see below, you need to subscribe to the CallStateChanged by calling the call_CallStateChanged() method (Code 6).
void phoneLine_PhoneLineStateChanged(object sender, VoIPEventArgs<PhoneLineState> e)
        {
            Console.WriteLine("Phone line state changed to {0}", e.Item);

            if (e.Item == PhoneLineState.RegistrationSucceeded)
            {
                if (startCall)
                {
                    var numberToDial = "101";
                    call = softphone.CreateCallObject(phoneLine, numberToDial);

                    call.CallStateChanged += call_CallStateChanged;
                    call.Start();
                }
            }

            var handler = PhoneLineStateChanged;
            if (handler != null)
                handler(this, e.Item);
        }
Code 6: Managing the phone line states
If the CallStateChanged event occurs (that is the call state changes), the state of the call will be displayed.
  • If the call state is Answered, you need to create a PhoneCallAudioSender and aPhoneCallAudioReceiver in order to be able to send and receive audio during a call. In order to ensure that both of the sending and receiving works properly, the contactIdHandler object should be connected to the phoneCallAudioSender and phoneCallAudioReceiver objects when the call is established. It can be completed by using the mediaConnector. It ensures that both of the incoming and outgoing communication will be carried out through the contactIdHandler. After that, you need to run the contactIdHandler by calling the Start() method.
  • If the call state is Completed, you need to disconnect the established connections, and stop thecontactIdHandler by calling the Stop() method (Code 7).
        void call_CallStateChanged(object sender, VoIPEventArgs<CallState> e)
        {
            Console.WriteLine("call state changed: {0}", e.Item);

            if (e.Item == CallState.Answered)
            {
                phoneCallAudioSender = new PhoneCallAudioSender();
                phoneCallAudioReceiver = new PhoneCallAudioReceiver();

                // 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
            }
            else if (e.Item == CallState.Completed)
            {
                contactIdHandler.Stop(); // stop the contactIdHandler

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

                phoneCallAudioReceiver.Detach();
                phoneCallAudioSender.Detach();
            }
        }
Code 7: Managing the call states
The following method (Code 8) examines whether is there an incoming call or not. By calling thecall_CallStateChanged() method you can subscribe to the events of the CallStateChanged concerning to the incoming calls. The call will be equal to the current call and the call will be accepted automatically. To hang up an existing call use the HangUpCall() method.
void softphone_IncomingCall(object sender, VoIPEventArgs<IPhoneCall> e)
        {
            Console.WriteLine("Incoming call...");
            e.Item.CallStateChanged += call_CallStateChanged;
            call = e.Item;
            call.Accept();
        }
Code 8: Accepting an incoming call
To hang up an existing call use the HangUpCall() method (Code 9).
public void HangUpCall()
        {
            call.HangUp();
        }
Code 9: The HangUpCall() method

The implementation of the Program.cs class

First you need to add some lines in the ’using section’ (Code 10):
using System;
using Ozeki.Media.MediaHandlers;
Code 10: Add some extra using lines

Tuesday, June 3, 2014

Diving into OOP : All About C# Access Modifiers

Public, Private, Protected at Class Level

Whenever we create a class, we always want to have the scope to decide who can access certain members of the class. In other words, we would sometimes need to restrict access to the class members. The one thumb rule is that members of a class can freely access each other. A method in one class can always access another method of the same class without any restrictions. When we talk about the default behavior, the same class is allowed complete access but no else is provided access to the members of the class. The default access modifier isprivate for class members.
Point to remember: The default access modifier is private for class members.
Let’s do some hands on lab. Just open your Visual Studio and add a console application in C# namedAccessModifiers. You’ll get a Program.cs class file by default. In the same file, add a new class namedModifiers and add the following code to it:
using System;

namespace AccessModifiers
{
    class Modifiers
    {
        static void AAA()
        {
            Console.WriteLine("Modifiers AAA");
        }

        public static void BBB()
        {
            Console.WriteLine("Modifiers BBB");
            AAA();
        }
    }

     class Program
    {
        static void Main(string[] args)
        {
            Modifiers.BBB();
        }
    }
   }
So, your Program.cs file becomes like shown in the above code snippet. We added a class Modifiers and twostatic methods AAA and BBB. Method BBB is marked as public. We call the method BBB from Mainmethod.The method is called directly by the class name because it is marked static.
When we run the application, we get the output as follows:

Output

Modifiers BBB
Modifiers AAA
BBB is marked public and so anyone is allowed to call and run it. Method AAA is not marked with any access modifier which automatically makes it private, that is the default. The private modifier has no effect on members of the same class and so method BBB is allowed to call method AAA. Now this concept is called member access.
Modify the Program class and try to access AAA as:
class Program
    {
        static void Main(string[] args)
        {
            Modifiers.AAA();
            Console.ReadKey();
        }
    }

Output

'AccessModifiers.Modifiers.AAA()' is inaccessible due to its protection level
So , since method AAA is private, therefore no one else can have access to it except Modifiers class.
Note: Each and every code snippet written in this article is tried and tested.
Modifiers
Now mark the AAA method as protected, our class looks like:
class Modifiers
    {
        protected static void AAA()
        {
            Console.WriteLine("Modifiers AAA");
        }

        public static void BBB()
        {
            Console.WriteLine("Modifiers BBB");
            AAA();
        }
    }

Program

    class Program
    {
        static void Main(string[] args)
        {
            Modifiers.AAA();
            Console.ReadKey();
        }
    }

Output

'AccessModifiers.Modifiers.AAA()' is inaccessible due to its protection level
Again the same output. We cannot access the method AAA even after we introduced a new modifier namedprotected. But BBB can access AAA method because it lies in the same class.


Wednesday, June 5, 2013

Twitter Client - Login to C# application using twitter

Background 

There is already a good article there on codeproject that describes twitter and facebook integration named "C# Application integration with facebook and twitter with oAuth".  
Please create your own secretKey and token as described in above mentioned article.
But the purpose of this article is to provide most used functions of twitter using Twitterizer. I was searching for twitterizer help and faced many problems, so i decide to write an article for someone else who is using twitterizer for C#.
This article uses xml and browser in WPF. So before continuing, make sure you know about these. There are many articles for xml and browser control, e.g. XML for Beginners So i will not discuss about these.

How it works

 
When the app runs, it checks whether user is already logged in or not. If not, then display a browser window to authenticate from twitter. User logs in to twitter, twitter generates a pin that user pastes to textbox provided there. Now main windows launches where all operations are performed. 

Login/Out

When user logs in to twitter, twitter sends a key value pair to the application called tokens. These tokens are then saved to an xml. Whenever user want to update status, send direct message or check for followers etc, these tokens must be sent to twitter with request.
When user first time logs in, this token is saved to xml, and next time when user launches app, the app first checks whether the tokens are saved in xml file or not. If tokens are already saved, it means user is logged in already, otherwise browser is displayed. 
When user want to logout, then simply delete that xml file by clicking log out button in main window. Next time, the user is again prompted to login.

Using the code  

Code contains three WPF windows and two classes. 
Browser Window & Class : 
public partial class Browser : Window
{
    public Browser()
    {
        InitializeComponent();
    }
    XMLStuff myXML;

    private void btnRefresh_Click(object sender, RoutedEventArgs e)
    {
        browserControl.Refresh();
    }
    // checks whether already logged in or not. if logged in then goto main window, else goto twitter
    private void Window_Loaded_1(object sender, RoutedEventArgs e)
    {
        myXML = new XMLStuff();
        statusBarMessage.Text = "Checking for login info..";
        bool loggedIn = AlreadyLoggedIn();
        statusBarMessage.Text = "Not logged in, shifting to login page.";
        if (!loggedIn)
        {
            Login();
            statusBarMessage.Text = "";
        }
        else
        {
            MainWindow mw = new MainWindow();
            mw.Show();
            this.Close();
        }
    }
 
    private void btnSend_Click(object sender, RoutedEventArgs e)
    {
        TwitterStuff.pin = tbPin.Text; //when user enters pin, it is saved to TwitterStuff class
        Properties.Settings.Default.Save();
        TwitterStuff.tokenResponse2 = OAuthUtility.GetAccessToken(TwitterStuff.consumerKey, 
          TwitterStuff.consumerSecret, TwitterStuff.tokenResponse.Token, tbPin.Text);
        myXML.writeToXML(TwitterStuff.tokenResponse2.ScreenName.ToString(), 
          TwitterStuff.tokenResponse2.Token, TwitterStuff.tokenResponse2.TokenSecret);
        TwitterStuff.screenName = TwitterStuff.tokenResponse2.ScreenName.ToString();
        SetLocalTokens();
        //MessageBox.Show("Logged In and local tokens are set");
        statusBarMessage.Text = "Successfuly logged in.";
        MainWindow mw = new MainWindow();
        mw.Show();
        this.Close();
    }

    private void browserControl_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
    {
        lblUri.Content = browserControl.Source.AbsoluteUri.ToString();
        progressBar.IsIndeterminate = false;
        progressBar.Visibility = System.Windows.Visibility.Hidden;
        // MessageBox.Show(browserControl.Source.AbsoluteUri.ToString());
    }
    // open twitter site with our consumerKey and consumerSecret to login
    private void Login()
    {
        TwitterStuff.tokenResponse = OAuthUtility.GetRequestToken(TwitterStuff.consumerKey, 
                  TwitterStuff.consumerSecret, TwitterStuff.callbackAddy);
        string target = "http://twitter.com/oauth/authenticate?oauth_token=" + 
                  TwitterStuff.tokenResponse.Token;
        try
        {
            browserControl.Navigate(new Uri(target));
        }
        catch (System.ComponentModel.Win32Exception noBrowser)
        {
            if (noBrowser.ErrorCode == -2147467259)
                MessageBox.Show(noBrowser.Message);
        }
        catch (Exception other)
        {
            MessageBox.Show(other.Message);
        }
    }

 
    /// <summary>
    /// Initialize token
    /// </summary>
    private void SetLocalTokens()
    {
        TwitterStuff.tokens = new OAuthTokens();
        TwitterStuff.tokens.AccessToken = TwitterStuff.tokenResponse2.Token;
        TwitterStuff.tokens.AccessTokenSecret = TwitterStuff.tokenResponse2.TokenSecret;
        TwitterStuff.tokens.ConsumerKey = TwitterStuff.consumerKey;
        TwitterStuff.tokens.ConsumerSecret = TwitterStuff.consumerSecret;
    }
    // if already logged in, then tokens are loaded from xml file using this method.
    private bool SetLocalTokens(string accessToken, string tokenSec)
    {
        try
        {
            TwitterStuff.tokens = new OAuthTokens();
            TwitterStuff.tokens.AccessToken = accessToken;
            TwitterStuff.tokens.AccessTokenSecret = tokenSec;
            TwitterStuff.tokens.ConsumerKey = TwitterStuff.consumerKey;
            TwitterStuff.tokens.ConsumerSecret = TwitterStuff.consumerSecret;
            // MessageBox.Show("Tokens with arguments initialized.");
            return true;
        }
        catch (Exception)
        {
            return false;
        }
    }
    // this method checks whether xml file exists and reads data,
    // if so, it means that user is logged in. and true is returned 
    private bool AlreadyLoggedIn()
    {
        try
        {
            //MessageBox.Show("Trying to get login info");
            List<string> LoginInfo = myXML.readFromXml();

            TwitterStuff.screenName = LoginInfo[1];
            if (!SetLocalTokens(LoginInfo[2], LoginInfo[3]))
                return false;
            //MessageBox.Show("Already logged in.");
            return true;
        }
        catch (Exception e)
        {
            statusBarMessage.Text = "Not logged in.";
            return false;
        }
    }

    private void browserControl_Navigating(object sender, 
                     System.Windows.Navigation.NavigatingCancelEventArgs e)
    {
        progressBar.IsIndeterminate = true;
        progressBar.Visibility = System.Windows.Visibility.Visible;
    }
}
XMLStuff class just writes token strings to xml file using writeToXML method and reads token using readFromXml.
When user clicks logout btn, then xml logout method is called that just deletes the XML file.

TwitterStuff

This class performs all twitter related functions.
public static string consumerKey = "your consumer key here";
public static string consumerSecret = "your consumer secret here"
Obtain your consumerKey and consumerSecret from twitter by following above mentioned article.
public static string pin = "xxxxxxx";
When user logins to twitter, twitter provides a pin, that pin is stored in this variable.
public static OAuthTokens tokens;
These tokens are passed as argument to all main twitter functions. e.g. sending message function:
TwitterDirectMessage.Send(tokens, receiverScreenName.Trim(), msg);

Method to Update Status: 

public bool tweetIt(string status)
{
    try
    {
        TwitterStatus.Update(tokens, status);
        MessageBox.Show("Status updated successfuly");
        return true;
    }
    catch (TwitterizerException te)
    {
        MessageBox.Show(te.Message);
        return false;
    }
} 
This method takes a string variable and posts it as a tweet to twitter.
public List<string> getMessages()
{
    List<string> temp = new List<string>();
    var receivedMessages = TwitterDirectMessage.DirectMessages(tokens);
    foreach (var v in receivedMessages.ResponseObject)
    {
        temp.Add(v.Recipient.ScreenName + " >> " + v.Text);
    }

    return temp;
}  
The above method gets all received messages of all users and then stores it to a string list.