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.

Multiple calls to a conference from the same UCMA endpoint

Posted: September 20th, 2011 | Author: | Filed under: UCMA 3.0 | Tags: , , | 2 Comments »

There are a number of situations where it is necessary for a UCMA application to connect more than one call to a conference. One example that I’ve seen more than once is the situation where you want your application to play messages to a caller, but you also want to record both the messages and the caller’s response. The way to do this is to create two separate instances of AudioVideoCall, join both of them to the conference, and establish them. One of them can then play the messages, while the other can be hooked up to a Recorder object to record both sides of the conversation.

Illustration of multiple conference joins from one application

The problem that developers often face when they first try to do this is that a Lync conference will only allow a given SIP URI to appear in the conference roster once. So if your application simply creates two calls into the conference, using the same endpoint, you will run into trouble with the conference join.

There are a couple of possible solutions for this, and which one you use depends on what exactly you are trying to do.

In most cases, the reason why you need multiple calls to the conference from your application has to do with providing a number of different services to the call: recording, announcements, hold music, or interactive voice response (IVR) menus, for instance. Generally, it’s best to provide these services by having your application join the conference as a trusted participant, meaning that it will not appear in the conference roster and will have elevated permissions in terms of the conference actions it can perform.

When your application is joining a conference multiple times as a trusted participant, you can set the UseGeneratedIdentityForTrustedConference property on CallEstablishOptions to true when establishing the AudioVideoCall that you have joined to the conference. This will cause UCMA to join the conference using a special ad hoc identity rather than using the SIP URI that belongs to the application’s Lync endpoint, allowing you to create more than one of these calls without the SIP URIs colliding.


AudioVideoCallEstablishOptions options = new AudioVideoCallEstablishOptions();

options.UseGeneratedIdentityForTrustedConference = true;

conferenceAvCall.BeginEstablish(options, OnEstablishCompleted, conferenceAvCall);

If you won’t be using trusted conference participants, you want your conference participants to be visible, or if you want complete control over the SIP URIs, there is another option. Before joining each call to the conference, you can call the Conversation.Impersonate method to set the SIP URI that your application will use for this call. Impersonation only works with ApplicationEndpoint, but generally any application that is joining multiple calls to conferences should be using ApplicationEndpoint anyway.


Conversation conv = new Conversation(_endpoint);

conv.Impersonate("sip:fakeuser@domain.local", "", "Fake User");

conv.ConferenceSession.BeginJoin(_conferenceUri, null, OnJoinCompleted, conv);

Again, as long as you use a different SIP URI for each instance of Conversation, you can avoid SIP URI collisions in the conference.

Another case where these two approaches come in handy is if you have several participants which you are connecting to a conference using instances of BackToBackCall. The “conference end” of the BackToBackCall will by default be associated with the SIP URI of your application. Depending on what you are trying to do, you may want to either (1) impersonate the SIP URI of the actual participant on the AudioVideoCall that is on the conference end of the BackToBackCall, or (2) if you are using trusted participants, set the UseGeneratedIdentityForTrustedConference property on CallEstablishOptions to true.


2 Comments on “Multiple calls to a conference from the same UCMA endpoint”

  1. 1 Marcel said at 11:31 am on February 14th, 2012:

    Hi Michael,

    I’m trying to get first “another case”.

    I want to backtoback an incoming AudioVideoCall into an existing Conference but impersonated as the incoming call.

    I just not get it to work.

    I get “A 400 (Bad request) response was received from the network and the operation failed.”

    Can you help me a bit?

    Here’s my code:

    Conversation conv = new Conversation(_applicationEndpoint);

    AudioVideoCall b2b2AvCall = new AudioVideoCall(conv);
    conv.Impersonate(_inboundAVCall.RemoteEndpoint.Participant.Uri,_inboundAVCall.RemoteEndpoint.Participant.PhoneUri, _inboundAVCall.RemoteEndpoint.Participant.DisplayName);

    //AudioVideoCallEstablishOptions opt = new AudioVideoCallEstablishOptions();
    //opt.UseGeneratedIdentityForTrustedConference = true;

    BackToBackCallSettings outgoingSettings = new BackToBackCallSettings(b2b2AvCall, ConferenceConversation.ConferenceSession.ConferenceUri);
    // outgoingSettings.CallEstablishOptions = opt;

    BackToBackCallSettings incomingSettings = new BackToBackCallSettings(_inboundAVCall);
    _b2bInboundToConference = new BackToBackCall(incomingSettings, outgoingSettings);

    _b2bInboundToConference.StateChanged += new EventHandler(_b2bout_StateChanged);
    _b2bInboundToConference.BeginEstablish(ar =>
    {
    BackToBackCall call = ar.AsyncState as BackToBackCall;
    call.EndEstablish(ar);
    _waitForB2BCallToBeEstablished.Set();
    }, _b2bInboundToConference);
    _waitForB2BCallToBeEstablished.WaitOne();

  2. 2 Michael said at 9:35 am on February 16th, 2012:

    Hi Marcel,

    Right now you have the conference URI provided as the destination URI for the “outgoing” leg of the B2B call. I think UCMA is getting confused because you’re giving it a conference URI as though it’s a two-party call.

    Instead of this, after your conv.Impersonate try doing:

    conv.ConferenceSession.BeginJoin(ConferenceConversation.ConferenceSession.ConferenceUri, null, OnConferenceJoinCompleted, null);

    Then, in the callback (OnConferenceJoinCompleted), you can set up the BackToBackCallSettings without providing the destination URI:

    BackToBackCallSettings outgoingSettings = new BackToBackCallSettings(b2b2AvCall);

    and then continue with the rest of your code.

    Let me know if that fixes the problem or if there’s anything you’d like me to clarify.


Leave a Reply

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

  •