Outbound calls from UCMA without Lync Server

In my past blog post on standalone UCMA applications, I described how to build a UCMA application that can answer calls totally independently of Lync Server. Since then, I've gotten a lot of questions about standalone UCMA applications, and I wanted to answer two of them in this post. The first is how to place outbound calls from a UCMA application that isn't connected to Lync Server. The second is how to bypass Lync Server for certain calls from a UCMA application that is connected to Lync Server. For both of these things, you can use an awesome, little-known UCMA class called ConnectionContext.

Let me start by talking a bit about what ConnectionContext does. You can find it as a property on the CallEstablishOptions class. The CallEstablishOptions class is used as an optional parameter to the Call.BeginEstablish method to change some of your application's behaviour when establishing a new call. In the case of the ConnectionContext property, the behaviour you are changing is where the SIP messages for the new call are sent.

Whenever I write something in italics, I feel obligated to take a little break for a diagram or two. Normally, when a UCMA application places a call, it goes through the Lync Front End Server, like so:

SIP INVITE through Front End

The INVITE message that the UCMA application generates contains the SIP URI of the destination user, but the app sends the message to the Front End Server. The Front End Server is then responsible for figuring out where it should go (based on where the user has a logged in endpoint).

In some cases, though, you may need to send an INVITE message directly to another server, bypassing the Front End Server entirely, as shown in this diagram:

Outbound call without FE server

When you want to do this, you can use ConnectionContext to tell UCMA where that SIP INVITE message should go. The ConnectionContext class has Host and Port properties that determine the host and port combination that UCMA will connect to when passing along the INVITE. If you don't set these manually, the default will be to send the call to the host and port combination that represents the Front End Server pool. If you do set the Host and Port properties on a ConnectionContext instance and then use it in the CallEstablishOptions for a new outgoing call, the INVITE message will be sent wherever you specify.

You can use this for a few different purposes. If you are trying to integrate with another non-Lync SIP server, you can send SIP messages directly to it using this method. Also, if you have a standalone UCMA application, you can use ConnectionContext to specify where calls should go (since there will be no Front End Server for them to be proxied through by default).

Here's an example of ConnectionContext in code:

[csharp] // Create the CallEstablishOptions CallEstablishOptions options = new CallEstablishOptions();

// Set the host and port to which the INVITE should be sent options.ConnectionContext = new ConnectionContext("192.168.0.56", 5060);

try { Conversation conv = new Conversation(_endpoint);

AudioVideoCall avcall = new AudioVideoCall(conv);

// Establish the call using the options we created avcall.BeginEstablish("sip:test@test.greenl.ee", options, ar => { try { avcall.EndEstablish(ar); } catch (RealTimeException ex) { Console.WriteLine(ex); } }, null);

} catch (InvalidOperationException ex) { Console.WriteLine(ex); } [/csharp]

As you can see, the usage is pretty simple; just create an instance of CallEstablishOptions, assign a new instance of ConnectionContext to the ConnectionContext property, providing the host and port, and then use the CallEstablishOptions object when calling BeginEstablish. In this case, the call will bypass the Front End Server (if any) and go straight to 192.168.0.56 on port 5060.

Hope this helps for anyone who is building standalone UCMA apps or integrating with other SIP platforms. Feel free to comment if you have questions.