Пример #1
0
 /// <summary>
 /// Delegate that is called when an incoming InstantMessagingCall arrives.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 void InstantMessagingCall_Received(object sender, CallReceivedEventArgs <InstantMessagingCall> e)
 {
     Task.Factory.StartNew(() =>
     {
         try
         {
             if (_activeConversationSessions.ContainsKey(e.Call.Conversation))
             {
                 _activeConversationSessions[e.Call.Conversation].AddIMIncomingCall(e);
             }
             else if (e.IsNewConversation)
             {
                 Conversation c = e.Call.Conversation;
                 TranscriptRecorderSession t          = new TranscriptRecorderSession(e);
                 t.TranscriptRecorderSessionChanged  += this.TranscriptRecorder_OnTranscriptRecorderSessionChanged;
                 t.TranscriptRecorderSessionShutdown += this.TranscriptRecorder_OnTranscriptRecorderSessionShutdown;
                 _activeConversationSessions.Add(c, t);
             }
             else if (e.IsConferenceDialOut)
             {
                 // TODO: Join Conference then accept IM call
                 throw new NotImplementedException("InstantMessagingCall_Received with ConferenceDialOut AudioVideoCall is not yet supported.");
             }
         }
         catch (Exception ex)
         {
             NonBlockingConsole.WriteLine("Error: Exception thrown in InstantMessagingCall_Received: " + ex.ToString());
         }
         finally
         {
             _waitForTranscriptSessionStarted.Set();
         }
     });
 }
Пример #2
0
        void On_InstantMessagingCall_Received(object sender, CallReceivedEventArgs <InstantMessagingCall> e)
        {
            //Type checking was done by the platform; no risk of this being any
            // type other than the type expected.
            _instantMessagingCall = e.Call;

            // Call: StateChanged: Only hooked up for logging, to show the call
            // state transitions.
            _instantMessagingCall.StateChanged += new
                                                  EventHandler <CallStateChangedEventArgs>(_instantMessagingCall_StateChanged);

            // Remote Participant URI represents the far end (caller) in this
            // conversation. Toast is the message set by the caller as the 'greet'
            // message for this call. In Microsoft Lync, the toast will
            // show up in the lower-right of the screen.
            Console.WriteLine("Call Received! From: " + e.RemoteParticipant.Uri + " Toast is: " +
                              e.ToastMessage.Message);

            // Now, decline the call. CallDeclineOptions can be used to supply a
            // response code, here, 486 (Busy Here). Decline is asynchronous, as
            // no reply will be received from the far end.
            _instantMessagingCall.Decline(new CallDeclineOptions(486));

            _autoResetEvent.Set();
        }
        private void OnIncomingAudioVideoCallReceived(object sender, CallReceivedEventArgs<AudioVideoCall> e)
        {
            _avCall = e.Call;

            _avCall.StateChanged += new EventHandler<CallStateChangedEventArgs>(OnCallStateChanged);

            try
            {
                // Accept the incoming call.
                _avCall.BeginAccept(ar =>
                {
                    try
                    {
                        _avCall.EndAccept(ar);

                        _logger.Log("Accepted incoming call.");

                        PerformAttendedTransfer();
                    }
                    catch (RealTimeException rtex)
                    {
                        _logger.Log("Failed accepting incoming A/V call.", rtex);
                    }
                },
                null);
            }
            catch (InvalidOperationException ioex)
            {
                _logger.Log("Failed accepting incoming A/V call.", ioex);
            }
        }
Пример #4
0
        private void ReceiveIncomingIMCall(object sender, CallReceivedEventArgs <InstantMessagingCall> e)
        {
            this.Logger.Log(Logger.LogLevel.Verbose,
                            string.Format(
                                CultureInfo.InvariantCulture,
                                "IMCall {0} received.",
                                Logger.Pointer(e.Call)));

            if (this.IsTerminatingTerminated || e.IsConferenceDialOut)
            {
                var declineOptions = new CallDeclineOptions();
                declineOptions.ResponseCode = ResponseCode.RequestTerminated;
                this.RejectCall(e.Call, declineOptions);
                return;
            }
            ConversationParticipant caller     = e.Call.RemoteEndpoint.Participant;
            RealTimeAddress         uriAddress = new RealTimeAddress(caller.Uri);

            if (!uriAddress.IsPhone &&
                e.Call.RemoteEndpoint.Participant.SourceNetwork == SourceNetwork.SameEnterprise)
            {
                System.Threading.ThreadPool.QueueUserWorkItem(this.HandleIMCall, e);
            }
            else
            {
                var declineOptions = new CallDeclineOptions();
                declineOptions.ResponseCode = ResponseCode.RequestTerminated;
                this.RejectCall(e.Call, declineOptions);
                return;
            }
        }
Пример #5
0
        void On_InstantMessagingCall_Received_ByCallee(object sender, CallReceivedEventArgs <InstantMessagingCall> e)
        {
            //Type checking was done by the platform; no risk of this being any
            // type other than the type expected.
            InstantMessagingCall instantMessagingCall = e.Call;

            // Call: StateChanged: Only hooked up for logging, to show the call
            // state transitions.
            instantMessagingCall.StateChanged += new EventHandler <CallStateChangedEventArgs>(_call_StateChanged);

            // Remote Participant URI represents the far end (caller) in this
            // conversation. Toast is the message set by the caller as the 'greet'
            // message for this call. In Microsoft Lync, the toast will
            // show up in the lower-right of the screen. Conversation ID demonstrates
            // that the two calls inhabit the same conversation container on
            // both ends of the call.
            Console.WriteLine("");
            Console.WriteLine(" Call Received! From: " + e.RemoteParticipant.Uri);
            Console.WriteLine(" Toast is: " + e.ToastMessage.Message);
            Console.WriteLine(" Conversation ID is: " + e.Call.Conversation.Id);
            Console.WriteLine("");

            // Now, accept the call.
            // EndAcceptCall will be raised on the same thread.
            instantMessagingCall.BeginAccept(EndAcceptCall, instantMessagingCall);

            // When an escalation request is received on the existing call, this
            // event handler will be called.
            instantMessagingCall.Conversation.EscalateToConferenceRequested +=
                this.CalleeConversation_EscalateToConferenceRequested;
        }
Пример #6
0
        void On_AudioVideoCall_Received(object sender, CallReceivedEventArgs <AudioVideoCall> e)
        {
            // Type checking was done by the platform; no risk of this being any
            // type other than the type expected.
            AudioVideoCall _audioVideoCall = e.Call;

            // Call: StateChanged: Only hooked up for logging, to show the call
            // state transitions. Only bound on the incoming side, to avoid
            // printing the events twice.
            _audioVideoCall.StateChanged += this.Call_StateChanged;

            // Remote Participant URI represents the far end (caller) in this
            // conversation. Toast is the message set by the caller as the 'greet'
            // message for this call. In Microsoft Lync, the toast will
            // show up in the lower-right of the screen.
            Console.WriteLine("");
            Console.WriteLine(" Audio Video Call Received! From: " + e.RemoteParticipant.Uri);
            Console.WriteLine(" Toast is: " + e.ToastMessage.Message);
            Console.WriteLine(" Conversation ID is: " + e.Call.Conversation.Id);
            Console.WriteLine("");

            try
            {
                // Now, accept the call. Threading note: AcceptCallCompleted will
                // be raised on the same thread. Blocking this thread in this
                // portion of the code will cause endless waiting.
                _audioVideoCall.BeginAccept(AcceptCallCompleted, _audioVideoCall);
            }
            catch (InvalidOperationException exception)
            {
                // InvalidOperationException indicates that the call was
                // disconnected before it could be accepted.
                Console.WriteLine(exception.ToString());
            }
        }
        private void OnIncomingInstantMessagingCallReceived(object sender, CallReceivedEventArgs<InstantMessagingCall> e)
        {
            _imCall = e.Call;

            try
            {
                // Accept the incoming call.
                _imCall.BeginAccept(ar =>
                {
                    try
                    {
                        _imCall.EndAccept(ar);

                        _logger.Log("Accepted incoming call.");
                    }
                    catch (RealTimeException rtex)
                    {
                        _logger.Log("Failed accepting incoming IM call.", rtex);
                    }
                },
                null);
            }
            catch (InvalidOperationException ioex)
            {
                _logger.Log("Failed accepting incoming IM call.", ioex);
            }
        }
Пример #8
0
        private void HandleIncomingInstantMessagingCalls(object sender, CallReceivedEventArgs <InstantMessagingCall> args)
        {
            if (_matchMakerState == MatchMakerState.Started)
            {
                AcdSupervisorSession supervisorSession = null;

                Configuration.Supervisors.ForEach(sup =>
                {
                    if (SipUriCompare.Equals(sup.SignInAddress, args.RemoteParticipant.Uri))
                    {
                        supervisorSession = new AcdSupervisorSession(this, sup, _logger);
                        supervisorSession.StateChanged += this.OnSupervisorSessionStateChanged;
                        lock (_syncRoot)
                        {
                            _sessions.Add(supervisorSession);
                        }
                        supervisorSession.HandleSupervisorInitialCall(args.Call);
                        return;
                    }
                });

                if (null == supervisorSession)
                {
                    args.Call.Decline();
                }
            }
            else
            {
                args.Call.Decline();
            }
        }
Пример #9
0
        /* private void audioVideoFlow_StateChanged(object sender, MediaFlowStateChangedEventArgs e)
         * {
         *  Console.WriteLine("Flow state changed from " + e.PreviousState + " to " + e.State);
         *
         *  // When the flow is active, media operations can begin.
         *  if (e.State == MediaFlowState.Active)
         *  {
         *      // Other samples demonstrate uses for an active flow.
         *  }
         * } */

        // The delegate to be called when the inbound call arrives (the call from a customer).
        private void inboundAVCall_CallReceived(object sender, CallReceivedEventArgs <AudioVideoCall> e)
        {
            _inboundAVCall = e.Call;
            // Register for notification of the StateChanged event on the incoming call.
            _inboundAVCall.StateChanged += new EventHandler <CallStateChangedEventArgs>(inboundAVCall_StateChanged);

            // Create a new conversation for the incoming call leg.
            _inboundConversation = new Conversation(_userEndpoint);

            _inboundCallLeg = new BackToBackCallSettings(_inboundAVCall);

            // Create the back-to-back call instance.
            // Note that you need a Destination URI for the outgoing call leg, but not for the incoming call leg.
            _b2bCall = new BackToBackCall(_inboundCallLeg, _outboundCallLeg);

            // Begin the back-to-back session; provide a destination.
            try
            {
                IAsyncResult result = _b2bCall.BeginEstablish(BeginEstablishCB, _b2bCall);

                /* IAsyncResult result = _b2bCall.BeginEstablish(
                 *  delegate(IAsyncResult ar)
                 * {
                 *  _b2bCall.EndEstablish(ar);
                 *  _waitForB2BCallToEstablish.Set();
                 * }, _b2bCall);*/
            }
            catch (InvalidOperationException ioe)
            {
                Console.WriteLine("_b2bCall must be in the Idle state." + ioe.Message.ToString());
            }
            _waitForB2BCallToEstablish.WaitOne();
        }
        private void OnIncomingAudioVideoCallReceived(object sender, CallReceivedEventArgs<AudioVideoCall> e)
        {
            // Build a list with the authorized URIs.
            List<string> authorizedSipUris = new List<string>()
            {
                "sip:[email protected]",
                "sip:[email protected]"
            };

            if (authorizedSipUris.Contains(e.RemoteParticipant.Uri))
            {
                _logger.Log("Call is from an authorized URI. Accepting.");

                AcceptCall(e.Call);
            }
            else
            {
                _logger.Log("Call is not from an authorized URI. Declining.");

                CallDeclineOptions options = new CallDeclineOptions()
                {
                    ResponseCode = ResponseCode.Forbidden
                };

                e.Call.Decline(options);
            }
        }
Пример #11
0
 protected override async void OnIncomingAudioVideoCall(object sender, CallReceivedEventArgs<AudioVideoCall> args)
 {
     // generate new call and move to the queue
     var call = new QueueCall(this, args.Call);
     await call.Queue();
     calls.Add(call);
 }
Пример #12
0
        //call received event handler
        public void AudioVideoCall_Received(CallReceivedEventArgs <AudioVideoCall> e)
        {
            if (_state == TranscriptRecorderState.Terminated)
            {
                NonBlockingConsole.WriteLine("Error: AVTranscriptRecorder is shutdown.");
                // TODO: Error message
                return;
            }

            if (_audioVideoCall != null)
            {
                NonBlockingConsole.WriteLine("Warn: AVCall already exists for this Conversation. Shutting down previous call...");
                // TODO: Info message
                TerminateCall();
            }

            _state = TranscriptRecorderState.Initialized;
            _waitForAudioVideoCallTerminated.Reset();

            //Type checking was done by the platform; no risk of this being any
            // type other than the type expected.
            _audioVideoCall = e.Call;

            // Call: StateChanged: Only hooked up for logging, to show the call
            // state transitions.
            _audioVideoCall.StateChanged += new EventHandler <CallStateChangedEventArgs>(AudioVideoCall_StateChanged);

            // Subscribe for the flow configuration requested event; the flow will be used to send the media.
            // Ultimately, as a part of the callback, the media will be sent/recieved.
            _audioVideoCall.AudioVideoFlowConfigurationRequested += new EventHandler <AudioVideoFlowConfigurationRequestedEventArgs>(AudioVideoCall_FlowConfigurationRequested);

            _audioVideoCall.ConversationChanged += new EventHandler <ConversationChangedEventArgs>(AudioVideoCall_ConversationChanged);

            // Remote Participant URI represents the far end (caller) in this
            // conversation. Toast is the message set by the caller as the 'greet'
            // message for this call. In Microsoft Lync, the toast will
            // show up in the lower-right of the screen.
            // TODO: change this to preserve confidentiality in the video demo
            //NonBlockingConsole.WriteLine("Call Received! From: " + e.RemoteParticipant.Uri + " Toast is: " + e.ToastMessage.Message);
            NonBlockingConsole.WriteLine("Call Received! From: " + e.RemoteParticipant.Uri);
            //NonBlockingConsole.WriteLine("Call Received!");

            Message m = new Message("AudioVideoCall Received. Inbound call state: " + _audioVideoCall.State.ToString(),
                                    e.RemoteParticipant.DisplayName, e.RemoteParticipant.UserAtHost, e.RemoteParticipant.Uri,
                                    MessageType.Audio, _transcriptRecorder.Conversation.Id, MessageDirection.Incoming);

            _transcriptRecorder.OnMessageReceived(m);

            // Accept the call. Before transferring the call, it must be in the Established state.
            // Note that the docs are wrong in the state machine for the AVCall. BeginEstablish
            // should be called on outgoing calls, not incoming calls.
            _audioVideoCall.BeginAccept(AudioVideoCallAccepted, _audioVideoCall);

            // Wait for a few seconds to give time for the call to get to the Established state.
            //_waitForAudioVideoCallAccepted.WaitOne(2000);
            NonBlockingConsole.WriteLine("Inbound call state is {0}\n", _audioVideoCall.State.ToString());
        }
Пример #13
0
        public void InstantMessagingCall_Received(CallReceivedEventArgs <InstantMessagingCall> e)
        {
            if (_state == TranscriptRecorderState.Terminated)
            {
                NonBlockingConsole.WriteLine("Error: IMTranscriptRecorder is shutdown.");
                // TODO: Info message
                return;
            }

            if (_instantMessagingCall != null)
            {
                NonBlockingConsole.WriteLine("Warn: IMCall already exists for this Conversation. Shutting down previous call...");
                // TODO: Info message
                TerminateCall();
            }

            _state = TranscriptRecorderState.Initialized;
            _waitForIMCallTerminated.Reset();

            // Type checking was done by the platform; no risk of this being any
            // type other than the type expected.
            _instantMessagingCall = e.Call;

            // Call: StateChanged: Only hooked up for logging, to show the call
            // state transitions.
            _instantMessagingCall.StateChanged +=
                new EventHandler <CallStateChangedEventArgs>(InstantMessagingCall_StateChanged);

            _instantMessagingCall.InstantMessagingFlowConfigurationRequested +=
                new EventHandler <InstantMessagingFlowConfigurationRequestedEventArgs>(InstantMessagingCall_FlowConfigurationRequested);

            _instantMessagingCall.ConversationChanged += new EventHandler <ConversationChangedEventArgs>(InstantMessagingCall_ConversationChanged);

            // Remote Participant URI represents the far end (caller) in this
            // conversation. Toast is the message set by the caller as the
            // 'greet' message for this call. In Microsoft Lync, the
            // toast will show up in the lower-right of the screen.
            // TODO: Change to protect privacy
            // NonBlockingConsole.WriteLine("IMCall Received! From: " + e.RemoteParticipant.Uri + " Toast is: " + e.ToastMessage.Message);
            NonBlockingConsole.WriteLine("IMCall Received! From: " + e.RemoteParticipant.Uri);
            // Console.Writelin("IMCall Received!");

            Message m = new Message("InstantMessagingCall Received. Inbound call state: " + _instantMessagingCall.State.ToString(),
                                    e.RemoteParticipant.DisplayName, e.RemoteParticipant.UserAtHost, e.RemoteParticipant.Uri,
                                    MessageType.InstantMessage, _transcriptRecorder.Conversation.Id, MessageDirection.Incoming);

            _transcriptRecorder.OnMessageReceived(m);

            // Now, accept the call. EndAcceptCall will be raised on the
            // same thread.
            _instantMessagingCall.BeginAccept(InstantMessagingCallAcceptedCallBack, _instantMessagingCall);
        }
        private void OnIncomingAudioVideoCallReceived(object sender, CallReceivedEventArgs<AudioVideoCall> e)
        {
            // Decline incoming A/V calls.

            try
            {
                e.Call.Decline();
            }
            catch (InvalidOperationException ioex)
            {
                _logger.Log("Failed declining incoming call.", ioex);
            }
        }
Пример #15
0
        /// <summary>
        /// Handles an incoming Application Sharing call. The incoming Application  Sharing call can be one of two things:
        /// this can be a brand new customer session or a modality escalation. Else decline.
        /// </summary>
        private void HandleApplicationSharingCallReceived(object sender, CallReceivedEventArgs <ApplicationSharingCall> args)
        {
            //Declines if it is a brand new Conversation as we only expect, modality escalation in
            // an existing customer session for Application Sharing.
            if (args.IsNewConversation == true)
            {
                try
                {
                    args.Call.Decline(new CallDeclineOptions(ResponseCode.TemporarilyUnavailable));
                }
                catch (InvalidOperationException ivoex)
                {
                    _logger.Log("AcdPortal cannot decline an imcoming Application Sharing Call properly", ivoex);
                }
                catch (RealTimeException ex)
                {
                    _logger.Log("AcdPortal cannot decline an imcoming Application Sharing Call properly", ex);
                }
            }
            else if (args.IsNewConversation == false)
            {
                //this an Application Sharing escalation, hand off the call to the AcdCustomerSession for futher processing
                if (null != args.Call.Conversation.ApplicationContext)
                {
                    AcdCustomerSession session = args.Call.Conversation.ApplicationContext as AcdCustomerSession;
                    args.RingBackDisabled = true;

                    ThreadPool.QueueUserWorkItem((waitState) =>
                    {
                        session.HandleNewModality(args.Call);
                    });
                }
                else
                {
                    // There was an issue retrieving the AcdCustomerSession, we are declining the call.
                    try
                    {
                        args.Call.Decline(new CallDeclineOptions(ResponseCode.TemporarilyUnavailable));
                    }
                    catch (InvalidOperationException ivoex)
                    {
                        _logger.Log("AcdPortal cannot decline an imcoming Application Sharing Call properly", ivoex);
                    }
                    catch (RealTimeException ex)
                    {
                        _logger.Log("AcdPortal cannot decline incoming Application Sharing call properly", ex);
                    }
                }
            }
        }
        private void OnIncomingAudioVideoCallReceived(object sender, CallReceivedEventArgs<AudioVideoCall> e)
        {
            // Forward incoming A/V calls.
            try
            {
                _logger.Log("Forwarding incoming call.");

                e.Call.Forward("sip:[email protected]");
            }
            catch (InvalidOperationException ioex)
            {
                _logger.Log("Failed forwarding incoming call.", ioex);
            }
        }
        // The delegate to be called when the inbound call arrives (the call from a customer).
        private void inboundAVCall_CallReceived(object sender, CallReceivedEventArgs <AudioVideoCall> e)
        {
            _waitForCallReceived.Set();
            _audioVideoCall = e.Call;

            _audioVideoCall.AudioVideoFlowConfigurationRequested += this.audioVideoCall_FlowConfigurationRequested;
            _audioVideoCall.StateChanged += new EventHandler <CallStateChangedEventArgs>(audioVideoCall_StateChanged);

            // Create a new conversation instance.
            _conversation = new Conversation(_userEndpoint);
            // Accept the call.
            _audioVideoCall.BeginAccept(CallAcceptCB, _audioVideoCall);
            _audioVideoFlow = _audioVideoCall.Flow;
        }
Пример #18
0
        // Delegate that is called when an incoming AudioVideoCall arrives.
        void AudioVideoCall_Received(object sender, CallReceivedEventArgs <AudioVideoCall> e)
        {
            _audioVideoCall = e.Call;
            _audioVideoCall.AudioVideoFlowConfigurationRequested += this.AudioVideoCall_FlowConfigurationRequested;

            // For logging purposes, register for notification of the StateChanged event on the call.
            _audioVideoCall.StateChanged +=
                new EventHandler <CallStateChangedEventArgs>(AudioVideoCall_StateChanged);

            // Remote Participant URI represents the far end (caller) in this conversation.
            Console.WriteLine("Call received from: " + e.RemoteParticipant.Uri);

            // Now, accept the call. CallAcceptCB will run on the same thread.
            _audioVideoCall.BeginAccept(CallAcceptCB, _audioVideoCall);
        }
Пример #19
0
        /// <summary>
        /// EventHandler raised when an incoming call arrives to the endpoint, above.
        /// </summary>
        /// <param name="sender">Object that sent the event</param>
        /// <param name="e">CallReceivedEventArgs object</param>
        private void AudioVideoCallReceived(object sender, CallReceivedEventArgs <AudioVideoCall> e)
        {
            //Assign the current call to the global keeper.
            currentCall = e.Call;

            currentCall.AudioVideoFlowConfigurationRequested += new EventHandler <AudioVideoFlowConfigurationRequestedEventArgs>(Call_AudioVideoFlowConfigurationRequested);

            //Bind handlers to the current call's state changed event to drive UI.
            //State change is used to inform the application of the current state of the call.
            //In particular, this should be used by the application to determine what operations are valid in a given state.
            currentCall.StateChanged
                += new EventHandler <CallStateChangedEventArgs>(HandleCallStateChanged);

            // accept the incoming call and waits for State and configuration requests.
            currentCall.EndAccept(currentCall.BeginAccept(null, null));
        }
Пример #20
0
        private void ReceiveIncomingAvCall(object sender, CallReceivedEventArgs <AudioVideoCall> e)
        {
            this.Logger.Log(Logger.LogLevel.Verbose,
                            string.Format(
                                CultureInfo.InvariantCulture,
                                "AvCall {0} received.",
                                Logger.Pointer(e.Call)));

            if (this.IsTerminatingTerminated || e.IsConferenceDialOut)
            {
                var declineOptions = new CallDeclineOptions();
                declineOptions.ResponseCode = ResponseCode.RequestTerminated;
                this.RejectCall(e.Call, declineOptions);
                return;
            }

            this.StartupCustomerSession(e.Call);
        }
Пример #21
0
        private void CompleteGetMohCallAsyncResult(
            object sender,
            CallReceivedEventArgs <AudioVideoCall> callReceivedArgs)
        {
            if (object.ReferenceEquals(callReceivedArgs.Call.Conversation.ApplicationContext, this))
            {
                EstablishMoHChannelAsyncResult result = null;
                lock (_syncRoot)
                {
                    try
                    {
                        result = _listOfPendingMohCallAsyncResults.First <EstablishMoHChannelAsyncResult>();
                    }
                    catch (InvalidOperationException)
                    {
                        return;
                    }
                    _listOfPendingMohCallAsyncResults.Remove(result);
                }

                AcdServiceChannel mohChannel = new AcdServiceChannel(result.Anchor, _logger);

                try
                {
                    object[] args = new object[4];
                    args[0] = mohChannel;
                    args[1] = result.ParticipantUri;
                    args[2] = callReceivedArgs;
                    args[3] = result;

                    mohChannel.BeginStartUp(callReceivedArgs.Call,
                                            ServiceChannelType.DialIn,
                                            McuMediaChannelStatus.None,
                                            this.StartUpMohChannelCompleted,
                                            args);
                }
                catch (InvalidOperationException ivoex)
                {
                    callReceivedArgs.Call.Decline();
                    result.SetAsCompleted(new OperationFailureException("AcdMusicOnHoldServer failed begin starting up the MOH channel", ivoex), false);
                }
            }
        }
Пример #22
0
        void On_AudioVideoCall_Received(object sender, CallReceivedEventArgs <AudioVideoCall> e)
        {
            // Type checking was done by the platform; no risk of this being any
            // type other than the type expected.
            _audioVideoCall = e.Call;

            // Call: StateChanged: Only hooked up for logging, to show the call
            // state transitions.
            _audioVideoCall.StateChanged += this.AudioVideoCall_StateChanged;

            // Remote Participant URI represents the far end (caller) in this
            // conversation. Toast is the message set by the caller as the 'greet'
            // message for this call. In Microsoft Lync, the toast will
            // show up in the lower-right of the screen.
            Console.WriteLine("Call Received! From: " + e.RemoteParticipant.Uri);

            // Now, accept the call.
            // EndAcceptCall will be raised on the same thread.
            _audioVideoCall.BeginAccept(EndAcceptCall, _audioVideoCall);
        }
        void InstantMessagingCall_Received(object sender, CallReceivedEventArgs <InstantMessagingCall> e)
        {
            // Type checking was done by the platform; no risk of this being any
            // type other than the type expected.
            _instantMessagingCall = e.Call;
            _incomingConversation = _instantMessagingCall.Conversation;

            // Call: StateChanged: Hooked up for logging, to show callstate transitions.
            _instantMessagingCall.StateChanged +=
                new EventHandler <CallStateChangedEventArgs>(InstantMessagingCall_StateChanged);

            // RemoteParticipantUri is the URI of the remote caller in this
            // conversation. Toast is the message set by the caller as the
            // 'greet' message for this call.
            Console.WriteLine("Call Received! From: " + e.RemoteParticipant.Uri + " Toast is: " +
                              e.ToastMessage.Message);

            // Accept the call.
            _instantMessagingCall.BeginAccept(CallAcceptCB, _instantMessagingCall);
        }
Пример #24
0
        /// <summary>
        /// Accept IM from Lync client
        /// </summary>
        /// <param name="sender">Source of the event</param>
        /// <param name="e">InstantMessagingCall arguments</param>
        private void IM_Received(object sender, CallReceivedEventArgs <InstantMessagingCall> e)
        {
            bool handled = false;

            if (e.IsNewConversation)
            {
                lock (this.activeCustomerSessions)
                {
                    if (!this.activeCustomerSessions.ContainsKey(e.Call.RemoteEndpoint.Uri))
                    {
                        Customer        customer        = new Customer(e.Call.RemoteEndpoint.Uri);
                        Menu            menu            = new Menu(this.moreInformationMessage, this.moreInformationLink, this.cweMessage, this.registryFilePath, this.XmlParser);
                        CustomerSession customerSession = new CustomerSession(customer, menu, this, this.logger);
                        this.activeCustomerSessions.Add(e.Call.RemoteEndpoint.Uri, customerSession);
                        customerSession.HandleIncomingInstantMessagingCall(e.Call);
                        handled = true;
                    }
                }
            }


            if (!handled)
            {
                try
                {
                    this.logger.Log("Declining IM call since this is a modality escalating call.");
                    Console.WriteLine("Declining IM call since this is a modality escalating call.");
                    e.Call.Decline();
                }
                catch (InvalidOperationException ioe)
                {
                    this.logger.Log("Exception while declining call {0}", ioe);
                    Console.WriteLine("Exception while declining call {0}", ioe);
                }
                catch (RealTimeException rte)
                {
                    this.logger.Log("Exception while declining call {0}", rte);
                    Console.WriteLine("Exception while declining call {0}", rte);
                }
            }
        }
Пример #25
0
        private void OnIncomingAudioVideoCallReceived(object sender, CallReceivedEventArgs<AudioVideoCall> e)
        {
            _avCall = e.Call;

            try
            {
                // Accept the incoming call.
                _avCall.BeginAccept(ar =>
                {
                    try
                    {
                        _avCall.EndAccept(ar);

                        _logger.Log("Accepted incoming call.");

                        switch (_transferType)
                        {
                            case TransferTypeSelection.Attended:
                                PerformAttendedTransfer();
                                break;
                            case TransferTypeSelection.Unattended:
                                PerformUnattendedTransfer();
                                break;
                            case TransferTypeSelection.Supervised:
                                PerformSupervisedTransfer();
                                break;
                        }
                    }
                    catch (RealTimeException rtex)
                    {
                        _logger.Log("Failed accepting incoming A/V call.", rtex);
                    }
                },
                null);
            }
            catch (InvalidOperationException ioex)
            {
                _logger.Log("Failed accepting incoming A/V call.", ioex);
            }
        }
Пример #26
0
        public void AddIMIncomingCall(CallReceivedEventArgs <InstantMessagingCall> e, CancellationTokenSource cts = null)
        {
            if (_state != TranscriptRecorderState.Active)
            {
                NonBlockingConsole.WriteLine("Warn: AddIMIncomingCall in unexpected TranscriptRecorderSession state: " + _state.ToString());
            }

            IMTranscriptRecorder    i      = new IMTranscriptRecorder(this);
            ConversationParticipant caller = e.RemoteParticipant;

            Message m = new Message("InstantMessaging Conversation Participant Added.", caller.DisplayName,
                                    caller.UserAtHost, caller.Uri, DateTime.Now,
                                    _conversation.Id, _conversation.ConferenceSession.ConferenceUri,
                                    MessageType.ConversationInfo, MessageDirection.Outgoing);

            this.OnMessageReceived(m);

            _transcriptRecorders.Add(i);
            _conversationToCallTranscriptMapping[_conversationTranscriptRecorder].Add(i);

            i.InstantMessagingCall_Received(e);
        }
Пример #27
0
        public TranscriptRecorderSession(CallReceivedEventArgs <InstantMessagingCall> e, CancellationTokenSource cts = null)
        {
            _sessionId           = Constants.NextGuid();
            _transcriptRecorders = new List <MediaTranscriptRecorder>();
            _conversationToCallTranscriptMapping = new Dictionary <ConversationTranscriptRecorder, List <MediaTranscriptRecorder> >();
            _messages     = new List <Message>();
            _state        = TranscriptRecorderState.Active;
            _conversation = e.Call.Conversation;
            _conversationTranscriptRecorder = new ConversationTranscriptRecorder(this, _conversation);
            _transcriptRecorders.Add(_conversationTranscriptRecorder);
            _conversationToCallTranscriptMapping.Add(_conversationTranscriptRecorder, new List <MediaTranscriptRecorder>());
            ConversationParticipant caller = e.RemoteParticipant;

            // Log IM conversation started
            Message m = new Message("InstantMessaging Conversation/Conference Started.", caller.DisplayName, caller.UserAtHost, caller.Uri, DateTime.Now,
                                    _conversation.Id, (_conversation.ConferenceSession == null) ? "null" : _conversation.ConferenceSession.ConferenceUri,
                                    MessageType.ConferenceInfo, MessageDirection.Outgoing);

            this.OnMessageReceived(m);

            AddIMIncomingCall(e);
        }
Пример #28
0
        private void StartUpMohChannelCompleted(IAsyncResult result)
        {
            object[] args = result.AsyncState as object[];

            AcdServiceChannel musicChannel   = args[0] as AcdServiceChannel;
            string            participantUri = args[1] as String;
            CallReceivedEventArgs <AudioVideoCall> callReceivedArgs = args[2] as CallReceivedEventArgs <AudioVideoCall>;
            EstablishMoHChannelAsyncResult         ear = args[3] as EstablishMoHChannelAsyncResult;

            try
            {
                musicChannel.EndStartUp(result);

                try
                {
                    musicChannel.BeginEstablishPrivateAudioChannel(participantUri,
                                                                   true /*outsideMix*/,
                                                                   EstablishPrivateAudioChannelCompleted,
                                                                   musicChannel);
                }
                catch (InvalidOperationException ivoex)
                {
                    musicChannel.BeginShutDown(dar =>
                    {
                        AcdServiceChannel channel = dar.AsyncState as AcdServiceChannel;
                        channel.EndShutDown(dar);
                    },
                                               musicChannel);

                    ear.SetAsCompleted(new OperationFailureException("AcdMusicOnHoldServer failed begin establishing private audio channel", ivoex), false);
                }
            }
            catch (RealTimeException rtex)
            {
                callReceivedArgs.Call.Decline();
                ear.SetAsCompleted(rtex, false);
            }
        }
Пример #29
0
        void On_AudioVideoCall_Received(object sender, CallReceivedEventArgs <AudioVideoCall> e)
        {
            //Type checking was done by the platform; no risk of this being any
            // type other than the type expected.
            _audioVideoCall = e.Call;

            // Call: StateChanged: Only hooked up for logging, to show the call
            // state transitions.
            _audioVideoCall.StateChanged += new
                                            EventHandler <CallStateChangedEventArgs>(_audioVideoCall_StateChanged);

            // Remote Participant URI represents the far end (caller) in this
            // conversation. Toast is the message set by the caller as the 'greet'
            // message for this call. In Microsoft Lync, the toast will
            // show up in the lower-right of the screen.
            Console.WriteLine("Call Received! From: " + e.RemoteParticipant.Uri + " Toast is: " +
                              e.ToastMessage.Message);

            // Now, forward the call to the user given above. Forwarding is not
            // an async operation; it completes as soon as the message is sent,
            // without waiting for a reply from the far end.
            _audioVideoCall.Forward(_forwardUserURI);
            _autoResetEvent.Set();
        }
 internal void OnAudioVideoCallReceived (object sender, CallReceivedEventArgs<AudioVideoCall> e)
 {
     
     
     //_avHelper.AcceptAVCall(e.Call);
     _avHelper.EscalateCalltoConference(e.Call, "sip:[email protected]" );  
     /*
     if (e.CallToBeReplaced == null)
     {
         Console.WriteLine("An initial audio/video call is received");
         // initial call (not a self-transfer).
         SupervisorJoinCallSession session = new SupervisorJoinCallSession(e.Call, _recipientSipUri, _supervisorSipUri);
         session.HandleIncomingCall();
     }
     else
     {
         Console.WriteLine("A self-transfer for a supervisor join audio/video call is received");
         // Self-transfer for a supervisor join. Get the session object out of the ApplicationContext property
         // on the replaced call (where we put it before doing the self-transfer).
         SupervisorJoinCallSession session = e.CallToBeReplaced.Conversation.ApplicationContext as SupervisorJoinCallSession;
         session.HandleIncomingSelfTransfer(e.Call);
     }
     */
 }
        internal void OnInstantMessagingCallReceived(object sender, CallReceivedEventArgs<InstantMessagingCall> e)
        {
            Console.WriteLine("An incoming Insatnt Messagine call is received");

            IMCallHandler handler = new IMCallHandler(e.Call, _recipientSipUri);
            handler.HandleIncomingCall();

            //handler.Echo();
                                    
        }
Пример #32
0
 private static async void GameStarted(object sender, CallReceivedEventArgs<InstantMessagingCall> e) {
     Log.Debug("Call received from " + e.RemoteParticipant.Uri);
     var call = e.Call;
     call.StateChanged += (o, args) => Log.DebugFormat("{0} -> {1}", e.RemoteParticipant.Uri, args.State);
     await call.AcceptAsync();
     var session = new ZMachineSession(call);
     session.Start();
 }
        public void AddIMIncomingCall(CallReceivedEventArgs<InstantMessagingCall> e, CancellationTokenSource cts = null)
        {
            if (_state != TranscriptRecorderState.Active)
            {
                NonBlockingConsole.WriteLine("Warn: AddIMIncomingCall in unexpected TranscriptRecorderSession state: " + _state.ToString());
            }

            IMTranscriptRecorder i = new IMTranscriptRecorder(this);
            ConversationParticipant caller = e.RemoteParticipant;

            Message m = new Message("InstantMessaging Conversation Participant Added.", caller.DisplayName, 
                caller.UserAtHost, caller.Uri, DateTime.Now,
                _conversation.Id, _conversation.ConferenceSession.ConferenceUri,
                MessageType.ConversationInfo, MessageDirection.Outgoing);
            this.OnMessageReceived(m);

            _transcriptRecorders.Add(i);
            _conversationToCallTranscriptMapping[_conversationTranscriptRecorder].Add(i);

            i.InstantMessagingCall_Received(e);
        }
Пример #34
0
        static void IncomingAVCallReceived(object sender, CallReceivedEventArgs <AudioVideoCall> e)
        {
            ApplicationEndpoint applicationEndpoint = (ApplicationEndpoint)sender;

            bool callReplaced = false;

            if (e.CallToBeReplaced != null)
            {
                callReplaced = true;
            }

            Console.WriteLine("IncomingAVCallReceived for endpoint " + applicationEndpoint.OwnerUri +
                              " RemoteEndpointUri=" + e.Call.RemoteEndpoint.Uri +
                              " CallReplaced=" + callReplaced);

            if (!callReplaced)
            {
                Console.WriteLine("Incoming call from " + e.RemoteParticipant.UserAtHost + " received");

                // Incoming call. Placing it into the random location
                Random rnd = new Random();

                int index = rnd.Next(0, _locations.Count - 1);

                Console.WriteLine("Placing " + e.RemoteParticipant.UserAtHost + " to \"" + _locations[index].Name + "\"");

                // Place user to location
                UserCall userCall = new UserCall(e.RemoteParticipant.UserAtHost, e.Call, _locations[index]);

                userCall.Terminated += new EventHandler(userCall_Terminated);

                e.Call.ApplicationContext = userCall;

                _userCalls.Add(userCall);
            }
            else
            {
                // Transfer user to the next location
                // We are getting here after BeginTransfer was called
                foreach (UserCall userCall in _userCalls)
                {
                    if (e.CallToBeReplaced.ApplicationContext == userCall)
                    {
                        int newLocationId = 0;
                        if (userCall.TransferPath == UserCallTransferPath.Next)
                        {
                            newLocationId = userCall.Location.Id + 1;
                            if (newLocationId >= _locations.Count)
                            {
                                newLocationId = 0;
                            }
                        }
                        else if (userCall.TransferPath == UserCallTransferPath.Previous)
                        {
                            newLocationId = userCall.Location.Id - 1;
                            if (newLocationId < 0)
                            {
                                newLocationId = _locations.Count - 1;
                            }
                        }

                        e.Call.ApplicationContext = userCall;

                        userCall.JoinLocation(e.Call, _locations[newLocationId]);

                        break;
                    }
                }
            }
        }
Пример #35
0
 //new incoming audio call
 private void OnIncomingCall(object sender, CallReceivedEventArgs <InstantMessagingCall> e)
 {
     Console.WriteLine(string.Format("Incoming call! Caller: {0}", e.Call.RemoteEndpoint.Uri));
     IncomingCall(this, e);
 }
Пример #36
0
        private void HandleIMCall(object state)
        {
            CallReceivedEventArgs <InstantMessagingCall> e = state as CallReceivedEventArgs <InstantMessagingCall>;
            ConversationParticipant caller = e.Call.RemoteEndpoint.Participant;
            InstantMessagingCall    imCall = e.Call;
            InstantMessagingFlow    imFlow = null;
            int messageCount = 0;

            imCall.InstantMessagingFlowConfigurationRequested +=
                delegate(object sender2, InstantMessagingFlowConfigurationRequestedEventArgs e2)
            {
                imFlow = e2.Flow;
                imFlow.MessageReceived +=
                    delegate(object sender3, InstantMessageReceivedEventArgs e3)
                {
                    messageCount++;
                    string message = e3.TextBody;
                    message = message.Trim();
                    if (!String.IsNullOrEmpty(message) && message.StartsWith("add", StringComparison.OrdinalIgnoreCase))
                    {
                        string[] tokens = message.Split(' ');
                        if (this.AppPlatform.ReverseNumberLookUp.AddEntry(tokens[1], caller.Uri))
                        {
                            this.SendIMResponse(imFlow, "Added telephone number.");
                        }
                        else
                        {
                            this.SendIMResponse(imFlow, "Telephone number exists.");
                        }
                    }
                    else if (!String.IsNullOrEmpty(message) && message.StartsWith("remove", StringComparison.OrdinalIgnoreCase))
                    {
                        string[] tokens = message.Split(' ');
                        if (this.AppPlatform.ReverseNumberLookUp.RemoveEntry(tokens[1], caller.Uri))
                        {
                            this.SendIMResponse(imFlow, "Removed telephone number.");
                        }
                        else
                        {
                            this.SendIMResponse(imFlow, "Telephone number does not exist or you do not own the tel #.");
                        }
                    }
                    else if (!String.IsNullOrEmpty(message) && message.Equals("list", StringComparison.OrdinalIgnoreCase))
                    {
                        Collection <string> list     = this.AppPlatform.ReverseNumberLookUp.FindPhoneNumbers(caller.Uri);
                        StringBuilder       response = new StringBuilder();
                        foreach (string s in list)
                        {
                            response.Append(s); response.Append("\r\n");
                        }
                        this.SendIMResponse(imFlow, response.ToString());
                    }
                    else
                    {
                        this.SendIMHelpMessage(imFlow);
                    }
                    if (messageCount > 5)         // We could also terminate based on timer.
                    {
                        this.TerminateIMCall(imCall);
                    }
                };
            };
            try
            {
                imCall.BeginAccept(
                    delegate(IAsyncResult ar)
                {
                    try
                    {
                        imCall.EndAccept(ar);
                        this.SendIMHelpMessage(imFlow);
                    }
                    catch (RealTimeException)
                    {
                    }
                },
                    null);
            }
            catch (InvalidOperationException)
            {
            }
        }
Пример #37
0
        /// <summary>
        /// Handles an incoming Instant Messaging call. The incoming Instant Messaging call can be one of two things:
        /// this can be a brand new customer session or a modality escalation. Else decline.
        /// </summary>
        private void HandleInstantMessagingCallReceived(object sender, CallReceivedEventArgs <InstantMessagingCall> args)
        {
            //Determines whether it is a new Call
            if (args.IsNewConversation == true)  //New acd customer session
            {
                //Decline the call if the portal is draining its calls, else hand it off to a newly created Acd Customer session.
                if (_portalState < PortalState.Draining)  //Only take new calls is we're not in the process of shutting down.
                {
                    AcdCustomerSession session = new AcdCustomerSession(_logger, _matchMaker, this);

                    //add the session to the list.
                    lock (_syncRoot)
                    {
                        _sessions.Add(session);
                        _numberOfSessionsEstablished++;
                    }
                    session.CustomerSessionStateChanged += CustomerSessionStateChanged;

                    if (args.CustomMimeParts.Count > 0)
                    {
                        productType       productInfo;
                        List <AgentSkill> listOfRequestedSkills = new List <AgentSkill>(this.ProcessMimeParts(args.CustomMimeParts, out productInfo));

                        ThreadPool.QueueUserWorkItem((waitState) =>
                        {
                            session.HandleInitialCall(args.Call, listOfRequestedSkills, productInfo);
                        });
                    }
                    else
                    {
                        ThreadPool.QueueUserWorkItem((waitState) =>
                        {
                            session.HandleInitialCall(args.Call, null, null);
                        });
                    }
                }
                else //If the call comes in while we're shutting down, terminate it
                {
                    //UNDONE: Nice to have: - Play a message to the user that the portal is shutting down.
                    try
                    {
                        args.Call.Decline(new CallDeclineOptions(ResponseCode.TemporarilyUnavailable));
                    }
                    catch (RealTimeException ex)
                    {
                        _logger.Log("AcdPortal cannot decline incoming IM call properly while draining/terminating the portal", ex);
                    }
                }
            }
            else
            {
                //this an audio escalation, hand off the call to the AcdCustomerSession for futher processing
                if (null != args.Call.Conversation.ApplicationContext)
                {
                    AcdCustomerSession session = args.Call.Conversation.ApplicationContext as AcdCustomerSession;

                    ThreadPool.QueueUserWorkItem((waitState) =>
                    {
                        session.HandleNewModality(args.Call);
                    });
                }
                else
                {
                    // There was an issue retrieving the AcdCustomerSession, we are declining the call.

                    try
                    {
                        args.Call.Decline();
                    }
                    catch (InvalidOperationException ex)
                    {
                        _logger.Log("AcdPortal cannot decline incoming IM call properly; the call must already be terminated", ex);
                    }
                    catch (RealTimeException ex)
                    {
                        _logger.Log("AcdPortal cannot decline incoming IM call properly", ex);
                    }
                }
            }
        }
Пример #38
0
        /// <summary>
        /// Handles incoming AudioVideoCall. The incoming call can be one of three things: a brand new conversation,
        /// a self transfer of an existing customer-facing call, an audio escalation. In Draining mode, only the incoming
        /// calls for existing Conversations will be processed. Initial Conversation calls coming in will be declined by the
        /// endpoint.
        /// </summary>
        private void HandleAudioVideoCallReceived(object sender, CallReceivedEventArgs <AudioVideoCall> args)
        {
            //Determines whether it is a new Call
            if (args.IsNewConversation && args.CallToBeReplaced == null)   //New Acd customer session
            {
                AcdCustomerSession session = new AcdCustomerSession(_logger, _matchMaker, this);

                //add the session to the list.
                lock (_syncRoot)
                {
                    _sessions.Add(session);
                    _numberOfSessionsEstablished++;
                }

                //registering for an event to monitor the customer session state in order to determine when the draining is complete.
                session.CustomerSessionStateChanged += CustomerSessionStateChanged;

                if (args.CustomMimeParts.Count > 0)
                {
                    productType productInformation;

                    List <AgentSkill> listOfRequestedSkills = new List <AgentSkill>(this.ProcessMimeParts(args.CustomMimeParts, out productInformation));

                    ThreadPool.QueueUserWorkItem((waitState) =>
                    {
                        session.HandleInitialCall(args.Call, listOfRequestedSkills, productInformation);
                    });
                }
                else
                {
                    ThreadPool.QueueUserWorkItem((waitState) =>
                    {
                        session.HandleInitialCall(args.Call, null, null);
                    });
                }
            }
            //it is not a new call but a modality addition
            else if (args.IsNewConversation == false && args.CallToBeReplaced == null)
            {
                if (null != args.Call.Conversation.ApplicationContext)
                {
                    //this an audio escalation, hand-off the call to the AcdCustomerSession for futher processing
                    AcdCustomerSession session = args.Call.Conversation.ApplicationContext as AcdCustomerSession;
                    args.RingBackDisabled = true;
                    session.HandleNewModality(args.Call);
                }
                else
                {
                    // There was an issue retrieving the AcdCustomerSession, we are declining the call.
                    try
                    {
                        args.Call.Decline(new CallDeclineOptions(ResponseCode.TemporarilyUnavailable));
                    }
                    catch (RealTimeException ex)
                    {
                        _logger.Log("AcdPortal cannot decline incoming audio call properly", ex);
                    }
                }
            }
            else if (args.CallToBeReplaced != null)
            {
                try
                {
                    args.Call.Decline();
                }
                catch (RealTimeException ex)
                {
                    _logger.Log("AcdPortal failed declining an incoming call replacing an exisiting one", ex);
                }
            }
            else
            {
                //unexpected. Decline the incoming call
                try
                {
                    args.Call.Decline();
                }
                catch (RealTimeException ex)
                {
                    _logger.Log("Acd customer session failed to decline an unexpected incoming Audio call", ex);
                }
            }
        }
Пример #39
0
        protected override async Task HandleAudioVideoCall(CallReceivedEventArgs<AudioVideoCall> args, CancellationToken cancellationToken)
        {
            try
            {
                // only new conversations supported
                if (!args.IsNewConversation)
                    return;

                // locate destination application URI
                var uri = applications.GetOrDefault(new RealTimeAddress(args.Call.Conversation.LocalParticipant.Uri));
                if (uri == null)
                    throw new Exception(string.Format("No configured Application for {0}.", args.Call.Conversation.LocalParticipant.Uri));

                // signals activation of flow
                var active = new TaskCompletionSource();

                // subscribe to flow configuration requested
                args.Call.AudioVideoFlowConfigurationRequested += (s, a) =>
                {
                    // subscribe to flow state changes
                    if (a.Flow != null)
                        a.Flow.StateChanged += (s2, a2) =>
                        {
                            if (a2.PreviousState != MediaFlowState.Active &&
                                a2.State == MediaFlowState.Active)
                                Dispatch(() =>
                                {
                                    active.TrySetResult();
                                });
                        };
                };

                // accept the call and wait for an active flow
                await args.Call.AcceptAsync();
                await active.Task;

                // initiate browser
                using (var browser = new Browser())
                {
                    var result = new TaskCompletionSource<VoiceXmlResult>();
                    browser.SessionCompleted += (s3, a3) => OnSessionCompleted(result, a3);
                    browser.Disconnecting += (s3, a3) => OnDisconnecting(result, a3);
                    browser.Disconnected += (s3, a3) => OnDisconnected(result, a3);
                    browser.Transferring += (s3, a3) => OnTransferring(result, a3);
                    browser.Transferred += (s3, a3) => OnTransfered(result, a3);
                    browser.SetAudioVideoCall(args.Call);
                    browser.RunAsync(uri, null);
                    await result.Task;
                }
            }
            catch (Exception e)
            {
                OnUnhandledException(new ExceptionEventArgs(e, ExceptionSeverityLevel.Error));
            }
        }
Пример #40
0
        static void IncomingAVCallReceived(object sender, CallReceivedEventArgs<AudioVideoCall> e)
        {
            ApplicationEndpoint applicationEndpoint = (ApplicationEndpoint)sender;

            bool callReplaced = false;
            if (e.CallToBeReplaced != null)
            {
                callReplaced = true;
            }

            Console.WriteLine("IncomingAVCallReceived for endpoint " + applicationEndpoint.OwnerUri +
                " RemoteEndpointUri=" + e.Call.RemoteEndpoint.Uri +
                " CallReplaced=" + callReplaced);

            if (!callReplaced)
            {
                Console.WriteLine("Incoming call from " + e.RemoteParticipant.UserAtHost + " received");

                // Incoming call. Placing it into the random location
                Random rnd = new Random();

                int index = rnd.Next(0, _locations.Count - 1);

                Console.WriteLine("Placing " + e.RemoteParticipant.UserAtHost + " to \"" + _locations[index].Name + "\"");

                // Place user to location
                UserCall userCall = new UserCall(e.RemoteParticipant.UserAtHost, e.Call, _locations[index]);

                userCall.Terminated += new EventHandler(userCall_Terminated);

                e.Call.ApplicationContext = userCall;

                _userCalls.Add(userCall);
            }
            else
            {
                // Transfer user to the next location
                // We are getting here after BeginTransfer was called
                foreach (UserCall userCall in _userCalls)
                {
                    if (e.CallToBeReplaced.ApplicationContext == userCall)
                    {
                        int newLocationId = 0;
                        if (userCall.TransferPath == UserCallTransferPath.Next)
                        {
                            newLocationId = userCall.Location.Id + 1;
                            if (newLocationId >= _locations.Count)
                            {
                                newLocationId = 0;
                            }
                        }
                        else if (userCall.TransferPath == UserCallTransferPath.Previous)
                        {
                            newLocationId = userCall.Location.Id - 1;
                            if (newLocationId < 0)
                            {
                                newLocationId = _locations.Count - 1;
                            }
                        }

                        e.Call.ApplicationContext = userCall;

                        userCall.JoinLocation(e.Call, _locations[newLocationId]);

                        break;
                    }
                }
            }
        }
 /// <summary>
 /// Delegate that is called when an incoming InstantMessagingCall arrives.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 void InstantMessagingCall_Received(object sender, CallReceivedEventArgs<InstantMessagingCall> e)
 {
     Task.Factory.StartNew(()=>
         {
         try
         {
             if (_activeConversationSessions.ContainsKey(e.Call.Conversation))
             {
                 _activeConversationSessions[e.Call.Conversation].AddIMIncomingCall(e);
             }
             else if (e.IsNewConversation)
             {
                 Conversation c = e.Call.Conversation;
                 TranscriptRecorderSession t = new TranscriptRecorderSession(e);
                 t.TranscriptRecorderSessionChanged += this.TranscriptRecorder_OnTranscriptRecorderSessionChanged;
                 t.TranscriptRecorderSessionShutdown += this.TranscriptRecorder_OnTranscriptRecorderSessionShutdown;
                 _activeConversationSessions.Add(c, t);
             }
             else if (e.IsConferenceDialOut)
             {
                 // TODO: Join Conference then accept IM call
                 throw new NotImplementedException("InstantMessagingCall_Received with ConferenceDialOut AudioVideoCall is not yet supported.");
             }
         }
         catch (Exception ex)
         {
             NonBlockingConsole.WriteLine("Error: Exception thrown in InstantMessagingCall_Received: " + ex.ToString());
         }
         finally
         {
             _waitForTranscriptSessionStarted.Set();
         }
     });
 }
        public void InstantMessagingCall_Received(CallReceivedEventArgs<InstantMessagingCall> e)
        {
            if (_state == TranscriptRecorderState.Terminated)
            {
                NonBlockingConsole.WriteLine("Error: IMTranscriptRecorder is shutdown.");
                // TODO: Info message
                return;
            }

            if (_instantMessagingCall != null)
            {
                NonBlockingConsole.WriteLine("Warn: IMCall already exists for this Conversation. Shutting down previous call...");
                // TODO: Info message
                TerminateCall();
            }

            _state = TranscriptRecorderState.Initialized;
            _waitForIMCallTerminated.Reset();

            // Type checking was done by the platform; no risk of this being any 
            // type other than the type expected.
            _instantMessagingCall = e.Call;

            // Call: StateChanged: Only hooked up for logging, to show the call
            // state transitions.
            _instantMessagingCall.StateChanged +=
                new EventHandler<CallStateChangedEventArgs>(InstantMessagingCall_StateChanged);

            _instantMessagingCall.InstantMessagingFlowConfigurationRequested +=
                new EventHandler<InstantMessagingFlowConfigurationRequestedEventArgs>(InstantMessagingCall_FlowConfigurationRequested);

            _instantMessagingCall.ConversationChanged += new EventHandler<ConversationChangedEventArgs>(InstantMessagingCall_ConversationChanged);

            // Remote Participant URI represents the far end (caller) in this 
            // conversation. Toast is the message set by the caller as the 
            // 'greet' message for this call. In Microsoft Lync, the 
            // toast will show up in the lower-right of the screen.
            // TODO: Change to protect privacy
            // NonBlockingConsole.WriteLine("IMCall Received! From: " + e.RemoteParticipant.Uri + " Toast is: " + e.ToastMessage.Message);
            NonBlockingConsole.WriteLine("IMCall Received! From: " + e.RemoteParticipant.Uri);
            // Console.Writelin("IMCall Received!");

            Message m = new Message("InstantMessagingCall Received. Inbound call state: " + _instantMessagingCall.State.ToString(),
                e.RemoteParticipant.DisplayName, e.RemoteParticipant.UserAtHost, e.RemoteParticipant.Uri,
                MessageType.InstantMessage, _transcriptRecorder.Conversation.Id, MessageDirection.Incoming);
            _transcriptRecorder.OnMessageReceived(m);

            // Now, accept the call. EndAcceptCall will be raised on the 
            // same thread.
            _instantMessagingCall.BeginAccept(InstantMessagingCallAcceptedCallBack, _instantMessagingCall);
        }
Пример #43
0
        /// <summary>
        /// Accept AV.
        /// </summary>
        /// <param name="sender">Source of the event</param>
        /// <param name="e">AudioVideoCall arguments</param>
        private void AV_Received(object sender, CallReceivedEventArgs <AudioVideoCall> e)
        {
            bool handled = false;

            if (e.IsConferenceDialOut)
            {
                if (e.Call.Conversation.Id != null)
                {
                    string customerUri = e.Call.Conversation.Id.Trim('>', '<');
                    lock (this.activeCustomerSessions)
                    {
                        if (activeCustomerSessions.ContainsKey(customerUri))
                        {
                            activeCustomerSessions[customerUri].HandleIncomingDialOutCall(e.Call);
                            handled = true;
                        }
                    }
                }
            }
            else if (e.IsNewConversation)
            {
                if (e.Call.Conversation.Id != null)
                {
                    string customerUri = e.Call.Conversation.Id.Trim('>', '<');
                    lock (this.activeCustomerSessions)
                    {
                        if (activeCustomerSessions.ContainsKey(customerUri))
                        {
                            activeCustomerSessions[customerUri].HandleIncomingAudioCall(e.Call);
                            handled = true;
                        }
                        else
                        {
                            string          uri             = e.Call.RemoteEndpoint.Uri;
                            Customer        customer        = new Customer(uri);
                            Menu            menu            = new Menu(this.moreInformationMessage, this.moreInformationLink, this.cweMessage, this.registryFilePath, this.XmlParser);
                            CustomerSession customerSession = new CustomerSession(customer, menu, this, this.logger);
                            this.activeCustomerSessions.Add(e.Call.RemoteEndpoint.Uri, customerSession);
                            customerSession.HandleIncomingAudioCall(e.Call);
                            handled = true;
                        }
                    }
                }
            }


            if (!handled)
            {
                try
                {
                    this.logger.Log("Declining AV call since this is a modality escalating call.");
                    Console.WriteLine("Declining AV call since this is a modality escalating call.");
                    e.Call.Decline();
                }
                catch (InvalidOperationException ioe)
                {
                    this.logger.Log("Exception while declining call {0}", ioe);
                    Console.WriteLine("Exception while declining call {0}", ioe);
                }
                catch (RealTimeException rte)
                {
                    this.logger.Log("Exception while declining call {0}", rte);
                    Console.WriteLine("Exception while declining call {0}", rte);
                }
            }
        }
        public TranscriptRecorderSession(CallReceivedEventArgs<InstantMessagingCall> e, CancellationTokenSource cts = null)
        {
            _sessionId = Constants.NextGuid();
            _transcriptRecorders = new List<MediaTranscriptRecorder>();
            _conversationToCallTranscriptMapping = new Dictionary<ConversationTranscriptRecorder, List<MediaTranscriptRecorder>>();
            _messages = new List<Message>();
            _state = TranscriptRecorderState.Active;
            _conversation = e.Call.Conversation;
            _conversationTranscriptRecorder = new ConversationTranscriptRecorder(this, _conversation);
            _transcriptRecorders.Add(_conversationTranscriptRecorder);
            _conversationToCallTranscriptMapping.Add(_conversationTranscriptRecorder, new List<MediaTranscriptRecorder>());
            ConversationParticipant caller = e.RemoteParticipant;

            // Log IM conversation started
            Message m = new Message("InstantMessaging Conversation/Conference Started.", caller.DisplayName, caller.UserAtHost, caller.Uri, DateTime.Now,
                _conversation.Id, (_conversation.ConferenceSession == null) ? "null" : _conversation.ConferenceSession.ConferenceUri,
                MessageType.ConferenceInfo, MessageDirection.Outgoing);
            this.OnMessageReceived(m);

            AddIMIncomingCall(e);
        }
 internal void OnAudioVideoCallReceived (object sender, CallReceivedEventArgs<AudioVideoCall> e)
 {
     
     
     _avHelper.AcceptAVCall(e.Call);
     
 }
Пример #46
0
 //new incoming instant message conversation
 private void OnIncomingIM(object sender, CallReceivedEventArgs<InstantMessagingCall> e)
 {
     log.Info(string.Format("New Message from {0} : {1}", e.Call.RemoteEndpoint.Uri, e.ToastMessage.Message));
     IncomingCall(this, e);
 }
Пример #47
0
 protected override async Task HandleAudioVideoCall(CallReceivedEventArgs<AudioVideoCall> args, CancellationToken cancellationToken)
 {
     var action = GetAction(args.Call) ?? DefaultAction;
     if (action != null)
         await action.Execute(args.Call.Conversation.Endpoint, args.Call, cancellationToken);
 }
        //call received event handler
        public void AudioVideoCall_Received(CallReceivedEventArgs<AudioVideoCall> e)
        {
            if (_state == TranscriptRecorderState.Terminated)
            {
                NonBlockingConsole.WriteLine("Error: AVTranscriptRecorder is shutdown.");
                // TODO: Error message
                return;
            }

            if (_audioVideoCall != null)
            {
                NonBlockingConsole.WriteLine("Warn: AVCall already exists for this Conversation. Shutting down previous call...");
                // TODO: Info message
                TerminateCall();
            }

            _state = TranscriptRecorderState.Initialized;
            _waitForAudioVideoCallTerminated.Reset();

            //Type checking was done by the platform; no risk of this being any 
            // type other than the type expected.
            _audioVideoCall = e.Call;

            // Call: StateChanged: Only hooked up for logging, to show the call 
            // state transitions.
            _audioVideoCall.StateChanged += new EventHandler<CallStateChangedEventArgs>(AudioVideoCall_StateChanged);

            // Subscribe for the flow configuration requested event; the flow will be used to send the media.
            // Ultimately, as a part of the callback, the media will be sent/recieved.
            _audioVideoCall.AudioVideoFlowConfigurationRequested += new EventHandler<AudioVideoFlowConfigurationRequestedEventArgs>(AudioVideoCall_FlowConfigurationRequested);

            _audioVideoCall.ConversationChanged += new EventHandler<ConversationChangedEventArgs>(AudioVideoCall_ConversationChanged);

            // Remote Participant URI represents the far end (caller) in this 
            // conversation. Toast is the message set by the caller as the 'greet'
            // message for this call. In Microsoft Lync, the toast will 
            // show up in the lower-right of the screen.
            // TODO: change this to preserve confidentiality in the video demo
            //NonBlockingConsole.WriteLine("Call Received! From: " + e.RemoteParticipant.Uri + " Toast is: " + e.ToastMessage.Message);
            NonBlockingConsole.WriteLine("Call Received! From: " + e.RemoteParticipant.Uri);
            //NonBlockingConsole.WriteLine("Call Received!");

            Message m = new Message("AudioVideoCall Received. Inbound call state: " + _audioVideoCall.State.ToString(),
                e.RemoteParticipant.DisplayName, e.RemoteParticipant.UserAtHost, e.RemoteParticipant.Uri,
                MessageType.Audio, _transcriptRecorder.Conversation.Id, MessageDirection.Incoming);
            _transcriptRecorder.OnMessageReceived(m);

            // Accept the call. Before transferring the call, it must be in the Established state.
            // Note that the docs are wrong in the state machine for the AVCall. BeginEstablish 
            // should be called on outgoing calls, not incoming calls.
            _audioVideoCall.BeginAccept(AudioVideoCallAccepted, _audioVideoCall);

            // Wait for a few seconds to give time for the call to get to the Established state.
            //_waitForAudioVideoCallAccepted.WaitOne(2000);
            NonBlockingConsole.WriteLine("Inbound call state is {0}\n", _audioVideoCall.State.ToString());
        }
 //new incoming audio call
 private void OnIncomingCall(object sender, CallReceivedEventArgs<AudioVideoCall> e)
 {
     Console.WriteLine(string.Format("Incoming call! Caller: {0}", e.Call.RemoteEndpoint.Uri));
     IncomingCall(this, e);
 }