A conversation is a concept that represents communication between a local participant (the conversation initiator) and one or more remote participants, which can be either real people or applications. A conversation can be thought of as two-dimensional, with the number of media modalities representing one dimension, and the number of participants representing the other.

A Unified Communications Managed API (UCMA) application can initiate a conversation in either of the following modalities:

  • A unimodal Instant Message (IM) or audio conversation. (Other modes are possible, but require extending the Unified Communications Managed API 2.0 Core SDK platform to work with calls that use different media types.)

  • A multimodal conversation.

A conversation is also distinguished by its number of participants: involving two parties, is a two-party conversation. A conversation with three or more participants is called a multiparty conversation.

  • A two-party conversation is one that consists of a local participant and a single remote participant.

  • A multiparty conversation is one that consists of a local participant and two or more remote participants. An application can start a multiparty conversation directly, or can escalate a two-party conversation to a conference.

MCU-type Conversations

A local endpoint associated with the conversation can have multiple calls with the same modality, provided that the value of the local endpoint’s EndpointTypeproperty is Conference. Such a conversation is called an MCU (Multi-point control unit) type conversation. If the endpoint’s EndpointTypeproperty is any other value ( User, Application, or Gateway), each media type present can be associated with only one call.

An MCU type conversation is a variation of multiparty conversation except for one main difference; an MCU type conversation can have multiple established calls with the same modality. Typically, an application would use a MCU type conversation when it wants to build a MCU application. A local endpoint which is hosting a MCU type conversation can only have at most one conversation.

Conversation State Transitions - Outbound

The Conversationstate transitions for outbound calls are shown in the following illustration. A list of the possible states can be seen in Conversation Properties, later in this topic.

  1. The transition from Idleto Establishingoccurs when Call. BeginEstablishexecutes for the first call bound to the Conversationinstance.

  2. The transition from Idleto Conferencingoccurs when Conversation.ConferenceSession. BeginJoinis called.

  3. The transition from Establishingto Establishedoccurs when the first call is successfully established, by Call. EndEstablish.

  4. The transition from Establishingto Terminatingoccurs when autotermination is triggered and all conditions are satisfied. For details, see the material immediately following this list.

  5. The transition from Conferencingto Idleoccurs when a conferencing failure occurs.

  6. The transition from Establishedto Terminatingoccurs when Conversation. BeginTerminateis called or when autotermination is triggered and all conditions are satisfied. For details, see the material immediately following this list.

  7. The transition from Establishedto Conferencingoccurs when Conversation.ConferenceSession. BeginJoinis called to escalate the conversation.

  8. The transition from Conferencingto Terminatingoccurs when Conversation. BeginTerminateis called.

  9. The transition from Conferencingto Establishedoccurs when there is an escalation failure for the established calls.

  10. The transition from Idleto Terminatingoccurs when Conversation. BeginTerminateis called or when autotermination is triggered and all conditions are satisfied. For details, see the material immediately following this list.

  11. The transition from Establishingto Idleoccurs when a call is terminated while there are other calls that are about to be established.

  12. The transition from Conferencingto Establishingoccurs when a conference failure occurs with no calls in the Establishedstate, but at least one call’s state is Establishing.

  13. The transition from Conferencingto Conferencedoccurs when the calls are successfully escalated or when the conversation is successfully joined to the conference session.

  14. The transition from Conferencedto Terminatingoccurs when Conversation. BeginTerminateis called or a conference participant is ejected from the conference.

  15. The transition from Terminatingto Terminatedoccurs when Conversation. EndTerminatecompletes.

Autoterminationis triggered when the last non-idle call in the conversation is terminated or when the ConferenceSessionjoin operation fails.

Autotermination occurs when all three of the following conditions are satisfied.

  1. All calls bound to the Conversationinstance are in the Idlestate.

  2. The state of the ConferenceSessioninstance that is bound to the Conversationinstance is neither Connectingnor Connected.

  3. The conversation does not involve an MCU.

Conversation State Transitions - Inbound

The Conversationstate transitions for inbound calls are shown in the following illustration.

  1. The transition from Incomingto Establishingoccurs when Call. BeginAcceptis called on the incoming call that is bound to the conversation.

  2. The transition from Incomingto Conferencingoccurs when Conversation.ConferenceSession. BeginJoinis called.

  3. The transition from Establishingto Establishedoccurs when the first call is successfully established. (Call. EndAcceptcompletes.)

  4. The transition from Establishingto Terminatingoccurs when autotermination is triggered and all conditions are satisfied. For details, see the material following the list of the preceding section.

  5. The transition from Conferencingto Idleoccurs when there is a conference failure.

  6. The transition from Establishedto Terminatingoccurs when Conversation. BeginTerminateis called or autotermination is triggered and all conditions are satisfied. For details, see the material following the list of the preceding section.

  7. The transition from Establishedto Conferencingoccurs when Conversation.ConferenceSession. BeginJoinis called to escalate the conversation to a conference.

  8. The transition from Conferencingto Terminatingoccurs when Conversation. BeginTerminateis called.

  9. The transition from Conferencingto Establishedoccurs when established calls cannot be escalated.

  10. The transition from Incomingto Terminatingoccurs when Conversation. BeginTerminateis called or when autotermination is triggered and all conditions are satisfied. For details, see the material following the list of the preceding section.

  11. The transition from Establishingto Idleoccurs when a call is terminated while there are other calls that are about to be established.

  12. The transition from Conferencingto Establishingoccurs when a conference failure occurs with no calls in the Establishedstate, but at least one call’s state is Establishing.

  13. The transition from Conferencingto Conferencedoccurs when the calls are successfully escalated or the conversation is successfully joined to the conference session.

  14. The transition from Conferencedto Terminatingoccurs when Conversation. BeginTerminateis called or a conference participant is ejected from the conference.

  15. The transition from Terminatingto Terminatedoccurs when Conversation. EndTerminatecompletes.

  16. The transition from Idleto Terminatingoccurs when autotermination is triggered and all conditions are satisfied. For details, see the material following the list of the preceding section.

Conversation Constructors

The following are the public constructors on the Conversationclass.

Copy Code
// Creates a new instance of the Conversation class.
public Conversation(LocalEndpoint localEndpoint);

// Creates a new instance of the Conversation class with the given
settings.
public Conversation(LocalEndpoint localEndpoint,
ConversationSettings settings);

Conversation Properties

The following are the public properties on the Conversationclass.

Copy Code
// Gets or sets the application context. This is useful for the
application
// to retrieve conversation-specific application context.
public object ApplicationContext {get;set;}

// Gets the current state of the conversation.
public ConversationState State {get;}

// Gets the endpoint of the conversation.
public LocalEndpoint Endpoint {get;}

// Gets the local participant used for the conversation.
// This matches either the endpoint's URI or the impersonated URI.
public ConversationParticipant LocalParticipant {get;}

// Gets the list of remote participants.
public ReadOnlyCollection<ConversationParticipant>
RemoteParticipants {get;}

// Gets the list of active media types for this conversation.
public Collection<String> ActiveMediaTypes {get;}

// Gets the conference session for this conversation. 
// This exposes a conference session whose behavior is based
// on the state of the conversation. For an established
// conversation, the conference session will use an ad hoc
// conference. For a conversation that is escalated by a remote
// participant, the conference session uses the conference
information
// that was sent by the remote via the conference invitaton.
// If the application created the conference session, this
// property will expose the conference session added by the
application.
public ConferenceSession ConferenceSession {get;}

// Gets the subject of the conversation.
public string Subject {get;}

// Gets the priority of the coonversation.
public string Priority {get;}

// Gets the ID of the conversation.
public string ID {get;}

// Gets the list of established calls from the conversation.
public ReadOnlyCollection<Call> Calls {get;}

The state of the conversation is reflected by the Stateproperty. The possible states are:

  • Idle

  • Incoming

  • Establishing

  • Established

  • Conferencing

  • Conferenced

  • Terminating

  • Terminated

With one exception, the meanings of the state transitions can be discerned from their names. The state transition that is not obvious occurs when a conversation is escalated from a two-party conversation to a conference. When the application joins a conference in an established conversation, the state will change to Conferencingand will remain there until the application calls the BeginEscalatemethod to escalate the conversation to a conference or until a timer expires if the conference remains too long in the Conferencingstate. If the escalation succeeds, the state will change to the Conferencedstate. If the escalation fails, the state will revert to the Establishedstate.

If the application joins a conference before any calls are added to the conversation, the state can change from Idleto Conferencingand then to Conferenced.

If a two-party conversation is established and the application intends to invite a third party, it should first join the conference, escalate the conversation, and then send the invitation to the third party. After the join is successfully completed, the conversation state will change from Establishedto Conferencing.

Conversation Methods

The following are the public methods on the Conversationclass.

Copy Code
// Impersonates a different user. This is allowed only when using
an application endpoint.
// The method can be called only when the conversation state is
Idle or Incoming.
public void Impersonate(string uri, string phoneUri, string
displayName);

// Updates the properties of the conversation.
// Sends a conversation property update message.
public IAsyncResult BeginUpdateProperties(
	ConversationProperties conversationProperties,
	AsyncCallback userCallback,
	object state);

// Completes the BeginUpdateProperties operation.
public void EndUpdateProperties(IAsyncResult result);

// Invites remote participants into the conversation.
// Sends a conference invitation to each member of the
destinationUris parameter.
// The conversation must already be joined to a conference.
public IAsyncResult BeginInviteRemoteParticipants(
	IEnumerable<string> destinationUris,
	ToastMessage toastMessage, 
	AsyncCallback userCallback,
	object state);

// Invites remote participants into the conversation.
// Sends a conference invitation to each member of the
destinationUris parameter.
// The conversation must already be joined to a conference.
public IAsyncResult BeginInviteRemoteParticipants(
	IEnumerable<string> destinationUris,
	IEnumerable<string> mediaTypes, 
	ToastMessage toastMessage,
	AsyncCallback userCallback,
	object state);

// Waits for the BeginInviteRemoteParticipants operation to
complete.
public void EndInviteRemoteParticipants(IAsyncResult result);

// Escalates the conversation to a conference.
// The application must join the conference before calling this
method.
public IAsyncResult BeginEscalateToConference(AsyncCallback
userCallback, object state);

// Waits for the EscalateToConference operation to complete.
public void EndEscalateToConference(IAsyncResult result);

// Terminates the conversation.
public IAsyncResult BeginTerminate(AsyncCallback userCallback,
object state);

// Waits for the pending terminate operation.
public void EndTerminate(IAsyncResult result);

The BeginEscalatemethod can be called to escalate a conversation in the Conferencingstate to the Conferencedstate by ensuring that calls are switched from two-party to MCU-based sessions, and that the remote party is informed by a conference invitation to join the conference and switch the calls to the MCU.

A conversation can be escalated to a conference by the existing remote participant at any time. When this happens, the EscalateToConferenceRequestedevent is raised. The application is expected to join the conference followed by a call to the BeginEscalatemethod.

After the conversation is in the Conferencedstate, one or more new participants can be invited into the conference by using the BeginInviteRemoteParticipantsmethod, which has two overloads. The first overload determines the media types to be added to the invitation, based on the active media types of the call (current behavior). The second overload allows the application to specify the media types. The application also indicates the toast message (in the toastMessageparameter of BeginInviteRemoteParticipants) to be sent along with the conference invitation.

After the conversation is in the Conferencedstate, the RemoteParticipantAttendanceChangedevent is raised to indicate added or removed parties. This event is also raised when the remote participant is added for a two-party conversation.

Note:
Each participant instance exposes the set of remote endpoints of that participant as a collection of ParticipantEndpointinstances.

The application can change the subject, priority, and ID of a conversation using the appropriate methods. There are some restrictions for changing the conversation ID. If the remote participant changes any of these properties, the PropertiesChangedevent is raised.

Conversation Events

The following are the public events on the Conversationclass.

Copy Code
// Raised when the state of the conversation changes.
public event
EventHandler<StateChangedEventArgs<ConversationState>>
StateChanged;

// Raised when one or more properties are changed in the
conversation.
public event
EventHandler<PropertiesChangedEventArgs<ConversationProperties>>
PropertiesChanged;

// Raised when the existing remote participant requests that
// the conversation be escalated to a conference. 
// The platform will autoaccept the invitation.
// The application is responsible for actually joining the
conference
// in the conversation. The application cannot
// create a new conference of its own for this conversation in this
state,
// but instead should use the ConferenceSession property of the
conversation.
public event EventHandler<EventArgs>
EscalateToConferenceRequested;

// Raised when the operation to add remote participants to the
conversation
// has finished sending the invitation to a specific participant. 
public event EventHandler<InviteParticipantUpdateEventArgs>
InviteRemoteParticipantUpdate;

// Raised when remote participants join or leave the conversation.
public event
EventHandler<ParticipantAttendanceChangedEventArgs>
RemoteParticipantAttendanceChanged;

// Raised when one or more properties of a remote participant have
changed.
public event
EventHandler<ParticipantPropertyChangedEventArgs>
ParticipantPropertiesChanged;

After the first call on the conversation is established, the remote participant for the conversation is locked and all new calls on the conversation should use the same remote participant. If the conversation has locked the remote participant (because the first call on the conversation is established) and a new call on the conversation is deflected to a new remote endpoint, a new derived conversation is created with the remote endpoint pointing to the deflected call endpoint. The deflected call now has the new associated conversation. When the conversation changes, the ConversationChangedevent on the call is raised, thereby notifying the application of this change.