You are on page 1of 126

SIP .

NET SDK Programmer's Guide

Konnetic Unity SIP .NET SDK


Programmer's Guide
Version 4.0 February 2011

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


Table of Contents
1. 2. Programmer's Guide Unity SIP .NET SDK 2.1. Prerequisites for Unity SIP .NET SDK 2.2. Redistributable Components for Unity SIP .NET SDK 2.3. License Key Information 2.4. Ordering 2.5. Legal Information (Unity SIP .NET SDK) 2.5.1. License Agreement 3. Session Initiation Protocol 3.1. SIP Entities 3.2. SIP Messages 3.3. Anatomy Of A Message 3.4. Header Fields 3.5. Call Flow Example 4. Session Description Protocol 4.1. SDP Contents 4.2. Message Structure 4.3. SDP Attributes 4.4. SDP Example 1-2 4 4-5 5 5-6 6-7 7 7-10 11 11-12 12-15 15-16 16-19 19-21 22 22-23 23-25 25-26 26-29

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

5.

Introduction to the Library 5.1. Features 5.2. RFCs Implemented 5.3. Terminology 5.4. Permissions 5.5. Architecture 5.5.1. The Exception Model 5.5.2. Threading Model 5.5.3. Class Diagrams 5.5.3.1. Transaction Class Diagram 5.5.3.2. Transport Class Diagram 5.6. Application Programming Interface 5.7. SIP Transaction Objects 5.8. The SIP URI 5.9. Walkthrough: Initiate a Session 5.10. Walkthrough: Accept Or Decline A Session Invite

30-31 31-32 32-34 34-36 36-37 37-38 38-41 41-42 42 42-44 44-46 46-48 48 48-51 51-55 55-57 58 58-60 60-64 64-66

6.

Configuration 6.1. Common Client Settings 6.2. Low-Level Client Settings 6.3. Internal Settings

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

7.

Working with the SipCore 7.1. Initialisation 7.2. Sip Core Behaviours 7.3. Event Processing 7.4. Listening For Incoming Messages 7.5. Sending Messages

67 67-69 69-70 70-73 73-74 74-76 77-78 78-79 79-82 82-83 83-85 85-87 88 88-89 89-90 90-91 91-95 95-96 97-98 98-99

8.

Working with Messages and Headers 8.1. SipMessage 8.2. Message Types 8.3. Adding Headers To Messages 8.4. Headers 8.5. Compact Form

9.

Working with Transactions 9.1. Transaction Entities 9.2. Transaction Types 9.3. Methods 9.4. State Machines 9.5. Timers

10.

Working with Authentication

10.1. The Http Digest Authentication Manager

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

10.2. The Authentication Exchange 11. Working with the Transport Layer 11.1. Sip Connections 11.2. Connection Reuse 11.3. Introduction to TLS in SIP 11.4. Event Processing 11.5. IPv6 11.6. Transport Buffers 11.7. Example 12. Working with SIP DNS

99-101 102 102-104 104-106 106-107 108-109 109-110 110-112 112-113 114 114-117 117-118 118

12.1. Implementation 12.2. Configuring DNS 12.3. The DNS Facade

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


1 Programmer's Guide

This document is intended to give you an overview of the SIP and SDP protocols and describes how to use Konnetic's Unity SIP .NET library for developing SIP applications. The current version is February 2011. New editions will have a new print date. Minor changes can occur without changing the print date. The latest version of the document is always available at: www.konnetic.com (http://www.konnetic.com/)

1.1 Intended Audience


This document is aimed at developers who wish to build SIP-based applications using the .NET platform. Readers are expected to be familiar with the following:

The C# .NET language. Basic Networking concepts. Threading and exception handling concepts.

1.2 Getting Started


For a quick start to the library try the walkthroughs first. The Walkthrough: Initiate a Session (Section 5.9) shows how an application developer can use the Unity SIP SDK to initiate a SIP session by sending an INVITE request, listen for replies to that request, and finally respond with an ACK request to establish the session - sometimes called a Dialog in SIP. The Walkthrough: Accept Or Decline A Session Invite (Section 5.10) takes the other side and listens for requests and accepts or declines the request. Read up about the License Key Information (Section 2.3) and how it is applied and works.

1.3 More Advanced


You can initiate sessions and receive incoming session requests using an intranet or local IP address - the samples make use of this technique (e.g. 'sip:Name@192.168.1.1'). However, for more advanced scenarios you will need a Fully Qualified Domain Name (FQDN) (e.g. 'sip:Name@Domain'). Ask your network administrator to provide you with a SIP URI or domain name, otherwise consider configuring a DNS server such as Windows Server 2008 or Bind. The SIP standard makes extensive use of DNS to resolve SIP URIs to IP Addresses, particularly in production

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


environments. In order to get the most out of SIP you will need a SIP Registrar and/or SIP Proxy. You can obtain trial downloads of stable products from Brekeke (http://brekeke.com/) or Asterisk (http://www.asterisk.org/).

1.4 Document Organisation


Section 2 Provides legal and conceptual information about Unity SIP .NET SDK. Section 3 Provides a technical overview of Session Initiation Protocol. Section 4 Provides a technical overview of Session Description Protocol. Section 5 Introduces the SIP library and its key components and architecture. Section 6 Details the configuration of the SIP library. Section 7 Describes the basic code necessary to write an application using the SIP libraries and SipCore. Describes the makeup of the SIP messages in the library and the header fields that make up the message. Looks at the inner state machines in Transactions and describes how to use them to work with counterparties. Introduces HTTP Digest and how it is handled in the SIP Library. Describes the functioning of the TransportLayer and describes how to use it to listen for and sending messages. Looks at how the SIP Library uses DNS.

Section 8

Section 9 Section 10 Section 11 Section 12

1.5 Konnetic Welcomes Your Comments


Konnetic welcomes your comments concerning this document. We are committed to providing documentation that meets your needs. Send your comments or suggestions to: support@konnetic.com Include the document title, the print date and any comment on the document. Also, include what we did well, so we can incorporate that into other documentation.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


2 Unity SIP .NET SDK

This document provides technical information about Konnetic's Unity SIP .NET SDK. It is intended to be read by application developers who are interested in creating and deploying SIP-based applications. Typically for applications that require high functionality communication and collaboration. This document consists of a general overview of the Unify SIP .NET API, guidance on some of the concepts involved with programming SIP applications using the Unify SIP .NET API.

2.1 Unity SIP .Net SDK


Use Konnetic's Unity SIP .NET SDK to create and deploy SIP-based applications and services. The applications can be client-based or server-based written in any .NET compliant language including C# and VB.NET. Target platforms include Mono and Microsoft's CLR. The SDK provides the developer with a feature rich and fully standards compliant .NET library, supplementary documentation, and samples. The .NET library is especially useful for client applications, including those with low-power form factors.

2.1 Prerequisites for Unity SIP .NET SDK


2.1.1 Prerequisites
The following are the prerequisites for developing applications using Konnetic's Unity SIP .NET SDK.

Unity SIP .NET SDK installed on the development computer. A license for the product obtainable from Konnetic's website (http://www.konnetic.com/).

A compatible .NET VSS (Virtual Execution System) and framework. Konnetic products support Mono and the Microsoft CLR. We are committed to ensuring our products run on the platforms our customers demand.

For Windows Platforms All our products are written against Microsoft's .NET 2.0 Framework and thus run against versions 2.0, 3.0, 3.5 and 4.0. We have found most of our customers support this version set. We are unable to provide binaries compiled against other, earlier, versions (i.e 1.0 and 1.1) of the Framework.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


For the time being min-CRL, the micro Framework and .NET CE are not supported. For Other Platforms

Furthermore, our products are designed to run against Mono 2.6 and 2.7. Again earlier versions are not supported.

2.2 Redistributable Components for Unity SIP .NET SDK


If you create an application that is built fromthe Unity SIP .NET SDK, the Redistributable Code is any software contained in the "bin" install directory. This will typically be .NET DLLs, supporting xml documents and possibly xsd scheme documents. The software contains code that you are permitted to distribute in programs you develop as long as you fully comply with the terms of the License Agreement.

2.3 License Key Information


We need to charge for our software in order to pay our developers and to continue to supply you with quality products. Therefore Konnetic provides license management for our products. We want you to use our product to create great applications and services your way. So once you have purchased a licensed copy you then have a royalty-free right to distribute the portions of the software designated as "Redistributable". Each license comes with a license key that you provide to unlock the software. The license key can be supplied at design time (license file or application configuration) or programatically at runtime.

2.3.1 Trial License


Konnetic provide a fully functional trial product using a license key that expires 30 after downloading the product. The licence key is found in the email sent at the same time as the download. If your trial runs out you can contact licensing@konnetic.com (mailto:licensing@konnetic.com)and tell us what product you are evaluating. We'll arrange for you to get a new 30 trial period license key.

2.3.2 Using the Key

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


You have three options when using the license key: 1. Programatically 2. Configuration file (e.g. app.config) 3. License file ('lic' file) The library will search each location in turn in the order specified above.

Programatically

Konnetic.Signalling.Sip.LicenseContainer.Key = "PUT LICENSE KEY FROM EMAIL HERE";

Configuration File

Add the "license" element to the "<konneticSettings><sip>" configuration element. <konneticSettings> <sip> <!--The default SIP URI for the client--> <license key="PUT LICENSE KEY FROM EMAIL HERE"/> </sip> </konneticSettings>

License File

Find or create a konnetic.signalling.lic file and replace the whole contents of the file with the key. You may need to copy the konnetic.signalling.lic file into the application directory for each solution you use the evaluation in.

2.4 Ordering
At Konnetic, we want to ensure you can get the most from our products. We offer freely available fully functional evaluations of our software. You can deploy full purchased products royalty free. Each license grants one developer the ability to use and integrate the class libraries into the products they are developing. We include license management software in all versions of the software, thus there is a license key to associate with the class library in order to use the product. You can achieve this though application configuration, programmatically at runtime or using a license file. We have worked hard to balance a solution that is not onerous to you, but at the same time deters piracy of our IP.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


We encourage you to evaluate our products extensively before making the decision to purchase. If you have any questions we will be happy to help during this period. Please note that we do not provide refunds. Unity SIP .NET SDK can be purchased via the Konnetic website for immediate download from our

partner site, Avangate.com. For further information, go to the purchase pages on the Konnetic web site: Konnetic Website (http://www.konnetic.com/purchase/purchase.aspx)

2.5 Legal Information (Unity SIP .NET SDK)


The information contained in this document, including web site references, is subject to change without notice. Complying with applicable copyright laws is the user's responsibility. No part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means, or for any purpose, without the express written permission of Konnetic Ltd. Konnetic Ltd has copyright and other intellectual property rights covering subject matter in this document. Sections of the documentation is the copyright of The Internet Society (2002). All other trademarks are the property of their respective owners.

2.5.1 License Agreement


KONNETIC LTD LICENSE AGREEMENT READ CAREFULLY BEFORE INSTALLING THE SOFTWARE. BY DOWNLOADING, INSTALLING AND/OR USING THE SOFTWARE OR CLICKING "I ACCEPT" WHEN PROMPTED IN CONJUNCTION THEREWITH, YOU ("LICENSEE") ACCEPT ALL OF THE TERMS AND CONDITIONS OF THIS LICENSE. IF YOU ARE ACCEPTING THESE TERMS ON BEHALF OF ANOTHER PERSON OR LEGAL ENTITY, YOU REPRESENT AND WARRANT THAT YOU HAVE FULL LEGAL AUTHORITY TO ACCEPT ON BEHALF OF AND BIND THAT PERSON

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


OR LEGAL ENTITY TO THESE TERMS. LICENSE AGREEMENT

This End User License Agreement ("EULA") is a legal agreement between you (either an individual or an entity) and Konnetic for the software product identified above, which may include user documentation provided in online or electronic form. By installing, copying, or otherwise using the SOFTWARE, you agree to be bound by the terms of this EULA. If you do not agree to the terms of this EULA, do not install or use the SOFTWARE. 1. GRANT OF LICENSE Konnetic grants to you as an individual or entity a non-exclusive License to make and use copies of the SOFTWARE in the manner provided below. The software is licensed, not sold. (a) Evaluation License Konnetic grants to you as an individual, a personal, nonexclusive License to install the SOFTWARE for the sole purposes of evaluating the SOFTWARE. You may evaluate the SOFTWARE for a period of thirty (30) days. After this period, you shall either (i) delete the SOFTWARE and all related documentation from all computers onto which it was installed or copied, or (ii) purchase a Single Developer License from Konnetic or one of its authorized suppliers to purchase the SOFTWARE. You may not under the terms of the evaluation License distribute any portion of the SOFTWARE or products generated using the SOFTWARE. (b) Single Developer License After you have purchased the License for the SOFTWARE, and have received a registration code enabling the registered copy, you are licensed to copy the SOFTWARE only into the memory of the number of computers corresponding to the number of Licenses purchased and activate the SOFTWARE using the supplied registration code. The primary user of the computer on which each registered copy of the SOFTWARE is installed may make a second copy for his or her exclusive use on a second computer. Under no other circumstances may the SOFTWARE be operated at the same time on more than the number of computers for which you have paid a separate License fee. You may not duplicate the SOFTWARE in whole or in part, except that you may make copies of the SOFTWARE for backup or archival purposes. You have a royalty-free right to distribute the portions of the SOFTWARE designated as "Redistributable Code" under the terms below. 2. REDISTRIBUTABLE CODE Portions of the software are designated as "Redistributable Code". The Software documentation

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


describes the files and Redistributable rights associated with each file of the Redistributable Code,

subject to the requirements described below. You have a royalty-free right to distribute the portions of the SOFTWARE designated as "Redistributable Code" only if: (a) You have purchased a License for the SOFTWARE. (b) You distribute only the portions of the SOFTWARE designated as "Redistributable Code". (c) You use and distribute the "Redistributable Code" only in conjunction with the binary files that make use of them as a part of your software product. (d) Your product(s) and application(s) must add significant and primary functionality to the SOFTWARE; (e) You do not expose, document or make public the SOFTWARE API (Application Programming Interface); (f) Your software product may not, in the reasonable opinion of Konnetic, compete with any Konnetic product. (g) You agree to indemnify, hold harmless, and defend Konnetic and its suppliers from and against any and all claims or lawsuits including attorney's fees that arise or result from the use or distribution of your software product. 3. RESTRICTIONS You must not redistribute the registration codes provided, neither on paper nor electronically outside of that required to activate the SOFTWARE. You must not redistribute any original or modified source code file or any portion of the source code contained within the files. You agree not to use the knowledge acquired from the source code in order to develop for yourself or any third party any program that is similar to or competitive with the Software. You are not allowed to port the source code to other programming languages. You may not reverse engineer copy, duplicate or distribute the License schema that is needed to use the SOFTWARE in a design, development or runtime environment. You may not disassemble, decompile or reverse engineer the SOFTWARE or any portions of it. You may not rent, lease, or lend the SOFTWARE. You may permanently transfer all of your rights under this EULA provided you transfer all copies of the SOFTWARE (including copies of all prior versions if the SOFTWARE is an upgrade) and registration codes and retain none, and the recipient agrees to the terms of this EULA. 4. TERMINATION Without prejudice to any other rights, Konnetic may terminate this EULA if you fail to comply with

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


the terms and conditions of this EULA. In such event, you must destroy all copies of the

10

SOFTWARE. You may terminate this License at any time by destroying the original and all copies of the SOFTWARE in whatever form. 5. COPYRIGHT The SOFTWARE is owned by Konnetic and is protected by Australian copyright laws and international treaty provisions. You may not copy the printed materials accompanying the SOFTWARE (if any), nor print copies of any user documentation provided in on-line or electronic form. 6. LIMITED WARRANTY THE PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL THE AUTHOR or AUTHORS BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF THE USE OF THE PROGRAM, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. YOU ACKNOWLEDGE THAT YOU HAVE READ THIS LICENSE, UNDERSTAND IT AND AGREE TO BE BOUND BY ITS TERMS AS THE COMPLETE AND EXCLUSIVE STATEMENT OF THE AGREEMENT BETWEEN US, SUPERSEDING ANY PROPOSAL OR PRIOR AGREEMENT, ORAL OR WRITTEN, AND ANY OTHER COMMUNICATIONS BETWEEN US RELATING TO THE SUBJECT MATTER OF THIS LICENSE. 7. LIMITATION OF LIABILITY IN NO EVENT SHALL KONNETIC OR ITS SUPPLIERS BE LIABLE TO YOU FOR ANY CONSEQUENTIAL, SPECIAL, INCIDENTAL, OR INDIRECT DAMAGES OF ANY KIND ARISING OUT OF THE DELIVERY, PERFORMANCE, OR USE OF THE SOFTWARE, EVEN IF KONNETIC HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN ANY EVENT, KONNETIC'S LIABILITY FOR ANY CLAIM, WHETHER IN CONTRACT, TORT, OR ANY OTHER THEORY OF LIABILITY, EXCEEDS THE LICENSE FEE PAID BY YOU.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


3 Session Initiation Protocol

11

Technical Overview
3.1 Introduction
Session Initiation Protocol (SIP) was designed from the bottom up to connect people and devices whenever and wherever they are in order to engage in a (possibly lengthy) exchange of information. Existing protocols, such as HTTP and SMTP, were not purpose-built for this essential human activity, and so SIP was born to fill the gap. However, SIP borrows from these two other protocols heavily. From using HTTPs message exchange pattern, message format and encoding, to SMTPs URI scheme. In 2002 revised version of the SIP standard was formalised into the Internet Engineering Task Forces (IEFT) standardisation process as RFC3261. Because of the open nature of the IETF standards process, the fact SIP is text based and shares many features with existing specifications, it has been readily understood, extended and implemented.

3.1 SIP Entities


A SIP environment consists of a number of connected entities. These include, User Agents, Proxy servers, Redirect servers, Registrar servers and Back-to-Back User Agents (B2BUA). It is the User Agent that tends to reside on the end users device. The other entities provide essential support services in many scenarios.

3.1.1 Clients
We naturally associate the concept of client software to the end users. This is even more applicable with SIP as it is indifferent to the device or application the person uses and attempts to abstract away the internet plumbing and make the person internet addressable. The User Agent (UA) is the entity typically hosted on client software and associated with end users. It has two modes of operation:

As a User Agent Client (UAC): Generates and sends requests those to servers (which may include a UAS, see next), and receives responses in return.

As a User Agent Server (UAS): Receives and processes requests, and generates responses.

Typically a single UA acts in both capacities.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


3.1.2 Servers

12

SIP servers are instrumental in the location of clients and the efficient and correct routing of SIP messages.

Proxy Server: These elements are involved in routing the SIP Request to the correct UAS and SIP Responses to the correct UAC. They are the most common type of server in a SIP environment. If an exact address of the recipient is not know at elaboration the client sends the request to a proxy server which forwards it onto another proxy server closer to the end point or the ultimate recipient itself.

Redirect Server: A redirect server accepts requests from a client and responds to the client with a new address or different route path to the recipient. They are important in supporting mobility when a recipient has moved location.

Registrar: These servers act as current repository of a clients location often utilising a separate Location Server. User Agents register with a Registrar on start up or when the client changes the point of attachment to the network.

B2BUA: These logical entities act in a dual capacity in that they receive requests like a UAS, process the request further in some manner, then behave as a UAC and forward the processed request on. B2BUAs maintain state between calls and participate in SIP transactions providing tight control over the exchange. A stateful Proxy Server may contain a B2BUA.

3.2 SIP Messages


SIP messages come in two flavours.

Request: sent from client to a server and define the operation sought by the client. Response: sent from server to a client and provide the status of that request

3.2.1 Requests
A SIP request is characterised as a method much like HTTP, and is considered a verb, since it requests actions to be performed by other User Agents or servers. RFC3261 defines six methods with subsequent standards defining the remaining extension methods (from INFO onwards).
Method Description

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


INVITE REGISTER BYE ACK CANCEL OPTIONS Used to set up a SIP session. Session parameters are negotiated. Authenticates the User Agent and provides a current location to the network. Terminates a open session. Confirms a success response to an INVITE. The third part to a three-way-handshake. Cancels an open request. BYE should be used to cancel (tear down) an existing request. Queries the capabilities of correspondents. Extension Methods INFO MESSAGE NOTIFY PRACK PUBLISH REFER Provides mid-call session-related information. It is rarely used. Used to transfer Instant Messages. Publishes the outcome of events. Used in combination with SUBSCRIBE requests. A Provisional Response ACKnowledgment. Confirms receipt of a provisional response. Publishes status information. Used for Instant Messaging presence services. Mechanism to pass a request to someone more appropriate to deal with it.

13

SUBSCRIBE Used to request receipt of future NOTIFY or PUBLISH requests. UPDATE Modifies session parameters in mid-call.

3.2.2 Responses
SIP Response messages are always sent in reply to a request. They convey status updates, confirmations, directions and error codes back to the UAC originating the request. Responses are characterised as either provisional or final and every response must be identified by a 3-digit code. Response Types Six classes of response have been defined and are categorised using the 3-digit code. The first five are borrowed from HTTP; the sixth is new to SIP.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


Class Description Confirms receipt of request and processing is continuing. Provisional responses to INVITEs are never ACKed. The request was received, processes and accepted. Provides location information or alternative services to try.

14

1xx Provisional

2xx Success 3xx Redirection 4xx Request Failure

The request contained an error or cannot be processed by the server.

5xx Server Failure The server is unable to fulfil the request because of an internal error. 6xx Global Failure

No service can be found to fulfil the request.

Within each class, numerous response codes have been predetermined - some copied from HTTP.
# 100 180 182 200 301 302 400 401 403 404 408 Reason Phrase Trying Ringing Queued OK Moved Permanently Moved Temporarily Bad Request Unauthorised Forbidden Not Found Request Timeout Description The next hop received the request. Attempting to alert the user. Temporarily unavailable and request is in a queue (not rejected). The request has succeeded. User is no longer available at the address given in the Request URI. Retry the request at a new address given in the Contact header. Could not understand or process correctly the request. The request either failed authentication or needs more information. The server is refusing to process the request. Do not retry. The server cannot identify the user in its domain. The server could not process the request in a reasonable time.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


415 480 485 486 500 513 603 Unsupported Media The format is not supported by the server.

15

Temporarily Unavailable The called party is currently unavailable. Ambiguous Busy Here Server Internal Error Message Too Large Declined The Request URI is ambiguous. The called party is currently not willing or able to take the call. The server encountered an unexpected condition. The message length exceeded a determined limit. The user explicitly refused to accept the request.

Warning Header Field The Warning header field is used to carry additional information about the status of the response. The header defines a 3-digit code between 300 and 399, the host name and a warning text.

Warning: 307 isi.edu "Session parameter foo not understood"

3.3 Anatomy Of A Message


Each SIP message begins with a Start-Line, is followed by a sequence of headers, and separated from the message body by a carriage-return line-feed sequence (CRLF).

Start-Line: formatted as a Request-Line for Requests or a Status-Line for Reponses. Headers: Named attributes that provide additional information about the message. Separator Line: Separator between header and body. Body: binary or textural payload. Typically Session Description Protocol (SDP) or a message text.

The start line, each header line and the separator line is terminated by a [CRLF] sequence.

3.3.1 Start Line


The start-line conveys the type of message and protocol version. For both Request (Request-Line)

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


and Responses (Status-Line), the start-line has three elements separated by spaces.

16

Request-Line: Contains a method, URI and ends with the protocol version ("SIP/2.0"). Status-Line: Starts with the protocol version, followed by a numeric status code and is completed with a short textural reason.

3.3.2 Headers
Headers follow the same generic header format as HTTP. Each consisting of a case-insensitive ASCII encoded name and colon followed by a value which is sometimes UTF8 encoded and usually casesensitive. Each header can have one or more semi-colon separated parameters appended to the value, providing additional tags and features. header-name: header-value(;parameter-name=parameter-value)*[CRLF] Each header can be separated on to different lines using a [CRLF][TAB or SPACE] sequence (known as folding). Whats more, multiple headers with the name same e.g. Contact can appear on separate lines, or, can be placed on the same line separated by commas. For example: Contact: <sip:alice@atlanta.com> Contact: <sip:alice1@chicago.com> Can be represented as: Contact: <sip:alice@atlanta.com>, <sip:alice1@chicago.com> Or using folding: Contact: <sip:alice@atlanta.com>, <sip:alice1@chicago.com>

3.3.3 Body
A message body describes the session (using SDP) or contains opaque text or binary body parts containing the payload related to the session (e.g. MIME or Message formats). Bodies can appear in request or response messages.

3.4 Header Fields


3.4.1 Creating the Request Message

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


1. Add the Request Line, which indicates the message is an INVITE request to 'sip:bob@897s.aarhus.com'.

17

InviteRequest invite = new InviteRequest(new SipUri("sip:bob@897s.aarhus.com"));

2. Create the Via header, the Via header indicates to the recipient the return path. invite.ViaHeaders.Add(new ViaHeaderField(new IPDomainPort("122.181.8.8:11506"), TransportProtocol.Udp)); 3. Create the addresses of the sender and recipient. The SipUris can be an IP address, but Fully Qualified Domain Names are recommended. Display names are possible. For security reasons the From header is allowed to by anonymous if desired. invite.From.Uri = new SipUri("sip:bob@897s.aarhus.com"); invite.From.DisplayName = "Bob"; invite.From.Tag = "769122"; invite.To.Uri = new SipUri("sip:alice@ml99.odense.com"); invite.To.DisplayName = "Alice";

4. Create the unique identifiers for the call and the conversation. The CallId is a unique value for the session. The sequence is incremented in subsequent Requests. The To, From, and Call-ID tuple provides a unique key for a call. invite.CallId.CallId = "afh7989asdfhf@ml99.odense.com"; invite.CSeq.SequenceNumber = 3434534; invite.CSeq.Method = SipMethod.Invite;

5. Create the alternate contact information for the sender. invite.ContactHeaders.Add(new ContactHeaderField( new SipUri("sip:alice2@vejle.com")));

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


6. Finally add the content definitions. We will omit the content in this example. invite.ContentType.MediaType = "application"; invite.ContentType.MediaSubType = "sdp"; invite.ContentLength = 136;

18

3.4.2 SIP request message.


The resulting SIP request message should look similar to the following: INVITE sip:bob@897s.aarhus.com SIP/2.0 Via: SIP/2.0/UDP 124.191.8.8:11506 Max-Forwards: 70 To: Bob <sip:bob@897s.aarhus.com> From: Alice <sip:alice@odense.com>;tag=769122 Call-ID: afh7989asdfhf@ml99.odense.com CSeq: 3434534 INVITE Contact: <sip:alice2@vejle.com> Content-Type: application/sdp Content-Length: 136

Creating the Response Message


If you recall in this example Bob answers Alice with a success Response. The message is an example of a "200" OK response. 1. Add the Status Line, which indicates the request was a Success. Pass in the Request this is a response to SipResponse okMessage = new SipResponse(invite, SipStatusCode.Ok);

2. Add the alternate contact information. This time it is for Bob. okMessage.ContactHeaders.Add(new ContactHeaderField(

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


new SipUri("sip:bob2@vejle.com")));

19

3. Finally add the content definitions. okMessage.ContentType.MediaType = "application"; okMessage.ContentType.MediaSubType = "sdp"; okMessage.ContentLength = 132;

3.4.3 SIP response message.


The resulting SIP response message will look similar to the following: SIP/2.0 200 OK Via: SIP/2.0/UDP 124.191.8.8:11506 To: Bob <sip:bob@897s.aarhus.com>;tag=abgj67 From: Alice <sip:alice@odense.com>;tag=769122 Call-ID: afh7989asdfhf@mel99.odense.com CSeq: 3434534 INVITE Contact: <sip:bob2@vejle.com> Content-Type: application/sdp Content-Length: 132

3.5 Call Flow Example


3.5.1 Successful Simple SIP to SIP
This section details a call flow between that same two SIP User Agents as above and could use the same message structures. The successful calls show the initial signalling, the establishment of the media session, then finally the termination of the call.
Figure 1. Alice completes a SIP call with Bob, exchanges media packets, then Bob terminates the call.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

20

Session Setup

Alices UA sends an INVITE message to Bobs SIP address (i.e. <sip:bob@897s.sydney.com>). The message contents are a Session Description Protocol message describing the expected media exchange.

Bobs UA receives the INVITE and responds with a 100 Trying message. The UA then attempts to attract the attention of Bob, and simultaneously sends a 180 Ringing message to Alice.

Bob respond and is UA sends a 200 OK message. The 200 OK contains the SDP message Bob is agreeing to.

Finally, Alices UA acknowledges receipt of the OK with an ACK request. Media streams are established directly between Alice and Bob.

Session Tear Down

Bob hangs up and his UA initiates a session termination by sending a BYE request to Alice. Alices UA response with a 200 OK.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

21

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


4 Session Description Protocol

22

Technical Overview
4.1 Introduction
With the advent of protocols used to negotiate and define a communication sessions parameters (e.g. Session Initiation Protocol), there was a need to explain the purpose and enrolment process. Session Description Protocol (SDP), defined in RFC4566, achieves that by providing a format for session characterisation and media definition. As part of a session negotiation, the parties are expected to agree on the descriptive values, timings, their respective capabilities and desired media formats. This exchange is referred to as the Offer/Answer Model and is formalised in RFC3264. SDP can be used with a number of transport protocols, such as Session Announcement Protocol (SAP), Session Initiation Protocol (SIP), Hypertext Transfer Protocol (HTTP), and others.

4.1 SDP Contents


Several important pieces of information are mandatory within an SDP message:

Session name. Time(s) the session is active. The media comprising the session. The owner/originator of the session. How to receive the media (addresses, ports etc.).

Other optional information may also be provided:

Bandwidth to be used by the conference. The purpose of the session. Contact information for the person responsible for the session. Time zone information. Session attributes extending SDP.

The encoding of the protocol is primarily UTF8 (descriptive fields can have other encoding as

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

23

specified with a 'charset' attribute defined later). Each piece of information is conveyed in a field. Each field is separated from the next by a carriage return/ line feed sequence [CRLF]. The form of each field is: <type> = <value> Where the <type> is a case-insensitive and unique single character field name. And <value> is structured text whose format depends upon <type>. They are separated by an unpadded '=' (equal) sign.

4.2 Message Structure


Message Structure
Within an SDP message there are three main sections, detailing the Session, Timing, and Media descriptions. Each message may contain more than one Timing and Media description. Each field must appear in the order shown:

4.2.1 Session description


Table 4 breaks down the message and describes each part in more detail. Table 1. Session Description.
Field Type Opt/ Description Mnd M M M O O O O The current protocol version. Always "0" using RFC4566. The session originators name and session identifiers. The textural session name. Textural information about the session. A pointer to supplemental session information. Email contact information for the person responsible. Phone contact information for the person responsible.

Protocol Version Origin Session Name

v o s

Session Information i Uri Email Address Phone Address u e p

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


Connection Data Bandwidth c b C C The connection type and address. Proposed bandwidth limits. Timing Descriptions Go Here Time Zones Encryption Keys Attributes z K A O O O Accounts for daylight saving information. A simple mechanism for exchanging keys. Rarely used. One or more attributes that extend the protocol. Media Descriptions Go Here

24

Note: M - mandatory; O- optional; C- Conditional (Connection Data must appear in either the Session or Media descriptions).

4.2.2 Timings description


Table 2. Timing Description.
Opt/ Description Mnd M O Start and end times. Specified the duration and intervals for any session repeats.

Field

Type

Timing

Repeat Times r

Times are represented as Network Protocol Time (RFC1305): the number of seconds since 1900; intervals can be represented with NTP times or in typed time: a value and time units (days ('d'), hours ('h'), minutes ('m') and seconds ('s')) sequence. Thus an hour meeting from 10am on 1st August 2010, with a single repeat time a week later at the same time can be represented as: t=3487140000 3487143600 r=604800 3600 0 Or using typed time: t=3487140000 3487143600

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


r=7d 3600 0

25

4.2.3 Media description


Table 3. Media Description.
Field Type Opt/ Description Mnd Media definitions including media type (e.g. 'audio'), transport details and formats.

Media Descriptions Session Information Connection Data Bandwidth Encryption Keys Attributes

Same as above

Same as above Same as above Same as above Same as above

4.3 SDP Attributes


Attributes
SDP uses attributes to extend the core protocol. Attributes can appear within the Session or Media sections and are scoped accordingly as "session-level" or "media-level". Attributes take two forms:

A property form: "a=<flag>" conveys a property of the session. A value form: "a=<attribute>:<value>" provides a named parameter.

Table 4. Sample Attributes.


Attribute Form Description

A dot-separated hierarchical category used

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


Category Keywords RTP Payload Type Receive Only Send/Receive cat:<category> keywds:<keywords> rtpmap:<payload type> <encoding name>/<clock rate> recvonly sendrecv for filtering sessions. Assists in the identification of sessions.

26

Maps an RTP payload to the encoding, format and clock rate. Tools should start in receive-only mode. Tools can start in send and receive mode. Types include "broadcast", "meeting" and "moderated" The character set used in the session name and information fields. The default language for the session.

Type

type:<conference type>

Charset

charset:<character set>

Language

lang:<language tag>

4.4 SDP Example


Example
Below is an example session description for a seminar presentation on "SDP Implementation" available in audio and video over RTP from address 124.198.100.6 using ports 49170 and 51372 respectively. It is an hour long seminar which starts at 10am on 1st August 2010 and the contact is John Doe at jdoe@mel99.melbourne.com. Note: All the code examples are fairly language agnostic. A list of recommended Java, .NET and C++ APIs is given at the end for those interested in exploring SDP further. And all the code should work with any of then with little annotation. Note: Alice calling Bob is SDP's equivalent of the archetypal Hello World applications. 1. Create and SDP message or structure. The version of the protocol is "0" for RFC4566. SdpMessage sdp = new SdpMessage(); 2. Add the Origin field with the unique session Id, version and originators name and address - the address can be either an IP address or a Fully Qualified Domain Name. In this example jdoe is

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

27

the originator. The session ID is 2890844526 and the version is 89. The session was created on machine 214.191.7.5. sdp.Origin.UserName = "jdoe"; sdp.Origin.SessionId = 2890844526; sdp.Origin.SessionVersion = 89; sdp.Origin.Address = new IPDomain("214.191.7.5"); 3. Add the session name and information including a pointer to a website with more info. sdp.SessionName = "SDP Implementation"; sdp.SessionInformation = "A Seminar on the session description protocol"; sdp.Uri = new Uri("http://www.mel99.melbournesdp.com/documents/sdpseminar.html"); 4. Add the contact information for the person responsible. The email for John Doe, which includes a full name. sdp.Emails.Add(new EmailHeaderField("jdoe@mel99.melbourne.com", "John Doe")); 5. Add the connection information about how to receive the session. The address can be either an IP address or a Fully Qualified Domain Name. In this example an IP connection to the session host is used. sdp.Connection.Address = new IPHost("124.198.100.6"); 6. Add the timings. There are at least one and can be more than one time field. A good API will allow you to provide either NTP time or a DateTime. The output for times will always be the number of seconds since 1900 for the timings (3487140000 and 3487143600 respectively). These timings represent an hour meeting at 10am on the 1st August 2010. TimeDescriptionHeaderField td = new TimeDescriptionHeaderField(); td.Timings.Start = new SdpTime(new DateTime(2010, 7, 1, 10, 0, 0, 0)); td.Timings.Stop = new SdpTime(new DateTime(2010, 7, 1, 11, 0, 0, 0)); sdp.TimeDescriptions.Add(td); 7. Now, we can add the attributes for the session. This attribute is scoped to the session and indicates that applications should begin the session in receive-only mode.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


sdp.Attributes.Add(new AttributeHeaderField("recvonly")); 8. In this example we are adding two media description sections. The first is for audio on port

28

49170 using RTP Profile for Audio and Video Conferences with minimal Control running over UDP. The final zero is extra parameter information for RTP/AVP. MediaHeaderField mh = new MediaHeaderField(SdpMedia.Audio,49172, SdpMediaProtocol.RtpAvp,"0"); sdp.MediaDescriptions.Add(new MediaDescriptionHeaderField(mh)); 9. The second media description is for video on port 51372 using RTP Profile for Audio and Video Conferences with minimal Control running over UDP. The final 31 is extra parameter information for RTP/AVP. This attribute is scoped to the media description. Any presentations will be in portrait. MediaHeaderField mh1 = new MediaHeaderField(SdpMedia.Video, 51372, SdpMediaProtocol.RtpAvp, "31"); MediaDescriptionHeaderField md = new MediaDescriptionHeaderField(mh1); md.Attributes.Add(new AttributeHeaderField("orient", "portrait")); sdp.MediaDescriptions.Add(md);

Note: The two media descriptions (the lines beginning with m), define an audio and a video profile. These profiles are described in the Real Time Protocol (RTP) specification, RFC3550, and its travel companion RTP Profile for Audio and Video Conferences with Minimal Control, RFC3551.

4.4.1 SDP message.

The resulting SDP message should look exactly like the following: v=0 o=jdoe 2890844526 89 IN IP4 214.191.7.5 s=SDP Implementation i=A Seminar on the session description protocol u=http://www.melbournesdp.com/documents/sdpseminar.html e=jdoe@mel99.melbourne.com (John Doe) c=IN IP4 124.198.100.6 t=3487140000 3487143600

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


a=recvonly m=audio 49170 RTP/AVP 0 m=video 51372 RTP/AVP 31 a=orient:portrait

29

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


5 Introduction to the Library

30

Konnetic's Unity SIP .NET SDK is a class library written in C# that runs on Microsoft's CLR or Mono. The libraries provide an object model for developing SIP (IETF RFC 3261) based applications and services written against the .NET Framework 2.0 and later. Many of SIP's requirements and demands have been abstracted away leaving the developer to concentrate on high-level high-value application implementation. But at the same time the library still allows low-level configuration and control over SIP message flows using an event-based model. The library provides advanced multi-threaded connection management designed to efficiently take advantage of multi-processor or multi-core hardware environments achieving high-performance in modern processors. It also enables a reliable communication model by supporting TCP (Transmission Control Protocol); or provides for authentication and encryption through the use of TLS (Transport Layer Security); or allows higher throughput by using UDP (User Datagram Protocol). SIP methods currently supported include REGISTER, INVITE, OPTIONS, ACK, BYE, CANCEL, INFO, UPDATE and MESSAGE. SIP URIs are an important and complex part of the SIP standard. The Unity SIP .NET SDK provides a type safe SIP URI mechanism derived from the .NET Framework's System.Uri, System.UriParser and System.UriBuilder classes. Other important features include full support for HTTP Digest Authentication, SIP DNS and an SDP library.

5.1 Overview
This section describes the SIP library architecture, the relationship between the objects, API, standards and different kinds of features. Konnetic's implementation of SIP is designed primarily for clients, but can be used in server applications also. It allows you to build the following types of applications and services:

Media over IP. Collaboration tools. A building block to develop a wide range of applications from mobile apps to desktop clients applications and services.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

31

Develop complete solutions for .NET managed platforms that implement call-level, transactionlevel and message-level functionality.

5.1 Features
The SIP Stack component of the SIP Stack was developed in conformity with the specifications of RFC 3261 and various SIP extensions (see RFCs Implemented (Section 5.2)).

5.1.1 Methods
The SIP Stack supports baseline SIP methods, such as INVITE (Re-INVITE), ACK, BYE, CANCEL, OPTIONS and REGISTER. In addition extension methods supported are INFO, UPDATE and MESSAGE

5.1.2 Responses
The SIP Stack supports all response code classes (1xx to 6xx) specified in RFC 3261.

5.1.3 New Message Parameters


The SIP library can accept and encode new non-standard message parameters which do not appear in the baseline specification, such as methods, response codes, headers (extension header fields) and header parameters.

5.1.4 SIP DNS


The Unity SIP Library supports RFC3263: Session Initiation Protocol (SIP): Locating SIP Servers. NAPTR, SRV, A, AAAA DNS queries are all supported.

5.1.5 Interoperability
The Unity SIP Library passes RFC and European Telecommunications Standards Institute testing suites.

5.1.6 Parsing
Parsing of incoming messages is a fundamental feature of any SIP Library. Unity SIP Library uses a unique and powerful directed Deterministic Finite Automa engine to manage all header parsing.

5.1.7 Transports

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


UDP, TCP and TLS transport mechanisms are available. In addition client-only and mutual authentication is supported during the TLS exchange.

32

5.1.8 Security
The SIP Stack can authenticate any SIP request using the Digest authentication scheme in conformity with the SIP specification. Both Client authentication and Server authentication (mutual) are supported. In addition Message Integrity (Auth-Int) is supported.

5.1.9 Multithreading
The SIP library runs in an internally multithreaded mode. Your application may either be singlethreaded or multithreaded. The SIP library uses synchronization mechanisms to ensure multithreading safety at the level of individual objects, such as dialogs and transactions, as well as groups of object as in the transport layer. The SIP library makes use of new threads to listen for incoming messages, and spawns new threads to handle each new message received. The main implication for developer's is exceptions occuring within the multithreaded environment are marshalled to either an event (e.g. OnListenerAborted event on the SipCore) or assigned to an exception property to be thrown on subsequent access to the object (e.g. Parsing exceptions on a SipMessage).

5.1.10 Low-Level Configuration


The SIP Stack configuration enables you to configure the following groups of parameters:

Default Message Properties Message Limits Network parameters Timer values Proxy Servers Miscellaneous

5.2 RFCs Implemented

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


5.2.1 RFCs Implemented
The following RFC have been directly implemented in the Unity SIP Library. Other RFC (e.g. covering TLS) are part of the underlying .NET framework and not included. RFC RFC4566 RFC4320 RFC3596 RFC3428 RFC3581 RFC3311 RFC3264 Title Session Description Protocol Actions Addressing Identified Issues with SIP's Non-INVITE Transaction. DNS Extension to Support IP Version 6 SIP Extension for Instant Messaging An Extension to SIP for Symmetric Response Routing SIP UPDATE Method An Offer/Answer Model with the Session Description Protocol None None None None None None None Section 4.1: NAPTR/SRV records being verified against TLS certificates. Section 4.4: Consideration for stateless proxies. Section 8.2.7: Stateless UAS Behaviour Section 8.3: Redirect Server Section 10.3: Processing REGISTER requests in a registrar Section 13.2.2: Dialog creation from multiple 2xx responses Section 16: Proxy Behaviour Section 23: S/MIME None Missing Functionality

33

RFC3263

Locating SIP Servers

RFC3261

Session Initiation Protocol

RFC2976 RFC2782

SIP INFO Method

A DNS RR for Specifying the Location of None Services (DNS SRV) HTTP Authentication: Basic and Digest Access Authentication None

RFC2617

RFC2119

The Naming Authority Pointer (NAPTR) None DNS Resource Record

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


5.2.2 Verification Standards

34

Testing of the library against industry standards in important to Konnetic. The following test suites have been used to verify that Unity SIP Library is fully compatible with the standard. Title RFC4475: SIP Torture Test Messages ETSI: Conformance Test Specification for SIP None Proxy, Registrar, Redirect functionality was not tested Missing Functionality

5.3 Terminology
Connection An association between two endpoints which carries packets across networks. Each endpoint is represented by a network address and port. In SIP, this concept is sometime referred to as a Flow. In the Unity SIP .NET API, a connection can use either TLS, TCP or UDP transport. Konnetic's Unity SIP .NET API supports two types of connections: inbound and outbound. An inbound connection listens for incoming packets on an assigned local endpoint. Outbound connections initiate transmissions from the local endpoint to the correspondent. Outbound connections will typically use an ephemeral port number and subsequently listen on that port for responses. Destination Tuple A destination tuple contains the information needed to connect to a remote network device. It is formed of the IP Adddress of the remote device, the remote listening port and the transport protocol. Clients can either use the libraries DNS facility to resolve addresses, ports and transports, or can send messages directly using a destination tuple contained in the DestinationTuple object. Dialog A dialog represents a peer-to-peer SIP relationship between two or more user clients that persists for some time. It is analogous to a conversation or call, and is sometimes refer to as such. A session is typically associated with a dialog. Header Field

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

35

A header field is a component of the SIP message header. A header field can appear as one or more header field rows. Header field rows consist of a header field name and zero or more header field values. Multiple header field values on a given header field row are seperated by commas. Some header fields can only hvae a sinlge field value, and as a result, always appear as a single header field row. Outbound Proxy A proxy that receives requests from a client, even though it may not be the server IP Address resolved by the Request-URI. Typically, a User Agent is manually configured with an outbound proxy, or can learn about one through auto-configuration protocols. The ProxyServers config section allows the client application to configure the default outbound proxy servers for request messages. Alternative mechanisms are available to provide the proxy services, including on the SipCore. The proxy servers are used by the outgoing message processsors to create a route-set on the message (unless a route header field is already present). The processor calculates the remote address of the message according to RFC3261 and RFC3263 and takes into account the existance of outbound proxy servers, Route header fields and loose routing rules. There is a separate configuration for secure proxy servers to be configured as an outbound route-set for all secure transmissions. Only proxy servers with secure SIP URIs are allowed (e.g. sips:proxy3.com) for secure transmissions. Route Set A route set is a collection of ordered SIP or SIP URI which represent a list of network nodes (typically proxies) that must be traversed when sending a particular request. A route set can be learned, through headers like Record-Route, or it can be configured. SDP Session Description Protocol, an IETF Internet standard (RFC 4566). It defines a format for representing multimedia sessions. SDP objects are carried in the body of SIP messages and, based on the offer/answer model, are used to negotiate the media characteristics of a session between users. Session A session provides the control channel in which a user client can invite another user client to

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


participate in some activity or exchange media descriptions required to establish media communication. SIP Session Initiation Protocol, an IETF Internet standard (RFC 3261). SIP Transaction SIP is a transactional protocol. Interactions between network elements take place in a series of

36

independent message exchanges (Message Exchange Patterns). A SIP transaction consists of a single request and all following responses to that request. Two categories of transaction exist: those that are initated with an INVITE request (Invite Transactions), and those that are not (Generic Transactions). User Client The device that hosts the SIP-based application.

5.4 Permissions
The Unity SIP Library relies upon certain external resources to operate. Those resources must be available at runtime and access-control permissions must be set so as to allow the executing thread to access them. Additionally the library issues Code Access Security (CAS) demands upon the call stack at certain points in the operation. The resources include:

Sockets - the SIP Library is a networked library and requires unrestricted access to network sockets. A CAS demand is placed on the call stack whenever the library access the network.

DNS - Domain Name Service querys are a fundamental part of using SIP. The library requires access to the DNS servers specified in the Konnetic.Net.NetworkInformation object. A CAS demand is placed on the call stack whenever the library issues a (non-cached) DNS query.

File IO - The library must have permission to read the configuration file, and any files it dynamically links to.

Reflection - Internally the Unity SIP Library uses information about certain types when executing. Furthermore, permission to invoke methods on types may be required in future

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


version.

37

5.5 Architecture
The following diagram illustrates the overall architecture of the Unity SIP .NET API and important dependencies.

5.5.1 SIP Core


The SIP Core is the library facade (sometimes called an Aggregated class). It exposes important events, can control the most significate behaviours and methods of the library, sets the system configuration and other resources. The Core is also responsible for the initialization and termination of other layers. The Core provides an extensive event model to manage the processing of incoming and outgoing messages, subsequent processing or transport failures, and authentication and state data.

5.5.2 (Transactional) State


The transaction layer creates and manages transaction. Dialogs are usually associated with transactions. Each transaction is responsible for maintaining states, and sending and receiving

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

38

messages, acknowledgements and retransmissions using the transactional Timer. The transaction layer maps incoming messages to existing transactions and dialogs.

5.5.3 Transport
The transport layer handles SIP networking I/O. This layer manages UDP sockets and TCP connections, as specified in RFC3261, and sends and receives messages. Secure transmission is provided via TLS certificate exchange on a client-only or mutual basis.

5.5.4 Messages
Messages handle parsing and encoding of SIP messages. The message objects allow the strongly typed browsing and editing of the contents of SIP messages and also comparison of message parts, such as the SIP address. Validation of updates is provided as specified in RFC3261.

5.5.5 Parsing Engine


SIP is a text-encoded protocol, which means that messages are sent down the wire as a UTF8 encoded byte steam. Although encoding text messages is relatively simple, parsing them can be more complex because of the large degree of freedom provided by text grammar. SIP grammar is specified in RFC 3261 and uses an Augmented Bakus-Naur Form to represent the message syntax and structure. The SIP library uses a dedicated rule based DFA (Deterministic Finite Automaton) tokeniser/parser implemented according to the syntax and grammar of the protocol. This parser is optomised for performance and is thread-safe so that multiple messages can be parsed simultaneously in different thread contexts.

5.5.6 Authentication
SIP employs HTTP Digest authentication when establishing identiyy between elements. The Unity SIP Library uses a sophisticated authentication managment routine to control the lifetime of HTTP Digest exchanges.

5.5.7 DNS
RFC3263 governs how SIP resolves SIP URIs to IP Addresses. The Unity SIP Library provides a Linq friendly interface to the DNS querys and cache.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


5.5.1 The Exception Model
Konnetic follow the standard CLS model for reporting exceptions. User defined exceptions are

39

thrown when a method cannot complete its task as indicated by its name. All user defined exceptions derive from SipException, which in turn derives from System.Exception. The following exceptions are explicitly thrown within the Unity SIP .NET API, but other exceptions may originate from the Framework Class Library and are propagated up through the Unity SIP .NET API stack. For example, a System.Net.Sockets.SocketException may be thrown by the underlying network subsystem, or a resource constraint may cause a System.OutOfMemoryException to be thrown. Application designers need to consider subsystem exceptions when designing a robust exception policy.

5.5.1.1 Framework Class Library Defined Exception Classes


The following is a list of some of the standard .NET Framework exceptions that may be returned from the Unity SIP .NET API.
ArgumentException The exception that is thrown when one of the arguments provided to a method is not valid. The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method that does not accept it as a valid argument. The exception that is thrown when the value of an argument is outside the allowable range of values as defined by the invoked method. The exception that is thrown when the format of an argument does not meet the parameter specifications of the invoked method. The exception that is thrown when a method call is invalid for the object's current state. The exception can be returned from the Transport Layer when sending messages. The exception that is thrown when the time allotted for a process or operation has expired.

ArgumentNullException

ArgumentOutOfRangeException

FormatException

InvalidOperationException

ObjectDisposedException

TimeoutException

5.5.1.2 Unity SIP .NET API Specific Exception Classes

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

40

SipAggregateException

The aggregate exception wraps one-or-more inner exceptions. The exception is used to marshal a number of exceptions beyond the thread boundary. For example, the parsing of incoming message occurs on a thread spawned within the Transport Layer. Any parsing exceptions are wrapped in a SipAggreagateException and assigned to the SipMessage. The exception may be thrown on subsequent access to the SipMessage. The exception that is thrown when a generic SIP error occur. All SIP exceptions ultimately derive from this exception. The exception that is thrown when a SIP formatting error occurs. The exception that is thrown when parameters of a SIP message exceed the limit set. The exception that is thrown when a value is semantically out of allowable range or a numeric overflow occurs. The exception that is thrown when the parse method is invoked and it is detected that the passed arguments would result in illegal SIP syntax or semantics. It does not signify an invalid object. The exception that is thrown when an exception occurs in the authorization of sip messages. The exception that is thrown concerning an error in the transactional state machine for the message. The exception that is thrown when an error occurs in the transport layer. The exception that is thrown when a method is invoked and it is detected

SipException

SipFormatException

SipMessageSizeLimitException

SipOutOfRangeException

SipParseException

SipSecurityException

SipTransactionException

SipTransportException

SipUriException

that the passed arguments would result in illegal SIP URI syntax or semantics. The exception that is thrown when a SIP formatting error occurs when dealing with the SipUri class.

SipUriFormatException

5.5.1.3 Exception Object Model

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

41

5.5.2 Threading Model


The Unity SIP Library makes extensive use of threads. The library uses asynchronous calls whenever possible. Thread pool worker threads are used to invoke application callbacks and some events are raised on seperate threads where responsivness is demanded. Applications using the Unity SIP Library should not throw exceptions in these worker threads

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

42

because they will not be caught and handled appropriately within the Library and failure will result in the termination of the application. The library does not raise events or invoke application-supplied callbacks inside syncronisation primatives.

5.5.3 Class Diagrams


5.5.3.1 Class Diagrams
The following diagrams illustrate some of the more important relationships within the class hierarchy of Unity SIP .NET API.

5.5.3.1 Transaction Class Diagram

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

43

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

44

5.5.3.2 Transport Class Diagram

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

45

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

46

5.6 Application Programming Interface


The SIP library provides an intuitive and object-orientated API for the development of SIP-enabled applications. The API includes a set of events that allow your application to intervene in different phases of message and transaction establishment and termination. The SIP library can be made fully functional and operational with the use of minimal configuration and initialisation. The SIP Library API is divided into three layers, giving the user increasingly lower-level control of the functionality of messages and SIP library state machines. The highest level layer APIs abstracts away protocol complexity and provides for a simple interface to build SIP applications with minimal coding effort. Mid-level APIs enable sending and receiving messages from the primitive (transaction) level interface, managing routing, authorization and configuration. Low-level APIs provide access to SIP messages and enable the application to modify the SIP Libraries core functionality and behaviour. These APIs give the user tight control over the core SIP functionality, enabling you to rapidly deploy innovative functionality and to interwork with standard and even non-standard SIP applications. These different levels of APIs may be used in parallel, as described in more detail throughout this guide. This following sections describe the main API modules.

5.6.1 SIP Core API


The SIP Core API enables your applications to perform the following:

Initialisation and termination. Configuration Event management Start Listening for incoming messages Send outgoing messages Authorization

5.6.2 Transaction State API


The Transaction API is centralised around the SipTransactionStateManager object, Transaction derived types and Dialog derived types. They manage the application's state. Dialogs

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

47

The SipTransactionStateManager object enables you to terminate dialogs, modify exiting dialogs (re-INVITE) and more. The Dialog objects provide a set of events that provide you with the ability to add your own call processing logic to the application. Dialogs are created automatically by Invite Transactions. Transactions The SipTransaction derived types (GenericClientTransaction, InviteClientTransaction, GenericServerTransaction, InviteServerTransaction) enable you to manage transactional state. The transaction may be related to a dialog (e.g. for a trasnaction begun with an INVITE) or not (e.g. OPTIONS related transactions). Using the API you can create new transactions, send outgoing requests, and respond to incoming requests. However, SipTransactions are typically automatically created when sending a request. Transactions provide a set of events that enable you to control some of the behaviour. In addition to their usage in clients you can use the transactions to implement SIP servers such as Registrars and Proxies.

5.6.3 Message API


The SipMessage object provides access to the SIP message content, enabling the application to browse and edit any part of the message. Messages parts are represented a First-Line, Headers and Body triumverate. The SipMessage object also interfaces with the parsers and encoding formatters provided in the library. Each message can be associated with a set of Authentication exchanges, a transaction and a recipient.

5.6.4 Transport API


The TransportLayer enables you to send a messages directly bypassing the authorization, routing and transactional processing. Furthoremore it provides control over connection reuse and listening on local ports. SIP utilises DNS extensivly in order to resolve SIP URIs to IP addresses. The Unity SIP Library contains DNS querying functionality complicit with RFC3263. The SipDnsCache object contains the Naming Authority, Service Location and A/AAAA (IPv4/IPv6) caches.

5.6.5 Configuration API

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

48

The SipConfiguration object enables low-level configuration of the client parameters, transaction timers, message limits and behaviour.

5.6.6 Authorization API


HTTP Digest authorization is an important part of SIP interoperability. The Unity SIP Library provided a sophisticated authorization mechanism to control HTTP Digest negotiations after an authorization challenge.

5.7 SIP Transaction Objects


5.7.1 Dialog
A SIP dialog maps to one-or-more SIP transactions. It is a signalling relationship between two-ormore SIP endpoints. The following fields uniquely identify SIP dialogs:

Call-ID. The SIP address of both endpoints (To and From headers). The tag value attached to the To header.

In the SIP library, a Dialog object stores states and manages transactions on behalf of the dialog.

5.7.2 Transactions
A SIP transaction involves all messages sent between a client and a server for the purposes of completing one signalling action, such as call establishment and call termination. The dialog to which a transaction may belong and an Command Sequence identifier called CSeq uniquely identifies the transaction. In the SIP library a transaction stores the state and manages the progress through the use of timers, event handling and state machines. A transaction can also be used outside of the context of a specific dialog to accomplish User Agent signalling action.

5.8 The SIP URI


5.8.1 SIP URI
SIP and SIPS URIs are used for addressing. They are similar to email addresses in that they are of

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


the form user@host where user is either a user name or telephone number, and host is a host or

49

domain name, or a numeric IP address. Additionally, SIP and SIPS URIs may contain parameters and headers (although headers are not legal in all contexts). A SIP or SIPS URI identifies a communications resource. Like all URIs, SIP and SIPS URIs may be placed in web pages, email messages, or printed literature. They contain sufficient information to initiate and maintain a communication session with the resource. The following example shows the general syntax for a SIP URI. Refer to section 19 of the IETF RFC SIP Standard (http://www.ietf.org/rfc/rfc3261.txt). The "sip" and "sips" schemes use a form similar to the mailto URL, allowing the specification of SIP request-header fields and the SIP message-body. This makes it possible to specify the subject, media type, or urgency of sessions initiated by using a URI on a web page or in an email message. SIP URI sip:user:password@host:port;parameters?headers The format for a SIPS URI is the same, except that the scheme is "sips" instead of sip.

Working with SIP URIs


Konnetic's Unity SIP .NET API contains a SIP URI, SIP Parser and SIP Builder derived from the System.Uri, System.UriBuilder, and System.UriParser classes. The SipUri class defines the properties and methods for handling SIP URIs, including parsing, comparing, and combining. The SipUri class properties are read-only; to create an object either use the SipUriBuilder class or parse a URI string in the classes constructor. The Sip Style Parser is used by the underlying runtime to parse SIP schemes. The parser has be to registered as a well-known parser with the underlying runtime. The SipUri automatically registers the Sip Style Parser within Konnetic's Unity SIP .NET API. Use the ToString method to obtain a textural representation of the URI.

Create a SIP URI


Use the SipUri constructor to create a new SipUri by parsing a string. Create A SipUri
SipUri uri = new SipUri("sip:bob@atlanta.com:2100;maddr=239.255.255.1;ttl=15? subject=project%20x&priority=urgent");

Alternatively the SipUriBuilder can be used to construct a SipUri. The default scheme is "sip" throughout the library.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


Use the SipUriBuilder
SipUriBuilder builder = new SipUriBuilder(); builder.UserName = "bob"; builder.Host = "atlanta.com"; builder.Port = 2100; builder.MulticastAddress = "239.255.255.1"; builder.TimeToLive = 15; builder.AddHeader(new SubjectHeaderField("project")); builder.AddHeader(new PriorityHeaderField("urgent")); SipUri uri = builder.SipUri;

50

SIP URI Components


The main SIP URI components are described here.
URI Component scheme

Example

Default

Description

sip

sip

Identifies the scheme. The identifier of a particular resource at the host being addressed. A password associated with the user. The host providing the SIP resource.

user

alice

password

password

host

konnetic.com The default is 5060 for a "sip" scheme and 5061 for a "sips" scheme.

port

2100

The port number where the request is to be sent.

parameters

transport=tcp;method=REGISTER

Parameters influence SIP transport and processing. URI parameters are added after the hostport component and are separated by semi-colons.

Headers fields in the SIP request can be specified with the ?

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

51
mechanism within a URI. They provide additional information and can be used to construct a SIP Request from the URI.

headers

to=alice%40atlanta.com

SIP URI Parameters


Parameter Default Description The identifier of a particular resource at the host being addressed. If the host being addressed can process telephone numbers, for instance, an Internet telephony gateway, a telephone- subscriber field defined in IETF RFC 2806 may be used to populate the user field.

user

ip

method

INVITE

The method of the SIP request constructed from the URI may be specified with the method parameter. Indicates the server address to be contacted for this user, overriding any address derived from the host field. Determines the time-to-live value of the UDP (User Datagram Protocol) and must only be used if maddr is a multicast address and the transport protocol is UDP

maddr

ttl

transport

For "sip" it is Determines the transport protocol to be used for sending SIP messages. For UDP. For "sips" a SIPS URI, the transport parameter must indicate a reliable transport it is TCP. protocol.

lr

Indicates that the element responsible for this resource implements the routing mechanisms specified in RFC 3261.

5.9 Walkthrough: Initiate a Session


Session Initiation Protocol is intended to be used to connect people and devices whenever and wherever they are in order to engage in a conversation or exchange of information of some sort. SIP achieves this aim through the use of an invitation and acceptance or decline of that invitation. It

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

52

does this through what is referred to as the Offer/Answer model - which is little more than one party sending an initial query and then waiting for an answer from the other party. This walkthrough creates a simple console application that initiates a call with an correspondent, waits for a response, and then, optionally, acknowledges that response. The walkthrough is intended to show the steps needed to setup a SIP session.

Open A New Project


Create a new C# Console application. 1. Open a new Visual C# Console project in Visual Studio or Mono development environment. 2. Name the project InitiateASession. 3. Add a reference to Konnetic.Signalling.dll, which is installed in the installation directory you specified at install time. 4. Add a new class to the project. Name the file InitiateASession.cs.

Configuring the Application


Select the project in the Solution Explorer. 1. Right-click the InitiateASession project item, choose Add->New Item. 2. In the Add New Item window select Application Configuration File. Leave the name as App.config. 3. Click Add. 4. Open up the App.config file and add the following configuration after the <configuration> element and before the </configuration> element. Optionally you can change the uri attribute in the defaultUserSipAddress element.

<configSections> <sectionGroup name="konneticSettings" type="Konnetic.KonneticConfigurationSectionGroup, Konnetic.Signalling, Culture=neutral, PublicKeyToken=255449bd8f8c3771" > <section name="sip" type="Konnetic.Signalling.Sip.Advanced.Configuration.SipConfigurationSection, Konnetic.Signalling, Culture=neutral, PublicKeyToken=255449bd8f8c3771" requirePermission="false"/> </sectionGroup> </configSections> <konneticSettings> <sip> <!--The default SIP URI for the client-->

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


<defaultUserSipAddress uri="sip:alice@yourcompany.com" /> </sip> </konneticSettings>

53

Adding The Code To Send the Invitation


1. Add the following statements to the Program class. using Konnetic.Signalling.Sip; 2. Add the following code to the Program class. //Declare the SIP library factored SIPCore class static SipCore core; 3. Add the following class declarations at the top of the body of the Program class. public static void Start(){ } 4. We first set the license key programmatically, then initialise the SipCore object in the Start() method.

//Set the license key and initialise the SipCore Konnetic.Signalling.Sip.LicenseContainer.Key = "******PUT LICENCE KEY FROM EMAIL HERE******"; core = new SipCore(); 5. Inside the Start() method add the following code to create a new INVITE message. Optionally change the destination address passed into the CreateInviteRequest method.

//Create an Invite message. Use the factory method on the Invite object. //This method //relies heavily on the configuration to provide default values for the //message. InviteRequest invite = InviteRequest.CreateInviteRequest(new SipUri ("sip:bob@mel99.melbourne.com")); 6. The following code example shows how to register with a Request message to receive ResponseReceived events. Add it to the Start() method.

//Register to receive notification of responses invite.ResponseReceived += new EventHandler<ResponseReceivedEventArgs> (OnInviteResponseReceived); 7. Finally, add code to send the request and wait for user input

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


//Send the message core.SendRequest(invite); //Make sure the main thread does not terminate Console.WriteLine("Press any key to finish."); Console.ReadLine();

54

Handling the Response


1. Add the following member to the class to handle the response to the INVITE.

//Recieve a response to the INVITE request private static void OnInviteResponseReceived(object sender, ResponseReceivedEventArgs e) { if(e.Response.StatusClass == SipStatusClass.Successful) { if(e.Response.StatusCode == SipStatusCode.Trying){ //The other party sent us a Trying message to say the request got through and it is trying to establish a call. Console.WriteLine("===Trying==="); } if(e.Response.StatusCode == SipStatusCode.Ringing) { //The other party sent us a Ringing message to say the request got through and it is actively obtaining a response. Console.WriteLine("===Ringing==="); } if(e.Response.StatusCode == SipStatusCode.Ok){ //We got an OK. //Reply with an Acknowledgment InviteClientTransaction transaction = e.Response.Transaction as InviteClientTransaction; if(transaction!=null){ AckRequest ack = AckRequest.CreateAck((InviteRequest) transaction.OriginalRequest, e.Response.To.Tag); core.SendRequestDirect(ack); Console.WriteLine("===Sent ACK==="); } Console.WriteLine("===INVITE Success==="); } } else{ //INVITE failed. Console.WriteLine("===INVITE failed==="); Console.WriteLine("Reason: " + e.Response.StatusLine.ReasonPhrase); } } 2. Build the solution and run.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

55

5.10 Walkthrough: Accept Or Decline A Session Invite


Unlike HTTP or SMTP, Session Initiation Protocol allows a party on the internet to initiate a data exchange with you. However, you must be able to accept or decline that invitation. SIP achieves this aim through the use of an response messages: OK and Decline in this example. It does this through what is referred to as the Offer/Answer model - which is little more than one party sending an initial query and then waiting for an answer from the other party. This walkthrough creates a simple console application that listens for incoming messages, queries any Invite request to see who is sending the request, and then either accepting the invitation or declining it. The walkthrough is intended to show the steps needed to accept and respond to invitations.

Open A New Project


Create a new C# Console application. 1. Open a new Visual C# Console project in Visual Studio or Mono development environment. 2. Name the project AcceptOrDeclineInvite. 3. Add a reference to Konnetic.Signalling.dll, which is installed in the installation directory you specified at install time. 4. Add a new class to the project. Name the file AcceptOrDeclineInvite.cs

Configuring the Application


Select the project in the Solution Explorer. 1. Right-click the InitiateASession project item, choose Add->New Item. 2. In the Add New Item window select Application Configuration File. Leave the name as App.config. 3. Click Add. 4. Open up the App.config file and add the following configuration after the <configuration> element and before the </configuration> element. Optionally you can change the uri attribute in the defaultUserSipAddress element.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

56

<configSections> <sectionGroup name="konneticSettings" type="Konnetic.KonneticConfigurationSectionGroup, Konnetic.Signalling, Culture=neutral, PublicKeyToken=255449bd8f8c3771" > <section name="sip" type="Konnetic.Signalling.Sip.Advanced.Configuration.SipConfigurationSection, Konnetic.Signalling, Culture=neutral, PublicKeyToken=255449bd8f8c3771" requirePermission="false"/> </sectionGroup> </configSections> <konneticSettings> <sip> <!--The default SIP URI for the client--> <defaultUserSipAddress uri="sip:alice@yourcompany.com" /> </sip> </konneticSettings>

Adding The Code To Listen for Messages


1. Add the following statements to the Program class. using Konnetic.Signalling.Sip; 2. Add the following declarations at the top of the body of the Program class.

//Declare the SIP library factored SIPCore class static SipCore core; 3. Add the following class declarations at the top of the body of the Program class. public static void Start(){ } 4. We first set the license key programmatically, then initialise the SipCore object in the Start() method.

//Set the license key and initialise the SipCore Konnetic.Signalling.Sip.LicenseContainer.Key = "******PUT LICENCE KEY FROM EMAIL HERE******"; core = new SipCore(); 5. Inside the Start() method add the following code to listen for incoming messages. Optionally change the local interface, port and transport protocol. //Start listening on the default local interfact on port 5060 for UDP messages only. core.StartListening(5060, TransportProtocol.Udp);

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


6.

57

The following code example shows how to register to receive request message receipt events. Finally wait for user input.

//Register to receive request messages core.RequestReceived += new EventHandler<RequestReceivedEventArgs>(OnRequestReceived); //Make sure the main thread does not terminate Console.WriteLine("Press any key to finish."); Console.ReadLine();

Handling the Request


1. Add the following member to the class. If the user is Bob then accept, otherwise decline

//Handle newly arrived request messages static void OnRequestReceived(object sender, RequestReceivedEventArgs e) { SipRequest request = e.Request; if(request.Method == SipMethod.Invite) { Console.WriteLine("Invite Arrived"); //Accept if it is Bob, otherwise decline. if(request.From.Uri.UserName=="Bob"){ sipCore.SendResponse(new SipResponse(request, SipStatusCode.Ok)); } else { sipCore.SendResponse(new SipResponse(request, SipStatusCode.Decline)); } } else{ Console.WriteLine(string.Format("{0} Request Arrived", request.Method)); } } 2. Build the solution and run.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


6 Configuration

58

Introduction
This chapter describes the configuration of the SIP library. You will find information about the SIP library configuration parameters and how to set the parameters to suit your specific application requirements. The SIP library configuration is performed upon initialisation of the SipCore type. The format of the configuration files follows that of the standard .Net application config (http://msdn.microsoft.com/en-us/library/0hyxd0xc(v=VS.71).aspx) files. The SipCore takes as an overloaded constructor a Configuration object that you can use with Web configuration files, or non-standard deployments. The configSections specifies the Konnetic config section element and type.
<configuration> <configSections> <sectionGroup name="konneticSettings" type="Konnetic.KonneticSipConfigurationSectionGroup, Konnetic.Common" > <section name="sip" type="Konnetic.Signalling.Sip.Advanced.Configuration.SipConfigurationSection, Konnetic.Signalling" requirePermission="false"/> </sectionGroup> </configSections> <konneticSettings> <sip/> </konneticSettings> </configuration>

6.1 Runtime
Although it will be typical to configure the library using the application configuration, all configuration options are exposed using the SipConfiguration static object.

6.1 Common Client Settings


This section details some of the more common config settings. It is recommended that all clients specify a defaultUserSipAddress, and userContacts.

Default User SIP Address

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

59

This config section details the the default SIP URI to use for a client's From URI. This value is used throughout the SIP library within the Request and Response factory methods. If this value is missing, then the factory methods will add an anonymous value into the From URI (e.g. "\"Anonymous\" <sip:anonymous@anonymous.invalid>"). The element name is defaultUserSipAddress. There is only one attribute: uri, containing the SIP URI of the default user. <konneticSettings> <sip> <!--The default SIP URI for the client--> <defaultUserSipAddress uri="sip:joe.b@contoso.com" /> </sip> </konneticSettings>

User Contacts
User contacts specify the alternate contact address for the user. Only SIP URIs are supported. The configuration section is a collection of URIs. If the section is missing, no alternate user contacts are specified. The element name is userContacts. There are no attributes. The element contains child elements. Use the add element with an attribute named uri to add new URIs to the UserContacts config section. <konneticSettings> <sip> <!--The (other) user contacts for the client, no user contacts are specified if empty--> <!--At least one contact should be a SIP URI--> <userContacts> <add uri="sip:joe.b@contoso.com" /> <add uri="mailto:joeb@gsip.com" /> </userContacts> </sip> </konneticSettings>

License
The License config section specifies the license key, type an registered name. Alternative mechanisms are available to provide the license key details are runtime including programmatically and via license files. The element name is license. There are three attributes. The type attribute must be set to "Konnetic.Signalling.Sip.License". The name attribute must be set to the registered name provided

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


when the product was acquired. The key attribute is the key provided to you in the confirmation email sent to the email address provided when the product was acquired. <konneticSettings> <sip> <license type="Konnetic.Signalling.Sip.License" name="Harry Hill" key="ABC-DEF-123-456" /> </sip> </konneticSettings>

60

ProxyServers
The ProxyServers config section allows the client application to configure the default outbound proxy servers for request messages. Alternative mechanisms are available to provide the proxy services, including on the SipCore. The proxy servers are used by the outgoing message processsors to create a route-set on the message (unless a route header field is already present). The processor calculates the remote address of the message according to RFC3261 and RFC3263 and takes into account the existiance of outbout proxy servers, Route header fields and loose routing rules. Passwords It is not recommended to store passwords in configuration files, although it is common. The SipCore provides a mechanism that you can use to add, edit and remove proxy servers <konneticSettings> <sip> <sipProxyServers> <add uri="sip:proxy1.com;lr" /> <add uri="sip:proxy2.com" realm="proxy1" username="username" password="password" /> </sipProxyServers> </sip> </konneticSettings>

6.1.1 Secure Proxy Servers


There is a separate configuration for secure proxy servers to be configured as an outbout route-set for all secure transmissions. Only proxy servers with secure SIP URIs are allowed (e.g. sips:proxy3.com).

6.2 Low-Level Client Settings

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


This section details some of the less common and low level configuration settings:

61

User Agent
SIP allows a client to specify the type of machine it is using in the UserAgent header field. This config element specifies the user agent setting. If the element is missing, by default, no UserAgent will be specified. The element name is userAgent. There is one attribute: value. The attribute is a textural (UTF8) value indicating the agent type. <konneticSettings> <sip> <userAgent value="Softphone Beta1.5"/> </sip> </konneticSettings>

Supported Methods
SIP allows a client to specify the methods that it supports using the Allow header field. The config element name is supportedMethods. There is one attribute: methods. The attribute is a comma delimited list of upper-case method names. If the section is missing, the default is to specify the minimum required by RFC3261: INVITE, BYE, OPTIONS, REGISTER, CANCEL and ACK. <konneticSettings> <sip> <supportedMethods methods="INVITE,BYE,OPTIONS,CANCEL,ACK,MESSAGE"/> </sip> </konneticSettings>

Supported Scheme
SIP allows a client to reject a message based on the scheme. This config section specifies the scheme supported. The config element name is supportedScheme. There is one attribute: scheme. The attribute is a comma delimited list of lower-case scheme names. If the section is missing, the default is to specify sip and sips. <konneticSettings> <sip> <supportedScheme scheme="sip,sips"/> </sip> </konneticSettings>

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


Supported Extensions

62

SIP allows a client to specify that it understands certain extension and options using the Supported header field. This config section specifies the options supported. The config element name is supportedExtensions. There is one attribute: options. The attribute is a comma delimited list of lower-case options. If the section is missing, the default is to specify no supported extensions. <konneticSettings> <sip> <supportedExtensions options="100rel"/> </sip> </konneticSettings>

Supported Languages
SIP allows a client to specify that its content is intended for a particular natural language audience using the Content-Language header field. This config section specifies the default languages. The config element name is defaultLanguages. There is one attribute: languages. The attribute is a comma delimited list of case insensitive ISO-639 language abbreviations. If the section is missing, the default is to specify no content-language. <konneticSettings> <sip> <supportedLanguages languages="en-gb,de" /> </sip> </konneticSettings>

Supported Content Encoding


SIP allows a client to specify additional content codings that have been applied to the entity-body using the Content-Encoding header field. This config section specifies the default encodings. The config element name is defaultEncodings. There is one attribute: encodings. The attribute is a comma delimited list of case insensitive IANA registered encodings. If the section is missing, the default is to specify no content-encoding. <konneticSettings> <sip> <supportedEncodings encodings="gzip"/> </sip> </konneticSettings>

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


Supported Content Types

63

SIP allows a client to specify the acceptable media type of the message entity-body using the Accept header field. This config section specifies the default media types supported by the client. The element name is supportedMediaTypes. There are no attributes. The element contains child elements. Use the add element with an attribute named media to add new media types to the supported media types config section. If the section is missing, the default is to specify no mediatypes. <konneticSettings> <sip> <supportedContentTypes> <add media="application/sdp"/> <add media="text/html"/> </supportedContentTypes> </sip> </konneticSettings>

Required Extensions
SIP allows a client to demand that the other party support an extension using the Require header field. This config section specifies the default extensions demanded by the client. The element name is requiredExtensions. There is one attribute: options. The attribute is a comma delimited list of lower-case options. If the section is missing, the default is to specify no required extensions. <konneticSettings> <sip> <requiredExtensions methods="100rel"/> </sip> </konneticSettings>

Default Transport Protocol


The default transport protocol config section must coincide with an supported and recognised protocol. UDP is used if the configuration section is missing. The configuration element is used a the default transport for the Via Header Field, and the default Transport for a (non-secure) SIP Uri. The element name is defaultTransportProtocol. There is only one attribute: protocol. Three values are supported: TLS, TCP or UDP.

<konneticSettings>

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

64

<sip> <!--The default transport protocol for the client, UDP is the default if empty--> <defaultTransportProtocol protocol="UDP" /> </sip> </konneticSettings>

6.3 Internal Settings


The configuration settings can be used to configure and optomise the internal behaviour of the SIP library:

Message Limits
The transport layer puts limits on certain internal message metrics. This primary reason is to prevent users and other parties from introducing poorly defined messages into the system. This may be to introduce security features that prevent harmful messages being processed. The following limits have been defined:
Limit Unit integer count integer count Default Description The maximum number of bytes allowed in the message body. The maximum number of SIP header fields on a message. The maximum number of bytes allowed for a header name. The maximum number of bytes allowed for a header value. The maximum number of parameters allowed on a header field. The maximum number of bytes allowed for whitespace in a header field.

maximumContentSize

5242880

maximumHeaderCount

256

maximumHeaderNameSize byte count

1024

maximumHeaderValueSize byte count

65537

maximumParameterCount

integer count

32

maximumWhitespaceSize

byte count

1024

The messageLimits config section specifies the default values. The element name is messageLimits . There is one attribute per limit. The attribute is a whole

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


integer number. If the section is missing, the default specifies above is used.

65

<konneticSettings> <sip> <messageLimits maximumHeaderCount="100" maximumHeaderNameSize="512" maximumHeaderValueSize="4000" maximumParameterCount="20" maximumWhiteSpaceSize="100"/> </sip> </konneticSettings>

Timers
The transaction layer uses timers to control their behaviour. These timers can be configured. This primary reason is to optomise the library to conditions experienced by your environment. The timers and the configuration names are shown in the following table:
Timer ConfigName Default Value 500ms default Description

T1

TimerT1

RTT Estimate

T2

TimerT2

4s

The maximum retransmit interval for non-INVITE requests and INVITE responses Maximum duration a message will remain in the network INVITE transaction retransmit interval, for UDP only INVITE transaction timeout timer Proxy INVITE transaction timeout

T4

TimerT4

5s initially T1 64*T1 > 3min > 32s for UDP initially T1 64*T1

Timer A TimerA Timer B TimerB Timer C TimerC Timer D TimerDUdp/ TimerDTcp

Wait time for response 0s for TCP/SCTP retransmits

Timer E TimerE Timer F Timer F Timer G Timer

Generic INVITE transaction retransmit interval, UDP only Generic INVITE transaction timeout timer

TimerG

initially T1

INVITE response retransmit interval

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


H TimerH TimerIUdp/ TimerITcp TimerJUdp/ TimerTcp TimerKUdp/ TimerKTcp 64*T1 Wait time for ACK receipt

66

Timer I

T4 for UDP

Wait time for 0s for TCP/SCTP ACK retransmits

Timer J

64*T1 for UDP

Wait time for 0s for TCP/SCTP non-INVITE request retransmits

Timer K

T4 for UDP

Wait time for 0s for TCP/SCTP response retransmits

The element name is timers. There are no attributes. The element contains child elements. Use the add element with an attribute named key to specify the timer name, and attribute value to add the default value in milliseconds. If the section is missing, the default value shown in the above table is used. <konneticSettings> <sip> <timers> <add key="TimerT2" value="600"/> </timers> </sip> </konneticSettings>

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


7 Working with the SipCore

67

Introduction
SipCore is an aggregate component which acts as a facade providing simplified views over the more complex but more powerful factored types, such as the HttpDigestAuthenticationManager, SipTransportLayer, SipTransactionStateManager and incoming and outgoing message processors which deal with parsing, Via header handling, address resolution, updating of state, and transmission management. This section deals with the basics necessary to write an application using the SIP library and the SipCore object, including:

Creation Destruction Event Processing Sending Messages Listening for Messages Configuration

7.1 Initialisation
7.1.1 Creation
Before performing any SIP-related activity, you must create and initialise a SipCore object. The SipCore performs the following:

Initialises a new SipTransportLayer object Initialises a new SipTransactionStateManager object. Initialises a new HttpDigestClientAuthenticationManager object. Parses any application configuration. Validates the license. Deserializes the SipConfiguration object.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


C#: Initialise the SIP Library using Konnetic.Signalling.Sip; ... SipCore core = new SipCore();

68

7.1.2 Disposal
The SipCore object exposes a finalizer method. The Finaliser thread will initiate a disposal of all messages, transactions and listeners created using the SipCore object.

7.1.3 Properties
LocalAddressPort Used by the MessageTransmitter to specify on the 'Via' header field which end point the application wants the returned messages to be sent to (the 'sentby' property). An application may wish to provide a fully qualified domain name or an internet addressable IP address. If empty the default local IP address is used. ProxyServerCollection Specifies a pre-existing route set for any outbound messages. The ProxyServerCollection property can be set by applications to force a particular route set for the message. SecureProxyServerCollection Specifies a pre-existing route set for any outbound secure messages using TLS. The SecureProxyServerCollection property can be set by applications to force a particular route set for the message. Only SIPS addresses are allowed on the route-set for a secure message transmission. TransportLayer The SipTransportLayer which is managing the transmission of messages to and from the network on behalf of this SipCore. SipTransactionState The SipTransactionStateManager which is managing the transactional and dialog state on behalf of this SipCore. ClientCertificates TLS message transmission requires clients to provide a certificate to the server for mutual

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


authentication. The ClientCertificates are copied directly to the SipTransportLayer. MultiHeaderFormat

69

A value indicating whether the SIP library should seperate multiple-valued headers onto seperate lines where possible. HeaderNameFormat A value indicating whether the SIP library should use compact header field names by default.

7.2 Sip Core Behaviours


SIP behavioural flag exposed as the Behaviour property of the SipCore object controls specific behaviour of the library and allow fine tuning of its functionality. The library can be directed to support RFC2543 style syntax, or use the Additional Headers stucture when querying DNS servers. The library can be made to frame messages off the network using a single NewLine as opposed to a CRLF combination. There are currently 10 behaviours specified. Certain behaviours, such as framing on a single new line, are not recommend in production systems. Behaviour SupportRFC2543Syntax Description The library supports RFC3261 style syntax by default. Use this flag to relax the behaviour of the library to support some of the RFC2543 style syntax. RFC3263 deals with the location of SIP servers using DNS. A DNS query may return more than the immediate result in what are known as Additional Headers. These may be used to reduce the overall number of DNS queries needed. RFC3261 makes it clear that header fields must be seperated by a carriage-return followed by a line-feed (CRLF). However some implementations, and some circumstances (e.g. in testing), we can expect to use a single newline character (i.e. a CR or a LF). Use this flag to relax the behaviour of the library and allow messages to be framed using a single newline character or a CRLF. The library detects the framing character(s) from the first line of the message. Consider running without this flag in production systems. If IPv6 is supported, AAAA type DNS queries are performed in order to obtain the IPv6 address.

UseAdditionalDnsRecords

AllowFramingOnSingleNewLine

SupportIPv6Dns

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

70

UseHttpDigestIntegrityAuthentication

The library contains sophisticated Authentication management routines. Message integrity can be provided using the Digest Auth-Int mechanism. The default behaviour is to support authentication only, use this flag to also support integrity.

The library validates incoming messages against the RFC3261 standard on a relaxed basis by default. This entails checking for the presence of mandatory fields and properties required for further processing. Use this ExtendedValidationOfIncomingMessages flag to increase the validation behaviour of the library and send automatic responses to some standard validation failures. The validation makes heavy use of the SIP configuration. The library parses incoming messages and validates them against the RFC3261 standard. Any exceptions are caught and housed in the ParseExceptions (SipAggregateExceptions) property on the SIP Message. The library is relaxed by default and does not automatically throw these exceptions. Use this flag to conveniently throw any exceptions on first access to an instance member of the SIP Message. RFC3261 describes a sophisticated call management routine. SIP DNS resolution can result in an ordered list of address, port, transport tuples to try. Only when the previous tuple fails (failure is defined as either a transport error or transaction timeout) does the next tuple get attempted. This can result in the same message being sent many times (each transaction will also retransmit the message a number of times). Use this flag to disable call managment and only rely upon the transaction retransmission to the first (preferred) tuple.

ThrowOnParseExceptions

DisableCallManagement

7.3 Event Processing


7.3.1 Event Processing
After intialising the library, you may want to listen for events emanating from SIP operations. You can conveniently do this by registering with the events of the SipCore object. Due to the multithreaded nature of the transport layer, events are used to convey failures in some instances.
Event Description

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


CertificateAuthenticationFailure Occurs when when SSL certificate authentication fails. Occurs when a server attempts to authenticate a certificate with this library.

71

CertificateValidation

ClientTransactionCreated

Occurs when client transaction is created is response to sending a request.

Occurs when a connection is created. ConnectionCreated Connections can be created when the user client begins to listen for requests and a recipient initates a transmission or when the user client sends a message to a new recipient. Occurs when a connection is dropped or forcably terminated. This occurs at timeout or because the other side dropped the connection. Occurs when data is received at the transport layer. Occurs when data is sent at the transport layer.

ConnectionDisposed

DataReceived DataSent

Occurs when a dialog is created. DialogCreated In the standard SIP implementation Dialog's are created on reciept of a successful response to an INVITE. Occurs when a listener aborts its operation. Occurs when there is a failure in the message processing. Occurs when the transaction failed to send a message. Occurs when a request is received from the transport layer. Occurs when a response is received from the transport layer. Occurs just before a request is sent and gives the user client an opportunity to cancel the transmission. Occurs just before a response is sent and gives the user client an opportunity to cancel the transmission. Occurs when a server transaction is created in response to receipt of a new request.

ListenerAborted MessageProcessingAborted MessageSendFailed RequestReceived ResponseReceived

SendingRequest

SendingResponse

ServerTransactionCreated

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


TransactionTimedOut Occurs when a transaction times out.

72

TransportFailure

Occurs when a message is received and the processing fails in the transport layer or when there is an asyncronous send failure. The event is fired when the transport layer cannot frame the message, or the message does not obey standard framing and basic parsing rules (e.g. lack of Content-Length field in TCP transports or missing CRLF at the end of a header field). Framing is the process of identifying discrete messages within a stream such as a TCP network stream. Occurs when an unmatched request is received from the transport layer. The event is fired when a CANCEL message is received that does not match any existing transaction. This is typically due to a recipient attempting to end a session with this user client where the transaction has timed out. Occurs when an unmatched response received from the transport layer. Occurs when the library is validating the request. Allows user client to cancel validation and/or send a response. Occurs prior to when the library validates the response. Allows the user client to authenticate the response and cancel validation, further processing and/or send a response.

UnmatchedCancelReceived

UnmatchedResponseReceived

UserRequestValidation

UserResponseValidation

The following code demonstrates how initalises the core, start listening for incoming messages on interface "124.191.1.8:5060" and print out the reason phrase to the console on creation of a new Server Transaction. C#: Register to receive notification of incoming messages using System; using System.Net; using Konnetic.Signalling.Sip; ... //Initialise SipCore core = new SipCore(); //Start Listening on IP 124.191.1.8 with the default SIP port of 5060. core.StartListening(new IPEndPoint(IPAddress.Parse("124.191.1.8"), 5060)); //Register to receive notificaton of new messages and print the Reason Phrase to the console core.ServerTransactionCreated += delegate(object sender, TransactionEventArgs e) { Console.WriteLine(e.Transaction.MostRecentResponse.StatusLine.ReasonPhrase);

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


};

73

7.4 Listening For Incoming Messages


The SIP library manages connections opened to the application using Listener objects within the TransportLayer object. In order to begin receiving incoming message on a particular interface the SipCore provides an overloaded StartListening() method and a corresponding StopListening() method. The application can specify an interface to begin listening to. Otherwise the local machines default registered IPv4 interface is used. A Socket exception will be thrown if the interface already has a handle attached. Generally, incoming connections should be closed by the party that initiated the connection. It is possible to manage incoming connections but it is recommended not to terminate incoming connections from the application to prevent unexpected interruptions in message reception and sending flow. The SIPTransportLayer provides a means to establish, maintain, and release transport connections, using SipConnection objects and the SipConnectionPool API. The following code demonstrates how to initalises the core, start listening for incoming messages on interface "124.191.1.8:5060" using UDP, then stop listening. C#: Listen on a Local Interface using System; using System.Net; using Konnetic.Signalling.Sip; ... //Initialise SipCore core = new SipCore(); //Start Listening on the default interface on SIP port of 5060. UDP is specified. core.StartListening(5060, TransportProtocol.Udp); //Register to receive notification of new data and print out who sent the data, how many header fields are contained in the message, and the length of the content core.TransportLayer.DataReceived += delegate(object sender, DataReceivedEventArgs e) { Console.WriteLine("From: " + e.Sender.HostPort); Console.WriteLine("HeaderField Count: " + e.Data.HeaderFields.Count); Console.WriteLine("Content Length: " + e.Data.ContentLength); }; //Now stop listening

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


core.StopListening();

74

7.5 Sending Messages


The SipCore API provides the SendRequest() and SendResponse() methods for sending messages. Responses should be sent using transactions, however one SendResponse() overload send the response direct to the SipTransportLayer for delivery, with the other simply using the Response's Transaction object to send the message. The SendRequest() methods sends a message to the remote party using DNS to resolve the IP Address and Transport, or specifies the destination explicitly. Either way transaction, authentication and validation processing is then undertaken before passing the message to the SipTransportLayer for delivery. The application should supply the message that it wishes the SipCore to send. In addition, for direct transmission, the application must supply a destination in the form of an DestinationTuple object. Otherwise the library will resolve the IP Address to use from the RequestURI or Route Headers using DNS. Once in receipt of the message, the Sip Library creates a new ClientTransaction and assigns the value to the Request's Transaction property. The Request is then passed to the OutgoingMessgeProcessor for handling and forward delivery. The following code demonstrates sending an INVITE message to 'sip:bob@mell99.melbourne.com'. The transport and IP address will be obtained via DNS resolution. C#: Send an Invite using System; using System.Net; using Konnetic.Signalling.Sip; ... //Initialise SipCore core = new SipCore(); //Create an Invite message. Use the factory method on the Invite object. This method relies heavily on the configuration to provide default values for the message. InviteRequest invite = InviteRequest.CreateInviteRequest(new SipUri ("sip:bob@mell99.melbourne.com")); //Send the message

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


core.SendRequest(invite);

75

Alternatively, the following code demonstrates sending the same message directly to "124.191.8.8" using TCP. C#: Send an Invite using System; using System.Net; using Konnetic.Signalling.Sip; ... //Initialise SipCore core = new SipCore(); //Create an Invite message. Use the factory method on the Invite object. This method relies heavily on the configuration to provide default values for the message. InviteRequest invite = InviteRequest.CreateInviteRequest(new SipUri ("sip:bob@mell99.melbourne.com")); //Create a destination for the message. DestinationTuple destination = new DestinationTuple("124.191.8.8", 9000, TransportProtocol.Tcp); //Send the message core.SendRequest(invite, destination);

7.5.1 Sending an INVITE and SDP message


The following code demonstrates sending an INVITE message with a Session Description Protocol payload to 'sip:bob@mell99.melbourne.com'. C#: Send an Invite and SDP using System; using System.Net; using Konnetic.Signalling.Sip; using Konnetic.Sdp; ... //Initialise SipCore core = new SipCore(); //Create an Invite message. Use the factory method on the Invite object. This method relies heavily on the configuration to provide default values for the message. InviteRequest invite = InviteRequest.CreateInviteRequest(new SipUri ("sip:bob@mell99.melbourne.com")); //Create the SDP message. SdpMessage sdp = new SdpMessage(); sdp.Origin = "UserA 2890844526 2890844526 IN IP4 here.com"; sdp.SessionName = "Session SDP"; sdp.Connection = "IN IP4 100.101.102.103";

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


TimeDescriptionHeaderField td = new TimeDescriptionHeaderField(); td.Timings = "0 0"; sdp.TimeDescriptions.Add(td); MediaDescriptionHeaderField md = new MediaDescriptionHeaderField(); md.MediaHeaderField = "audio 49172 RTP/AVP 0"; md.Attributes.Add(new AttributeHeaderField("rtpmap", "0 PCMU/8000")); sdp.MediaDescriptions.Add(md); //Assign the SDP messsage to the INVITE. invite.Body = sdp.GetBytes(); //Send the message core.SendRequest(invite);

76

7.5.2 Proxy Servers


SIP supports the concept of Proxy Servers as intermediary nodes to aid in the delivery of messages, security as well as mobility. The SIP Stack lets you configure a set of outbound proxys for both secure and non-seucre message that will be used for all outgoing requests (unless a record-route is used). You can supply the outbound proxy as a SIP Uri. You should also supply the credentials for the proxy if required. The list of proxy servers goes to for a Route-Set for the outbound request. When the message includes one or more Route headers, the outgoing message processor will always ignore the outbound proxys. If there are no Route headers and an outbound proxy is configured, it will be used as the remote address of the message. In some cases, the application will want the outgoing message processor to ignore the outbound proxy even if it is configured to use one. An example is the case of strict routing when a single Route header becomes the message request URI, and therefore the message does not include any Route headers but the outgoing message processor still needs to ignore its outbound proxy.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


8 Working with Messages and Headers

77

The SIP library provides a flexible API for working with SIP messages and message parts such as headers and addresses. The Message API provides functions for working with the following objects:

SipMessage SipUri Body Owning Transactions Parsing Exceptions Authentication Context

Header objects:

Accept AcceptEncoding AcceptLanguage AlertInfo Allow AuthenticationInfo Authorization Body CallId CallInfo Contact ContentDisposition ContentEncoding ContentLanguage ContentLength ContentType CSeq Date ErrorInfo Expires

MaxForwards MimeVersion MinExpires Organization Priority ProxyAuthenticate ProxyAuthorization ProxyRequire RecordRoute ReplyTo Require RetryAfter Route Server Subject Supported Timestamp To Unsupported UserAgent

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


Extension From InReplyTo Via Warning WwwAuthenticate

78

8.1 SipMessage
The SipMessage object manages the collection of Header Fields, content, parsing exceptions and managing transaction. It is used to construct stand alone messages or represent messages received from the Transport Layer. It is an abstract class with two concrete derived classes:

Response Request (base class of InviteRequest, OptionRequest, RegisterRequest, AckRequest, ByeRequest, CancelRequest, InfoRequest, UpdateRequest, MessageRequest types)

The SipResponse and SipRequest classes contain all the message parts, including the message start line, one or more header fields and an optional message-body. The SipMessage API functions can be categorised as follows

Constructors Header Fields and functions Encoding and Parsing Functions Owning Transaction Parsing Exceptions

8.1.1 Parsing Exceptions


When the SIP library receives an incoming SIP message, the message can contain headers with various syntax errors. The SIP library default behavior is to automatically store the exception and continue. Clients can investigate incoming messages with syntax errors and respond by a) behaving as if the message was never received b) sending a Response indicating the error c) attempt to process the message.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


8.1.2 RequestTypeProxy and ResponseTypeProxy
The MultiValued properties are lazy-added to the SipMessage header collection when accessed.

79

Because of this side-effect with the MultiValued properties, the debugger will dirty the debugging process when accessing any property to display the value in the IDE. For this reason, the SipMessage derived objects have their DebuggerTypeProxy attribute set. The proxy displays only the header fields present, the first line, transaction and exception properties. Access to the underlying type can be obtained during debugging by accessing the base set property.

8.2 Message Types


Message Types
The SIP library supports all Response and Request types specified in RFC3261, RFC2976, RFC3311 and RFC3428. This includes the following:

8.2.1 Request Types

AckRequest ByeRequest CancelRequest InviteRequest OptionsRequest RegisterRequest UpdateRequest InfoRequest MessageRequest

8.2.2 Response Types


AddressIncomplete AlternativeService Ambiguous BadExtension NotFound NotImplemented Ok PaymentRequired

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


BadGateway BadRequest BusyEverywhere BusyHere CallIsBeingForwarded CallOrTransactionDoesNotExist Decline DoesNotExistAnywhere ExtensionRequired Forbidden Gone IntervalTooBrief LoopDetected MessageTooLarge MethodNotAllowed MovedPermanently MovedTemporarily MultipleChoices NotAcceptableGlobal NotAcceptableHere NotAcceptableRequest ProxyAuthenticationRequired Queued RequestEntityTooLarge RequestPending RequestTerminated RequestTimeout RequestUriTooLong Ringing ServerInternalError ServerTimeout ServiceUnavailable SessionProgress TemporarilyUnavailable TooManyHops Trying Unauthorized Undecipherable UnsupportedMediaType UnsupportedUriScheme UseProxy VersionNotSupported

80

8.2.3 Creating a New SIP Message


You can create a new message by either using the factory methods provided on the concrete message types, or constructing a message by performing the following steps: 1. Create a message using the Response or Request types. 2. Set the start line (Status Line for Responses and Request Line for Requests). 3. Add or modify headers as required. 4. Optional add a message body. C#: Construct an INVITE Request without using factory method //Create a new Invite request. public static Invite CreateInvite() { //This example constructs a new header field directly for each header, //alternatively you could have used strings which are implicitly parsed //e.g. invite.ViaHeaders.Add("SIP/2.0/UDP there.com:5060");

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


InviteRequest invite = new InviteRequest(new SipUri ("sip:UserB@there.com")); invite.ViaHeaders.Add(new ViaHeaderField(new IPDomainPort ("here.com:5060"),TransportProtocol.Udp)); invite.From.Uri = new SipUri("sip:UserB@here.com"); invite.From.DisplayName = "BigGuy"; invite.To.Uri = new SipUri("sip:UserB@there.com"); invite.To.DisplayName = "LittleGuy"; invite.CallId.CallId = "12345601@here.com"; invite.CSeq.SequenceNumber=1; //In this example we are using the SipMethod structure. It emulates an expandable enumeration. invite.CSeq.Method = SipMethod.Invite; invite.ContactHeaders.Add(new ContactHeaderField(new SipUri ("sip:UserA@100.101.102.103"))); invite.ContentType.MediaType = "application"; invite.ContentType.MediaSubType = "sdp"; invite.ContentLength = new ContentLengthHeaderField(0); return invite; }

81

8.2.4 Factory Methods


Most of the Request types contain static factory methods that create predefined instances that have defaults set according to the configuration and SIP specified default values. This mechanism considerably aids in development and increases programmer productivity. It is necessary to configure the application to gain most benefit from the factory methods. See the Configuration (Section 6) section for more details. We can then send a message with as little as four lines of code: C#: Send an INVITE message with factory methods //Sends an INVITE message to 'sip:bob@mell99.melbourne.com'. static void SendAnInvite() { //Initialise SipCore core = new SipCore(); //Create an Invite message. Use the factory method on the Invite object. This method relies heavily on the configuration to provide default values for the message. InviteRequest invite = InviteRequest.CreateInviteRequest(new SipUri

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


("sip:bob@mell99.melbourne.com")); //Send the message core.SendRequest(invite); }

82

8.3 Adding Headers To Messages


The SIP Header API provides a set of properties for reading and modifying various parameters of the headers. In addition, in order to support prototyping, testing and a more dynamic style, headers can be implicitly converted from strings and explicitly converted to a string. The three patterns of working with headers and setting their values are:

Constructors (fastest) Properties (fast) String Conversions (slowest)

Internally the string conversion uses parsing and string encoding. Parsing can be orders of magnitude slower than direct assignment of properties. The following code demonstrates how to get and set parameters in a To header field using each pattern: C#: Working with Header properties static void WorkingWithHeaders(){ //Use constructors to set the value of the URI on the TO header field ToHeaderField to = new ToHeaderField("sip:bob@melbourne.com"); //Use properties to set and get header field parameters to.DisplayName = "Bob The Builder"; Console.WriteLine(string.Format("{0} is at {1}",to.DisplayName,to.Uri.ToString())); //Use string conversion to set and get header field parameters to = "bob <sip:bob@sydney>"; Console.WriteLine((string)to); }

8.3.1 Adding Headers to a Message

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

83

There are two types of functions you can use to insert headers into messages. The function type you choose will depend on the headers you wish to insert. The function types you may use are as follows:

Properties - for well-known (i.e. non-extension) header fields, properties are provided. Addition methods - for all types of headers, Add and Insert methods are provided.

C#: Adding and Removing Header Fields static void AddAndRemoveHeaderFields() { //Create a new header field ContactHeaderField contact = new ContactHeaderField(new SipUri ("sip:bob@melbourne.com"), "Bob"); //Creat a new Invite request message InviteRequest i = InviteRequest.CreateInviteRequest(new SipUri ("sip:bob@melbourne.com")); //Add the field to the message i.AddHeader(contact); //Check if the Contact header exists, if so, remove it if(i.ContainsHeader(ContactHeaderField.LongName)){ i.RemoveHeader(ContactHeaderField.LongName); } }

8.3.2 Response, Request Header Fields


Not all header fields are applicable, optional or allowed on certain message types or in particular circumstances. Each Request or Response class only contains the header field properties allowed for that message type. For example, the Contact header field is only allowed on Request type messages. The Response class does not contain a Contact property. However, users may still deliberately add this header, or any other, by using the AddHeader method.

8.4 Headers
8.4.1 Header Fields
The header fields are managed via properties. They can be either multi or single valued. Multivalued header fields are contained within a MultiValued collection, with each item representing a header field value for a particular header field type. Single valued header fields are represented by

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


the header field itself. The following figure illustrates a SIP message whereby Via, Contact and Route header fields are contained within a MultiValued and all other fields (e.g. From, To, Content-Type) are self represented.

84

8.4.2 MultiValued<>
Multi-valued header fields are those fields that may occur more than once in the message. They can be formed on separate lines, or on a single line separated by token (usually a comma). These header fields are treated as a read-write collection and returned in a read-only property. You can distinguish between the header collection properties as their names all end with "Headers". The following code block show an example of working with the MultiValued. We first create a new SipMessage using the derived Invite class, we then add a new Accept-Encoding value; insert a new Accept-Encoding value; check if "gzip" exists in the collection, and if so, remove it. Working with MultiValued static void WorkWithSipMessage(){ InviteRequest i = InviteRequest.CreateInviteRequest(new SipUri ("sip:bob@melbourne.com")); // Add a new value to the AcceptEncoding header field collection. i.AcceptEncodingHeaders.Add(new AcceptEncodingHeaderField("gzip")); //Insert a value at the end of the collection. i.AcceptEncodingHeaders.Insert(1, new AcceptEncodingHeaderField("x-zip")); //Remove 'gzip' if the collection contains the value if(i.AcceptEncodingHeaders.Contains("gzip")){ i.AcceptEncodingHeaders.Remove("gzip");

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


} }

85

8.4.3 Header Objects


The SIP library has several types of header objects. Each header object represents a SIP header. The header object holds the header fields according to the header Bakus-Naur Form definition. The following figure illustrates a To header object. The To header field contains a SipUri, a display name, an optional Tag parameter, and other generic parameters.

SIP headers that do not have a dedicated object in the SIP message, called Extension Headers, are stored in the SipMessage header collection.

8.4.4 Parameters
Many header fields will adhere to the general form of a value followed by a semi-colon separated sequence of parameter-name, parameter-value pairs. Even though an arbitrary number of parameter pairs may be attached to a header field value, any given paramter-name must not appear more than once. Parameters are segregated in the SIP library into well-known and extension parameters. Well-known are expected and validated, extension parameters are simple are generally not known to the SIP library and follow the name/value form, where the name is a token (alphanum + unreserved ASCII marks) and value is a token or quoted UTF8 string.

8.5 Compact Form

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

86

SIP provides a mechanism for representing header field names in a compact form. For example, the header, "from: Bob <sip:bob@melbourne>" will become "f: Bob <sip:bob@melbourne>" when compact form is used. The following table represents the headers that can accept compact form and the corresponding compact form for each header.
Long Name Compact Name a c e f i k l m s t v

Accept-Contact Content-Type Content-Encoding From Call-ID Supported Content-Length Contact Subject To Via

8.5.1 Forcing Compact Form on messages


An application can instruct a SipMessage to force all of its headers to use the compact form when encoding the message. This is done by using the FieldNameDisplay enumeration with some overloaded methods on the SipMessage type. When such a message is encoded, all headers that can take compact form will be encoded with compact form. All other headers will use the long form

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


version. C#: Using the Compact Form static void UsingTheCompactForm() { //Create a new Invite request message InviteRequest i = InviteRequest.CreateInviteRequest(new SipUri ("sip:bob@melbourne.com")); //Set the compact form as the header name format. i.HeaderNameFormat = FieldNameDisplay.Compact; byte[] compactFormBytes = i.GetBytes(FieldNameDisplay.Compact); }

87

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


9 Working with Transactions

88

A SIP transaction comprises all messages sent within a message exchange. Specifically a transaction consists of an initial request and any responses to that request. The Transaction API of the SIP library contains a set of methods and events that can be used for two purposes. The first is for handling transactions that are related to the User Agent (UA) and not related to a Dialog. An example of such a transaction is one that handles an OPTION request. Using the Transaction API, you can create and initialize a transaction and control a transaction according to the transaction state. You can create a transaction with any method (except ACK). The second purpose of the Transaction API is for writing a SIP server. Using the Transaction API, you can implement a Proxy server, Redirect server and Registrar. You can receive incoming requests and decide whether to redirect or proxy the request according to the request method and the transaction state. Using these functions, you can fully implement both stateless and stateful proxies.

9.1 Transaction Entities


Transaction Entities
The transaction API related to the following two entities:

Transactions (SipTransaction and derived types) Transaction Registry (SipTransactionStateManager)

9.1.1 Transactions
A transaction represents a SIP transaction as defined in RFC 3261. The transaction consists of a request (and its retransmissions) together with the response triggered by that request. Your application can initiate transactions, send requests and respond to incoming requests using the Transaction API. A transaction is a stateful object, which can assume any state from a set defined in the Transaction API. The Transaction state machine represents the state of the transaction between the client and the server.

An Invite transaction also includes the ACK request when the final response to the Invite request is non-2xx.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

89

Transactions represent the state of the transaction between client and the server. Thus transactions are divided into:

Client Transactions Server Transactions

Furthermore, in the case of a transaction where the original request was an INVITE the transactions is known as an InviteTransaction. These transactions are distinguished from all other general transactions, referred to as GenericTransaction. Thus the state machine is divided into the following parts:

InviteClientTransaction GenericClientTransaction InviteServerTransaction GenericServerTransaction

9.1.2 Transaction State Manager


The SipTransactionStateManager manages the collection of all transactions (and Dialogs). The SipTransactionStateManager is mainly used for matching new messages to existing transactions.

9.2 Transaction Types


The Transaction type contains a set of properties , methods and events that allow you to set or examine transaction parameters and to control a transaction request or response.

9.2.1 Properties
The following properties are available on all transactions: Method Specifies the method of the SIP request. For client transactions, you supply the method when sending the initial request. For server transactions it is the method of the initial request that was received.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

90

MostRecentResponse Returns the most resent response sent or received by the transaction. OriginalRequest Returns the original request message that initiated the transaction. RecipientEndPoint Returns the end point for the recipient of the transaction's transmissions. TransactionState Represents the state of the transaction between the client and the server.

9.2.2 InviteServerTransaction
The following property is only available on the InviteServerTransaction: BlockTrying Blocks the automatic sending of a Trying message from this transaction upon receipt of an INVITE. Otherwise the transaction will automatically send a Trying message back to the correspondent.

9.3 Methods
9.3.1 SendResponse
Use this instance method to send a provisional or final response to a transaction that received an incoming request. You can use this method with any response code and reason phrase. The following code demonstrates a response to receiving a BYE request. C#: Acknowledging a BYE request //Server transactions handle incoming Requests. //This example handles the BYE request. private static void OnServerTransactionCreated(object sender, TransactionEventArgs e) { ServerTransaction trans = (ServerTransaction)e.Transaction; if(trans.OriginalRequest.Method == SipMethod.Bye) { Console.WriteLine("===BYE Received===");

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


//Send and OK response. //Populate the OK with the standard field from the Request Console.WriteLine("===Sending OK==="); core.SendResponse(new Response(trans.OriginalRequest, SipStatusCode.Ok)); } }

91

9.3.2 SendCancel
Use this method to cancel a transaction that reached the Proceeding state. You can use this function only on INVITE client transactions. You supply this function with the transaction you wish to cancel. A CANCEL transaction will be created and a CANCEL request will be sent to the remote party.

9.3.3 StopTimers
Use this method to halt transactional timers firing. This can be useful when debugging.

9.3.4 RestartTimers
Use this method to restart transactional timers firing again after stopping them. This can be useful when debugging.

9.3.5 TerminateAndDispose
Use this method to cause an immediate shut-down of the transaction. A transaction is a selfterminated object. The termination of a transaction depends on the transaction state and timer configurations. By using this function, the application can terminate a transaction before its normal termination. After calling this function, the transaction will assume the Terminated state.

9.4 State Machines


The state machine represents the state of the transaction between the client and the server. There are two states common to all transactions:

9.4.1 Idle
The Idle state is the initial state of the Transaction state machine. Upon transaction creation, the transaction assumes the Idle state. It remains in this state until SendRequest, SendResponse,

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


ProcessRequest or ProcessResponse is called.

92

9.4.2 Terminated
This is the final state of the transaction. When a transaction is terminated, the transaction assumes the Terminated state. Upon reaching the Terminated state, you can no longer reference the transaction and it will be disposed.

Non-Invite Client Transaction


A transaction may assume any of the following states in the Non-Invite Client State machine:

9.4.3 Trying
After calling SendRequest() with a method other than INVITE, which generates and sends a Request message, the transaction enters the Trying state. The client transaction remains in this state until it receives a provisional or final response from the server. Receipt of a provisional response will cause the transaction to assume the Proceeding state. Receipt of a final response will cause the transaction to assume the Completed state. While in the Trying state, the transaction retransmits the request message according to the rules defined in RFC 3261, and the values configured for T1, T2 and timer F. The retransmissions take place only if the transport is an unreliable transport (UDP). If no response is received when Timer F expired, the transaction is terminated automatically and assumes the Terminated state (in any transport).

9.4.4 Proceeding
Upon receipt of the first provisional response by a client transaction (not a retransmission), the transaction assumes the Proceeding state. The transaction will continue to retransmit the request message until the Timer F expires using a consistent interval of T2 seconds as defined in RFC 3261 (only if the transport is unreliable (UDP)). Receipt of a final response will move the transaction to the Completed state. If no final response is received when the Timer F is expires, the transaction is terminated and assumes the Terminated state.

9.4.5 Completed
Upon receipt of a final response, the transaction assumes the Completed state. When entering this state, a transaction timer is set to T4 if the transport is an unreliable transport. When T4 expires, the transaction is terminated and assumes the Terminated state. If the transport is a reliable transport, no timer is set and the transaction is terminated and assumes the Terminated state immediately

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


when it reaches this state. (Timer K as defined in RFC 3261).

93

Non-Invite Server Transaction


A transaction may assume any of the following states in the Non-Invite Server State machine:

9.4.6 Trying
Upon receipt of a request (that is not a retransmission) by a server transaction, the transaction assumes the Trying state. In this state, it is up to you to respond to the request using the transaction API. You may begin with sending provisional responses. You must end with sending a final response, or terminating the transaction. The transaction does not set any timer in this state.

9.4.7 Proceeding
When calling SendResponse(), the transaction generates and sends a response message. If the response is Informational the transaction will then assume the Proceeding state.

9.4.8 Completed
When calling SendResponse(), the transaction generates and sends a response message. If the response is not Informational the transaction will then assume the Completed state. When entering this state, a transaction timer is set to Time J if the transport is an unreliable transport (i.e. UDP). When this timer expires, the transaction is terminated and assumes the Terminated state. If the transport is a reliable transport, the transaction is terminated and assumes the Terminated state immediately when it reaches this state.

Invite Client Transaction


9.4.9 Calling
After calling SendRequest() with the INVITE method which generates and sends an INVITE request message, the transaction enters the Calling state. The client transaction remains in this state until it receives a provisional or final response from the server. Receipt of a provisional response will cause the transaction to assume the Proceeding state. Receipt of a final response will cause the transaction to assume the Completed state.

While in this state, the transaction retransmits the request message according to the rules defined in RFC 3261, and the value configured for T1. The retransmissions take place only if the transport is an

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

94

unreliable transport. If no response is received when 64*T1 timer (Timer B according to RFC 3261) expires, the transaction is terminated automatically and assumes the Terminated state (in any transport).

9.4.10 Proceeding
Upon receipt of the first provisional response by a client INVITE transaction,the transaction assumes the Proceeding state. When entering this state, a transaction timer is set to provisional Timer. When this timer expires, the transaction is terminated. Receipt of a final response in the Proceeding state will move the transaction to Completed state.

9.4.11 Completed
Upon receipt of an INVITE final response, the transaction assumes the Completed state. If the response is a 2xx response, the transaction will then assume the Terminated state. If the response is a non-2xx response, the application should initiate the ACK request by calling the SendAcknowledgement() method. After sending the ACK, the transaction will move to the Completed state.

Invite Server Transaction


9.4.12 Proceeding
Upon receipt of an INVITE request (that is not a retransmission) by a server INVITE transaction, the transaction assumes the Proceeding state. In this state, it is up to you to respond to the request using the Transaction API. You may begin with sending provisional responses. You must end with sending a final response, or terminating the transaction.

9.4.13 Completed
When calling SendResponse() on an INVITE transaction, the transaction generates and sends a response message. The transaction will then assume the Completed state. For a non-2xx response, the transaction retransmits the final response according to RFC 3261, and the value configured for T1 and T2. The retransmissions take place only if the transport is an unreliable transport (i.e. UDP). If no ACK response is received when 64*T1 timer (Timer H according to RFC 3261) expires, the transaction is terminated automatically and assumes the Terminated state (unless the state has changed). If an ACK message is received, the transaction moves to the Confirmed state. For a 2xx response, the transaction sets the Timer I after sending the 2xx response. The transaction terminates

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


when this timer expires.

95

9.4.14 Confirmed
When entering this state (the transaction received an ACK message), a transaction timer is set to T4 if the transport is an unreliable transport (i.e. UDP). When T4 expires, the transaction is terminated and assumes the Terminated state. If the transport in a reliable transport, no timer is set and the transaction is terminated and assumes the Terminated state immediately when it reaches this state. (Timer I as defined in RFC 3261).

9.5 Timers
SIP transactions make extensive use of timers to control their behaviour. The following table lists the most common timers:
Default Value 500ms default

Timer

ConfigName

Description

T1

TimerT1

RTT Estimate

T2

TimerT2

4s

The maximum retransmit interval for non-INVITE requests and INVITE responses Maximum duration a message will remain in the network INVITE request retransmit interval, for UDP only INVITE transaction timeout timer proxy INVITE transaction timeout

T4

TimerT4

5s initially T1 64*T1 > 3min > 32s for UDP initially T1 64*T1

Timer A TimerA Timer B TimerB Timer C TimerC Timer D TimerDUdp/ TimerDTcp

Wait time for response 0s for TCP/SCTP retransmits

Timer E TimerE Timer F Timer F

non-INVITE request retransmit interval, UDP only non-INVITE transaction timeout timer

Timer

TimerG

initially T1

INVITE response retransmit interval

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


G Timer H

96

TimerH

64*T1

Wait time for ACK receipt

Timer I

TimerIUdp/ TimerITcp TimerJUdp/ TimerTcp TimerKUdp/ TimerKTcp

T4 for UDP

Wait time for 0s for TCP/SCTP ACK retransmits

Timer J

64*T1 for UDP

Wait time for 0s for TCP/SCTP non-INVITE request retransmits

Timer K

T4 for UDP

Wait time for 0s for TCP/SCTP response retransmits

The table also shows the configuration name given to the timer. See the configuration section later for implementation details.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


10 Working with Authentication

97

The authentication mechanism enables User Agent Clients to prove their identity (client authentication) to servers and proxies which require authentication. In turn the mechanism supports the ability of the server to prove its identity (mutual authentication). Furthermore, message integrity can be established with the use of integity functionality (Auth-Int Quality of Service). The SIP Library supports SIP authentication using the HTTP Digest Scheme as described in RFC3261 and RFC2617. The HttpDigestClientAuthenticationManager object is responsible for applying the authentication mechanisms described in the RFCs and manage both client and server authentication processes.

10.1 Overview
The basic concept of the authentication mechanism is the shared secret between client and server or proxy. Prior to establishing SIP communication, the client should obtain a username and password (Credentials) that the server acknowledges. In addition a domain or realm should be provided, the realm is a string to be displayed to users so they know which username and password to use. The password is the shared secret between the client and the server. The Digest Authentication method implemented by the SIP library used the MD5 algorithm in the authentication process. MD5 is a one-way hash function that operates on a given string and produces a fixed length hash value. The Sip Library hashes certain information, including the password, username and realm, and includes the hash as the Response value in any authentication exchange when prompted by a Challenge. A SIP server will verify the clients authenticity using the HTTP Digest Scheme as follows: 1. A server responds to the originator of an incoming request with a 401 Unauthorised response. A Proxy server responds with the 407 Proxy Aithentication Required response. These responses each include special Authentication headers with infomation required by the client in the Authentication process. Within a 401 the header is WWW-Authenticate, and within a 407 it is ProxyAuthenticate. The information included in the Authentication header is called the Challenge. 2. A client uses the Challenge parameters and the user Credentials to generate a hash value using the MD5 algorithm. 3. The hash value and certain other proeprties, such as a one-time ClientNonce (opaque 32

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

98

dimensioned random hex array) are included inside an Authorization or ProxyAuthorization header field. The header field is added to the original request message that was challenged. 4. The client retransmits the request message. 5. The server uses the hashed value in the Response property of the (Proxy)Authorization header field to verify the authenticity of the originator by hashing the same information using the MD5 algorithm and comparing hashes. The process of receiving a challenge and sending credentials is refered to as an exchange. Integrity HTTP Digest can provide for message integrity if both parties support it. Authentication with message integrity can be used if the 'auth-int' flag is provided on the quality of protection (QoP) property of the challenge. Client applications can request message integrity be used by setting the SupportAuthenticationIntegrity property of the HttpDigestAuthenticator static class. In this mechanism, the message body (the whole body excluding the initial (CRLF)CRLF seperator combination) is hashed along with the credentials.

10.1 The Http Digest Authentication Manager


The HttpDigestClientAuthenticationManager is responsible for applying the authentication mechanism to incoming and outgoing messages. The object manages a cache of Credentials provided by the client application. In addition it manages all the HTTP Digest Authentication exchanges - an exchange is the challenge followed by one-or-more credentials, which in turn can be followed by another challenge, a rejection or an acceptance. The HttpDigestClientAuthenticationManager can respond to Challenges automatically if the AutoResponse property is set to True in the Event Argument of the AuthenticationChallengedReceived event and the manager has the credentials for the realm provided in the challenge. In addition, outgoing message with the same Call-ID (i.e. within the same Dialog) as found on another message with an accepted authentication exchange will automatically have an (Proxy) Authorization header field assigned.

10.1.1 Authenticator

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


The HttpDigestClientAuthenticationManager automatically performs the authentication

99

mechanism on incoming and outgoing messages. However, client applications can independently access the MD5 and HTTP Digest algorithms via the static HttpDigestAuthenticator class.

10.2 The Authentication Exchange


The exchange of authentication information is managed by the HttpDigestClientExchange. The HttpDigestClientExchange object includes a HttpDigestChallengeData object containing the properties from the challenge and response to that challenge; a HttpDigestClientExchangeState object manages the exchange's state machine; a SipUri matches the SipUri in the To header field of the original request; the Call-ID value of the original request; and the time the challenge took place.

10.2.1 SIP Message Authentication Context


Each SipMessage has an AuthenticationContext object containing a collection of exchanges, listing all the authentication exchanges from the lifetime of the request and any responses. The majority of messages will simply have one exchange (i.e. in the Accepted state). When sending a request or response object via SipCore's SendRequest() or SendResponse() the Unity SIP Library will insert an equivalent Authorization header into each outbound message matching any Exchange in the AuthenticationContext collection with a state of Accepted. The client application can go over the collection of authorization exchanges in the message and manipulate the exchange objects or collection in order to manage the allocation of Authorization headers.

10.2.2 Authenticating A Message in Advance


Sometimes it is convenient to authenticate requests in advance of sending them. However, this is only possible within SIP for messages with the same Call-ID. The underlying authentication mechanims takes care of this scenario, and automatically add an Authorization header field and HttpDigestClientAuthenticationContext to the outbound request. Another more fundamental reason why we cannot pre-authenticate all request message where we have the credentials and realm is HTTP Digest specifies an opaque Nonce value to be included in the hashing algorithm. The Nonce value is provided on the challenge, and is likely to be either a one-off or time-sensitive. The HttpDigestClientExchangeState flag Expired indicates when a nonce value has been rejected as stale.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


10.2.3 AuthenticationChallengedReceived

100

The SipCore and the HttpDigestClientAuthenticationManager on the SipCore both expose the AuthenticaionChallengeReceived event. The event is fired when a message is received containing a challenge. The event argument object, ChallengedReceivedEventArgs, contains a property indicating whether the challenge should be meet with an auto response (AutoRespond). During auto response, a set of credentials are found for each realm/domain challenging. Authorization headers are added to the original request message, and the message's CSeq sequence number is incremented. Finally the request is resent.

10.2.4 State Machine


Each exchange instance contains a HttpDigestExchangeState object managing the exchange's state machine which manages the lifetime of the exchange.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

101

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


11 Working with the Transport Layer

102

Transport Layer
The Transport layer is responsible for the actual transmission of requests and responses over network transports. SIP permits the usage of unreliable transports, such as UDP, and reliable transports, such as TCP, using both IPv4 and IPv6 addresses. Or using authentication and encryption using TLS. However, TLS is still carried via TCP. TCP and UDP differ in many ways. The most fundamental difference is that UDP is connection-less, while TCP are connection-oriented and therefore create a reliable data transfer service. The SIP library supports UDP datagrams and TCP connection-oriented transports. This section explains how to maintain a persistent connection and how to use the TCP and UDP transports with the SIP library API. In addition, this chapter describes the abilities that the SIP library provides for monitoring buffers that are sent or received from the sockets.

11.1 Sip Connections


SipConnections are used to reliably deliver data between two user agents using UDP, TCP or TLS. A SipConnection is identified by its Local EndPoint, Remote End Point and TransportProtocol. For TCP (and TLS) a Connection is equivalent to a TCP connection. For UDP a Connection represents a bi-directional stream of datagrams between a pair of end points. In SIP parlance, a connection is sometimes referred to as a Flow. A Connection provides a data buffer for reading and writing to and from the network.

11.1.1 Sockets
The SIP library uses asynchronous non-blocking sockets. The result of using non-blocking sockets is that the sending of messages can be completed after the API call has returned. For example, a call to Send() on the TransportLayer object may return before the bytes are actually queued up in the network infrastructure, and before being pushing onto the physical layer. The SIP library will manage the sending operation until it is complete.

11.1.2 Established Connections

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

103

In many cases a single Connection may be used for different messages, transactions or dialogs. Opening and closing connections is often not desirable because of the extra messaging overhead. RFC3261 encourages connection persistency, which is the reuse of an open client connection. The feature of the SIP library add the capability to identifying that a message can be sent on an existing open connection. The message is then sent using this connection. Connections can be used for client or server purposes. Connection Persistency referes to a technique in which connection information and configuration is persisted to disk and provides a robust failover mechanism. The Unity SIP Library does not provide this functionality.

11.1.3 Lifetime
Each connection manages its own lifetime.

For connection-oriented protocols (TCP and TLS) connections will dispose if the far side disconnects.

The connection timeout fires. The timeout is governed by the connectionInactivityTimeout attribute of the transportLayer configuration element. The timeout can also be changed on each individual Connection object.

An exception in the processing of incoming or outgoing transmissions may disconnect the connection.

11.1.4 Connection Pool


The ConnectionPool provides an API that enables you to examine existing connections parameters, connect and disconnect connections and attach and detach from connections. All Connections are inserted into the ConnectionPool upon initialisation. Connection objects are inserted into a HybridDictionary in the ConnectionPool which uses an simple Dictionary with a small number of open connections and a HashTable when many connections are added. Termination A Connection will terminate automatically after an inactivity period specified by the connectionInactivityTimeout Configuration element (20 minutes by default), or if the other side forcibly terminates the connection. The Connection will be automatically removed from the ConnectionPool. Terminating the Connection has no effect on the Listeners.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


11.1.5 Properties
A Connection contains the following properties: Local And Remote Addresses

104

A Connection is opened from a specific local endpoint and specific remote endpoint using one type of transport protocol. The LocalEndPoint and RemoteEndPoint indicate these network interfaces. A System.Net.IPEndPoint is used to contain the invariant. The IPEndPoint contains an IPAddress and Port value. The two endpoints along with the Transport protocol provide the Connection key used in the ConnectionPool. Transport Indicates whether the connection is a TCP or UDP connection. The transport is part of the SipConnection key used in the SipConnectionPool. Direction Indicates the transmission direction which initiated this connection. Whether the connection was started by a client or server activity. LastTransmissionTime The timing of the last transmission to or from this connection

11.2 Connection Reuse


In many cases a single Connection (UDP, TCP or TLS) may be reused for sending or receiving messages. Opening and closing of reliable connection-oriented transports such as TCP, and to an even greater extent TLS with its exchange of authentication information, can be undesirable because of the message overhead. RFC3261 demands that applications are capable of listening on the address/port that sent the message, that is the reuse of an open client connection. The connection reuse feature of the Unity SIP library adds the capability of identifying that a message can be sent on an exsting open connection to the recipient, the message is then sent using this connection.

11.2.1 Sending Requests


When SIP entities use a connection to send a request, the connection typically originates from an

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

105

ephemeral port number. The SIP protocol includes mechanisms which ensure that responses to a request reuse the existing connection, and ports, if available. However, this works both ways between two entities. With each using an ephemeral port number to send the initial request message. This frequently causes a pair of SIP entities to use one connection for requests and responses in each direction. The following figure illustrates the connection establishment of two requests one originated in each agent.

11.2.2 Sending Responses


For reliable transports (TCP and TLS) the response is send using the existing connection to the source of the original request that created the transaction. If that connection is no longet open, or we are using UDP, a server will open a connection to the IP address in the received parameter of the top-most Via header field, if present, using the port in the sent-by value of the top-most Via Header, or the default port for that transport, if no port is specified.e If that fails, then the SIP library will use DNS against the Via Header's sent-by to establish the IP Address and port. Ultimately, a trapizoid of connection can be established between two Agents with transmission of data is each direction:

11.2.3 Connection Pool


To reuse open connections, client connections (connections opened by the UAC when sending a request) and server connections (connection established by Listeners from incoming connection requests) are cached in the ConnectionPool. The connections are stored in a dictionary whose key is formed from the transport protocol and remote endpoint (IP Address + Port). Whenever the Unity SIP Library needs to send a message it first queries the connection pool for an existing active connection.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


11.2.4 Connection Pool Capacity

106

RFC3261 recommends that connection should be kept open for a period of time after the last messge was exchanged over the connection. However, the exact time period to leave the connection open is not defined and is implementation specific. This means connections can build up inside the connection pool. To manage the size of the connection pool the Unity SIP Library uses the maximumConnectionPoolCount configuration value which determines the recommended number of opened connections that the SIP Library is allowed to hold at any given moment from its pool of connections. When the limit is reached connection pruning takes place, with a percentage of the oldest connections being disconnected and disposed.

11.2.5 Timeout
A inactivty timeout is available for each connection. Once the timeout fires the connection is disconnected, disposed and removed from the connection pool.

11.3 Introduction to TLS in SIP


TLS is a security mechanism that operates over the TCP transport in order to send data in a secure authenticated manner. TLS, together with the commonly used Public Key Infrastructure certification distribution mechanism achived the following goals:

Guarantees the identity of a remote computer. Transmits messages to that remote computer in a secure encrypted manner.

TLS uses pairs of asymmetrical encryption keys to guarantee the identiy of a remote computer. The public key of each remote computer is published in a certificate. A certificate is a document digitally signed by a certifcate authority that both sides of the connection agreed to traust before the TLS connection establishment has stared. (VeriSign and Thawte are examples of such vertificate authorities). In the TLS connection establishment process, the certificate of the remote computer is retrieved and verified and a new key and encryption algorithm is negotiated for the specifiec connection.

11.3.1 Establishment
TLS connection establishment requires the completion of the following three phases:

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

107

Phase 1: TCP Connection Establishmentas stated above,TLS uses TCP as its underlying transport protocol. Therefore, a TLS handshake can start only after a TCP connection has reached the connected state.

Phase 2: TLS Handshakethe basic TLS handshake process consists of several TCP messages which go from client to server and from server to client, in which the client retrieves the servers certificate, verifies it, negotiates an encryption key and algorithm for the session, and both parties make sure that the security of the handshake has not been compromised. For more information on the TLS handshake see RFC 2246 and RFC 3546.

Phase 3 (Optional):Mutual AuthenticationThe server may request the client authenticates during the process and demand client certificates be provided in the certificate exchange

Phase 4: ValidationIn this phase, the client makes sure that the certificate handed to it by the server does indeed belong to server. This step is taken to prevent the situation in which a server named malise.com will present a valid certificate of someonelse.com.

After these phases have been completed, encrypted messages can be transmitted on the connection in a secure manner.

11.3.2 SIP Scheme


RFC 3261 defines the use of TLS as a transport mechanism by using the sips: scheme. When using the sips: scheme in a URIor any other header that indicates the next hop of a message, such as Route, Via, and so onRFC 3261 mandates the transport to be TLS. (For this reason TLS will not guarantee a secure delivery end-to-end, but only to the next hop).

11.3.3 Mutual Authentication


The Unity SIP Library provides for Mutual Authentication, in which the client provides one-or-more certificates in order to establish its identity before messages can be transmitted. The ClientCertificates property on the SipTransportLayer allows a client to provide certificates. Alternativly, you can subcribe to receive the ClientCertificateSelection event, where you can provide a certificate for a particular context dyanmically. Client certificate must have a private key, and it must be available to the Unity SIP Library. The library must have the permissions to access the private key. Use the WinHttpCertCfg tool to user access rights.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


11.4 Event Processing

108

The TransportLayer of the SIP library is a low-level API. It provides several events that can be used to inspect and control the buffers that are sent or received by the sockets controlled by the SIP library. The events are implemented for all transport protocol types - TCP or UDP. The buffers contain encoded SIP messages. Each message will contain header fields that may have unique encoding specifications, consult each header field documentation for information. To get the events, and application registers to the event.

11.4.1 Event Processing


After intitialising the library, you may want to listen for events emanating from SIP operations. You do this by registering with the events of the TransportLayer object. Just before parsing an incoming SIP message the SIP Stack gives the application the chance to look at the message raw buffer. The event supplies a buffer with exactly one byte array containing the contents of the SIP message and an ArrayList with the list of SIP message headers (including the First Line). Before the SIP library passes the buffer containing exactly one encoded SIP message to the sending sub-system call, it calls either the SendingRequest or SendingResponse event. Additional details, such as the local and remote addresses for UDP sockets, or connection handles for TCP sockets, are provided with the event. As a result of the details and buffer inspection, an application can instruct the SIP Stack to discard the buffer by updating the corresponding Cancel property of the event arguments.
Event Description

CertificateAuthenticationFailure Occurs when when SSL certificate authentication fails. Occurs when a server attempts to authenticate a certificate with this library and allows a listening client to validate the certificate. Occurs when a client requests a certificate from this library. Occurs when a server requests a certificate from this library. Occurs when a connection is created.

CertificateValidation

ServerCertificateSelection ClientCertificateSelection ConnectionCreated

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

109

ConnectionRefused

Occurs when a connection is refused. Typically this is because the pool is full. Occurs when data is received from a connection. The message has been framed but not yet parsed or processed. Occurs when the transaction failed to send a message.

DataReceived

MessageSendFailure

The following code demonstrates how to initalise the core, start listening for incoming message on interface "124.191.1.8:5060" and print out the recipient information, and data parameters when a new message arrives. C#: Register to receive notification of incoming messages using System; using System.Net; using Konnetic.Signalling.Sip; using Konnetic.Signalling.Sip.Advanced; ... //Initialise SipCore core = new SipCore(); //Start Listening on port 5060 using TCP and UDP. core.ListenForConnections(5060)); //Register to receive notficiaton of new data and print out who sent the data, how many header fields are contained in the message, and the length of the content core.Transport.DataReceived += delegate(object sender, DataReceivedEventArgs e) { Console.WriteLine("From: " + e.Sender.HostPort); Console.WriteLine("HeaderField Count: " + e.Data.HeaderFields.Count); Console.WriteLine("Content Length: " + e.Data.ContentLength); };

11.5 IPv6
Working with IPv6 Addresses
IPv6 (Internet Protocol Version 6) is the "next generation" protocol designed by the International engineering task Force (IETF), the Internet standardisation body, to replace the current internet protocol, IPv4. IPv6 overcomes a number of problems in IPv4, such as the limited number of available IPv4 addresses. It also adds many improvements to IPv4 in areas such as routing and network auto-configuration. IPv6 is expected to gradually replace IPv4, with the two coexisting for a

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

110

number of years during a transition period. The most significant change is that IPv6 supports an address scheme that uses 128 bit address space compared with the 32 bit IPv4 address. The SIP Library enables an application to work with the IPv4 IP Stack, IPv6 IP Stack or dual stacks. Supporting the IPv6 scheme affects the low-level services needed from the operating system as well as message and headers syntax. It does not affect the way SIP works with transactions or dialogs or other objects. In IPv6 addresses there are eight groups of four digits each. The hexadecimal number system is used for the digits. Thus, each group occupies 16 bits of space and the entire address represents (but does not always require) 128 bits. For example, 3ffe:6a88:85a3:08d3:1319:8a2e:0370:7344. is a valid address. If a 4 digit group is 0000, it may be omitted, thus in the syntax of IPv6, 3ffe:6a88:85a3:0000:1319:8a2e:0370:7344 is the same as 3ffe:6a88:85a3::1319:8a2e:0370:7344. Following this rule, if more than two consecutive colons result from this omission, they may be reduced to two colons, as long as there is only one group of more than two consecutive colons. Thus, all the following addresses are valid and have the same meaning,

2001:2353:0000:0000:0000:0000:1428:57ab 2001:2353:0000:0000:0000::1428:57ab 2001:2353:0:0:0:0:1428:57ab 2001:2353:0::0:1428:57ab 2001:2353::1428:57ab

However, 2001::25de::cade is invalid. Also, leading zeros in all groups can be omitted, thus 2001:2353:02de::0e13 is the same as 2001:2353:2de::e13. If the address is an IPv4 address in disguise, the last 32 bits may be written in decimal. Thus, ::ffff:192.168.89.9 is the same as ::ffff:c0a8:5909, but not the same as ::192.168.89.9 or ::c0a8:5909.

11.5.1 IPv6 Addresses and SIP


The SIP protocol denotes that IPv6 addresses should be included in square brackets, []. For example, when using the IPv6 local loop address in a To header, the To header will appear as follows: To: <sip:[::1]>

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


11.6 Transport Buffers
Transport Layer Buffer
The Transport layer of the SIP library provides events that are dedicated to inspecting and controlling the buffers that are sent or received by the SIP library sockets. The events are implemented for all transportsUDP and TCP transports. The buffers contain encoded SIP messages. To get the events, an application should register to the events.

111

The layer can also be used to send and receive messages directly, thereby bypassing the transaction layer.

11.6.1 TransportDataBuffer
The Transport Layer returns a TransportDataBuffer container in the DataReceived event. The buffer contains:

A collection of HeaderFieldDataBuffer objects in the HeaderFields property. A byte array containing the message content. Two field indicating the content length.

The HeaderFields collection is an ordered list of the CRLF separated bytes received off the network wire. The first item in the collection will be with the Status Line for a Response message, or the Request Line for a Request message. The HeaderFieldDataBuffer container for the first line only includes the Value byte array, the Name byte array is missing. Each following item is an unprocessed object containing the byte array of the field Name, and field Value. The message content beyond the SIP header fields is contained within the Content byte array. Finally, two fields show the content length. They are derived from two sources, firstly the ContentLength is the actual length of the content byte array. Secondly the ContentLengthHeaderFieldValue is the value shown in the ContentLength header field.

11.6.2 Receiving Messages


The following example registers to receive DataReceived events from the Transport Layer. Within the event handler the DataReceivedEventArgs contains a reference to the TransportDataBuffer. We are using two properties of the buffer, the HeaderField collection and the ContentLength discrete value.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


C#: Data Received Event Args using System.Collections.ObjectModel; using System.Text; using Konnetic.Signalling.Sip; using Konnetic.Signalling.Sip.Advanced; ... SipCore core = new SipCore(); ... core.Transport.DataReceived += new EventHandler<DataReceivedEventArgs> (Transport_DataReceived); }

112

static void Transport_DataReceived(object sender, DataReceivedEventArgs e) { TransportDataBuffer db = e.Data; Collection<HeaderFieldDataBuffer> buffer = db.HeaderFields; Console.WriteLine(string.Format("SIP message received with {0} lines and with a content length of {1}.", buffer.Count, db.ContentLength)); HeaderFieldDataBuffer buf = buffer[0]; char[] chars = Encoding.UTF8.GetChars(buf.Value); Console.WriteLine(string.Format("First line: ", new string(chars))); }

11.7 Example
Listening for and Sending Messages Directly
Once the SipCore is initialised we have to manually start listening for incoming messages. The following example illustrates the mechanism to listen for incoming messages and registering to receive notification on receipt of an new Request message. C#: Listen for Messages Directly
static SipCore core; static void SendResponseDirectly() { //1. Initialise, listen and register for the RequestReceived event core = new SipCore(); core.Transport.ListenForTcpConnections(new IPEndPoint(IPAddress.Loopback, 5060)); core.RequestReceived += new EventHandler<RequestReceivedEventArgs> (core_RequestReceived); }

The next code block sends a response to the receipt of the message. In this example, if the message is

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

113

an Invite, a Ringing message is returned, to indicate the User Agent is trying to get the attention of the user. C#: Respond to an Invite with a Ringing message static void core_RequestReceived(object sender, RequestReceivedEventArgs e) {

//2. Create the response message, which in this instance only allows INVITE messages. SipResponse response = null; if(e.Request.Method == SipMethod.Invite){ response = new SipResponse(e.Request, SipStatusCode.Ringing); } else { response = new SipResponse(e.Request, SipStatusCode.MethodNotAllowed); } //3. Send the response directly bypassing the transaction layer using the DestinationTuple from the response message. core.Transport.Send(response.GetBytes(), response.Recipient); }

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


12 Working with SIP DNS

114

SIP uses DNS procedures, laid out in RFC3263, extensively during normal operation in order to allow clients and servers to resolve SIP URIs to an ordered list of IP Address, port, and the transport protocol of the next hop to pass the message to. The Unity SIP library's DNS features are implemented in the SipDnsCache and SipDnsFacade, and are utilised in the outgoing message processors that deal with sending Request and Response messages prior to actual transmission using the Transport layer. The DNS query implementation is blocking, lazy and contains blacklists. That is, outgoing messages are not put on a seperate thread, but only the DNS queries necessary to accomplish the next successful send operation are performed at any one time. In addition, blacklists of previously failed DNS queries are kept for NAPTR and SRV DNS queries. Queries on the blacklist are not performed again. The DNS functionality includes:

A/AAAA queries resolve IP IPv4/IPv6 address respectively, given a domain/host string. SRV queries resolve the location (domain/host and port) of SIP services. NAPTR queries resolve a SIP target (Request-URI, Route URI or SentBy value) to a prioritised list of supported SIP services.

The result of the usage of NAPTR, SRV, A and AAAA DNS queries is a list of resolved addresses, ports and transports that the library is able to try one after the other, in case of a send failure. The Unity SIP Library only supports DNS queries over UDP. The client application call stack must have the permission to access the DNS servers on the network to perform DNS queries.

12.1 Implementation
12.1.1 When DNS is Used
If the target host text (see below) for a request is an IP Address then that is used in the first instance, otherwise DNS queries are required to resolve the host text to a transport protocol, IP Address and port.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

115

For response messages where the request was sent via a reliable transport (e.g. TCP), the inbound connection is used, if still open. Otherwise the top-most Via header field's received parameter alongside the port from the SentBy parameter is used. Finally DNS queries are required to resolve the host text. When the response uses UDP. The multicast address on the top-most Via header alongside the port from the SentBy parameter is used in the first instance. If that is not present, or fails, the top-most Via header field's Received parameter alongside the port from the SentBy parameter is used. Finally, if that is not present, or fails, DNS queries are required to resolve the host text.

12.1.2 Deriving the Target Host Text


Before sending a message, the SIP library obtains the destination for the message. That may involve deciding on the target host text. Requests If the first header field in the route set (the list of Route header fields on the request) indicates a loose router (i.e. the SipUri contains the 'lr' parameter), the DNS procedures are applied to the SIP URI of the first Route header field value, if one exists. Otherwise, the procedures are applied to the request's Request-URI. Response For responses the target host text is derived from the top-most Via header field's SentBy value.

12.1.3 Caching
The Unity SIP library is configured to support DNS caching. Positive DNS answers are kept in the caching module for further usage. Negative NAPTR and negative SRV querys are also kept in a blacklist that can be access via the SipDnsFacade class.

12.1.4 DNS Queries


RFC3263 governs the querying of DNS servers for locating SIP servers. It specifies the usages of four DNS record types:

NAPTR: used to determine the transport and services locations and their respective preferences. SRV: used to determine the port and the service host. A and AAAA: used to determine the IPv4 and IPv6 addresses for a specific host.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

116

The combination of the three types of records creates a hierarchy of results and DNS records, as illustracted in the following figure. Each NAPTR query can return several SRV records, which, in turn can result in serveral host records, each with several IP addresses (A/AAAA records). Each IP Address is tries in turn untill a sucessful transmission of the message. The SIP library is designed to issues the minimum number of DNS queries in order to sucessfuly transmit the message. So, if the message is transmitted using the first A query from the first SRV query from the first NAPTR query, other queries are not issued.

12.1.5 Additional Resource Records

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide

117

A DNS query may return more than the immediate result in what are known as Additional Resource Records. These may be used to reduce the overall number of DNS queries needed. However, implementers should consider that there have been instances of DNS poisoning with the use of Additional Resource Records. Each additional resource record can contain the next SRV, A and AAAA records, thereby bypassing the need to query for them. In addition, there is no guarentee that all the possible SRV, A, and AAAA records will be returned in the Additional Resource Record. The Unity SIP Library does not issue further DNS queries once the IP addresses in the Additional Resource Record have been exhausted.

12.1.6 Transmission Attempts


The Unity SIP library contains a call management mechanism that controls the transmission of messages. The result of the DNS resolution is an orderd list of destination tuples (IPAddress, Port, Transport Protocol). Each tuple is attempted in turn. On a failure (either an transport failure or transaction timeout), the next tuple is attempted. The call management feature can be disabled using the DisableCallManagement flag on the SipCore Behavours property.

12.2 Configuring DNS


To work with SIP DNS, the library requires information about at least one IPv4 DNS server, and at least one IPv6 DNS server if IPv6 is supported. The list of DNS servers informs the SIP library where to issue DNS queries. Additionally, each DNS server can specify a domain suffix. This tells the SIP library which domain suffixes should be appended to the domain names being queried. Using suffixes allows using shorter versions of a name that is within the suffix domain. The SIP library supports two ways of configuring the information required. Firstly, the Unity SIP Library will try to obtain the data from the operating system. Secondly, the information can be provided using the Konnetic.Net.NetworkInformation static class. The DnsIPv4Collection and DnsIPv6Collection properties expose collections that can be manipulated. Client applications must take care, as manipulating these classes is not thread safe.

12.2.1 Supporting IPV6


IPv6 DNS queries can be turned off or on using the Behaviour static property on the SipCore object.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


12.2.2 Additional Resource Records

118

The use of Additional Resource Records in DNS queries can be turned off or on using the Behaviour static property on the SipCore object.

12.3 The DNS Facade


The Unity SIP Library uses the SipDnsFacade to provide data that is related to DNS. The object is responsible for retrieving DNS information from the SipDnsCache. In some cases the information can be obtained with no DNS query (e.g. obtaining the transport when a transport has been specified on the SipUri); from a single DNS query (such as a NAPTR resolution for the transport protocol); or in other cases several queries (e.g. for host and port resolution for a Fully Qualified Domain Name). The SipDnsFacade is used mainly by the outgoing message processors to implement RFC3263: Session Initation Protocol (SIP): Locating SIP Servers. This RFC describes the way to retrieve the transport protocol of the destination, as well as the IP Address and port number. The destination details can be obtained in a single method call by calling the functions of the SipDnsFacade.

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


Index
Adding Headers To Messages, 82-83 Anatomy Of A Message, 15-16 Application Programming Interface, 46-48 Architecture, 37-38 Call Flow Example, 19-21 Class Hierarchy, 42 Common Client Settings, 58-60 Compact Form, 85-87 Conceptual Overview, 4 Configuration, 58 Configuring DNS, 117-118 Connection Reuse, 104-106 Event Processing, 70-73, 108-109 Example, 112-113 Features, 31-32 Header Fields, 16-19 Headers, 83-85 Implementation, 114-117 Initialisation, 67-69 Internal Settings, 64-66 Introduction, 1-2, 77-78 Introduction to the Library, 30-31 Introduction to TLS in SIP, 106-107 IPv6, 109-110 Legal Information (Unity SIP .NET SDK), 7

119

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


License Agreement, 7-10 License Key Information, 5-6 Listening For Incoming Messages, 73-74 Low-Level Client Settings, 60-64 Message Structure, 23-25 Message Types, 79-82 Methods, 90-91 Ordering, 6-7 Permissions, 36-37 Prerequisites for Unity SIP .NET SDK, 4-5 Redistributable Components for Unity SIP .NET SDK, 5 RFCs Implemented, 32-34 SDP Attributes, 25-26 SDP Contents, 22-23 SDP Example, 26-29 Sending Messages, 74-76 Session Description Protocol, 22 Session Initiation Protocol, 11 Sip Connections, 102-104 Sip Core Behaviours, 69-70 SIP Entities, 11-12 SIP Messages, 12-15 SIP Transaction Objects, 48 SipMessage, 78-79 State Machines, 91-95 Terminology, 34-36 The Authentication Exchange, 99-101

120

2011 Konnetic Ltd. All Rights Reserved.

SIP .NET SDK Programmer's Guide


The DNS Facade, 118 The Exception Model, 38-41 The Http Digest Authentication Manager, 98-99 The SIP URI, 48-51 Threading Model, 41-42 Timers, 95-96 Transaction Class Diagram, 42-44 Transaction Entities, 88-89 Transaction Types, 89-90 Transport Buffers, 110-112 Transport Class Diagram, 44-46 Walkthrough: Accept Or Decline A Session Invite, 55-57 Walkthrough: Initiate a Session, 51-55 Working with Authentication, 97-98 Working with SIP DNS, 114 Working with the SipCore, 67 Working with the Transport Layer, 102 Working with Transactions, 88

121

2011 Konnetic Ltd. All Rights Reserved.

You might also like