public void Run()
{
// A helper class to take care of platform and endpoint setup and cleanup.
UCMADemoHelper odh = new UCMADemoHelper();
// Prepare and instantiate the platform.
_collabPlatform = odh.InitalizePlatform(_applicationName, _transportType);
// Create a user endpoint, using the network credential object defined above.
UserEndpoint callerEndpoint = odh.InitalizeRegisteredUserEndpoint(_collabPlatform, _callerUserURI, _userServer, _callerCredential);
// Create a second user endpoint, using the network credential object defined above.
UserEndpoint calleeEndpoint = odh.InitalizeRegisteredUserEndpoint(_collabPlatform, _calleeUserURI, _userServer, _calleeCredential);
// Here, we are accepting an Audio Video call only.
// If the incoming call is not an Audio Video call (for example, a custom (Foo) Call,
// then it will not get raised to the application. UCMA 2.0 handles this silently by having the call types register
// for various modalities (as part of the extensibility framework). The appropriate action (accepting the call)
// will be handled in the handler assigned to the method call below.
calleeEndpoint.RegisterForIncomingCall<AudioVideoCall>(On_AudioVideoCall_Received);
// Setup the call and conversation objects for the initial call (IM), and place the call (synchronously).
Conversation conversation = new Conversation(callerEndpoint);
audioVideoCall = new AudioVideoCall(conversation);
audioVideoCall.BeginEstablish(_calleeUserURI , null, EndCallEstablish, audioVideoCall);
// Force synchronization to ensure that the call is now complete.
_waitForCallAccept.WaitOne();
_waitForCallEstablish.WaitOne();
Console.WriteLine("");
Console.WriteLine(" Beginning conference creation and escalation...");
Console.WriteLine("");
//
// START OF MODIFIED CODE.
//
// Create a new conversation and call with the Audio Video MCU.
Conversation confConversation = new Conversation(callerEndpoint);
confConversation.ConferenceSession.StateChanged += new EventHandler<StateChangedEventArgs<ConferenceSessionState>>(ConferenceSession_StateChanged);
// Create and join an ad-hoc conference with two participants
ConferenceParticipantInformation[] participants = new ConferenceParticipantInformation[2];
participants[0] = new ConferenceParticipantInformation(_calleeUserURI, ConferencingRole.Attendee);
participants[1] = new ConferenceParticipantInformation(_callerUserURI, ConferencingRole.Leader);
// create an ad-hoc conference (added to sample to show more conferencing features)
Conference conference = CreateAdHocConference("Ad-hoc Conference", callerEndpoint, McuType.AudioVideo, participants);
ConferenceJoinInformation confJoinInfo = new ConferenceJoinInformation(new RealTimeAddress(conference.ConferenceUri));
confConversation.ConferenceSession.BeginJoin(confJoinInfo, EndJoinConference, confConversation.ConferenceSession);
//Wait for call to be transfered.
_waitForConferenceEscalation.WaitOne();
// Note that the original peer-to-peer conversation is now defunct.
// Go ahead and shut it down.
// check the call state on the audioVideoCall object
audioVideoCall.EndTerminate(audioVideoCall.BeginTerminate(null, null));
// just so don't have to change the rest of the code
conversation = confConversation;
Console.WriteLine("");
Console.WriteLine(" Beginning conference command and control..." );
Console.WriteLine("");
// END OF MODIFIED CODE
// Promote a participant to leader; Leaders can lock and unlock the conference, as well as possessing the ability
// to eject and control other participants, and mute participants (in an Audio conference).
// For purposes of the demonstration, choose an arbitrary conferene participant, here, the first.
ConversationParticipant target = null;
if (conversation.RemoteParticipants.Count >= 1)
{
target = conversation.RemoteParticipants[0];
}
else
{
// TODO: Error handling is left to the reader.
}
Console.WriteLine("User " + target.UserAtHost + " is currently an " + target.Role + ".");
// Note: This is the naive synch implementation, and is not generally suitable for production code.
// It is only used here for brevity.
conversation.ConferenceSession.EndModifyRole(conversation.ConferenceSession.BeginModifyRole(target, ConferencingRole.Leader, null, null));
Console.WriteLine("User " + target.UserAtHost + " is now a " + target.Role + ".");
Console.WriteLine("The conference lock's state is currently " + conversation.ConferenceSession.IsLocked + ".");
// Locking the conference prevents new users from joining the conference, unless explicitly called into the
// conference through the dialout API.
conversation.ConferenceSession.EndLockConference(conversation.ConferenceSession.BeginLockConference(null,null));
Console.WriteLine("The conference lock's state is now " + conversation.ConferenceSession.IsLocked + ".");
// On the AudioVideoMCU, a leader can mute remote, or local participants at will.
// This line will mute the target's endpoint until Unmuted, or the call is torn down.
ParticipantEndpoint targetPE = null;
if (conversation.ConferenceSession.AudioVideoMcuSession.GetRemoteParticipantEndpoints()[0] != null)
{
targetPE = conversation.ConferenceSession.AudioVideoMcuSession.GetRemoteParticipantEndpoints()[0]; //Again, we assume that there is the participant from above present.
}
else
{
// TODO: Error handling is left to the reader.
}
conversation.ConferenceSession.AudioVideoMcuSession.EndMute(conversation.ConferenceSession.AudioVideoMcuSession.BeginMute(targetPE, null, null));
// Now, eject the participant, and then shut down the platform.
Console.WriteLine("The conference currently has " + conversation.ConferenceSession.GetRemoteParticipantEndpoints().Count + " attendees.");
//Ejection can only be performed by leaders of the conference.
conversation.ConferenceSession.EndEject(conversation.ConferenceSession.BeginEject(target, null, null));
Console.WriteLine("The conference now has " + conversation.ConferenceSession.GetRemoteParticipantEndpoints().Count + " attendees.");
Console.WriteLine("");
Console.WriteLine("Success!");
Console.WriteLine("");
Console.WriteLine("Now shutting down the platform...");
odh.ShutdownPlatform(_collabPlatform);
Console.WriteLine("");
Console.WriteLine("Press any key to exit");
Console.ReadLine();
}
/// <summary>
/// Added by Unify Square just to show more conferencing features.
/// </summary>
/// <param name="conferenceName"></param>
/// <param name="localEndpoint"></param>
/// <param name="mcuType"></param>
/// <param name="participants"></param>
/// <returns></returns>
Conference CreateAdHocConference(String conferenceName, LocalEndpoint localEndpoint, String mcuType, IList<ConferenceParticipantInformation> participants)
{
Conference conference = null;
// Set up the conference properties
ConferenceScheduleInformation conferenceScheduleInformation = new ConferenceScheduleInformation();
conferenceScheduleInformation.AdmissionPolicy = ConferenceAdmissionPolicy.OpenAuthenticated;
conferenceScheduleInformation.IsPasscodeOptional = true;
conferenceScheduleInformation.Passcode = ConferenceServices.GeneratePasscode();
conferenceScheduleInformation.Description = conferenceName; // The verbose description of the conference.
conferenceScheduleInformation.ExpiryTime = System.DateTime.Now.AddHours(2); // delete time
conferenceScheduleInformation.ConferenceId = ConferenceServices.GenerateConferenceId();
// add our participants
foreach (ConferenceParticipantInformation participantInfo in participants)
{
conferenceScheduleInformation.Participants.Add(participantInfo);
}
// These two lines assign a set of modalities from the available MCUs to the conference.
// Custom modalities (and their corresponding MCUs) may be added at this time.
ConferenceMcuInformation conferenceMCU = new ConferenceMcuInformation(mcuType);
conferenceScheduleInformation.Mcus.Add(conferenceMCU);
// Now that the setup object is complete, schedule the conference using the conference services
// Note: the conference organizer is considered a leader of the conference by default.
conference = localEndpoint.ConferenceServices.EndScheduleConference(localEndpoint.ConferenceServices.BeginScheduleConference(conferenceScheduleInformation, null, null));
return conference;
}