473,406 Members | 2,633 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes and contribute your articles to a community of 473,406 developers and data experts.

How to Build 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 quickests 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 succeded 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.

Expand|Select|Wrap|Line Numbers
  1. public partial class PhoneMain : Form
  2.     {
  3.         ISoftPhone softPhone;
  4.         IPhoneLine phoneLine;
  5.         PhoneLineInformation phoneLineInformation;
  6.         IPhoneCall call;
  7.         OzPipeStream speakerStream;
  8.         ozWavePlayer wavePlayer;
  9.         ozWaveRecorder waveRecorder;
  10.         bool inComingCall;
  11.         Stream ReceivedStream;
  12.         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.

Expand|Select|Wrap|Line Numbers
  1. private void InitializeSoftPhone()
  2.         {
  3.             softPhone = SoftPhoneFactory.CreateSoftPhone("192.168.91.42", 5700, 5750, 5780);
  4.             softPhone.IncommingCall += new EventHandler<VoIPEventArgs<IPhoneCall>>(softPhone_IncommingCall);
  5.             phoneLine = softPhone.CreatePhoneLine(new SIPAccount(true, "oz891", "oz891", "oz891", "oz891", "192.168.91.212", 5060));
  6.             phoneLine.PhoneLineInformation += new EventHandler<VoIPEventArgs<PhoneLineInformation>>(phoneLine_PhoneLineInformation);
  7.  
  8.             softPhone.RegisterPhoneLine(phoneLine);
  9.         }
  10.  
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.


Expand|Select|Wrap|Line Numbers
  1. private void buttonPickUp_Click(object sender, EventArgs e)
  2.         {
  3.             if (inComingCall)
  4.             {
  5.                 inComingCall = false;
  6.                 call.Accept();
  7.                 return;
  8.             }
  9.  
  10.             if (call != null)
  11.                 return;
  12.  
  13.             if (string.IsNullOrWhiteSpace(labelDialingNumber.Text))
  14.                 return;
  15.  
  16.             if (phoneLineInformation != PhoneLineInformation.RegistrationSucceeded && phoneLineInformation != PhoneLineInformation.NoRegNeeded)
  17.             {
  18.                 MessageBox.Show("Phone line state is not valid!");
  19.                 return;
  20.             }
  21.  
  22.             call = softPhone.Call(phoneLine, labelDialingNumber.Text);
  23.             WireUpCallEvents();
  24.             call.Start();
  25.         }

Below you can see how I did the wire up.


Expand|Select|Wrap|Line Numbers
  1. private void WireUpCallEvents()
  2.         {
  3.             call.CallStateChanged += new EventHandler<VoIPEventArgs<CallState>>(call_CallStateChanged);
  4.             call.MediaDataReceived += new EventHandler<VoIPEventArgs<VoIPMediaData>>(call_MediaDataReceived);
  5.             call.DtmfReceived += new EventHandler<VoIPEventArgs<Tuple<VoIPMediaType, DtmfSignal>>>(call_DtmfReceived);
  6.             call.CallErrorOccured += new EventHandler<VoIPEventArgs<CallError>>(call_CallErrorOccured);
  7.         }

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 publicates the incoming calls through the ’ISoftphone’ InComingCall event.


Expand|Select|Wrap|Line Numbers
  1. private void softPhone_IncommingCall(object sender, VoIPEventArgs<IPhoneCall> e)
  2.         {
  3.             InvokeGUIThread(()=>
  4.                          {
  5.                              labelCallStateInfo.Text = "Incoming call";
  6.                              labelDialingNumber.Text = String.Format("from {0}", e.Item.DialInfo);
  7.                              call = e.Item;
  8.                              WireUpCallEvents();
  9.                              inComingCall = true;
  10.                          });
  11.         }
  12.  
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.


Expand|Select|Wrap|Line Numbers
  1. private void buttonHangUp_Click(object sender, EventArgs e)
  2.  
  3.      {
  4.             if (call != null)
  5.             {   
  6.                 inComingCall = false;
  7.                 call.HangUp();
  8.                 call = null;
  9.             }
  10.             labelDialingNumber.Text = string.Empty;
  11.         }

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.

Expand|Select|Wrap|Line Numbers
  1. private void call_CallStateChanged(object sender, VoIPEventArgs<CallState> e)
  2.         {
  3.             InvokeGUIThread(() => { labelCallStateInfo.Text = e.Item.ToString(); });
  4.  
  5.             switch (e.Item)
  6.             {
  7.                ozWaveFormat waveFormat = new ozWaveFormat(8000, 16, 1);
  8.           ReceivedStream = new ozWaveFileWriter(waveFormat, receivedFilePath);
  9.               SentStream = new ozWaveFileWriter(waveFormat, sentFilePath);
  10.  
  11.               waveRecorder = new ozWaveRecorder();
  12.               waveRecorder.DataArrived += waveRecorder_DataArrived;
  13.               waveRecorder.StartRecording();
  14.  
  15.               speakerStream = new OzPipeStream();
  16.               wavePlayer = new ozWavePlayer(speakerStream);
  17.               wavePlayer.Play();
  18.               break;
  19.                 case CallState.Completed:
  20.                     waveRecorder.Dispose();
  21.                     speakerStream.Dispose();
  22.                     speakerStream = null;
  23.                     wavePlayer.Dispose();
  24.  
  25.                     call = null;
  26.                     InvokeGUIThread(() => { labelDialingNumber.Text = string.Empty; });
  27.                     break;
  28.                 case CallState.Cancelled:
  29.                     call = null;
  30.                     break;
  31.             }        }
  32.  
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.


Expand|Select|Wrap|Line Numbers
  1. private void call_MediaDataReceived(object sender, VoIPEventArgs<VoIPMediaData> e)
  2.         {
  3.             if (speakerStream != null)
  4.                 speakerStream.Write(e.Item.PCMData, 0, e.Item.PCMData.Length);
  5.        if (ReceivedStream.CanWrite)
  6.             {
  7.                 ((ozWaveFileWriter)ReceivedStream).Save(e.Item.PCMData);
  8.             }
  9.         }
  10.  
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.


Expand|Select|Wrap|Line Numbers
  1. private void waveRecorder_DataArrived(object sender, ozDataArrivedEventArgs e)
  2.         {
  3.             if (call != null)
  4.                 call.SendMediaData(VoIPMediaType.Audio, e.Data);
  5.        if (SentStream.CanWrite)
  6.             {
  7.                 ((ozWaveFileWriter)SentStream).Save(e.Data);
  8.             }
  9.         }

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.

Expand|Select|Wrap|Line Numbers
  1. private void buttonKeyPadButton_MouseDown(object sender, MouseEventArgs e)
  2.         {
  3.             if (call != null && call.CallState == CallState.InCall)
  4.             {
  5.                 var btn = sender as Button;
  6.                 if (btn != null)
  7.                 {
  8.                     int id;
  9.  
  10.                     if (btn.Tag != null && int.TryParse(btn.Tag.ToString(), out id))
  11.                     {
  12.                         call.StartDTMFSignal(VoIPMediaType.Audio, id);
  13.                     }
  14.                 }
  15.             }
  16.         }
  17.  
  18.  
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.


Expand|Select|Wrap|Line Numbers
  1. 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.


Expand|Select|Wrap|Line Numbers
  1. OzSIP.Log.SIPMessageLogger.NewSIPMessage += SIPMessageLogger_NewSIPMessage;

Now check the message content


Expand|Select|Wrap|Line Numbers
  1. void SIPMessageLogger_NewSIPMessage(object sender, VoIPEventArgs<string> e)
  2.   { 
  3.     if (e.Item.Contains(txb_SIPText.Text))
  4.       {
  5.          SendSMS();
  6.       }
  7.   }

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


Expand|Select|Wrap|Line Numbers
  1. private void SendSMS()
  2.  {
  3.    string url =
  4.    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);
  5.  
  6.    WebRequest request = WebRequest.Create(url);
  7.  
  8.    request.GetResponse();
  9.  }

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 webpage. I can only recommend this solution to everyone.
Jun 9 '11 #1
0 7290

Sign in to post your reply or Sign up for a free account.

Similar topics

2
by: AIM | last post by:
Error in msvc in building inheritance.obj to build hello.pyd Hello, I am trying to build the boost 1.31.0 sample extension hello.cpp. I can not compile the file inheritance.cpp because the two...
2
by: Torsten Bronger | last post by:
Hallöchen! I write a module, and so I must raise exceptions at several points. The PEP 8 says that a module should define their own exceptions base class, derived from "Exception", and...
15
by: cody | last post by:
We have a huge project, the solutuion spans 50 projects growing. Everytime I want to start the project I have to wait nearly over 1 minute for the compiler to complete building. This is...
10
by: Douglas Buchanan | last post by:
I am using the following code instead of a very lengthly select case statement. (I have a lot of lookup tables in a settings form that are selected from a ListBox. The data adapters are given a...
11
by: ajikoe | last post by:
Hello, I used Visual C# Standard Edition. I want to comment my program using xml commentary method, I don't know why if I use value and example tag, it is not working / showed in the html...
3
by: michael.lang | last post by:
I am using PostBuild events in a C# project to run some tasks, but only when in release configuration mode. The build events run perfectly as expected when run. The problem comes when I save the...
5
by: Al | last post by:
Hi all We have created a xml file that imports a single project using the Import element. This project compiles to a class library, but has references to two other projects that are also class...
6
by: Soren | last post by:
Hi! I'm trying to extend my python program with some C++ code. Right now I've spent hours just trying to get boost to work! I'm trying to get the example hello.cpp to work. Using Windows XP...
1
by: gimme_this_gimme_that | last post by:
This is a clip from the new book Learning the Yahoo! User Interface Library ... (An example of doing things and not using YUI) Why does this return a NS_ERROR_DOM_HIERARCHY_REQUEST _ERR code 3...
5
by: Charlie | last post by:
Hi All, I am new to using swig/C++/python. I got some problem with function pointers. I posted in swig-user, but got no response. So I forwarded it here. You help is greatly appreciated. ...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.