.NET Tutorials, Forums, Interview Questions And Answers
Welcome :Guest
 
Sign In
Register
 
Win Surprise Gifts!!!
Congratulations!!!


Top 5 Contributors of the Month
david stephan

Home >> Articles >> C# >> Post New Resource Bookmark and Share   

 Subscribe to Articles

C# SIP SMS Example

Posted By:Tim Davis       Posted Date: June 09, 2011    Points: 200    Category: C#    URL: http://www.dotnetspark.com  

This article is about how to create a C# SIP SMS Example.
 

SIP SMS Example

The importance of SIP messages is great because often they are used for various purposes. They are for establishing phone calls, making complementary actions etc. Today when we live in a rushing world fast and efficient communication is more important than ever. SMS technology offers one of the quickest ways to send information to each other. This way you can be absolutely sure that your message will be received by the recepient because most of the people keep their mobile phones near themselves.

This sample program was developed to give an effective solution for this kind of matter. During the development I used the SDK offered by Ozeki and the Microsoft Windows Forms presentation technology.

I developed a telephone which can forward and receive phone calls and it also sends and receives DTMF signals to navigate in IVR systems.

Program running

After running the program the telephone automatically registers to the given SIP PBX with the given SIP account. If the registration process is ended successfully on the display Registration succeeded can be seen. From now on the softpohne is ready to make, receive calls, during the calls it can send, receive DTMF signals to navigate in IVR systems. (The source code of the sample program contains settings that depend on the environment so after the download do not forget to customize it). When the call is ended a notification is received about the keywords.

Code

The PhoneMain.cs code behind file writes down the actuating events which are related to the interface and connects the logics to the GUI. The sample program lacks design samples and other proprieties and focuses on simplicity because it is only for presentation. This means that the PhoneMain.cs file consists the full logic of the sample program. As you open the file you can see a few lines of declaration which are needed to use Ozeki VoIP SIP SDK.

public partial class PhoneMain : Form
    {
        ISoftPhone softPhone;
        IPhoneLine phoneLine;
        PhoneLineInformation phoneLineInformation;
        IPhoneCall call;
        OzPipeStream speakerStream;
        ozWavePlayer wavePlayer;
        ozWaveRecorder waveRecorder;
        bool inComingCall;
        Stream ReceivedStream;
        Stream SentStream;

ISoftphone
It represents a telephone, and its telephone line is represented by the IphoneLine. There can be more telephone lines which means that we can develop a multi line phone.

Iphoneline
It represents a telephone line that can be registered to a SIP PBX for example, Asterisk, 3CX, or maybe to other PBXs that are offered by SIP providers. Registration happens through SIP account.

PhoneLineInformation
It is an enum type that represents the status of the telephone line with the PBX. For example registered, not registered, successful/unsuccessful registration.

IphoneCall
It represents a call: the status of the call, the direction of the call, on which telephone line it was created, the called person, etc.

OzPipeStream
It is an optional device and it helps in the processing of the incoming sound data which comes from the other party.

ozWavePlayer
It plays the received sound data on the speaker.

ozWavRecorder
It processes the sound data which comes from the default input device (microphone) of the operation system.

ReceivedStream
It is the stream that saves the received stream.

SentStream
It is the stream that saves the sent stream.

Thereby assign to the 'Loaded' events of Windows Form window and after the loading of 'PhoneMain' window the initialization and registration of Ozeki SDK softphone can be started.

private void InitializeSoftPhone()
        {
            softPhone = SoftPhoneFactory.CreateSoftPhone("192.168.91.42", 5700, 5750, 5780);
            softPhone.IncommingCall += new EventHandler>(softPhone_IncommingCall);
            phoneLine = softPhone.CreatePhoneLine(new SIPAccount(true, "oz891", "oz891", "oz891", "oz891", "192.168.91.212", 5060));
            phoneLine.PhoneLineInformation += new EventHandler>(phoneLine_PhoneLineInformation);

            softPhone.RegisterPhoneLine(phoneLine);
        }

The SDK represents the incoming and outgoing calls through IpPhoneCall interface. This interface contains the status of the given call, on which line it was created and who is the called person. On this object you can pick up or hang up calls. Let's see the event of the sample program.

For an outgoing call we provide the number we want to dial. Then press the Pick Up button and the call starts. The interface buttons are addressed to triggers so let us look it in the case of the 'Pick Up' button.

private void buttonPickUp_Click(object sender, EventArgs e)
        {
            if (inComingCall)
            {
                inComingCall = false;
                call.Accept();
                return;
            }

            if (call != null)
                return;

            if (string.IsNullOrWhiteSpace(labelDialingNumber.Text))
                return;

            if (phoneLineInformation != PhoneLineInformation.RegistrationSucceeded && phoneLineInformation != PhoneLineInformation.NoRegNeeded)
            {
                MessageBox.Show("Phone line state is not valid!");
                return;
            }

            call = softPhone.Call(phoneLine, labelDialingNumber.Text);
            WireUpCallEvents();
            call.Start();
        }

Below you can see how I did the wire up.

private void WireUpCallEvents()
        {
            call.CallStateChanged += new EventHandler>(call_CallStateChanged);
            call.MediaDataReceived += new EventHandler>(call_MediaDataReceived);
            call.DtmfReceived += new EventHandler>>(call_DtmfReceived);
            call.CallErrorOccured += new EventHandler>(call_CallErrorOccured);
        }

Through the CallErrorOccured event information is received about why the was not created. They can be the following: the call is rejected, the called party is busy, the called number is not available or the number does not exist.
In order to wire up to these essential events start a real call. You can achieve this with the Start function of the call object. It is the 'call.Start()' line in the example.

The Ozeki VoIP SIP SDK publishes the incoming calls through the 'ISoftphone' InComingCall event.

private void softPhone_IncommingCall(object sender, VoIPEventArgs e)
        {
            InvokeGUIThread(()=>
                         {
                             labelCallStateInfo.Text = "Incoming call";
                             labelDialingNumber.Text = String.Format("from {0}", e.Item.DialInfo);
                             call = e.Item;
                             WireUpCallEvents();
                             inComingCall = true;
                         });
        }

The code sample shown above handles this and if there is an incoming call it signals the call on the display. Then register to the necessary events of the incoming calls. The incoming call variable signals for the 'Pick Up' button if it is an outgoing or an incoming call.

The 'Hang Up' button is also connected to the event handler similarly to the 'Pick Up' button. The event handler shown below ends the call, you only need to press the 'Hang Up' button.

private void buttonHangUp_Click(object sender, EventArgs e)
   
     {
            if (call != null)
            {   
                inComingCall = false;
                call.HangUp();
                call = null;
            }
            labelDialingNumber.Text = string.Empty;
        }

Ozeki VoIP SIP SDK gives information about the status of the calls. They can be the follows: InCall, Completed, Rejected, ringing etc. Through the CallStateChange event the displaying of these call status happen. The sample program does not handle all possibilities because I only concentrated on the vital ones. According to these significant programs the other programs can be created easily.

private void call_CallStateChanged(object sender, VoIPEventArgs e)
        {
            InvokeGUIThread(() => { labelCallStateInfo.Text = e.Item.ToString(); });

            switch (e.Item)
            {
               ozWaveFormat waveFormat = new ozWaveFormat(8000, 16, 1);
          ReceivedStream = new ozWaveFileWriter(waveFormat, receivedFilePath);
              SentStream = new ozWaveFileWriter(waveFormat, sentFilePath);
 
              waveRecorder = new ozWaveRecorder();
              waveRecorder.DataArrived += waveRecorder_DataArrived;
              waveRecorder.StartRecording();
 
              speakerStream = new OzPipeStream();
              wavePlayer = new ozWavePlayer(speakerStream);
              wavePlayer.Play();
              break;
                case CallState.Completed:
                    waveRecorder.Dispose();
                    speakerStream.Dispose();
                    speakerStream = null;
                    wavePlayer.Dispose();

                    call = null;
                    InvokeGUIThread(() => { labelDialingNumber.Text = string.Empty; });
                    break;
                case CallState.Cancelled:
                    call = null;
                    break;
            }        }

Since at the outgoing/incoming wire up to the 'call' MediaDataReceived the incoming PCM sound data only needs to be forwarded to the sound system as it  is shown below.

private void call_MediaDataReceived(object sender, VoIPEventArgs e)
        {
            if (speakerStream != null)
                speakerStream.Write(e.Item.PCMData, 0, e.Item.PCMData.Length);
       if (ReceivedStream.CanWrite)
            {
                ((ozWaveFileWriter)ReceivedStream).Save(e.Item.PCMData);
            }
        }

Pass the PCM sound data that is originated from the microphone to the call object that represents the actual call. This happens through the process of SendMediaData and the sound will be sent according to the built communication channel. The sound data will be compressed with the help of the right sound codec and then it will be forwarded to the recipient.

private void waveRecorder_DataArrived(object sender, ozDataArrivedEventArgs e)
        {
            if (call != null)
                call.SendMediaData(VoIPMediaType.Audio, e.Data);
       if (SentStream.CanWrite)
            {
                ((ozWaveFileWriter)SentStream).Save(e.Data);
            }
        }

After the call has been established there is an opportunity to send DTMF signals. You can navigate in the called customer service's  IVR system. Ozeki VoIP SIP SDK sends DTMF signals in a simple way. Invite the 'StartDTMFSignal' method on the object that represents the current call as it is shown below.

private void buttonKeyPadButton_MouseDown(object sender, MouseEventArgs e)
        {
            if (call != null && call.CallState == CallState.InCall)
            {
                var btn = sender as Button;
                if (btn != null)
                {
                    int id;

                    if (btn.Tag != null && int.TryParse(btn.Tag.ToString(), out id))
                    {
                        call.StartDTMFSignal(VoIPMediaType.Audio, id);
                    }
                }
            }
        }

Ending DTMF signal is similar to the start. On the object which represents the current call the 'StopDTMFSignal'method is invited. Below this can be seen, where the id is a referential number type DTMF signal and it is related to the pressed button.

call.StopDTMFSignal(VoIPMediaType.Audio, id);

Ozeki VoIP SIP SDK informs the content of SIP messages in a  simple way. To do so assign to the event that is shown below.

OzSIP.Log.SIPMessageLogger.NewSIPMessage += SIPMessageLogger_NewSIPMessage;

Now check the message content

void SIPMessageLogger_NewSIPMessage(object sender, VoIPEventArgs e)
  {
    if (e.Item.Contains(txb_SIPText.Text))
      {
         SendSMS();
      }
  }

If there is a match for the searched SIP text snippet you only need to send an SMS. It can be implemented with a request sent to the http API of an SMS server

private void SendSMS()
 {
   string url =
   string.Format(@"http://{0}/api?action=sendmessage&username={1}&password={2}&recipient={3}&messagetype=SMS:TEXT&messagedata={4}",Txb_IpAddress.Text, txb_UserName.Text, Txb_Password.Text, Txb_recipient.Text, Txb_SmsText.Text);
 
   WebRequest request = WebRequest.Create(url);
 
   request.GetResponse();
 }

Summary

SMS sending became the part of our lives just like mobile phones, TV or the Internet. It is a very efficient and fast way to communicate with each other. The implementation is simple so it is easy to create your own C# SIP SMS example.  More specific information can be found on the web-page. I can only recommend this solution to everyone.


 Subscribe to Articles

     

Further Readings:

    Responses

    No response found. Be the first to respond this post

    Post Comment

    You must Sign In To post reply

      Read also another Resources from the same Author

    Find More Articles on C#, ASP.Net, Vb.Net, SQL Server and more Here

    Hall of Fame    Twitter   Terms of Service    Privacy Policy    Contact Us    Archives   Tell A Friend