At the SIP level, a Callis represented as a SIP INVITE with Session Description Protocol (SDP) that contains information about the media types that are included in the call, together with other information that helps negotiate a connection between the sender and recipient of the INVITE.

Similarly, a ConferenceInvitationis also represented at the SIP level as a SIP INVITE, although the SDP contains XML data that describes the conference and the media types that are available in the conference.

The following list describes the steps an application must perform when it receives a conference invitation. Several steps refer to the code example that follows the list.

  1. The application registers for the ConferenceInvitationReceivedevent (an event on the LocalEndpointclass).

  2. When the ConferenceInvitationReceivedevent is raised, the application accepts the invitation by calling the BeginAcceptmethod on the Invitationproperty. This is shown in the following example, in the ConferenceInvitationReceivedmethod.

    For the sake of simplicity, the example does not ask the application user whether to accept the invitation. If the IsImmediateAutoAcceptNeededproperty on inviteis true, the application should accept the invitation without consulting the user. If IsImmediateAutoAcceptNeededis false, the application should register for the AutoAcceptNeededevent and should immediately consult the user to ask whether the invitation should be accepted. If, after 15 seconds, the user has not responded to the query, the AutoAcceptNeededevent is raised, provided that the invitation contains MediaType.Message(see the first ifstatement in the ConferenceSession_JoinCompletedmethod) and eventArgs.IsForkedis true. If the AutoAcceptNeededevent is raised, the application must accept the invitation without further consultation with the user.

  3. After the conference invatation has been accepted successfully, the application joins the conference by calling BeginJoin. This is shown in the following example, in the ConferenceInvitation_AcceptCompletedmethod.

  4. If the join operation has completed successfully, (when the ConferenceSession. EndJoinmethod returns successfully), the application can participate by creating an instant message call or an audio/video call, and then establishing the call, using BeginEstablish. This is shown in the following example, in the ConferenceInvitation_JoinCompletedmethod.

  5. After the call is established successfully, (when the ConferenceSession. EndEstablishmethod returns successfully), the application can use the call to exchange media (that is, the application is ready to send and receive instant messages in an InstantMessagingCallor to send and receive audio in an AudioVideoCall). The ImCall_EstablishCompletedand AvCall_EstablishCompletedmethods in the following example show how to check that an instant message call and an audio/video call, respectively, have been successfully established.

Copy Code
public class ConferenceInvitationExample
// This class is shown for demonstration purposes only. It is
incomplete,
// and so will fail to compile.
{
  private Conversation m_conversation;
  private InstantMessagingCall m_imCall;
  private AudioVideoCall m_avCall;

  public ConferenceInvitationExample()
  {
  }

  private void ConferenceInvitationReceived(object sender,
ConferenceInvitationReceivedEventArgs eventArgs)
  {
	ConferenceInvitation invite = eventArgs.Invitation;
	invite.
BeginAccept(ConferenceInvitation_AcceptCompleted, invite);
  }

  private void ConferenceInvitation_AcceptCompleted(IAsyncResult
result)
  {
	try
	{
	ConferenceInvitation invite = result.AsyncState as
ConferenceInvitation;
	invite.EndAccept(result);
	m_conversation = invite.Conversation;
	RegisterConversationHandlers();
	m_conversation.ConferenceSession.
BeginJoin(ConferenceSession_JoinCompleted, invite);
}
	catch (RealTimeException ex)
	{
	Trace.TraceError("invite.EndAccept failed. Exception: {0}",
ex.ToString());
}
	catch (InvalidOperationException ex)
	{
	Trace.TraceError("m_conversation.ConferenceSession.BeginJoin
failed. Exception: {0}", ex.ToString());
}
  }

  private void ConferenceSession_JoinCompleted(IAsyncResult result)
  {
	try
	{
	ConferenceInvitation invite = result.AsyncState as
ConferenceInvitation;
	Collection<string> activeMediaTypes =
invite.GetAvailableMediaTypes();

	m_conversation.ConferenceSession.
EndJoin(result);
	if (activeMediaTypes.Contains(MediaType.Message))
	{
		try
		{
		InstantMessagingCall imCall = new
InstantMessagingCall(m_conversation);
		imCall.
BeginEstablish(ImCall_EstablishCompleted, imCall);
	}
		catch (InvalidOperationException ex)
		{
		Trace.TraceError("imCall.BeginEstablish failed.
Exception: {0}", ex.ToString());   
	}
}
	if (activeMediaTypes.Contains(MediaType.Audio))
	{
		try
		{
		AudioVideoCall avCall = new
AudioVideoCall(m_conversation);
		avCall.
BeginEstablish(AvCall_EstablishCompleted, avCall);
	}
		catch (InvalidOperationException ex)
		{
		Trace.TraceError("avCall.BeginEstablish failed.
Exception: {0}", ex.ToString());
	}
}
}
	catch (RealTimeException ex)
	{
	Trace.TraceError("m_conversation.ConferenceSession.EndJoin
failed. Exception: {0}", ex.ToString());
}
  }

  private void ImCall_EstablishCompleted(IAsyncResult result)
  {
	try
	{
	InstantMessagingCall imCall = result.AsyncState as
InstantMessagingCall;
	imCall.
EndEstablish(result);
	m_imCall = imCall;
}
	catch (RealTimeException ex)
	{
	Trace.TraceError("imCall.EndEstablish failed. Exception:
{0}", ex.ToString());
}
  }

  private void AvCall_EstablishCompleted(IAsyncResult result)
  {
	try
	{
	AudioVideoCall avCall = result.AsyncState as AudioVideoCall;
	avCall.
EndEstablish(result); 
	m_avCall = avCall;
}
	catch (RealTimeException ex)
	{
	Trace.TraceError("avCall.EndEstablish failed. Exception:
{0}", ex.ToString());
}
  }

  public void RegisterConversationHandlers()
  {
	Debug.Assert(null != m_conversation);
	m_conversation.EscalateToConferenceRequested +=
Conference_EscalateToConferenceRequested;
	m_conversation.InviteRemoteParticipantUpdate +=
Conversation_InviteRemoteParticipantUpdate;
	m_conversation.PropertiesChanged +=
Conversation_PropertiesChanged;
	m_conversation.StateChanged += Conversation_StateChanged;
	m_conversation.RemoteParticipantAttendanceChanged +=
Conversation_RemoteAttendanceChanged;
	m_conversation.ParticipantPropertiesChanged +=
Conversation_RemoteParticipantPropertyChanged;
  }

}