/// <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(); } }); }
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); } }
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; } }
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; }
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); } }
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(); } }
/* 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); } }
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); }
//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()); }
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); } }
/// <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; }
// 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); }
/// <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)); }
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); }
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); } } }
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); }
/// <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); } } }
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); } }
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); }
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); }
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); } }
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(); }
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); }
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; } } } }
//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); }
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) { } }
/// <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); } } } }
/// <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); } } }
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)); } }
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); }
/// <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); }
//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); }
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); }