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.

Unexpected places to find information in UCMA

Posted: October 26th, 2011 | Author: | Filed under: UCMA 3.0 | 2 Comments »

Once in a while I need to find a specific detail on a call or some other Lync object, and have to pore over the SDK documentation for long periods of time to figure out where to get it. After doing this many times, I’ve found that there are a few unintuitive places where useful pieces of information often turn out to be hiding. I thought I would share a few of these in this post.

End methods

Many of the End methods for asynchronous operations in UCMA (probably the majority) have a void return type. Some of the methods, though, do return something, and at times this return value can be quite important. Because writing the code to call the End method often feels like a repetitive step that you need to go through simply to make the asynchronous operation complete properly, it’s easy to overlook the useful things these methods return.

An easy example is scheduling a conference using LocalEndpoint.ConferenceServices.BeginScheduleConference. When you call this method, you pass in a ConferenceScheduleInformation object which contains details like the conference ID, but you don’t know the conference URI until after the conference has actually been scheduled by Lync. The easiest way to find out this URI is to look at the Conference object returned by the EndScheduleConference method, as shown in the following code:

try
{
    _endpoint.ConferenceServices.BeginScheduleConference(
        scheduleInfo,
        ar =>
        {
            try
            {
                Conference newConference =
                    _endpoint.ConferenceServices.EndScheduleConference(ar);

                DoSomethingWithTheConference(newConference);
            }
            catch (RealTimeException ex)
            {
                Console.WriteLine(ex);
            }
        },
        null);
}
catch (InvalidOperationException ex)
{
    Console.WriteLine(ex);
}

This is a case where the return value is harder to miss, but there are plenty of less obvious uses for the return values of End methods. For instance, several of the call-related End methods (e.g., EndEstablish, EndAccept, EndTransfer, etc.) return an instance of CallMessageData. This seemingly unimportant object can be extremely handy if you ever need to find out what exactly your application is sending out in the SIP messages generated by UCMA. The code below demonstrates how this can work.

try
{
    avCall.BeginEstablish(ar =>
        {
            try
            {
                CallMessageData data =
                    avCall.EndEstablish(ar);

                Console.WriteLine("Request URI: {0}",
                    data.MessageData.RequestUri);
            }
            catch (RealTimeException ex)
            {
                Console.WriteLine(ex);
            }
        },
        null);
}
catch (InvalidOperationException ex)
{
    Console.WriteLine(ex);
}

There are all manner of other specific examples of this, such as call parking, where you need to get the call orbit:

try
{
    avCall.BeginPark(ar =>
        {
            try
            {
                CallParkResponseData data =
                    avCall.EndPark(ar);

                StoreOrbit(data.Orbit);
            }
            catch (RealTimeException ex)
            {
                Console.WriteLine(ex);
            }
        },
        null);
}
catch (InvalidOperationException ex)
{
    Console.WriteLine(ex);
}

Options classes

Another often overlooked area of the API which I’ve mentioned before is the several “options” classes that you can use to change the behaviour of UCMA when executing certain operations. An example is the CallEstablishOptions object. You can create an instance of this class and pass it in to Call.BeginEstablish in order to do things like add custom SIP headers, add custom MIME content to the message body, or change the maximum length of time the call will ring before giving up.

AudioVideoCallEstablishOptions options;

options.MaximumEstablishTime = new TimeSpan(0, 2, 0);
options.Headers.Add(new SignalingHeader("Telemarketer", "true"));

Another example: using CallTerminateOptions, you can specify your own diagnostic information for why a call was terminated.

CallTerminateOptions options;
options.DiagnosticsInformation = new DiagnosticsInformation(8157, "Solar flare",
    "An error occurred because of an unexpected error.", DiagnosticVisibility.Public);

avCall.BeginTerminate(options, OnTerminateCompleted, null);

As with the End methods, these options classes are worth poking through if you’re searching for a way to do something very specific with UCMA.

Flow classes

Another set of classes that gets overlooked quite a bit is the MediaFlow class and its subclasses. These classes represent the media data that are exchanged between the two endpoints in a call. Probably the most frequent use of a flow class is to send IM messages using the BeginSendInstantMessage method, but there are several other noteworthy things you can do with them. For example, you can set the “composing state” on an IM call, which determines whether remote participants using the Lync client see the “typing…” message at the bottom of the window.

imCall.Flow.LocalComposingState = ComposingState.Composing;

For audio calls, you can use the AudioVideoFlow object to put a call on hold or take it off hold:

avCall.Flow.BeginHold(HoldType.BothEndpoints, OnHoldCompleted, null);

Like the options classes, these classes are worth exploring for things you didn’t know you could do with UCMA.

Request data

When a UCMA application receives a SIP request from Lync Server, it generally causes an event to be invoked on one of the UCMA objects — an endpoint, a call, etc. Consequently, you as the developer don’t need to interpret the individual bits and pieces of the SIP message. As I discussed in a previous post, though, sometimes you actually want to see the details of the SIP message in your application. For this purpose, the SipRequestData class is invaluable.

You will usually find these objects on the event arguments for events like CallReceived, MessageReceived, ConferenceInvitationReceived, and so forth. Look for properties called RequestData or MessageData.

By looking at the properties on the SipRequestData object, particularly SipRequestData.SignalingHeaders, you can dissect the exact SIP message that your application received and find whatever specific pieces you need.


2 Comments on “Unexpected places to find information in UCMA”

  1. 1 Unexpected places to find information in UCMA | CodeLync said at 6:18 am on November 1st, 2011:

    […] will no doubt save the typical UCMA developer countless hours of head-scratching. You can read it here. This entry was posted in Uncategorized by Paul Nearney. Bookmark the […]

  2. 2 rishi said at 8:32 am on September 4th, 2014:

    I am, not able to get the URI for the conference i am scheduling. I want to schedule conference on button click event. Here is my code..

    private void button1_Click(object sender, EventArgs e)
    {

    ConferenceScheduleInformation CSI = new ConferenceScheduleInformation();

    CSI.AccessLevel = ConferenceAccessLevel.Everyone;
    CSI.AutomaticLeaderAssignment = AutomaticLeaderAssignment.Everyone;
    CSI.ConferenceId = “Whatever”;
    CSI.Description = “Test Conference”;
    CSI.Subject = “Testing_Subject”;
    CSI.Mcus.Add(new ConferenceMcuInformation(McuType.AudioVideo));

    try
    {
    _localendpoint.ConferenceServices.BeginScheduleConference(CSI,
    ar =>
    {
    try
    {
    Conference newConference = _localendpoint.ConferenceServices.EndScheduleConference(ar);
    //DoSomethingWithTheConference(newConference);
    }
    catch (RealTimeException ex)
    {
    Console.WriteLine(ex);
    }
    },
    null);
    }
    catch (InvalidOperationException ex)
    {
    Console.WriteLine(ex);
    }

    }


Leave a Reply

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

  •