// Callback method referred to in the call to BeginEscalate on the Conference instance.
        private void ConferenceEscalateCB(IAsyncResult ar)
        {
            Conversation conversation = ar.AsyncState as Conversation;

            try
            {
                conversation.EndEscalateToConference(ar);
            }

            // A production application should have catch blocks for a number
            // of other exceptions, including OperationTimeoutException and
            // OperationFailureException.
            catch (RealTimeException exception)
            {
                Console.WriteLine(exception.ToString());
            }
            // Synchronize with main thread.
            // _waitUntilConferenceIsEscalated.Set();

            ConferenceInvitation conferenceInvite = new ConferenceInvitation(_incomingConversation);

            conferenceInvite.StateChanged += new EventHandler <ConferenceInvitationStateChangedEventArgs>(conferenceInvite_StateChanged);
            ConferenceInvitationDeliverOptions confDeliverOptions = new ConferenceInvitationDeliverOptions();

            confDeliverOptions.ToastMessage = new ToastMessage("Join the conference!");
            conferenceInvite.BeginDeliver(_remoteContactUri.ToString(), confDeliverOptions, InvitationDeliverCB, conferenceInvite);
        }
Example #2
0
 public static Task AcceptAsync(this ConferenceInvitation invitation,
                                ConferenceInvitationAcceptOptions options)
 {
     return(Task.Factory.FromAsync(
                invitation.BeginAccept, invitation.EndAccept, options,
                null));
 }
Example #3
0
        private void EndDeliverInvitation(IAsyncResult ar)
        {
            ConferenceInvitation invitation = ar.AsyncState as ConferenceInvitation;

            try
            {
                invitation.EndDeliver(ar);
            }
            catch (OperationFailureException opFailEx)
            {
                // OperationFailureException: Indicates failure to connect the
                // call to the remote party.
                // TODO (Left to the reader): Add error handling code
                Console.WriteLine(opFailEx.ToString());
            }
            catch (RealTimeException exception)
            {
                // RealTimeException may be thrown on media or link-layer failures.
                // TODO (Left to the reader): Add error handling code
                Console.WriteLine(exception.ToString());
            }
            finally
            {
                //Again, just to sync the completion of the code.
                _waitForConversationInviteRemoteParticipants.Set();
            }
        }
Example #4
0
 /// <summary>
 /// Delegate that is called when an incoming ConferenceInvite is received.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 void UserEndpoint_ConferenceInvitationReceived(object sender, ConferenceInvitationReceivedEventArgs e)
 {
     Task.Factory.StartNew(() =>
     {
         try
         {
             ConferenceInvitation invite = e.Invitation;
             Conversation conversation   = invite.Conversation;
             // TODO: indexing by conv id doesn't work for "public meeting recording" scenario
             if (_activeConversationSessions.ContainsKey(conversation))
             {
                 _activeConversationSessions[conversation].AddIncomingInvitedConference(e);
             }
             else
             {
                 TranscriptRecorderSession t = new TranscriptRecorderSession(e);
                 _activeConversationSessions.Add(conversation, t);
             }
         }
         catch (Exception ex)
         {
             NonBlockingConsole.WriteLine("Error: Exception thrown in UserEndpoint_ConferenceInvitationReceived: " + ex.ToString());
         }
         finally
         {
             _waitForTranscriptSessionStarted.Set();
         }
     });
 }
Example #5
0
        /// <summary>
        /// Sends a conference invitation to the specified uri.
        /// </summary>
        /// <param name="invitationTargetUri">The uri that the invitation should
        /// be sent to.</param>
        private void InviteUserToConference(string invitationTargetUri)
        {
            ConferenceInvitation confInvitation = new ConferenceInvitation(_impersonatingAvCall.Conversation);
            ConferenceInvitationDeliverOptions deliverOptions = new ConferenceInvitationDeliverOptions();

            const string sipPrefix = "sip:";

            if (!invitationTargetUri.Trim().StartsWith(sipPrefix, StringComparison.OrdinalIgnoreCase))
            {
                invitationTargetUri = sipPrefix + invitationTargetUri.Trim();
            }

            Console.WriteLine("Inviting {0} to the conference.", invitationTargetUri);
            _invitedParticipantAccepted = false;
            var confInvitationResult = confInvitation.BeginDeliver(invitationTargetUri,
                                                                   deliverOptions,
                                                                   ConfInvitationCompleted,
                                                                   confInvitation);

            Console.WriteLine("Waiting for the conference invitation to complete.");
            _conferenceInvitationCompleted.WaitOne();

            Console.WriteLine("Finished inviting {0} to the conference.", invitationTargetUri);
            Console.WriteLine();
        }
Example #6
0
 private void SendConferenceInvitation(AsyncTask task, object state)
 {
     task.DoOneStep(
         delegate()
     {
         string uriToDialOutTo     = (string)state;
         McuDialOutOptions options = new McuDialOutOptions();
         options.Issuer            = this.CustomerSession.CustomerConversation.LocalParticipant;
         ConferenceInvitationSettings convSettings = new ConferenceInvitationSettings();
         convSettings.AvailableMediaTypes.Add(MediaType.Audio);
         var confInvitation = new ConferenceInvitation(this.CustomerSession.CustomerConversation, convSettings);
         this.StartMusic();
         confInvitation.BeginDeliver(
             uriToDialOutTo,
             delegate(IAsyncResult ar)
         {
             task.DoFinalStep(
                 delegate()
             {
                 this.StopMusic();
                 confInvitation.EndDeliver(ar);
             });
         },
             null);
     });
 }
Example #7
0
 public static Task <ConferenceInvitationResponse> DeliverAsync(this ConferenceInvitation invitation,
                                                                string destinationUri, ConferenceInvitationDeliverOptions options)
 {
     return(Task <ConferenceInvitationResponse> .Factory.FromAsync(
                invitation.BeginDeliver, invitation.EndDeliver,
                destinationUri, options,
                null));
 }
        // Callback method referred to in the call to BeginDeliver on the ConferenceInvitation instance.
        private void InvitationDeliverCB(IAsyncResult ar)
        {
            ConferenceInvitation conferenceInvite = ar.AsyncState as ConferenceInvitation;

            try
            {
                conferenceInvite.EndDeliver(ar);
            }

            // A production application should have catch blocks for a number
            // of other exceptions, including FailureResponseException, OperationTimeoutException,
            // and OperationFailureException.
            catch (RealTimeException exception)
            {
                Console.WriteLine(exception.ToString());
            }
            // Synchronize with main thread.
            _waitUntilConferenceInvitationIsDelivered.Set();
        }
Example #9
0
        private void ConferenceInvitation_AcceptCompleted(IAsyncResult result)
        {
            try
            {
                ConferenceInvitation invite = result.AsyncState as ConferenceInvitation;
                invite.EndAccept(result);

                if (_conversation == null)
                {
                    _conversation = invite.Conversation;

                    _conversationTranscriptRecorder = new ConversationTranscriptRecorder(this, _conversation);
                    _transcriptRecorders.Add(_conversationTranscriptRecorder);
                    _conversationToCallTranscriptMapping.Add(_conversationTranscriptRecorder, new List <MediaTranscriptRecorder>());

                    // TODO: Handle case where we're already joined into a different meeting for this conv?

                    ConferenceTranscriptRecorder conferenceTranscriptRecorder = new ConferenceTranscriptRecorder(this, _conversation);
                    _transcriptRecorders.Add(conferenceTranscriptRecorder);
                    _conversationToCallTranscriptMapping[_conversationTranscriptRecorder].Add(conferenceTranscriptRecorder);

                    conferenceTranscriptRecorder.ConferenceInviteAccepted(result);
                }
                else
                {
                    NonBlockingConsole.WriteLine("Warn: Already have a Conference/active conversation");
                    // Treat this as a sub conversation?

                    /*
                     * subConvRecorder = new ConversationTranscriptRecorder(this, subConversation, true);
                     * _transcriptRecorders.Add(subConvRecorder);
                     * _conversationToCallTranscriptMapping.Add(subConvRecorder, new List<MediaTranscriptRecorder>());
                     * _conversationToCallTranscriptMapping[subConvRecorder].Add(addingTranscriptRecorder);
                     */
                }
            }
            catch (Exception e)
            {
                NonBlockingConsole.WriteLine("Error: Exception occurred during conference invite acceptance: " + e.ToString());
            }
        }
Example #10
0
        private void InviteToConference(string uri, CompletionDelegate completionDelegate)
        {
            Debug.Assert(!string.IsNullOrEmpty(uri), "New user could not be null.");

            ConferenceInvitationSettings convSettings = new ConferenceInvitationSettings();

            convSettings.AvailableMediaTypes.Add(MediaType.Audio);
            var confInvitation = new ConferenceInvitation(this.CustomerSession.CustomerConversation, convSettings);

            try
            {
                if (this.CustomerSession.RosterTrackingService.ParticipantCount == 1)
                {
                    this.StartMusic(this.CustomerSession.CustomerServiceChannel.ServiceChannelCall);
                }
                confInvitation.BeginDeliver(
                    uri,
                    ar =>
                {
                    try
                    {
                        confInvitation.EndDeliver(ar);
                        completionDelegate(null);
                    }
                    catch (RealTimeException rte)
                    {
                        this.StopMusic(this.CustomerSession.CustomerServiceChannel.ServiceChannelCall);
                        completionDelegate(rte);
                    }
                }, null);
            }
            catch (InvalidOperationException ioe)
            {
                this.Logger.Log(Logger.LogLevel.Error, ioe);
                this.StopMusic(this.CustomerSession.CustomerServiceChannel.ServiceChannelCall);
                completionDelegate(ioe);
            }
        }
        public void ConferenceInviteAccepted(IAsyncResult result)
        {
            try
            {
                ConferenceInvitation invite = result.AsyncState as ConferenceInvitation;
                // ConferenceInvite already accepted in TranscriptRecorder.ConferenceInvitation_AcceptCompleted()

                Message m = new Message("ConferenceSession.ConferenceInviteAccepted()",
                                        MessageType.ConferenceInfo, _conversation.Id, invite.ConferenceUri);
                _transcriptRecorder.OnMessageReceived(m);

                ConferenceJoinOptions cjo = new ConferenceJoinOptions();
                //cjo.JoinAsTrustedApplication = false;
                _conversation.ConferenceSession.BeginJoin(cjo, EndJoinInvitedConference, invite);
            }
            catch (RealTimeException ex)
            {
                NonBlockingConsole.WriteLine("invite.EndAccept failed. Exception: {0}", ex.ToString());
            }
            catch (InvalidOperationException ex)
            {
                NonBlockingConsole.WriteLine("m_conversation.ConferenceSession.BeginJoin failed. Exception: {0}", ex.ToString());
            }
        }
Example #12
0
 /// <summary>
 /// Issues an invitation for the hold agent
 /// </summary>
 /// <returns></returns>
 async Task InviteHoldParticipant()
 {
     // invite the hold music service to the conference
     var holdInvitation = new ConferenceInvitation(trustedConversation);
     var holdResponse = await holdInvitation.DeliverAsync(holdUri);
 }
Example #13
0
        private void InviteRecipientToConference()
        {
            Console.WriteLine("Inviting the recipient (" + _recipientSipUri + ") to incoming call.");
            ConferenceInvitation invitation = new ConferenceInvitation(_backEndCallLeg.Conversation);

            try
            {
                // Invite the recipient to the conference using a conference invitation.
                invitation.BeginDeliver(
                    _recipientSipUri,
                    deliverAsyncResult =>
                    {
                        try
                        {
                            invitation.EndDeliver(deliverAsyncResult);
                            Console.WriteLine("Invited recipient to the conference.");
                        }
                        catch (RealTimeException ex)
                        {
                            Console.WriteLine(ex);
                        }
                    },
                    null);
            }
            catch (InvalidOperationException ex)
            {
                Console.WriteLine(ex);
            }
        }
Example #14
0
        private void Run()
        {
            // A helper class to take care of platform and endpoint setup and
            // cleanup. This has been abstracted from this sample to focus on
            // Call Control.
            _helper = new UCMASampleHelper();

            // Create a user endpoint, using the network credential object
            // defined above.
            _callerEndpoint = _helper.CreateEstablishedUserEndpoint(
                "Conference Leader" /* friendly name for conference leader endpoint */);

            // Create a second user endpoint, using the network credential object
            // defined above.
            _calleeEndpoint = _helper.CreateEstablishedUserEndpoint(
                "Conference Attendee" /* friendly name for conference attendee endpoint */);

            // Get the URI for the user logged onto Microsoft Lync
            String _ocUserURI = "sip:" + UCMASampleHelper.PromptUser(
                "Enter the URI for the user logged onto Microsoft Lync, in the User@Host format => ",
                "RemoteUserURI" /* key to specify remote user's URI in app.config */);

            // One of the endpoints schedules the conference in advance. At
            // schedule time, all the conference settings are set.

            // The base conference settings object, used to set the policies for the conference.
            ConferenceScheduleInformation conferenceScheduleInformation = new ConferenceScheduleInformation();

            // An open meeting (participants can join who are not on the list),
            // but requiring authentication (no anonymous users allowed.)
            conferenceScheduleInformation.AccessLevel = ConferenceAccessLevel.SameEnterprise;
            // The below flag determines whether or not the passcode is optional
            // for users joining the conference.
            conferenceScheduleInformation.IsPasscodeOptional = true;
            conferenceScheduleInformation.Passcode           = "1357924680";
            // The verbose description of the conference
            conferenceScheduleInformation.Description = "Interesting Description";
            // The below field indicates the date and time after which the conference can be deleted.
            conferenceScheduleInformation.ExpiryTime = System.DateTime.Now.AddHours(5);

            // These two lines assign a set of modalities (here, only
            // InstantMessage) from the available MCUs to the conference. Custom
            // modalities (and their corresponding MCUs) may be added at this
            // time as part of the extensibility model.
            ConferenceMcuInformation instantMessageMCU = new ConferenceMcuInformation(McuType.InstantMessaging);

            conferenceScheduleInformation.Mcus.Add(instantMessageMCU);

            // Now that the setup object is complete, schedule the conference
            // using the conference services off of Endpoint. Note: the conference
            // organizer is considered a leader of the conference by default.
            _callerEndpoint.ConferenceServices.BeginScheduleConference(conferenceScheduleInformation,
                                                                       EndScheduleConference, _callerEndpoint.ConferenceServices);

            // Wait for the scheduling to complete.
            _waitForConferenceScheduling.WaitOne();

            // Now that the conference is scheduled, it's time to join it. As we
            // already have a reference to the conference object populated from
            // the EndScheduleConference call, we do not need to get the
            // conference first. Initialize a conversation off of the endpoint,
            // and join the conference from the uri provided above.
            Conversation callerConversation = new Conversation(_callerEndpoint);

            callerConversation.ConferenceSession.StateChanged += new
                                                                 EventHandler <StateChangedEventArgs <ConferenceSessionState> >(ConferenceSession_StateChanged);

            // Join and wait, again forcing synchronization.
            callerConversation.ConferenceSession.BeginJoin(_conference.ConferenceUri, null /*joinOptions*/,
                                                           EndJoinConference, callerConversation.ConferenceSession);
            _waitForConferenceJoin.WaitOne();

            // Placing the calls on the conference-connected conversation
            // connects to the respective MCUs. These calls may then be used to
            // communicate with the conference/MCUs.
            InstantMessagingCall instantMessagingCall = new InstantMessagingCall(callerConversation);

            // Hooking up event handlers and then placing the call.
            instantMessagingCall.InstantMessagingFlowConfigurationRequested +=
                this.instantMessagingCall_InstantMessagingFlowConfigurationRequested;
            instantMessagingCall.StateChanged += this._call_StateChanged;
            instantMessagingCall.BeginEstablish(EndCallEstablish, instantMessagingCall);

            //Synchronize to ensure that call has completed.
            _waitForCallEstablish.WaitOne();

            //send conf invite
            ConferenceInvitationDeliverOptions deliverOptions = new ConferenceInvitationDeliverOptions();

            deliverOptions.ToastMessage = new ToastMessage("Welcome to my conference");

            ConferenceInvitation invitation = new ConferenceInvitation(callerConversation);

            invitation.BeginDeliver(_ocUserURI, deliverOptions, EndDeliverInvitation, invitation);

            // Synchronize to ensure that invitation is complete
            _waitForConversationInviteRemoteParticipants.WaitOne();

            //And from the other endpoint's perspective:
            //Initialize a conversation off of the endpoint, and join the
            //conference from the uri provided above.
            Conversation calleeConversation = new Conversation(_calleeEndpoint);

            calleeConversation.ConferenceSession.StateChanged += new
                                                                 EventHandler <StateChangedEventArgs <ConferenceSessionState> >(ConferenceSession_StateChanged);

            // Join and wait, again forcing synchronization.
            calleeConversation.ConferenceSession.BeginJoin(_conference.ConferenceUri, null /*joinOptions*/,
                                                           EndJoinConference, calleeConversation.ConferenceSession);
            _waitForConferenceJoin.WaitOne();

            // Placing the calls on the conference-connected conversation
            // connects to the respective MCUs. These calls may then be used to
            //communicate with the conference/MCUs.
            InstantMessagingCall instantMessagingCall2 = new InstantMessagingCall(calleeConversation);

            //Hooking up event handlers and then placing the call.
            instantMessagingCall2.InstantMessagingFlowConfigurationRequested +=
                this.instantMessagingCall2_InstantMessagingFlowConfigurationRequested;
            instantMessagingCall2.StateChanged += this._call_StateChanged;
            instantMessagingCall2.BeginEstablish(EndCallEstablish, instantMessagingCall2);

            //Synchronize to ensure that call has completed.
            _waitForCallEstablish.WaitOne();

            //Synchronize to ensure that all messages are sent and received
            _waitForMessageReceived.WaitOne();

            //Wait for shutdown initiated by user
            _waitForShutdown.WaitOne();

            UCMASampleHelper.PauseBeforeContinuing("Press ENTER to shutdown and exit.");
        }
        /// <summary>
        /// Occurs when bot joined the conference.
        /// </summary>
        /// <param name="result">The argument.</param>
        /// <remarks></remarks>
        public void EndJoinInvitedConference(IAsyncResult result)
        {
            ConferenceInvitation invite           = result.AsyncState as ConferenceInvitation;
            Exception            exception        = null;
            List <String>        activeMediaTypes = new List <string>();

            try
            {
                NonBlockingConsole.WriteLine("Joined the invited conference");
                activeMediaTypes = invite.AvailableMediaTypes.ToList();

                _conversation.ConferenceSession.EndJoin(result);
                _conference = _conversation.ConferenceSession;

                NonBlockingConsole.WriteLine(string.Format(
                                                 "Conference Url: conf:{0}%3Fconversation-id={1}",
                                                 _conversation.ConferenceSession.ConferenceUri,
                                                 _conversation.ConferenceSession.Conversation.Id));

                RegisterConferenceEvents();

                // Raise event on TranscriptRecorderSession
                _transcriptRecorder.RaiseTranscriptRecorderSessionChanged(_conference);

                // Establish Calls for Conference's supported modalities
                if (activeMediaTypes.Contains(MediaType.Audio))
                {
                    _transcriptRecorder.OnActiveMediaTypeCallToEstablish(_conversation, TranscriptRecorderType.AudioVideo);
                }
                if (activeMediaTypes.Contains(MediaType.Message))
                {
                    _transcriptRecorder.OnActiveMediaTypeCallToEstablish(_conversation, TranscriptRecorderType.InstantMessage);
                }

                _waitForInvitedConferenceActiveMediaTypeCallEstablished.Set();
            }
            catch (ConferenceFailureException conferenceFailureException)
            {
                // ConferenceFailureException may be thrown on failures due to MCUs being absent or unsupported, or due to malformed parameters.
                // It is left to the application to perform real error handling here.
                NonBlockingConsole.WriteLine(conferenceFailureException.ToString());
                exception = conferenceFailureException;
            }
            catch (RealTimeException realTimeException)
            {
                // It is left to the application to perform real error handling here.
                NonBlockingConsole.WriteLine(realTimeException.ToString());
                exception = realTimeException;
            }
            finally
            {
                // Again, for sync. reasons.
                _state = TranscriptRecorderState.Active;
                _waitForInvitedConferenceJoined.Set();

                if (exception != null)
                {
                    string originator = string.Format("Error when joining the invited conference: {0}", exception.ToString());
                    NonBlockingConsole.WriteLine(originator);
                }
            }
        }