public static Task <bool> CheckPasscodeIsOptional(this ConferenceServices cs, RealTimeAddress conferenceAddress) { return(Task <bool> .Factory.FromAsync( cs.BeginCheckPasscodeIsOptional, cs.EndCheckPasscodeIsOptional, conferenceAddress, null)); }
public static Task<bool> CheckPasscodeIsOptional(this ConferenceServices cs, RealTimeAddress conferenceAddress) { return Task<bool>.Factory.FromAsync( cs.BeginCheckPasscodeIsOptional, cs.EndCheckPasscodeIsOptional, conferenceAddress, null); }
public override Collection <string> FindPhoneNumbers(string sipUri) { Collection <string> list = new Collection <string>(); RealTimeAddress sipUriAddress = null; try { sipUriAddress = new RealTimeAddress(sipUri); if (sipUriAddress.IsPhone) // Should not be phone uri { return(list); } } catch (ArgumentException) { return(list); } lock (this.SyncRoot) { foreach (string key in m_directory.Keys) { RealTimeAddress valueAddress = new RealTimeAddress(m_directory[key]); if (valueAddress == sipUriAddress) { list.Add(key); } } } return(list); }
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; } }
/// <summary> /// Sends the Notify message back to the PIC user /// /// </summary> /// <param name="e"></param> /// <param name="_sipAddressessOfBot"></param> public void SendBotsOnlineStatusToPicClient(string sipUriOfPicClient, string sipUriOfBot, string callId, string cseq, string toHeaderValue, string fromHeaderValue) { Console.WriteLine("Sending Bot's Open status to PIC client as a NOTIFY using UCMA..."); try { List <SignalingHeader> headers = new List <SignalingHeader>(); headers.Add(new SignalingHeader("EVENT", "presence")); headers.Add(new SignalingHeader("Subscription-State", "active")); headers.Add(new SignalingHeader("Call-Id", callId)); headers.Add(new SignalingHeader("CSeq", cseq)); headers.Add(new SignalingHeader("To", toHeaderValue)); headers.Add(new SignalingHeader("From", fromHeaderValue)); Console.WriteLine("App-configured SignalingHeaders:"); foreach (SignalingHeader h in headers) { Console.WriteLine(h.Name + ": " + h.GetValue()); } Console.WriteLine("PIC user URI: " + sipUriOfPicClient); Console.WriteLine("Bot Uri: " + sipUriOfBot); string displayName = this.GetDisplayNameForApplicationEndpoint(sipUriOfBot); System.Net.Mime.ContentType contentType = new System.Net.Mime.ContentType("application/pidf+xml"); System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding(); byte[] notifyBody = enc.GetBytes(String.Format(_pidfNotifyText, "open", displayName, sipUriOfBot)); Console.WriteLine("PIDFNotifyBody =" + System.Text.UTF8Encoding.UTF8.GetString(notifyBody)); // Target address of the NOTIFY RealTimeAddress targetAddress = new RealTimeAddress(sipUriOfPicClient); // Shouldn't be synchronized call in production code _superP2PEndpoint.BeginSendMessage( sipUriOfBot, MessageType.Notify, targetAddress, contentType, notifyBody, headers, (a) => { try { _superP2PEndpoint.EndSendMessage(a); } catch (RealTimeException rtex) { // report and ignore the failure Console.WriteLine("EndSendMessage: Notify failed with exception: {0}", rtex.Message); } }, null); Console.WriteLine("End calling SendBotsOnlineStatusToPicClient!"); } catch (Exception e) { Console.WriteLine("Failed in SendBotsOnlineStatusToPicClient: \r\n{0}\r\n{1}", e.Message, e.StackTrace); } }
public static Task <bool> VerifyPasscodeAsync(this ConferenceServices cs, RealTimeAddress conferenceAddress, string passcode) { return(Task <bool> .Factory.FromAsync( cs.BeginVerifyPasscode, cs.EndVerifyPasscode, conferenceAddress, passcode, null)); }
/// <summary> /// Menu level changed handler. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MenuLevelChanged(object sender, MenuLevelChangedEventArgs e) { if (e.Level == MenuLevel.HelpDeskRequested) { lock (this.syncRoot) { if (this.callAnchor == null) { this.callAnchor = new CustomerCallAnchor(this, this.logger, this.conversation); } try { var helpdeskNumber = e.HelpdeskNumber; if (String.IsNullOrEmpty(helpdeskNumber)) { Console.WriteLine("Null or empty help desk number"); this.logger.Log("Null or empty help desk number"); } else { try { RealTimeAddress address = new RealTimeAddress(helpdeskNumber); this.callAnchor.BeginEstablish(address, (asyncResult) => { try { this.callAnchor.EndEstablish(asyncResult); } catch (Exception ex) { this.callAnchor.BeginTerminate((terminateAsyncResult) => { this.callAnchor.EndTerminate(terminateAsyncResult); }, null); Console.WriteLine("Call anchor failed with {0}", ex); this.logger.Log("Call anchor failed with {0}", ex); } }, null); } catch (ArgumentException ae) { Console.WriteLine("Invalid help desk number {0}, Exception ={1}", helpdeskNumber, ae); this.logger.Log("Invalid help desk number {0}, Exception ={1}", helpdeskNumber, ae); } } } catch (Exception ex) { Console.WriteLine("Call anchor failed with {0}", ex); this.logger.Log("Call anchor failed with {0}", ex); } } } }
/// <summary> /// Override process method. /// </summary> public override void Process() { bool unhandledExceptionDetected = true; Exception exceptionCaught = null; try { RealTimeEndpoint innerEndpoint = this.LocalEndpoint.InnerEndpoint; SendMessageOptions options = new SendMessageOptions(); options.ContentDescription = ContactCenterDiscoveryAsyncResult.GetDiscoveryRequestContentDescription(); RealTimeAddress targetAddress = new RealTimeAddress(this.TargetUri); innerEndpoint.BeginSendMessage(MessageType.Service, targetAddress, options, this.ServiceRequestCompleted, innerEndpoint /*state*/); unhandledExceptionDetected = false; } catch (ArgumentException ae) { Helper.Logger.Error("Exception = {0}", EventLogger.ToString(ae)); exceptionCaught = ae; unhandledExceptionDetected = false; } catch (InvalidOperationException ioe) { Helper.Logger.Info("Exception = {0}", EventLogger.ToString(ioe)); exceptionCaught = ioe; unhandledExceptionDetected = false; } catch (RealTimeException rte) { Helper.Logger.Info("Exception = {0}", EventLogger.ToString(rte)); exceptionCaught = rte; unhandledExceptionDetected = false; } finally { if (unhandledExceptionDetected) { exceptionCaught = new Exception("Unhandled exception"); Helper.Logger.Info("Exception = {0}", EventLogger.ToString(exceptionCaught)); } if (exceptionCaught != null) { this.Complete(exceptionCaught); } } }
private void UserEndpointStateChanged(object sender, LocalEndpointStateChangedEventArgs e) { UserEndpoint userEndpoint = sender as UserEndpoint; RealTimeAddress ownerAddress = new RealTimeAddress(userEndpoint.OwnerUri); if (e.State == LocalEndpointState.Terminating) { lock (this.SyncRoot) { // Lost the cache. if (m_userEndpoints.ContainsKey(ownerAddress)) { m_userEndpoints.Remove(ownerAddress); m_userEndpointReferenceCounts.Remove(ownerAddress); } } } }
public override bool RemoveEntry(string telUri, string sipUri) { bool removed = false; lock (this.SyncRoot) { if (!telUri.StartsWith("tel")) { telUri = "tel:" + telUri; } if (m_directory.ContainsKey(telUri)) { bool shouldRemove = true; if (!String.IsNullOrEmpty(sipUri)) { string oldSipUri = m_directory[telUri]; try { RealTimeAddress oldSipUriAddress = new RealTimeAddress(oldSipUri); RealTimeAddress telUriAddress = new RealTimeAddress(telUri); RealTimeAddress sipUriAddress = new RealTimeAddress(sipUri); if (oldSipUriAddress != sipUriAddress) { shouldRemove = false; // Does not match. One can only remove their own number. } } catch (ArgumentException) { shouldRemove = false; } } if (shouldRemove) { m_directory.Remove(telUri); removed = true; m_isModified = true; } } } return(removed); }
private void InviteUserStatementCompleted() { if (this.CustomerSession.IsTerminatingTerminated) { this.EndService(null); return; } this.RestartDtmfCommand(); RealTimeAddress address = new RealTimeAddress(m_selectedContact.Uri); if (address.IsPhone) { this.DialOut(m_selectedContact.Uri, m_selectedContact.Uri, m_selectedContact.Uri, this.UserInvitationWorkCompleted); } else { this.InviteToConference(m_selectedContact.Uri, this.UserInvitationWorkCompleted); // Conf } }
/// <summary> /// Constructor. /// </summary> public EstablishAsyncResult(CustomerCallAnchor parent, Conversation trustedConversation, Conversation customerConversation, RealTimeAddress helpdeskNumber, ILogger logger, AsyncCallback asyncCallback, object state) : base(asyncCallback, state) { if (helpdeskNumber == null) { throw new ArgumentNullException("helpdeskNumber"); } this.trustedConversation = trustedConversation; this.customerConversation = customerConversation; this.logger = logger; this.parent = parent; this.helpdeskNumber = helpdeskNumber; }
/// <summary> /// Establishes the call anchor for a customer session. /// </summary> /// <param name="callback"></param> /// <param name="state"></param> /// <returns></returns> public IAsyncResult BeginEstablish(RealTimeAddress helpdeskNumber, AsyncCallback callback, object state) { EstablishAsyncResult establishAsyncResult = null; if (helpdeskNumber == null) { throw new ArgumentNullException("helpdeskNumber"); } lock (this.syncRoot) { if (this.pendingEstablishAsyncResult != null) { throw new InvalidOperationException("Already a pending async result is in progress"); } if (this.customerRemoteParticipant == null) { throw new InvalidOperationException("Customer has already left the conversation"); } if (this.trustedConversation == null) { ConversationSettings settings = new ConversationSettings(ConversationPriority.Normal, "Dialout", "<" + this.CustomerUri + ">"); this.trustedConversation = new Conversation(this.customerConversation.Endpoint, settings); // Config change: We cannot impersonate with user endpoint. if (!Boolean.Parse(System.Configuration.ConfigurationManager.AppSettings["UseUserEndPoint"])) { this.trustedConversation.Impersonate(this.customerRemoteParticipant.Uri, this.customerRemoteParticipant.PhoneUri, this.customerRemoteParticipant.DisplayName); } this.RegisterTrustedConversationEventHandlers(this.trustedConversation); } establishAsyncResult = new EstablishAsyncResult(this, this.trustedConversation, this.customerConversation, helpdeskNumber, this.logger, callback, state); this.pendingEstablishAsyncResult = establishAsyncResult; } establishAsyncResult.Process(); return(establishAsyncResult); }
public static bool TryExtractCleanPhone(string uri, out string phone) { bool result = false; phone = null; try { RealTimeAddress address = new RealTimeAddress(uri); if (address.IsPhone) { phone = address.UserAtHost; string[] parts = phone.Split('@'); phone = parts[0]; // Just the user part. result = true; } } catch (ArgumentException) { } return(result); }
/// <summary> /// Compares if 2 uris are equal. /// </summary> /// <param name="uri1">Uri1</param> /// <param name="uri2">Uri2</param> /// <returns>True if 2 uris are equal. False otherwise.</returns> public static bool Equals(string uri1, string uri2) { bool areEqual = false; if (String.Equals(uri1, uri2, StringComparison.OrdinalIgnoreCase)) { areEqual = true; } else if (!String.IsNullOrEmpty(uri1)) { try { RealTimeAddress address1 = new RealTimeAddress(uri1); RealTimeAddress address2 = new RealTimeAddress(uri2); areEqual = (address1 == address2); } catch (ArgumentException) { } } return(areEqual); }
public override bool AddEntry(string telUri, string sipUri) { bool wasAdded = false; try { if (!telUri.StartsWith("tel")) { telUri = "tel:" + telUri; } RealTimeAddress telUriAddress = new RealTimeAddress(telUri); if (!telUriAddress.IsPhone) // Should be phone uri. { return(wasAdded); } RealTimeAddress sipUriAddress = new RealTimeAddress(sipUri); if (sipUriAddress.IsPhone) // Should not be phone uri { return(wasAdded); } } catch (ArgumentException) { return(wasAdded); } lock (this.SyncRoot) { if (!m_directory.ContainsKey(telUri)) { m_directory.Add(telUri, sipUri); wasAdded = true; m_isModified = true; } } return(wasAdded); }
/// <summary> /// Releases the user endpoint from usage from a component. /// </summary> /// <param name="task">The task to be done.</param> /// <param name="state">The user endpoint to release.</param> /// <remarks>If ref count is reduced to 0, the userendpoint will be terminated.</remarks> public void RelaseUserEndpoint(AsyncTask task, object state) { MyUserEndpoint myUserEndpoint = state as MyUserEndpoint; RealTimeAddress ownerAddress = new RealTimeAddress(myUserEndpoint.UserEndpoint.OwnerUri); bool completeNeeded = true; lock (this.SyncRoot) { if (m_userEndpoints.ContainsKey(ownerAddress)) { MyUserEndpoint storedEndpoint = m_userEndpoints[ownerAddress]; if (storedEndpoint == myUserEndpoint) // What we have matches the released endpoint. Reduce ref count. { int count = m_userEndpointReferenceCounts[ownerAddress]; count--; m_userEndpointReferenceCounts[ownerAddress] = count; if (count == 0) { // Terminate the endpoint. AsyncTask terminateEndpointTask = new AsyncTask(this.ShutdownUserEndpoint, myUserEndpoint.UserEndpoint); terminateEndpointTask.TaskCompleted += delegate(object sender, AsyncTaskCompletedEventArgs e) { task.Complete(e.ActionResult.Exception); }; terminateEndpointTask.StartTask(); completeNeeded = false; } } } } if (completeNeeded) { task.Complete(null); } }
public static Task<bool> VerifyPasscodeAsync(this ConferenceServices cs, RealTimeAddress conferenceAddress, string passcode) { return Task<bool>.Factory.FromAsync( cs.BeginVerifyPasscode, cs.EndVerifyPasscode, conferenceAddress, passcode, null); }
public void CreateOrGetUserEndpoint(AsyncTask task, object state) { string ownerUri = state as string; if (String.IsNullOrEmpty(ownerUri)) { task.Complete(new InvalidOperationException("OwnerUri is needed to request a user endpoint.")); return; } RealTimeAddress ownerAddress = null; try { ownerAddress = new RealTimeAddress(ownerUri); } catch (ArgumentException exception) { task.Complete(exception); return; } MyUserEndpoint myUserEndpoint = null; lock (this.SyncRoot) { if (m_userEndpoints.ContainsKey(ownerAddress)) { myUserEndpoint = m_userEndpoints[ownerAddress]; if (myUserEndpoint.UserEndpoint.State == LocalEndpointState.Terminating || myUserEndpoint.UserEndpoint.State == LocalEndpointState.Terminated) { myUserEndpoint = null; // Loose it since it is going away. m_userEndpoints.Remove(ownerAddress); m_userEndpointReferenceCounts.Remove(ownerAddress); } else { int count = m_userEndpointReferenceCounts[ownerAddress]; count++; m_userEndpointReferenceCounts[ownerAddress] = count; } } if (myUserEndpoint == null) { // Create and add user endpoint into dictionary. // One could use the platform discover server from uri if the topology has DNS srv records for server auto discovery. // Normally, this would point to a director. Here, we will use the proxy of the application endpoint. UserEndpointSettings userEndpointSettings = new UserEndpointSettings(ownerUri, m_settings.ProxyHost, m_settings.ProxyPort); UserEndpoint userEndpoint = new UserEndpoint(m_parent.Platform, userEndpointSettings); myUserEndpoint = new MyUserEndpoint(userEndpoint); m_userEndpoints.Add(ownerAddress, myUserEndpoint); m_userEndpointReferenceCounts.Add(ownerAddress, 1); myUserEndpoint.UserEndpoint.StateChanged += UserEndpointStateChanged; // Ensures that only one registration per endpoint. } UserEndpointCreationActionResult result = new UserEndpointCreationActionResult(myUserEndpoint, null); task.TaskResult = result; // Store it for now. if (myUserEndpoint.UserEndpoint.State == LocalEndpointState.Established) { task.Complete(null, result); } else if (myUserEndpoint.UserEndpoint.State == LocalEndpointState.Establishing) { // Wait till the endpoint establish completes. lock (this.SyncRoot) { m_pendingUserEndpointCreationTasks.Add(task); } } else if (myUserEndpoint.UserEndpoint.State == LocalEndpointState.Idle) { AsyncTask establishTask = new AsyncTask(this.StartupUserEndpoint, myUserEndpoint.UserEndpoint); establishTask.TaskCompleted += delegate(object sender, AsyncTaskCompletedEventArgs e) { task.TaskResult.Exception = e.ActionResult.Exception; // Transfer task.Complete(e.ActionResult.Exception, task.TaskResult); lock (this.SyncRoot) { // Complete pending tasks foreach (AsyncTask pendingTask in m_pendingUserEndpointCreationTasks) { pendingTask.TaskResult.Exception = e.ActionResult.Exception; pendingTask.Complete(e.ActionResult.Exception, pendingTask.TaskResult); } m_pendingUserEndpointCreationTasks.Clear(); } }; establishTask.StartTask(); } } }
public override async Task<AcdActionResult> Execute(LocalEndpoint localEndpoint, AudioVideoCall call, CancellationToken cancellationToken) { if (Endpoint == null) return AcdActionResult.Continue; // extract information from incoming caller var callParticipant = call.RemoteEndpoint.Participant; var callAddress = new RealTimeAddress(callParticipant.Uri, localEndpoint.DefaultDomain, localEndpoint.PhoneContext); var callSipUri = new SipUriParser(callAddress.Uri); callSipUri.RemoveParameter(new SipUriParameter("user", "phone")); var callUri = callSipUri.ToString(); var callPhoneUri = callParticipant.OtherPhoneUri; var callName = callParticipant.DisplayName; // impersonate incoming caller to agent var remoteConversation = new Conversation(localEndpoint); remoteConversation.Impersonate(callUri, callPhoneUri, callName); // establish call to endpoint var remoteCall = new AudioVideoCall(remoteConversation); var remoteOpts = new CallEstablishOptions(); remoteOpts.Transferor = localEndpoint.OwnerUri; remoteOpts.Headers.Add(new SignalingHeader("Ms-Target-Class", "secondary")); // initiate call with duration var destCallT = remoteCall.EstablishAsync(Endpoint.Uri, remoteOpts, cancellationToken); try { // wait for agent call to complete await destCallT; } catch (OperationCanceledException) { // ignore } catch (RealTimeException) { // ignore } // ensure two accepted transfers cannot both complete using (var lck = await call.GetContext<AsyncLock>().LockAsync()) if (call.State == CallState.Established) if (remoteCall.State == CallState.Established) { var participant = remoteConversation.RemoteParticipants.FirstOrDefault(); if (participant != null) { var endpoint = participant.GetEndpoints().FirstOrDefault(i => i.EndpointType == EndpointType.User); if (endpoint != null) { var ctx = new ConversationContextChannel(remoteConversation, endpoint); // establish conversation context with application await ctx.EstablishAsync( new Guid("FA44026B-CC48-42DA-AAA8-B849BCB43A21"), new ConversationContextChannelEstablishOptions()); // send context data await ctx.SendDataAsync( new ContentType("text/plain"), Encoding.UTF8.GetBytes("Id=123")); } } return await TransferAsync(call, remoteCall); } // terminate outbound call if still available if (remoteCall.State != CallState.Terminating && remoteCall.State != CallState.Terminated) await remoteCall.TerminateAsync(); // we could not complete the transfer attempt return AcdActionResult.Continue; }