Download: | sip-message-modification.zip |
This article is about to introduce the basic knowledge about SDP (Session Description Protocol)
in connection with Ozeki VoIP SIP SDK support and softphone building, and also reveals
how to manipulate SIP messages. To fully understand this
article, you might have to study the
How to register to a SIP PBX chapter first.
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.
What is SDP? How does it work?
Since some of the SIP's (Session Initiation Protocol) features has been already introduced, this guide provides
some information about the SDP for better understanding.
The Session Description Protocol (SDP) is a format for describing streaming media initialization
parameters. SDP is intended for describing multimedia communication sessions for
the purposes of session announcement, session invitation and parameter negotiation.
SDP does not deliver media itself, but is used for negotiation between end points
of media type, format and alol associated properties. The set of properties and parameters are
often called session profile.
SDP is designed to be extensible to support new media types and formats.
You can modify SDP messages by their fields, which can be optional or even required. For more information about SDP, you can find the whole standard for SDP at the RFC 4566 standard documentation.
How to work with SIP and SDP in C# using Ozeki VoIP SIP SDK?
Ozeki VoIP SIP SDK provides a great support for SIP and SDP. There is a set of namespaces (for example Ozeki.VoIP.SIP, Ozeki.VoIP.SDP and other namespaces within them), that are for SIP and SDP handling, and setting the above mentioned fields and more.
From the previous guides you could learn how to use some of the SIP messages,
for example the SIP REGISTER and the SIP INVITE
requests. From this guide you can learn how to modify an outgoing SIP message's User-Agent field.
Please note that, this c# example only registers to a pbx with a modified user-agent field,
but to manipulate SDP messages you would need an established voip call.
SIP message manipulation example in C#
using System; using System.Collections.Generic; using Ozeki.VoIP; namespace SIP_Message_Modification { class Program { static ISoftPhone softphone; static IPhoneLine phoneLine; static SIP_CustomMessageManipulator sipMessageManipulator; // creates a custom sip message manipulator object private static void Main(string[] args) { // Create a softphone object with RTP port range 5000-10000 softphone = SoftPhoneFactory.CreateSoftPhone(5000, 10000); // SIP account registration data, (supplied by your VoIP service provider) var registrationRequired = true; var userName = "sipusername"; var displayName = "sipdisplayname"; var authenticationId = "authenticationid"; var registerPassword = "Password"; var domainHost = "pbxip.voipprovider.com"; var domainPort = 5060; sipMessageManipulator = new SIP_CustomMessageManipulator(); // initializes the custom message manipulator softphone.SetSIPMessageManipulator(sipMessageManipulator); var account = new SIPAccount(registrationRequired, displayName, userName, authenticationId, registerPassword, domainHost, domainPort); // Send SIP regitration request RegisterAccount(account); // Prevents the termination of the application Console.ReadLine(); } 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.NotRegistered || e.State == RegState.Error) Console.WriteLine("Registration failed!"); if (e.State == RegState.RegistrationSucceeded) Console.WriteLine("Registration succeeded - Online!"); } } class SIP_CustomMessageManipulator : ISIPMessageManipulator // the class to implement a custom message manipulator needs to use the ISIPMessageManipulator interface { public string ModifyIncomingMessage(MessageModifierInfo incomingMessageInfo) // modifies the incoming SIP message, if set { return incomingMessageInfo.Message; // gives back the message without any modification } public string ModifyOutgoingMessage(MessageModifierInfo outgoingMessageInfo) // modifies the outgoing sip message, if set { return outgoingMessageInfo.Message.Replace("Ozeki VoIP SIP SDK", "Ozeki User-Agent"); // modifies the message's part to the set string } public IEnumerable<PreparedExtensionHeader> PrepareAdditionalHeaders(MessageModifierInfo outgoingMessageInfo) // you can add additional headers to the SIP message { return null; // no additional headers has been added to the sip message } } }
Communcation through the network
As in the How to register to a SIP PBX example you could see, the SIP messages indicates to the PBX that a client would like to register, and the PBX responds to these requests. In the example it asks for authentication information as well, and recives another REGISTER SIP message with the wanted authentication information. You can check the REGISTER request's User-Agent field (indicated with bold) to get notified about the changes; as you can see the "Ozeki VoIP SIP SDK" part of the package has been changed to "Ozeki User-Agent", as it supposed to.
You can see the PDUs responsible for these below:
Step 1: Registration request (UDP message, Softphone -> PBX)
REGISTER sip:192.168.115.149 SIP/2.0 Via: SIP/2.0/UDP 192.168.115.149:7071;branch=z9hG4bKc2cdb015-27c9-4703-adc5- 7c33cf2ccbc6;rport To: "1001"<sip:1001@192.168.115.149> From: "1001"<sip:1001@192.168.115.149>;tag=cdkgowkl CSeq: 1 REGISTER Call-ID: kvoflrnxyjhawrftfmtbqnkccfyiynynoqoqkxfqueqhgqybnf Max-Forwards: 70 Contact: <sip:1001@192.168.115.149:7071;rinstance=301fa1d56bca9948> User-Agent: Ozeki User-Agent v10.1.8 Content-Length: 0 Expires: 3600 Supported: 100rel Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, SUBSCRIBE, NOTIFY, REFER, INFO, MESSAGE
Step 2: Reply from PBX with request for authentication (UDP message, PBX -> softphone)
SIP/2.0 407 Proxy Authentication Required Via: SIP/2.0/UDP 192.168.115.149:7071;branch=z9hG4bKc2cdb015-27c9-4703-adc5- 7c33cf2ccbc6;rport=7071; received=192.168.115.149 From: "1001"<sip:1001@192.168.115.149>;tag=cdkgowkl Call-ID: kvoflrnxyjhawrftfmtbqnkccfyiynynoqoqkxfqueqhgqybnf CSeq: 1 REGISTER To: "1001"<sip:1001@192.168.115.149>;tag=oaqrtonc User-Agent: Ozeki Phone System XE v5.2.1 Content-Length: 0 Proxy-Authenticate:Digest nonce="99ac0a42196c469f94c2f5fcd1ea2443", realm="OzekiPBX", algorithm=MD5
Step 3: Sending the authentication information for registration (UDP message, Softphone -> PBX)
REGISTER sip:192.168.115.149 SIP/2.0 Via: SIP/2.0/UDP 192.168.115.149:7071;branch=z9hG4bK2c83a245-475c-4a17-b98e- d2e236b8012e;rport To: "1001"<sip:1001@192.168.115.149> From: "1001"<sip:1001@192.168.115.149>;tag=cdkgowkl CSeq: 2 REGISTER Call-ID: kvoflrnxyjhawrftfmtbqnkccfyiynynoqoqkxfqueqhgqybnf Max-Forwards: 70 Contact: <sip:1001@192.168.115.149:7071;rinstance=301fa1d56bca9948> User-Agent: Ozeki User-Agent v10.1.8 Content-Length: 0 Expires: 3600 Supported: 100rel Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, SUBSCRIBE, NOTIFY, REFER, INFO, MESSAGE Proxy-Authorization:Digest username="1001",realm="OzekiPBX", nonce="99ac0a42196c469f94c2f5fcd1ea2443", response="f73515df8701b9ce5945f193d9459f00",uri="sip:192.168.115.149",algorithm=MD5
Step 4: Acknowledge of registration (UDP message, PBX -> Softphone)
SIP/2.0 200 OK Via: SIP/2.0/UDP 192.168.115.149:7071;branch=z9hG4bK2c83a245-475c-4a17-b98e- d2e236b8012e;rport=7071; received=192.168.115.149 From: "1001"<sip:1001@192.168.115.149>;tag=cdkgowkl Call-ID: kvoflrnxyjhawrftfmtbqnkccfyiynynoqoqkxfqueqhgqybnf CSeq: 2 REGISTER To: "1001"<sip:1001@192.168.115.149>;tag=vtaywqks User-Agent: Ozeki Phone System XE v5.2.1 Content-Length: 0 Contact: <sip:1001@192.168.115.149:7071;rinstance=301fa1d56bca9948>;expires=3600
Related Pages
More information
- How to build a softphone voip sip client
- Register to SIP PBX
- Voip softphone development
- How to encrypt voip sip calls with sip encryption
- How to encrypt voip sip calls with rtp encryption
- How to ring a sip extension csharp example for sip invite
- How to make a sip voice call using csharp
- Voip multiple phone lines
- How to send stream of voice data into call using csharp microphone
- How to receive voice from SIP voice call using csharp speaker
- How to make conference voice call using voip sip
- How to play an mp3 file into a voice call using csharp
- How to convert text to speech and play that into a call using csharp
- How to use Microsoft Speech Platform 11 for TTS and STT
- How to record voip sip voice call
- How to accept incoming call using csharp
- How to reject incoming call using csharp
- How to read Headset buttons using Bluetooth
- How to implement auto answer using csharp
- How to recognize incoming voice using speech to text conversion
- Voip forward call
- Voip blind transfer
- Voip attended transfer
- Voip do not disturb
- Voip call hold
- SIP Message Waiting Indication
- Voip DTMF signaling
- How to work with sip and sdp in voip sip calls
- How to work with rtp in voip sip calls
- How to make voip video calls in csharp
- Voip video codec
- Shows how to use SpeechToText Google API
- How to convert Text to Speech using C# and Google
- Azure Text-to-Speech