private void Answered(SDP sdp) { Console.WriteLine("XMPP client call answered."); IsUACAnswered = true; SIPResponse okResponse = new SIPResponse(SIPResponseStatusCodesEnum.Ok, "Ok", new SIPEndPoint(new IPEndPoint(IPAddress.Loopback, 0))); okResponse.Header.ContentType = SDP.SDP_MIME_CONTENTTYPE; okResponse.Body = sdp.ToString(); SIPDialogue = new SIPDialogue(null, null, null, null, -1, null, null, null, Guid.NewGuid(), Owner, AdminMemberId, null, sdp.ToString()); SIPDialogue.CallDurationLimit = CallDescriptor.CallDurationLimit; CallAnswered(this, okResponse); }
public SIPEventSubscription( SIPMonitorLogDelegate log, string sessionID, SIPURI resourceURI, SIPURI canonicalResourceURI, string filter, SIPDialogue subscriptionDialogue, int expiry) { MonitorLogEvent_External = log; SessionID = sessionID; ResourceURI = resourceURI; CanonicalResourceURI = canonicalResourceURI; Filter = filter; SubscriptionDialogue = subscriptionDialogue; Expiry = expiry; }
public SIPDialogEventSubscription( SIPMonitorLogDelegate log, string sessionID, SIPURI resourceURI, SIPURI canonincalResourceURI, string filter, SIPDialogue subscriptionDialogue, int expiry, SIPAssetGetListDelegate<SIPDialogueAsset> getDialogues, SIPAssetGetByIdDelegate<SIPDialogueAsset> getDialogue ) : base(log, sessionID, resourceURI, canonincalResourceURI, filter, subscriptionDialogue, expiry) { GetDialogues_External = getDialogues; GetDialogue_External = getDialogue; DialogInfo = new SIPEventDialogInfo(0, SIPEventDialogInfoStateEnum.full, resourceURI); }
public SIPPresenceEventSubscription( SIPMonitorLogDelegate log, string sessionID, SIPURI resourceURI, SIPURI canonincalResourceURI, string filter, SIPDialogue subscriptionDialogue, int expiry, SIPAssetPersistor<SIPAccount> sipAccountPersistor, SIPAssetCountDelegate<SIPRegistrarBinding> getBindingsCount, bool switchboardSIPAccountsOnly ) : base(log, sessionID, resourceURI, canonincalResourceURI, filter, subscriptionDialogue, expiry) { m_sipAccountPersistor = sipAccountPersistor; GetSIPRegistrarBindingsCount_External = getBindingsCount; Presence = new SIPEventPresence(resourceURI); m_switchboardSIPAccountsOnly = switchboardSIPAccountsOnly; }
public SIPTransferServerUserAgent( SIPMonitorLogDelegate logDelegate, BlindTransferDelegate blindTransfer, SIPTransport sipTransport, SIPEndPoint outboundProxy, SIPDialogue dialogueToReplace, SIPDialogue oppositeDialogue, string callDestination, string owner, string adminID) { Log_External = logDelegate; BlindTransfer_External = blindTransfer; m_sipTransport = sipTransport; m_outboundProxy = outboundProxy; m_dialogueToReplace = dialogueToReplace; m_oppositeDialogue = oppositeDialogue; m_callDestination = callDestination; m_owner = owner; m_adminID = adminID; m_dummyRequest = CreateDummyRequest(m_dialogueToReplace, m_callDestination); }
public SIPDialogue Answer(string contentType, string body, string toTag, SIPDialogueTransferModesEnum transferMode, string[] customHeaders) { try { m_transferMode = transferMode; if (m_uasTransaction.TransactionFinalResponse != null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "UAS Answer was called on an already answered call, ignoring.", m_owner)); return(null); } else { UASStateChanged?.Invoke(this, SIPResponseStatusCodesEnum.Ok, null); if (!toTag.IsNullOrBlank()) { m_uasTransaction.LocalTag = toTag; } SIPResponse okResponse = m_uasTransaction.GetOkResponse(contentType, body); if (body != null) { okResponse.Header.ContentType = contentType; okResponse.Header.ContentLength = body.Length; okResponse.Body = body; } if (customHeaders != null && customHeaders.Length > 0) { foreach (string header in customHeaders) { okResponse.Header.UnknownHeaders.Add(header); } } if (OfferSDP == null) { // The INVITE request did not contain an SDP offer. We need to send the offer in the response and // then get the answer from the ACK. m_uasTransaction.OnAckReceived += OnAckAnswerReceived; } m_uasTransaction.SendFinalResponse(okResponse); if (OfferSDP != null) { SIPDialogue = new SIPDialogue(m_uasTransaction, m_owner, m_adminMemberId); SIPDialogue.TransferMode = transferMode; OnDialogueCreated?.Invoke(SIPDialogue); return(SIPDialogue); } else { // The dialogue cannot be created until the ACK is received. return(null); } } } catch (Exception excp) { logger.LogError("Exception SIPServerUserAgent Answer. " + excp.Message); throw; } }
public SIPDialogue Answer(string contentType, string body, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode) { try { logger.Debug("SIPB2BUserAgent Answer."); m_sipDialogue = answeredDialogue; if (UASStateChanged != null) { UASStateChanged(this, SIPResponseStatusCodesEnum.Ok, null); } SIPResponse uasOkResponse = SIPTransport.GetResponse(m_uasTransaction.TransactionRequest, SIPResponseStatusCodesEnum.Ok, null); m_uasTransaction.SendFinalResponse(uasOkResponse); m_uasTransaction.ACKReceived(m_blackhole, m_blackhole, null); SIPResponse uacOkResponse = SIPTransport.GetResponse(m_uacTransaction.TransactionRequest, SIPResponseStatusCodesEnum.Ok, null); uacOkResponse.Header.Contact = new List<SIPContactHeader>() { new SIPContactHeader(null, new SIPURI(SIPSchemesEnum.sip, m_blackhole)) }; m_uacTransaction.GotResponse(m_blackhole, m_blackhole, uacOkResponse); uacOkResponse.Header.ContentType = contentType; if (!body.IsNullOrBlank()) { uacOkResponse.Body = body; uacOkResponse.Header.ContentLength = body.Length; } CallAnswered((ISIPClientUserAgent)this, uacOkResponse); return null; } catch (Exception excp) { logger.Error("Exception SIPB2BUSerAgent Answer. " + excp.Message); throw; } }
public SIPDialogueAsset() { SIPDialogue = new SIPDialogue(); }
/// <summary> /// Sends a request to the remote call party to initiate an attended transfer. /// </summary> /// <param name="transferee">The dialog that will be replaced on the initial call party.</param> /// <returns>True if the transfer was accepted or false if not.</returns> public Task <bool> AttendedTransfer(SIPDialogue transferee) { return(m_userAgent.AttendedTransfer(transferee, TimeSpan.FromSeconds(TRANSFER_RESPONSE_TIMEOUT_SECONDS), _cts.Token)); }
private void UACCallAnswered(ISIPClientUserAgent answeredUAC, SIPResponse answeredResponse) { try { // Remove the current call from the pending list. lock (m_switchCalls) { m_switchCalls.Remove(answeredUAC); } if (m_switchCallTransactions != null && answeredUAC.ServerTransaction != null) { m_switchCallTransactions.Add(answeredUAC.ServerTransaction); } if (answeredResponse != null && answeredResponse.StatusCode >= 200 && answeredResponse.StatusCode <= 299) { #region 2xx final response. if (!m_callAnswered && !m_commandCancelled) { // This is the first call we've got an answer on. m_callAnswered = true; m_answeredUAC = answeredUAC; AnsweredSIPResponse = answeredResponse; SIPDialogueTransferModesEnum uasTransferMode = SIPDialogueTransferModesEnum.Default; if (m_answeredUAC.CallDescriptor.TransferMode == SIPDialogueTransferModesEnum.NotAllowed) { answeredUAC.SIPDialogue.TransferMode = SIPDialogueTransferModesEnum.NotAllowed; uasTransferMode = SIPDialogueTransferModesEnum.NotAllowed; } else if (m_answeredUAC.CallDescriptor.TransferMode == SIPDialogueTransferModesEnum.BlindPlaceCall) { answeredUAC.SIPDialogue.TransferMode = SIPDialogueTransferModesEnum.BlindPlaceCall; uasTransferMode = SIPDialogueTransferModesEnum.BlindPlaceCall; } else if (m_answeredUAC.CallDescriptor.TransferMode == SIPDialogueTransferModesEnum.PassThru) { answeredUAC.SIPDialogue.TransferMode = SIPDialogueTransferModesEnum.PassThru; uasTransferMode = SIPDialogueTransferModesEnum.PassThru; } /*else if (m_answeredUAC.CallDescriptor.TransferMode == SIPCallTransferModesEnum.Caller) * { * answeredUAC.SIPDialogue.TransferMode = SIPDialogueTransferModesEnum.NotAllowed; * uasTransferMode = SIPDialogueTransferModesEnum.Allowed; * } * else if (m_answeredUAC.CallDescriptor.TransferMode == SIPCallTransferModesEnum.Callee) * { * answeredUAC.SIPDialogue.TransferMode = SIPDialogueTransferModesEnum.Allowed; * uasTransferMode = SIPDialogueTransferModesEnum.NotAllowed; * } * else if (m_answeredUAC.CallDescriptor.TransferMode == SIPCallTransferModesEnum.Both) * { * answeredUAC.SIPDialogue.TransferMode = SIPDialogueTransferModesEnum.Allowed; * uasTransferMode = SIPDialogueTransferModesEnum.Allowed; * }*/ if (CallAnswered != null) { logger.Debug("Transfer mode=" + m_answeredUAC.CallDescriptor.TransferMode + "."); CallAnswered(answeredResponse.Status, answeredResponse.ReasonPhrase, null, null, answeredResponse.Header.ContentType, answeredResponse.Body, answeredUAC.SIPDialogue, uasTransferMode); if (answeredUAC.CallDescriptor.ImmediateReinvite == true) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, $"Initiating re-INVITE request due to dial string options.", m_username)); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, $"Re-sending SDP: {answeredUAC.SIPDialogue.SDP}", m_username)); SIPDialogue dummyDialogue = new SIPDialogue(); dummyDialogue.RemoteSDP = answeredUAC.SIPDialogue.SDP; m_callManager.ReInvite(answeredUAC.SIPDialogue, dummyDialogue); } } // Cancel/hangup and other calls on this leg that are still around. CancelNotRequiredCallLegs(CallCancelCause.NormalClearing); } else { // Call already answered or cancelled, hangup (send BYE). FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Call leg " + answeredUAC.CallDescriptor.Uri + " answered but call was already answered or cancelled, hanging up.", m_username)); SIPDialogue sipDialogue = new SIPDialogue(answeredUAC.ServerTransaction, m_username, m_adminMemberId); sipDialogue.Hangup(m_sipTransport, m_outboundProxySocket); } #endregion CallLegCompleted(); } else if (answeredUAC.SIPDialogue != null) { // Google Voice calls create the dialogue without using a SIP response. if (!m_callAnswered && !m_commandCancelled) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Call leg for Google Voice call to " + answeredUAC.CallDescriptor.Uri + " answered.", m_username)); // This is the first call we've got an answer on. m_callAnswered = true; m_answeredUAC = answeredUAC; CallAnswered?.Invoke(SIPResponseStatusCodesEnum.Ok, null, null, null, answeredUAC.SIPDialogue.ContentType, answeredUAC.SIPDialogue.RemoteSDP, answeredUAC.SIPDialogue, SIPDialogueTransferModesEnum.NotAllowed); // Cancel/hangup and other calls on this leg that are still around. CancelNotRequiredCallLegs(CallCancelCause.NormalClearing); } else { // Call already answered or cancelled, hangup (send BYE). FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Call leg for Google Voice call to " + answeredUAC.CallDescriptor.Uri + " answered but call was already answered or cancelled, hanging up.", m_username)); answeredUAC.SIPDialogue.Hangup(m_sipTransport, m_outboundProxySocket); } } else if (answeredResponse != null && answeredResponse.StatusCode >= 300 && answeredResponse.StatusCode <= 399) { ProcessRedirect(answeredUAC, answeredResponse); } else if (answeredResponse != null) { // This call leg failed, record the failure status and reason. m_lastFailureStatus = answeredResponse.Status; m_lastFailureReason = answeredResponse.ReasonPhrase; if (m_switchCallTransactions != null && answeredUAC.ServerTransaction != null) { m_switchCallTransactions.Add(answeredUAC.ServerTransaction); } CallLegCompleted(); } } catch (Exception excp) { logger.Error("Exception ForkCall UACCallAnswered. " + excp); } }
public SIPDialogue Answer(string contentType, string body, string toTag, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode) { TransactionComplete.Invoke(this); throw new NotImplementedException(); }
public SIPDialogue Answer(string contentType, string body, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode) { NoRingTimeout.Invoke(this); throw new NotImplementedException(); }
public SIPDialogueAsset(SIPDialogue sipDialogue) { SIPDialogue = sipDialogue; }
public void Load(DataRow row) { SIPDialogue = new SIPDialogue(); SIPDialogue.Id = new Guid(row["id"] as string); SIPDialogue.Owner = row["owner"] as string; SIPDialogue.AdminMemberId = row["adminmemberid"] as string; SIPDialogue.LocalTag = row["localtag"] as string; SIPDialogue.RemoteTag = row["remotetag"] as string; SIPDialogue.LocalUserField = SIPUserField.ParseSIPUserField(row["localuserfield"] as string); SIPDialogue.RemoteUserField = SIPUserField.ParseSIPUserField(row["remoteuserfield"] as string); SIPDialogue.CallId = row["callid"] as string; SIPDialogue.CSeq = Convert.ToInt32(row["cseq"]); SIPDialogue.BridgeId = new Guid(row["bridgeid"] as string); SIPDialogue.RemoteTarget = SIPURI.ParseSIPURI(row["remotetarget"] as string); SIPDialogue.RouteSet = (row["routeset"] != null && row["routeset"] != DBNull.Value && !(row["routeset"] as string).IsNullOrBlank()) ? SIPRouteSet.ParseSIPRouteSet(row["routeset"] as string) : null; SIPDialogue.ProxySendFrom = (row["proxysipsocket"] != null && row["proxysipsocket"] != DBNull.Value) ? row["proxysipsocket"] as string : null; SIPDialogue.CDRId = new Guid(row["cdrid"] as string); SIPDialogue.CallDurationLimit = (row["calldurationlimit"] != null && row["calldurationlimit"] != DBNull.Value) ? Convert.ToInt32(row["calldurationlimit"]) : 0; SIPDialogue.Direction = (row["direction"] != null) ? (SIPCallDirection)Enum.Parse(typeof(SIPCallDirection), row["direction"] as string, true) : SIPCallDirection.None; Inserted = DateTimeOffset.Parse(row["inserted"] as string); TransferMode = row["transfermode"] as string; SDP = row["sdp"] as string; RemoteSDP = row["remotesdp"] as string; //SIPDialogue.SwitchboardCallerDescription = (row["switchboardcallerdescription"] != null && row["switchboardcallerdescription"] != DBNull.Value) ? row["switchboardcallerdescription"] as string : null; //SIPDialogue.SwitchboardDescription = (row["switchboarddescription"] != null && row["switchboarddescription"] != DBNull.Value) ? row["switchboarddescription"] as string : null; SIPDialogue.SwitchboardOwner = (row["switchboardowner"] != null && row["switchboardowner"] != DBNull.Value) ? row["switchboardowner"] as string : null; SIPDialogue.SwitchboardLineName = (row["switchboardlinename"] != null && row["switchboardlinename"] != DBNull.Value) ? row["switchboardlinename"] as string : null; SIPDialogue.CRMPersonName = (row["crmpersonname"] != null && row["crmpersonname"] != DBNull.Value) ? row["crmpersonname"] as string : null; SIPDialogue.CRMCompanyName = (row["crmcompanyname"] != null && row["crmcompanyname"] != DBNull.Value) ? row["crmcompanyname"] as string : null; SIPDialogue.CRMPictureURL = (row["crmpictureurl"] != null && row["crmpictureurl"] != DBNull.Value) ? row["crmpictureurl"] as string : null; }
public void Load(XElement dialogueElement) { SIPDialogue = new SIPDialogue(); SIPDialogue.Id = new Guid(dialogueElement.Element("id").Value); SIPDialogue.Owner = dialogueElement.Element("owner").Value; SIPDialogue.AdminMemberId = dialogueElement.Element("adminmemberid").Value; SIPDialogue.LocalTag = dialogueElement.Element("localtag").Value; SIPDialogue.RemoteTag = dialogueElement.Element("remotetag").Value; SIPDialogue.LocalUserField = SIPUserField.ParseSIPUserField(dialogueElement.Element("localuserfield").Value); SIPDialogue.RemoteUserField = SIPUserField.ParseSIPUserField(dialogueElement.Element("remoteuserfield").Value); SIPDialogue.CallId = dialogueElement.Element("callid").Value; SIPDialogue.CSeq = Convert.ToInt32(dialogueElement.Element("cseq").Value); SIPDialogue.BridgeId = new Guid(dialogueElement.Element("bridgeid").Value); SIPDialogue.RemoteTarget = SIPURI.ParseSIPURI(dialogueElement.Element("remotetarget").Value); SIPDialogue.RouteSet = (dialogueElement.Element("routeset") != null && !dialogueElement.Element("routeset").Value.IsNullOrBlank()) ? SIPRouteSet.ParseSIPRouteSet(dialogueElement.Element("routeset").Value) : null; SIPDialogue.ProxySendFrom = (dialogueElement.Element("proxysipsocket") != null) ? dialogueElement.Element("proxysipsocket").Value : null; SIPDialogue.CDRId = new Guid(dialogueElement.Element("cdrid").Value); SIPDialogue.CallDurationLimit = (dialogueElement.Element("calldurationlimit") != null) ? Convert.ToInt32(dialogueElement.Element("calldurationlimit").Value) : 0; SIPDialogue.Direction = (dialogueElement.Element("direction") != null) ? (SIPCallDirection)Enum.Parse(typeof(SIPCallDirection), dialogueElement.Element("direction").Value, true) : SIPCallDirection.None; Inserted = DateTimeOffset.Parse(dialogueElement.Element("inserted").Value); TransferMode = dialogueElement.Element("transfermode").Value; SDP = dialogueElement.Element("sdp").Value; RemoteSDP = dialogueElement.Element("remotesdp").Value; //SIPDialogue.SwitchboardCallerDescription = (dialogueElement.Element("switchboardcallerdescription") != null) ? dialogueElement.Element("switchboardcallerdescription").Value : null; //SIPDialogue.SwitchboardDescription = (dialogueElement.Element("switchboarddescription") != null) ? dialogueElement.Element("switchboarddescription").Value : null; SIPDialogue.SwitchboardOwner = (dialogueElement.Element("switchboardowner") != null) ? dialogueElement.Element("switchboardowner").Value : null; SIPDialogue.SwitchboardLineName = (dialogueElement.Element("switchboardlinename") != null) ? dialogueElement.Element("switchboardlinename").Value : null; SIPDialogue.CRMPersonName = (dialogueElement.Element("crmpersonname") != null) ? dialogueElement.Element("crmpersonname").Value : null; SIPDialogue.CRMCompanyName = (dialogueElement.Element("crmcompanyname") != null) ? dialogueElement.Element("crmcompanyname").Value : null; SIPDialogue.CRMPictureURL = (dialogueElement.Element("crmpictureurl") != null) ? dialogueElement.Element("crmpictureurl").Value : null; }
/// <summary> /// Cleans up after a SIP call has completely finished. /// </summary> private void CallFinished(SIPDialogue dialogue) { m_pendingIncomingCall = null; CallEnded(this); }
public SIPDialogue Answer(string contentType, string body, string toTag, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode) { throw new NotImplementedException(); }
public SIPDialogue Answer(string contentType, string body, string toTag, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode) { return Answer(contentType, body, answeredDialogue, transferMode); }
public SIPDialogue Answer(string contentType, string body, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode) { return(Answer(contentType, body, null, answeredDialogue, transferMode)); }
public SIPDialogue Answer(string contentType, string body, string toTag, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode) { try { if (m_uasTransaction.TransactionFinalResponse != null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "UAS Answer was called on an already answered call, ignoring.", m_owner)); return null; } else { if (UASStateChanged != null) { UASStateChanged(this, SIPResponseStatusCodesEnum.Ok, null); } if (!toTag.IsNullOrBlank()) { m_uasTransaction.SetLocalTag(toTag); } SIPResponse okResponse = m_uasTransaction.GetOkResponse(m_uasTransaction.TransactionRequest, m_uasTransaction.TransactionRequest.LocalSIPEndPoint, contentType, body); if (body != null) { okResponse.Header.ContentType = contentType; okResponse.Header.ContentLength = body.Length; okResponse.Body = body; } m_uasTransaction.SendFinalResponse(okResponse); m_sipDialogue = new SIPDialogue(m_uasTransaction, m_owner, m_adminMemberId); m_sipDialogue.TransferMode = transferMode; return m_sipDialogue; } } catch (Exception excp) { logger.Error("Exception SIPServerUserAgent Answer. " + excp.Message); throw; } }
private void ServerFinalResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { //if (Thread.CurrentThread.Name.IsNullOrBlank()) //{ // Thread.CurrentThread.Name = THREAD_NAME + DateTime.Now.ToString("HHmmss") + "-" + Crypto.GetRandomString(3); //} Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Response " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + " for " + m_serverTransaction.TransactionRequest.URI.ToString() + ".", Owner)); //m_sipTrace += "Received " + DateTime.Now.ToString("dd MMM yyyy HH:mm:ss") + " " + localEndPoint + "<-" + remoteEndPoint + "\r\n" + sipResponse.ToString(); m_serverTransaction.UACInviteTransactionInformationResponseReceived -= ServerInformationResponseReceived; m_serverTransaction.UACInviteTransactionFinalResponseReceived -= ServerFinalResponseReceived; m_serverTransaction.TransactionTraceMessage -= TransactionTraceMessage; if (m_callCancelled && sipResponse.Status == SIPResponseStatusCodesEnum.RequestTerminated) { // No action required. Correctly received request terminated on an INVITE we cancelled. } else if (m_callCancelled) { #region Call has been cancelled, hangup. if (m_hungupOnCancel) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "A cancelled call to " + m_sipCallDescriptor.Uri + " has been answered AND has already been hungup, no further action being taken.", Owner)); } else { m_hungupOnCancel = true; Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "A cancelled call to " + m_sipCallDescriptor.Uri + " has been answered, hanging up.", Owner)); if (sipResponse.Header.Contact != null && sipResponse.Header.Contact.Count > 0) { SIPURI byeURI = sipResponse.Header.Contact[0].ContactURI; SIPRequest byeRequest = GetByeRequest(sipResponse, byeURI, localSIPEndPoint); //SIPEndPoint byeEndPoint = m_sipTransport.GetRequestEndPoint(byeRequest, m_outboundProxy, true); // if (byeEndPoint != null) // { SIPNonInviteTransaction byeTransaction = m_sipTransport.CreateNonInviteTransaction(byeRequest, null, localSIPEndPoint, m_outboundProxy); byeTransaction.SendReliableRequest(); // } // else // { // Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Could not end BYE on cancelled call as request end point could not be determined " + byeRequest.URI.ToString(), Owner)); //} } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "No contact header provided on response for cancelled call to " + m_sipCallDescriptor.Uri + " no further action.", Owner)); } } #endregion } else if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised) { //logger.Debug("AuthReqd Final response " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + " for " + m_serverTransaction.TransactionRequest.URI.ToString() + "."); #region Authenticate client call to third party server. if (!m_callCancelled) { if (m_sipCallDescriptor.Password.IsNullOrBlank()) { // No point trying to authenticate if there is no password to use. Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Forward leg failed, authentication was requested but no credentials were available.", Owner)); FireCallFailed(this, "Authentication requested when no credentials available"); } else if (m_serverAuthAttempts == 0) { m_serverAuthAttempts = 1; // Resend INVITE with credentials. string username = (m_sipCallDescriptor.AuthUsername != null && m_sipCallDescriptor.AuthUsername.Trim().Length > 0) ? m_sipCallDescriptor.AuthUsername : m_sipCallDescriptor.Username; SIPAuthorisationDigest authRequest = sipResponse.Header.AuthenticationHeader.SIPDigest; authRequest.SetCredentials(username, m_sipCallDescriptor.Password, m_sipCallDescriptor.Uri, SIPMethodsEnum.INVITE.ToString()); SIPRequest authInviteRequest = m_serverTransaction.TransactionRequest; //if (SIPProviderMagicJack.IsMagicJackRequest(sipResponse)) //{ // authInviteRequest.Header.AuthenticationHeader = SIPProviderMagicJack.GetAuthenticationHeader(sipResponse); //} //else //{ authInviteRequest.Header.AuthenticationHeader = new SIPAuthenticationHeader(authRequest); authInviteRequest.Header.AuthenticationHeader.SIPDigest.Response = authRequest.Digest; //} authInviteRequest.Header.Vias.TopViaHeader.Branch = CallProperties.CreateBranchId(); authInviteRequest.Header.CSeq = authInviteRequest.Header.CSeq + 1; // Create a new UAC transaction to establish the authenticated server call. var originalCallTransaction = m_serverTransaction; m_serverTransaction = m_sipTransport.CreateUACTransaction(authInviteRequest, m_serverEndPoint, localSIPEndPoint, m_outboundProxy); if (m_serverTransaction.CDR != null) { m_serverTransaction.CDR.Owner = Owner; m_serverTransaction.CDR.AdminMemberId = AdminMemberId; m_serverTransaction.CDR.DialPlanContextID = m_sipCallDescriptor.DialPlanContextID; m_serverTransaction.CDR.Updated(); if (AccountCode != null) { //var rtccCDR = new SIPSorcery.Entities.CDR() //{ // ID = m_serverTransaction.CDR.CDRId.ToString(), // Owner = m_serverTransaction.CDR.Owner, // AdminMemberID = m_serverTransaction.CDR.AdminMemberId, // Inserted = DateTimeOffset.UtcNow.ToString("o"), // Created = DateTimeOffset.UtcNow.ToString("o"), // DstHost = "", // DstURI = m_sipCallDescriptor.Uri, // CallID = "", // FromHeader = m_sipCallDescriptor.From, // LocalSocket = "udp:0.0.0.0:5060", // RemoteSocket = "udp:0.0.0.0:5060", // Direction = m_serverTransaction.CDR.CallDirection.ToString(), // DialPlanContextID = m_sipCallDescriptor.DialPlanContextID.ToString() //}; #if !SILVERLIGHT && !MIN_BUILD m_customerAccountDataLayer.UpdateRealTimeCallControlCDRID(originalCallTransaction.CDR.CDRId.ToString(), m_serverTransaction.CDR); #endif //m_serverTransaction.CDR.AccountCode = AccountCode; //m_serverTransaction.CDR.Rate = Rate; // Transfer any credit reservations from the original call to the new call. //m_serverTransaction.CDR.SecondsReserved = originalCallTransaction.CDR.SecondsReserved; //m_serverTransaction.CDR.Cost = originalCallTransaction.CDR.Cost; //m_serverTransaction.CDR.IncrementSeconds = originalCallTransaction.CDR.IncrementSeconds; //originalCallTransaction.CDR.SecondsReserved = 0; //originalCallTransaction.CDR.Cost = 0; //originalCallTransaction.CDR.ReconciliationResult = "reallocated"; //originalCallTransaction.CDR.IsHangingUp = true; } logger.Debug("RTCC reservation was reallocated from CDR " + originalCallTransaction.CDR.CDRId + " to " + m_serverTransaction.CDR.CDRId + " for owner " + Owner + "."); } m_serverTransaction.UACInviteTransactionInformationResponseReceived += ServerInformationResponseReceived; m_serverTransaction.UACInviteTransactionFinalResponseReceived += ServerFinalResponseReceived; m_serverTransaction.UACInviteTransactionTimedOut += ServerTimedOut; m_serverTransaction.TransactionTraceMessage += TransactionTraceMessage; //logger.Debug("Sending authenticated switchcall INVITE to " + ForwardedCallStruct.Host + "."); m_serverTransaction.SendInviteRequest(m_serverEndPoint, authInviteRequest); //m_sipTrace += "Sending " + DateTime.Now.ToString("dd MMM yyyy HH:mm:ss") + " " + localEndPoint + "->" + ForwardedTransaction.TransactionRequest.GetRequestEndPoint() + "\r\n" + ForwardedTransaction.TransactionRequest.ToString(); } else { //logger.Debug("Authentication of client call to switch server failed."); FireCallFailed(this, "Authentication with provided credentials failed"); } } #endregion } else { if (sipResponse.StatusCode >= 200 && sipResponse.StatusCode <= 299) { if (sipResponse.Body.IsNullOrBlank()) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Body on UAC response was empty.", Owner)); } else if (m_sipCallDescriptor.ContentType == m_sdpContentType) { if (!m_sipCallDescriptor.MangleResponseSDP) { IPEndPoint sdpEndPoint = SDP.GetSDPRTPEndPoint(sipResponse.Body); string sdpSocket = (sdpEndPoint != null) ? sdpEndPoint.ToString() : "could not determine"; Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "SDP on UAC response was set to NOT mangle, RTP socket " + sdpEndPoint.ToString() + ".", Owner)); } else { //m_callInProgress = false; // the call is now established //logger.Debug("Final response " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + " for " + ForwardedTransaction.TransactionRequest.URI.ToString() + "."); // Determine of response SDP should be mangled. IPEndPoint sdpEndPoint = SDP.GetSDPRTPEndPoint(sipResponse.Body); //Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "UAC response SDP was mangled from sdp=" + sdpEndPoint.Address.ToString() + ", proxyfrom=" + sipResponse.Header.ProxyReceivedFrom + ", mangle=" + m_sipCallDescriptor.MangleResponseSDP + ".", null)); if (sdpEndPoint != null) { if (!IPSocket.IsPrivateAddress(sdpEndPoint.Address.ToString())) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "SDP on UAC response had public IP not mangled, RTP socket " + sdpEndPoint.ToString() + ".", Owner)); } else { bool wasSDPMangled = false; string publicIPAddress = null; if (!sipResponse.Header.ProxyReceivedFrom.IsNullOrBlank()) { IPAddress remoteUASAddress = SIPEndPoint.ParseSIPEndPoint(sipResponse.Header.ProxyReceivedFrom).Address; if (IPSocket.IsPrivateAddress(remoteUASAddress.ToString()) && m_sipCallDescriptor.MangleIPAddress != null) { // If the response has arrived here on a private IP address then it must be // for a local version install and an incoming call that needs it's response mangled. if(!IPSocket.IsPrivateAddress(m_sipCallDescriptor.MangleIPAddress.ToString())) { publicIPAddress = m_sipCallDescriptor.MangleIPAddress.ToString(); } } else { publicIPAddress = remoteUASAddress.ToString(); } } else if (!IPSocket.IsPrivateAddress(remoteEndPoint.Address.ToString()) && remoteEndPoint.Address != IPAddress.Any) { publicIPAddress = remoteEndPoint.Address.ToString(); } else if (m_sipCallDescriptor.MangleIPAddress != null) { publicIPAddress = m_sipCallDescriptor.MangleIPAddress.ToString(); } if (publicIPAddress != null) { sipResponse.Body = SIPPacketMangler.MangleSDP(sipResponse.Body, publicIPAddress, out wasSDPMangled); } if (wasSDPMangled) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "SDP on UAC response had RTP socket mangled from " + sdpEndPoint.ToString() + " to " + publicIPAddress + ":" + sdpEndPoint.Port + ".", Owner)); } else if (sdpEndPoint != null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "SDP on UAC response could not be mangled, RTP socket " + sdpEndPoint.ToString() + ".", Owner)); } } } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "SDP RTP socket on UAC response could not be determined.", Owner)); } } } m_sipDialogue = new SIPDialogue(m_serverTransaction, Owner, AdminMemberId); m_sipDialogue.CallDurationLimit = m_sipCallDescriptor.CallDurationLimit; // Set switchboard dialogue values from the answered response or from dialplan set values. //m_sipDialogue.SwitchboardCallerDescription = sipResponse.Header.SwitchboardCallerDescription; m_sipDialogue.SwitchboardLineName = sipResponse.Header.SwitchboardLineName; m_sipDialogue.CRMPersonName = sipResponse.Header.CRMPersonName; m_sipDialogue.CRMCompanyName = sipResponse.Header.CRMCompanyName; m_sipDialogue.CRMPictureURL = sipResponse.Header.CRMPictureURL; if (m_sipCallDescriptor.SwitchboardHeaders != null) { //if (!m_sipCallDescriptor.SwitchboardHeaders.SwitchboardDialogueDescription.IsNullOrBlank()) //{ // m_sipDialogue.SwitchboardDescription = m_sipCallDescriptor.SwitchboardHeaders.SwitchboardDialogueDescription; //} m_sipDialogue.SwitchboardLineName = m_sipCallDescriptor.SwitchboardHeaders.SwitchboardLineName; m_sipDialogue.SwitchboardOwner = m_sipCallDescriptor.SwitchboardHeaders.SwitchboardOwner; } } FireCallAnswered(this, sipResponse); } } catch (Exception excp) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.Error, "Exception ServerFinalResponseReceived. " + excp.Message, Owner)); } }
/// <summary> /// An answer on a blind transfer means the remote end of the dialogue being replaced should be re-invited and then the replaced dialogue /// should be hungup. /// </summary> /// <param name="contentType"></param> /// <param name="body"></param> /// <param name="toTag"></param> /// <param name="answeredDialogue"></param> /// <param name="transferMode"></param> /// <returns></returns> public SIPDialogue Answer(string contentType, string body, string toTag, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode) { try { if (m_answered) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "A blind transfer received an answer on an already answered call, hanging up dialogue.", m_owner)); answeredDialogue.Hangup(m_sipTransport, m_outboundProxy); } else { m_answered = true; Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "A blind transfer received an answer.", m_owner)); if (UASStateChanged != null) { UASStateChanged(this, SIPResponseStatusCodesEnum.Ok, null); } BlindTransfer_External(m_dialogueToReplace, m_oppositeDialogue, answeredDialogue); } return null; } catch (Exception excp) { logger.Error("Exception SIPTransferServerUserAgent Answer. " + excp.Message); throw; } }
private SIPRequest CreateDummyRequest(SIPDialogue dialogueToReplace, string callDestination) { SIPRequest dummyInvite = new SIPRequest(SIPMethodsEnum.INVITE, SIPURI.ParseSIPURIRelaxed(callDestination + "@sipsorcery.com")); SIPHeader dummyHeader = new SIPHeader("<sip:[email protected]>", "<sip:[email protected]>", 1, CallProperties.CreateNewCallId()); dummyHeader.CSeqMethod = SIPMethodsEnum.INVITE; dummyHeader.Vias.PushViaHeader(new SIPViaHeader(new IPEndPoint(SIPTransport.BlackholeAddress, 0), CallProperties.CreateBranchId())); dummyInvite.Header = dummyHeader; dummyInvite.Header.ContentType = "application/sdp"; dummyInvite.Body = dialogueToReplace.SDP; return dummyInvite; }
public void CallAnswered(SIPResponseStatusCodesEnum answeredStatus, string reasonPhrase, string toTag, string[] customHeaders, string answeredContentType, string answeredBody, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum uasTransferMode) { try { if (!m_isAnswered) { m_isAnswered = true; Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Answering client call with a response status of " + (int)answeredStatus + ".", Owner)); SIPDialogue uasDialogue = m_sipServerUserAgent.Answer(answeredContentType, answeredBody, toTag, answeredDialogue, uasTransferMode); if (!m_sipServerUserAgent.IsB2B && answeredDialogue != null) { if (uasDialogue != null) { // Duplicate switchboard dialogue settings. uasDialogue.SwitchboardDescription = answeredDialogue.SwitchboardDescription; uasDialogue.SwitchboardCallerDescription = answeredDialogue.SwitchboardCallerDescription; uasDialogue.SwitchboardOwner = answeredDialogue.SwitchboardOwner; // Record the now established call with the call manager for in dialogue management and hangups. CreateBridge_External(uasDialogue, answeredDialogue, m_dialPlan.Owner); } else { logger.Warn("Failed to get a SIPDialogue from UAS.Answer."); } } } else { logger.Warn("DialPlanContext CallAnswered fired on already answered call."); } } catch (Exception excp) { logger.Error("Exception DialPlanContext CallAnswered. " + excp.Message); } finally { DialPlanExecutionFinished(); } }