Microsoft Lync and Skype for Business have a rich set of .NET APIs which make it easy to extend the platform and integrate it with other applications. This blog helps explain how to use those APIs.

Multi-part SDP and non-Lync endpoints

Posted: May 7th, 2013 | Author: | Filed under: MSPL | Tags: , , , , | 1 Comment »

Lync endpoints, including UCMA applications, are capable of communicating directly with non-Lync SIP endpoints under certain circumstances, without going through the Mediation Server. This can be advantageous for a few reasons. For one, the Mediation Server removes non-standard SIP headers when passing along messages, so any information you try to include in custom SIP headers when connecting to an endpoint through the Mediation Server will be lost. Also, you may need to communicate with other internal SIP systems — a voice mail system, for example — in an environment where the Mediation Server is not in use.

The first limitation is codecs: the remote endpoint must support a codec that Lync supports, such as G.711. Beyond this, though, there are some other unique features of Lync’s dialect of SIP that sometimes confuse or upset other SIP endpoints. One of these is Lync’s use of multi-part SDP.

You can identify a SIP INVITE that contains multi-part SDP by looking at the Content-Type header in the request. Normally, a SIP INVITE that is designed to initiate a call has a content type of application/sdp. This is what most SIP endpoints will expect. Lync endpoints, however, often instead use the content type multipart/alternative. If you look at the body of a message with this content type, you will see that it is split into several parts, with what appears to be gibberish in between:

------=_NextPart_000_27C7_01CE45DC.5D4863F0
Content-Type: application/sdp
Content-Transfer-Encoding: 7bit
Content-ID: <eb8c50acd33a623b8010f97df13317d3@claritycon.com>
Content-Disposition: session; handling=optional; ms-proxy-2007fallback
v=0
o=- 0 0 IN IP4 192.168.100.0
s=session
c=IN IP4 192.168.100.0
b=CT:99980
t=0 0
m=audio 50363 RTP/AVP 117 114 9 112 111 0 8 116 115 97 13 118 101
...
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
------=_NextPart_000_27C7_01CE45DC.5D4863F0
Content-Type: application/sdp
Content-Transfer-Encoding: 7bit
Content-ID: <4554325e494643e6f50b1a5e1bfb950b@claritycon.com>
Content-Disposition: session; handling=optional
v=0
o=- 0 1 IN IP4 192.168.100.0
s=session
c=IN IP4 192.168.100.0
b=CT:99980
t=0 0
...
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
------=_NextPart_000_27C7_01CE45DC.5D4863F0--

What is going on here? What’s the reason for this bizarre behaviour from Lync?

The body of these messages is actually multipart MIME. The purpose of this multipart SDP is to provide a simpler version of the media offer that the older (OCS) endpoints can handle, while also including the current version for Lync endpoints. Unfortunately, non-Lync endpoints generally don’t support the multipart/alternative content type for the SDP, and so to them it appears that the message is malformed or missing the SDP. To make matters worse, there is no way to disable this behaviour, even if you don’t plan to support the 2007 versions of the client in your environment.

So how can we get ourselves out of this mess? An interesting option is to use the Lync Server SDK, specifically the Managed SIP Application API, to modify the INVITE message and turn the multi-part SDP into ordinary SDP. If you’re looking for an explanation of the Managed SIP Application API and how to use it, check out my earlier post.

Here is an example of some code you might use to convert the multipart SDP in an outgoing INVITE to ordinary SDP (I’m assuming here that the MSPL script is only dispatching requests to the managed code when they need to be changed in this way). This is a very basic code sample, without any exception handling or anything, so obviously don’t use it in a production environment.

private void OnRequest(RequestReceivedEventArgs e) 
{ 
    Header contentType = e.Request.AllHeaders.FindFirst(
        Microsoft.Rtc.Sip.Header.StandardHeaderType.ContentType); 
    Header contentLength = e.Request.AllHeaders.FindFirst(
        Microsoft.Rtc.Sip.Header.StandardHeaderType.ContentLength); 
    string messageBody = e.Request.Content; 
    
    // Grab the boundary string from the Content-Type header
    var boundary = "--" + contentType.Value.Split('=').LastOrDefault(); 
    
    // Grab the first MIME part that is long enough to contain SDP
    string firstSdpPart = requestContent.Split(new string[] { boundary }, 
        StringSplitOptions.None).FirstOrDefault(
        sdp => sdp.Length > 10) ?? "";
    
    // Remove the headers at the beginning of the MIME 
    // part so we take only the SDP itself
    string newBody = firstSdpPart.Substring(
        firstSdpPart.IndexOf("v=", 
        StringComparison.InvariantCulture)).Trim();
    
    // Set the new content type to application/sdp
    contentType.Value = "application/sdp"; 
    
    // Set the new content length to the actual length of 
    // the new application/sdp body
    contentLength.Value = newBody.Length.ToString(); 
    
    // Put the new body into the message
    e.Request.Content = newBody; 

    // Send the message along to its original destination
    e.ServerTransaction.CreateBranch().SendRequest(e.Request); 
    
    Console.WriteLine(
        "Changed multipart/alternative SDP to application/sdp");
}

With something like this in place, your Lync endpoints can gleefully send multipart SDP and it will be turned into normal SDP for the non-Lync endpoints on the other end.

Let me know if you have questions about this approach. Also, credit goes to my colleague Dan Gardiner, who worked together with me to figure out this solution and who wrote the test code that the sample above is based on.


One Comment on “Multi-part SDP and non-Lync endpoints”

  1. 1 Kunal said at 11:50 pm on November 26th, 2013:

    Hi,
    I am trying to integrate Lync 2013 with Genesys. Lync and genesys agent share the same extension and they are using Lync USB phones to talk. So that means RTP flows through lync no matter if you call using the Genesys client. the integration part works fine. When we receive a call on the hotline, that call reaches the client and can be transferred in case need arises without any problem.
    The issue is with the consult transfer. A Call when initiated from a third party phone calls the hotline, it rings the genesys and lync agent and the call is picked on the lync phone and it works, when i initiate a consult transfer from the Genesys Agent to another agent, the call drops and gives a busy message on the client.
    I checked the SIP debugs and i see that when the call first lands on the Lync Server the invite header comes with the SDP.. and for consult transfer when Genesys tries to send another invite, that invite does not come with the SDP. and then i receive a reply from the FE server saying that it is a 400 BAD message.

    The transfer or blind transfer when initiated from genesys works fine. The SIP message on the transfer call contains the SDP in the invite header..

    Is it possible for Lync to support reinvite message without the SDP at all. can this API help in this case.

    the Genesys version is for the Contact center version 8. the genesys software used is IWS or I work Space. the Lync Server is 2013 with 3 FE Servers and HLB, Mediation server Collocated. Audio Codes 1000 gateway with E1 PRI line to Telco.
    Everything works fine from Lync client.


Leave a Reply

  • Note: Comment moderation is in use because of excessive spam. Your comment may not appear immediately.

  •