How to tell where a call is ringing in UCMA

Lately I've been spending a lot of time looking at "forking," the process where a call (audio, IM, video, whatever) to a user is sent to all devices where that user is logged into Lync, and various ways to handle it in UCMA. A while back, I described how you can look at the SIP headers in the response when an outgoing call is answered to find out if, for example, a voicemail box answered the call. By looking at "provisional responses," you can get details like this before the call is even answered, while it's still "ringing" to the user's various endpoints. 180 Ringing messages going to UCMA app

There are a few reasons why this might be useful. The way a call behaves when ringing can be slightly different depending on whether the recipient is logged in from one or multiple endpoints, so this allows you to find out the number of endpoints and anticipate these differences in behaviour. Also, if a user is logged in from multiple endpoints, in certain situations you might want to send messages to one or more specific endpoints once the call is answered. If the user answers the call on a Lync Phone Edition device, maybe your application needs to send an IM directly to the Lync client on the PC. Or maybe you want to send notifications to the devices that didn't answer, indicating that the call was picked up elsewhere.

Finally, you might want your application to take actions while the call is still ringing, like try to set up early media, based on the information you get in the provisional responses.

Let me take a minute to define "provisional response." In this context, a provisional response is a response with a 1xx response code, such as 100 Trying or 180 Ringing. These responses indicate that the SIP session is still in the process of being established, and a final response (a "yes" or "no," so to speak) hasn't come back yet.

A 100 Trying indicates that the proxy server (the Lync Front End Server) has received the message and is passing it along to the user's endpoints.

A 180 Ringing indicates that an endpoint has received the message and is alerting the user to the call in some way. The 180 Ringing will contain details of the endpoint, such as that endpoint's GRUU.

Moving along to the practical details, you can receive notifications of provisional responses when establishing a call by subscribing to the AudioVideoCall.ProvisionalResponseReceived event before calling AudioVideoCall.BeginEstablish. Here's an example:

[csharp] avCall.ProvisionalResponseReceived += new EventHandler<CallProvisionalResponseReceivedEventArgs( OnProvisionalResponseReceived);

avCall.BeginEstablish(sipUri, null, OnCallEstablished, null); [/csharp]

In the event arguments, you'll have access to the entire response message through the ResponseData property, so you can do things like the following:

[csharp] void OnProvisionalResponseReceived(object sender, CallProvisionalResponseReceivedEventArgs e) { Console.WriteLine("provisional response!"); Console.WriteLine(e.ResponseData.ResponseCode + " " + e.ResponseData.ResponseText); foreach (SignalingHeader header in e.ResponseData.SignalingHeaders) { Console.WriteLine(header.Name + ": " + header.GetValue()); } Console.WriteLine("********************"); } [/csharp]

By looking at the 180 Ringing message, you can find out a few interesting facts. The Contact header on the 180 Ringing message tells you the GRUU of the specific endpoint where the call is ringing, which you can use to direct messages to that exact endpoint. You can also look at the User-Agent header to find out what type of device the call is ringing on, such as a Lync Phone Edition device, a Lync mobile client, or a PC. There are plenty of other potentially useful things you can find out, but those are a few to start.