private void SIPCancelTransaction_TransactionFinalResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { if (sipResponse.StatusCode < 200) { logger.Warn("A SIP CANCEL transaction received an unexpected SIP information response " + sipResponse.ReasonPhrase + "."); } else { if (CancelTransactionFinalResponseReceived != null) { CancelTransactionFinalResponseReceived(localSIPEndPoint, remoteEndPoint, sipTransaction, sipResponse); } } }
private Dictionary<string, DateTime> m_connectionFailures = new Dictionary<string, DateTime>(); // Tracks sockets that have had a connection failure on them to avoid endless re-connect attmepts. public SIPTCPChannel(IPEndPoint endPoint) { m_localSIPEndPoint = new SIPEndPoint(SIPProtocolsEnum.tcp, endPoint); LocalTCPSockets.Add(endPoint.ToString()); m_isReliable = true; Initialise(); }
private void SIPCancelTransaction_TransactionRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPRequest sipRequest) { try { //logger.Debug("CANCEL request received, attempting to locate and cancel transaction."); //UASInviteTransaction originalTransaction = (UASInviteTransaction)GetTransaction(GetRequestTransactionId(sipRequest.Header.Via.TopViaHeader.Branch, SIPMethodsEnum.INVITE)); SIPResponse cancelResponse; if (m_originalTransaction != null) { //logger.Debug("Transaction found to cancel " + originalTransaction.TransactionId + " type " + originalTransaction.TransactionType + "."); m_originalTransaction.CancelCall(); cancelResponse = GetCancelResponse(sipRequest, SIPResponseStatusCodesEnum.Ok); } else { cancelResponse = GetCancelResponse(sipRequest, SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist); } //UpdateTransactionState(SIPTransactionStatesEnum.Completed); SendFinalResponse(cancelResponse); } catch (Exception excp) { logger.Error("Exception SIPCancelTransaction GotRequest. " + excp.Message); } }
internal UASInviteTransaction( SIPTransport sipTransport, SIPRequest sipRequest, SIPEndPoint dstEndPoint, SIPEndPoint localSIPEndPoint, SIPEndPoint outboundProxy) : base(sipTransport, sipRequest, dstEndPoint, localSIPEndPoint, outboundProxy) { TransactionType = SIPTransactionTypesEnum.Invite; m_remoteTag = sipRequest.Header.From.FromTag; if (sipRequest.Header.To.ToTag == null) { // This UAS needs to set the To Tag. m_localTag = CallProperties.CreateNewTag(); } else { // This is a re-INVITE. m_localTag = sipRequest.Header.To.ToTag; } //logger.Debug("New UASTransaction (" + TransactionId + ") for " + TransactionRequest.URI.ToString() + " to " + RemoteEndPoint + "."); CDR = new SIPCDR(SIPCallDirection.In, sipRequest.URI, sipRequest.Header.From, sipRequest.Header.CallId, LocalSIPEndPoint, dstEndPoint); //UpdateTransactionState(SIPTransactionStatesEnum.Proceeding); TransactionRequestReceived += UASInviteTransaction_TransactionRequestReceived; TransactionInformationResponseReceived += UASInviteTransaction_TransactionResponseReceived; TransactionFinalResponseReceived += UASInviteTransaction_TransactionResponseReceived; TransactionTimedOut += UASInviteTransaction_TransactionTimedOut; TransactionRemoved += UASInviteTransaction_TransactionRemoved; }
public void RecordDispatch(SIPRequest sipRequest, SIPEndPoint internalEndPoint) { lock(m_transactionEndPoints) { if (m_transactionEndPoints.ContainsKey(sipRequest.Header.CallId)) { if (m_transactionEndPoints[sipRequest.Header.CallId] == internalEndPoint.ToString()) { // The application server end point has not changed for this Call-Id return; } else { // The application server end point has changed within the lifetime of the Call-Id. Remove the old mapping. lock (m_transactionEndPoints) { m_transactionEndPoints.Remove(sipRequest.Header.CallId); } } } m_transactionEndPoints.Add(sipRequest.Header.CallId, internalEndPoint.ToString()); m_transactionIDAddedAt.Add(sipRequest.Header.CallId, DateTime.Now); //ProxyLogger_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.SIPProxy, SIPMonitorEventTypesEnum.CallDispatcher, "Record dispatch for " + sipRequest.Method + " " + sipRequest.URI.ToString() + " to " + internalEndPoint.ToString() + " (id=" + transactionID + ").", null)); } if (m_lastRemove < DateTime.Now.AddSeconds(REMOVE_EXPIREDS_SECONDS * -1)) { RemoveExpiredDispatchRecords(); } }
public SIPAppServerWorker(XmlNode xmlConfigNode) { WorkerProcessPath = xmlConfigNode.SelectSingleNode("workerprocesspath").InnerText; WorkerProcessArgs = xmlConfigNode.SelectSingleNode("workerprocessargs").InnerText; AppServerEndpoint = SIPEndPoint.ParseSIPEndPoint(xmlConfigNode.SelectSingleNode("sipsocket").InnerText); CallManagerAddress = new EndpointAddress(xmlConfigNode.SelectSingleNode("callmanageraddress").InnerText); }
public IncomingMessage(SIPChannel sipChannel, SIPEndPoint remoteEndPoint, byte[] buffer) { LocalSIPChannel = sipChannel; RemoteEndPoint = remoteEndPoint; Buffer = buffer; ReceivedAt = DateTime.Now; }
private void SIPNonInviteTransaction_TransactionRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPRequest sipRequest) { if (NonInviteRequestReceived != null) { NonInviteRequestReceived(localSIPEndPoint, remoteEndPoint, this, sipRequest); } }
public static NATKeepAliveMessage ParseNATKeepAliveMessage(byte[] buffer) { if (buffer != null && buffer.Length == 20) { byte[] sendToAddrBuffer = new byte[4]; Buffer.BlockCopy(buffer, 0, sendToAddrBuffer, 0, 4); IPAddress sendToAddress = new IPAddress(sendToAddrBuffer); int sendToPort = BitConverter.ToInt32(buffer, 4); int proxyProtocol = BitConverter.ToInt32(buffer, 8); byte[] proxyFromAddrBuffer = new byte[4]; Buffer.BlockCopy(buffer, 12, proxyFromAddrBuffer, 0, 4); int sendFromPort = BitConverter.ToInt32(buffer, 16); SIPEndPoint proxySendFrom = new SIPEndPoint((SIPProtocolsEnum)proxyProtocol, new IPEndPoint(new IPAddress(proxyFromAddrBuffer), sendFromPort)); //SIPProtocolsEnum protocol = SIPProtocolsType.GetProtocolTypeFromId(BitConverter.ToInt32(buffer, 16)); //SIPProtocolsEnum protocol = SIPProtocolsEnum.udp; NATKeepAliveMessage natKeepAliveMsg = new NATKeepAliveMessage(proxySendFrom, new IPEndPoint(sendToAddress, sendToPort)); return natKeepAliveMsg; } else { return null; } }
//private SIPNotifyManager m_notifyManager; public SIPAppServerCore( SIPTransport sipTransport, GetCanonicalDomainDelegate getCanonicalDomain, SIPAssetGetDelegate<SIPAccount> getSIPAccount, SIPMonitorLogDelegate proxyLog, SIPCallManager callManager, SIPDialogueManager sipDialogueManager, //SIPNotifyManager notifyManager, SIPAuthenticateRequestDelegate sipAuthenticateRequest, SIPEndPoint outboundProxy) { try { m_sipTransport = sipTransport; m_callManager = callManager; m_sipDialogueManager = sipDialogueManager; //m_notifyManager = notifyManager; m_sipTransport.SIPTransportRequestReceived += GotRequest; m_sipTransport.SIPTransportResponseReceived += GotResponse; m_outboundProxy = outboundProxy; GetCanonicalDomain_External = getCanonicalDomain; GetSIPAccount_External = getSIPAccount; SIPMonitorLogEvent_External = proxyLog; SIPRequestAuthenticator_External = sipAuthenticateRequest; } catch (Exception excp) { logger.Error("Exception SIPAppServerCore (ctor). " + excp.Message); throw excp; } }
internal SIPCancelTransaction(SIPTransport sipTransport, SIPRequest sipRequest, SIPEndPoint dstEndPoint, SIPEndPoint localSIPEndPoint, UASInviteTransaction originalTransaction) : base(sipTransport, sipRequest, dstEndPoint, localSIPEndPoint, originalTransaction.OutboundProxy) { m_originalTransaction = originalTransaction; TransactionType = SIPTransactionTypesEnum.NonInvite; TransactionRequestReceived += SIPCancelTransaction_TransactionRequestReceived; TransactionFinalResponseReceived += SIPCancelTransaction_TransactionFinalResponseReceived; TransactionRemoved += SIPCancelTransaction_TransactionRemoved; }
public bool Cancel; // If set to true indicates the NAT keep alive job should be removed. public NATKeepAliveJob(SIPEndPoint proxyEndPoint, SIPEndPoint remoteEndPoint, DateTime endTime, string owner) { ProxyEndPoint = proxyEndPoint; RemoteEndPoint = remoteEndPoint; NextSendTime = null; EndTime = endTime; Owner = owner; Cancel = false; }
public bool IsAppServerEndPoint(SIPEndPoint remoteEndPoint) { if (m_appServerEndPoints == null || m_appServerEndPoints.Count == 0) { return false; } else { return m_appServerEndPoints.ContainsKey(remoteEndPoint.ToString()); } }
internal SIPNonInviteTransaction(SIPTransport sipTransport, SIPRequest sipRequest, SIPEndPoint dstEndPoint, SIPEndPoint localSIPEndPoint, SIPEndPoint outboundProxy) : base(sipTransport, sipRequest, dstEndPoint, localSIPEndPoint, outboundProxy) { TransactionType = SIPTransactionTypesEnum.NonInvite; TransactionRequestReceived += SIPNonInviteTransaction_TransactionRequestReceived; TransactionInformationResponseReceived += SIPNonInviteTransaction_TransactionInformationResponseReceived; TransactionFinalResponseReceived += SIPNonInviteTransaction_TransactionFinalResponseReceived; TransactionTimedOut += SIPNonInviteTransaction_TransactionTimedOut; TransactionRemoved += SIPNonInviteTransaction_TransactionRemoved; TransactionRequestRetransmit += SIPNonInviteTransaction_TransactionRequestRetransmit; }
internal UACInviteTransaction(SIPTransport sipTransport, SIPRequest sipRequest, SIPEndPoint dstEndPoint, SIPEndPoint localSIPEndPoint, SIPEndPoint outboundProxy) : base(sipTransport, sipRequest, dstEndPoint, localSIPEndPoint, outboundProxy) { TransactionType = SIPTransactionTypesEnum.Invite; m_localTag = sipRequest.Header.From.FromTag; CDR = new SIPCDR(SIPCallDirection.Out, sipRequest.URI, sipRequest.Header.From, sipRequest.Header.CallId, localSIPEndPoint, dstEndPoint); TransactionFinalResponseReceived += UACInviteTransaction_TransactionFinalResponseReceived; TransactionInformationResponseReceived += UACInviteTransaction_TransactionInformationResponseReceived; TransactionTimedOut += UACInviteTransaction_TransactionTimedOut; TransactionRequestReceived += UACInviteTransaction_TransactionRequestReceived; TransactionRemoved += UACInviteTransaction_TransactionRemoved; }
public GoogleVoiceUserAgent( SIPTransport sipTransport, ISIPCallManager callManager, SIPMonitorLogDelegate logDelegate, string username, string adminMemberId, SIPEndPoint outboundProxy) { Owner = username; AdminMemberId = adminMemberId; m_googleVoiceCall = new GoogleVoiceCall(sipTransport, callManager, logDelegate, username, adminMemberId, outboundProxy); m_googleVoiceCall.CallProgress += new CallProgressDelegate(CallProgress); }
public override bool IsSIPEndPointMonitored(SIPEndPoint sipEndPoint) { lock (m_activeAppServerEntry) { foreach (AppServerEntry appServerEntry in m_appServerEntries) { if (new SIPEndPoint(appServerEntry.AppServerURI).ToString() == sipEndPoint.ToString()) { return true; } } } return false; }
public DialPlanScriptContext( SIPMonitorLogDelegate monitorLogDelegate, SIPTransport sipTransport, DialogueBridgeCreatedDelegate createBridge, SIPEndPoint outboundProxy, ISIPServerUserAgent sipServerUserAgent, SIPDialPlan dialPlan, List<SIPProvider> sipProviders, string traceDirectory, string callersNetworkId, Guid customerId) : base(monitorLogDelegate, sipTransport, createBridge, outboundProxy, sipServerUserAgent, dialPlan, sipProviders, traceDirectory, callersNetworkId, customerId) { ContextType = DialPlanContextsEnum.Script; }
public SIPNonInviteClientUserAgent( SIPTransport sipTransport, SIPEndPoint outboundProxy, SIPCallDescriptor callDescriptor, string owner, string adminMemberID, SIPMonitorLogDelegate logDelegate) { m_sipTransport = sipTransport; m_outboundProxy = outboundProxy; m_callDescriptor = callDescriptor; m_owner = owner; m_adminMemberID = adminMemberID; Log_External = logDelegate; }
public SIPNotifyManager( SIPTransport sipTransport, SIPEndPoint outboundProxy, SIPMonitorLogDelegate logDelegate, SIPAssetGetDelegate<SIPAccount> getSIPAccount, SIPAssetGetListDelegate<SIPRegistrarBinding> getSIPAccountBindings, GetCanonicalDomainDelegate getCanonicalDomain) { m_sipTransport = sipTransport; m_outboundProxy = outboundProxy; Log_External = logDelegate; GetSIPAccount_External = getSIPAccount; GetSIPAccountBindings_External = getSIPAccountBindings; GetCanonicalDomain_External = getCanonicalDomain; ThreadPool.QueueUserWorkItem(delegate { ProcessNewNotifications(PROCESS_NOTIFICATIONS_THREAD_NAME); }); }
public CallbackApp( SIPTransport sipTransport, ISIPCallManager callManager, DialStringParser dialStringParser, SIPMonitorLogDelegate logDelegate, string username, string adminMemberId, SIPEndPoint outboundProxy) { m_sipTransport = sipTransport; m_callManager = callManager; m_dialStringParser = dialStringParser; Log_External = logDelegate; m_username = username; m_adminMemberId = adminMemberId; m_outboundProxy = outboundProxy; }
public DialPlanLineContext( SIPMonitorLogDelegate monitorLogDelegate, SIPTransport sipTransport, DialogueBridgeCreatedDelegate createBridge, SIPEndPoint outboundProxy, ISIPServerUserAgent sipServerUserAgent, SIPDialPlan dialPlan, List<SIPProvider> sipProviders, string traceDirectory, string callersNetworkId, Customer customer) : base(monitorLogDelegate, sipTransport, createBridge, outboundProxy, sipServerUserAgent, dialPlan, sipProviders, traceDirectory, callersNetworkId, customer, null, null) { ContextType = DialPlanContextsEnum.Line; string[] dialPlanEntries = dialPlan.DialPlanScript.Split(new char[] { '\n' }); ParseDialPlan(dialPlanEntries); }
public SIPEndPoint LocalSIPEndPoint; // The local SIP socket the message was received on or sent from. public static SIPMessage ParseSIPMessage(byte[] buffer, SIPEndPoint localSIPEndPoint, SIPEndPoint remoteSIPEndPoint) { string message = null; try { if(buffer == null || buffer.Length < m_minFirstLineLength) { // Ignore. return null; } else if (buffer.Length > SIPConstants.SIP_MAXIMUM_RECEIVE_LENGTH) { throw new ApplicationException("SIP message received that exceeded the maximum allowed message length, ignoring."); } else if(!ByteBufferInfo.HasString(buffer, 0, buffer.Length, SIP_MESSAGE_IDENTIFIER, m_CRLF)) { // Message does not contain "SIP" anywhere on the first line, ignore. return null; } else { message = Encoding.UTF8.GetString(buffer, 0, buffer.Length); SIPMessage sipMessage = ParseSIPMessage(message, localSIPEndPoint, remoteSIPEndPoint); if (sipMessage != null) { sipMessage.RawBuffer = buffer; return sipMessage; } else { return null; } } } catch(Exception excp) { message = message.Replace("\n", "LF"); message = message.Replace("\r", "CR"); logger.Error("Exception ParseSIPMessage. " + excp.Message + "\nSIP Message=" + message + "."); return null; } }
public SIPDialogueManager( SIPTransport sipTransport, SIPEndPoint outboundProxy, SIPMonitorLogDelegate logDelegate, SIPAssetPersistor<SIPDialogueAsset> sipDialoguePersistor, SIPAssetPersistor<SIPCDRAsset> sipCDRPersistor, SIPAuthenticateRequestDelegate authenticateRequestDelegate, SIPAssetGetDelegate<SIPAccount> getSIPAccount, GetCanonicalDomainDelegate getCanonicalDomain) { m_sipTransport = sipTransport; m_outboundProxy = outboundProxy; Log_External = logDelegate; m_sipDialoguePersistor = sipDialoguePersistor; m_sipCDRPersistor = sipCDRPersistor; SIPAuthenticateRequest_External = authenticateRequestDelegate; GetSIPAccount_External = getSIPAccount; GetCanonicalDomain_External = getCanonicalDomain; }
private Dictionary<string, SIPEventSubscription> m_subscriptions = new Dictionary<string, SIPEventSubscription>(); // [monitor session ID, subscription]. public NotifierSubscriptionsManager( SIPMonitorLogDelegate logDelegate, SIPAssetGetListDelegate<SIPDialogueAsset> getDialogues, SIPAssetGetByIdDelegate<SIPDialogueAsset> getDialogue, SIPAssetPersistor<SIPAccount> sipAssetPersistor, SIPAssetCountDelegate<SIPRegistrarBinding> getBindingsCount, SIPTransport sipTransport, SIPEndPoint outboundProxy, ISIPMonitorPublisher publisher) { MonitorLogEvent_External = logDelegate; GetDialogues_External = getDialogues; GetDialogue_External = getDialogue; GetSIPRegistrarBindingsCount_External = getBindingsCount; m_sipAssetPersistor = sipAssetPersistor; m_sipTransport = sipTransport; m_outboundProxy = outboundProxy; m_publisher = publisher; m_publisher.MonitorEventReady += MonitorEventAvailable; }
public SIPTLSChannel(X509Certificate2 serverCertificate, IPEndPoint endPoint) { if (serverCertificate == null) { throw new ArgumentNullException("serverCertificate", "An X509 certificate must be supplied for a SIP TLS channel."); } if (endPoint == null) { throw new ArgumentNullException("endPoint", "An IP end point must be supplied for a SIP TLS channel."); } m_localSIPEndPoint = new SIPEndPoint(SIPProtocolsEnum.tls, endPoint); LocalTCPSockets.Add(endPoint.ToString()); m_isReliable = true; m_isTLS = true; //m_certificatePath = certificateFileName; ///base.Name = "s" + Crypto.GetRandomInt(4); m_serverCertificate = serverCertificate; Initialise(); }
/// <summary> /// Asynchronous SIP message send to a remote end point. /// </summary> /// <param name="dstEndPoint">The remote end point to send the message to.</param> /// <param name="buffer">The data to send.</param> /// <param name="canInitiateConnection">Indicates whether this send should initiate a connection if needed. /// The typical case is SIP requests can initiate new connections but responses should not. Responses should /// only be sent on the same TCP or TLS connection that the original request was received on.</param> /// <param name="connectionIDHint">Optional ID of the specific client connection that the message should be sent on. It's only /// a hint so if the connection has been closed a new one will be attempted.</param> /// <returns>If no errors SocketError.Success otherwise an error value.</returns> public abstract Task <SocketError> SendAsync(SIPEndPoint dstEndPoint, byte[] buffer, bool canInitiateConnection, string connectionIDHint = null);
/// <summary> /// Checks whether the SIP channel has an existing connection for a remote end point. /// Existing connections include connections that have been accepted by this channel's listener /// and connections that have been initiated due to sends from this channel. /// </summary> /// <param name="remoteEndPoint">The remote end point to check for an existing connection.</param> /// <returns>True if a match is found or false if not.</returns> public abstract bool HasConnection(SIPEndPoint remoteEndPoint);
public static bool AreEqual(SIPEndPoint endPoint1, SIPEndPoint endPoint2) { return(endPoint1 == endPoint2); }
/// <summary> /// The UDP channel does not support connections. Always returns false. /// </summary> public override bool HasConnection(SIPEndPoint remoteEndPoint) { return(false); }
public SIPNonInviteTransaction(SIPTransport sipTransport, SIPRequest sipRequest, SIPEndPoint outboundProxy) : base(sipTransport, sipRequest, outboundProxy) { TransactionType = SIPTransactionTypesEnum.NonInvite; TransactionRequestReceived += SIPNonInviteTransaction_TransactionRequestReceived; TransactionInformationResponseReceived += SIPNonInviteTransaction_TransactionInformationResponseReceived; TransactionFinalResponseReceived += SIPNonInviteTransaction_TransactionFinalResponseReceived; TransactionTimedOut += SIPNonInviteTransaction_TransactionTimedOut; TransactionRemoved += SIPNonInviteTransaction_TransactionRemoved; TransactionRequestRetransmit += SIPNonInviteTransaction_TransactionRequestRetransmit; sipTransport.AddTransaction(this); }
private void UACInviteTransaction_TransactionRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPRequest sipRequest) { logger.LogWarning("UACInviteTransaction received unexpected request, " + sipRequest.Method + " from " + remoteEndPoint.ToString() + ", ignoring."); }
private Task <SocketError> SIPNonInviteTransaction_TransactionRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPRequest sipRequest) { return(NonInviteRequestReceived?.Invoke(localSIPEndPoint, remoteEndPoint, this, sipRequest)); }
/// <summary> /// See overload. /// </summary> /// <param name="switchCallTransactions">An empty list that will be filled with transactions that the ForkCall creates and that each /// represent an outgoing call. The calling object can use the list to check response codes to determine the result of each leg in the /// ForkCall.</param> public ForkCall( SIPTransport sipTransport, SIPMonitorLogDelegate statefulProxyLogEvent, QueueNewCallDelegate queueNewCall, DialStringParser dialStringParser, string username, string adminMemberId, SIPEndPoint outboundProxy, ISIPCallManager callManager, DialPlanContext dialPlanContext, out List<SIPTransaction> switchCallTransactions) : this(sipTransport, statefulProxyLogEvent, queueNewCall, dialStringParser, username, adminMemberId, outboundProxy, callManager, dialPlanContext) { switchCallTransactions = m_switchCallTransactions; }
public SIPServerUserAgent( SIPTransport sipTransport, SIPEndPoint outboundProxy, string sipUsername, string sipDomain, SIPCallDirection callDirection, SIPAssetGetDelegate<SIPAccount> getSIPAccount, SIPAuthenticateRequestDelegate sipAuthenticateRequest, SIPMonitorLogDelegate logDelegate, UASInviteTransaction uasTransaction) { m_sipTransport = sipTransport; m_outboundProxy = outboundProxy; m_sipUsername = sipUsername; m_sipDomain = sipDomain; m_sipCallDirection = callDirection; GetSIPAccount_External = getSIPAccount; SIPAuthenticateRequest_External = sipAuthenticateRequest; Log_External = logDelegate ?? Log_External; m_uasTransaction = uasTransaction; m_uasTransaction.TransactionTraceMessage += TransactionTraceMessage; m_uasTransaction.UASInviteTransactionTimedOut += ClientTimedOut; m_uasTransaction.UASInviteTransactionCancelled += UASTransactionCancelled; m_uasTransaction.TransactionRemoved += new SIPTransactionRemovedDelegate(UASTransaction_TransactionRemoved); //m_uasTransaction.TransactionStateChanged += (t) => { logger.Debug("Transaction state change to " + t.TransactionState + ", uri=" + t.TransactionRequestURI.ToString() + "."); }; }
public override Task <SocketError> SendAsync(SIPEndPoint dstEndPoint, byte[] buffer, string connectionIDHint) { return(SendSecureAsync(dstEndPoint, buffer, null, connectionIDHint)); }
private Task <SocketError> SIPNonInviteTransaction_TransactionFinalResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { return(NonInviteTransactionFinalResponseReceived?.Invoke(localSIPEndPoint, remoteEndPoint, this, sipResponse)); }
public void Answered(int answerStatusCode, SIPResponseStatusCodesEnum answerStatus, string answerReason, SIPEndPoint localEndPoint, SIPEndPoint remoteEndPoint) { try { IsAnswered = true; AnswerTime = DateTime.UtcNow; AnswerStatus = (int)answerStatus; AnswerReasonPhrase = answerReason; AnsweredAt = DateTime.Now; if (localEndPoint != null) { LocalSIPEndPoint = localEndPoint; } if (remoteEndPoint != null) { RemoteEndPoint = remoteEndPoint; } CDRAnswered(this); } catch (Exception excp) { logger.LogError("Exception SIPCDR Answered. " + excp); } }
public void SendInviteRequest(SIPEndPoint dstEndPoint, SIPRequest inviteRequest) { this.RemoteEndPoint = dstEndPoint; base.SendReliableRequest(); }
private void UASInviteTransaction_TransactionRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPRequest sipRequest) { try { if (TransactionState == SIPTransactionStatesEnum.Terminated) { logger.LogDebug("Request received by UASInviteTransaction for a terminated transaction, ignoring."); } else if (sipRequest.Method != SIPMethodsEnum.INVITE) { logger.LogWarning("Unexpected " + sipRequest.Method + " passed to UASInviteTransaction."); } else { if (TransactionState != SIPTransactionStatesEnum.Trying) { SIPResponse tryingResponse = GetInfoResponse(m_transactionRequest, SIPResponseStatusCodesEnum.Trying); SendProvisionalResponse(tryingResponse); } // Notify new call subscribers. if (NewCallReceived != null) { NewCallReceived(localSIPEndPoint, remoteEndPoint, this, sipRequest); } else { // Nobody wants to answer this call so return an error response. SIPResponse declinedResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Decline, "Nothing listening"); SendFinalResponse(declinedResponse); } } } catch (Exception excp) { logger.LogError("Exception UASInviteTransaction GotRequest. " + excp.Message); } }
/// <summary> /// Attempts a send to a remote web socket server. If there is an existing connection it will be used /// otherwise an attempt will made to establish a new one. /// </summary> /// <param name="serverEndPoint">The remote web socket server URI to send to.</param> /// <param name="buffer">The data buffer to send.</param> /// <returns>A success value or an error for failure.</returns> private async Task <SocketError> SendAsync(SIPEndPoint serverEndPoint, byte[] buffer) { try { string uriPrefix = (serverEndPoint.Protocol == SIPProtocolsEnum.wss) ? WEB_SOCKET_SECURE_URI_PREFIX : WEB_SOCKET_URI_PREFIX; var serverUri = new Uri($"{uriPrefix}{serverEndPoint.GetIPEndPoint()}"); string connectionID = GetConnectionID(serverUri); serverEndPoint.ChannelID = this.ID; serverEndPoint.ConnectionID = connectionID; if (m_egressConnections.TryGetValue(connectionID, out var conn)) { logger.LogDebug( $"Sending {buffer.Length} bytes on client web socket connection to {conn.ServerUri}."); ArraySegment <byte> segmentBuffer = new ArraySegment <byte>(buffer); await conn.Client.SendAsync(segmentBuffer, WebSocketMessageType.Text, true, m_cts.Token) .ConfigureAwait(false); return(SocketError.Success); } else { // Attempt a new connection. ClientWebSocket clientWebSocket = new ClientWebSocket(); await clientWebSocket.ConnectAsync(serverUri, m_cts.Token).ConfigureAwait(false); logger.LogDebug($"Successfully connected web socket client to {serverUri}."); ArraySegment <byte> segmentBuffer = new ArraySegment <byte>(buffer); await clientWebSocket.SendAsync(segmentBuffer, WebSocketMessageType.Text, true, m_cts.Token) .ConfigureAwait(false); var recvBuffer = new ArraySegment <byte>(new byte[2 * SIPStreamConnection.MaxSIPTCPMessageSize]); Task <WebSocketReceiveResult> receiveTask = clientWebSocket.ReceiveAsync(recvBuffer, m_cts.Token); // There's currently no way to get the socket IP end point used by the client web socket to establish // the connection. Instead provide a dummy local end point that has as much of the information as we can. IPEndPoint localEndPoint = new IPEndPoint( (serverEndPoint.Address.AddressFamily == AddressFamily.InterNetwork) ? IPAddress.Any : IPAddress.IPv6Any, 0); SIPEndPoint localSIPEndPoint = new SIPEndPoint(serverEndPoint.Protocol, localEndPoint, this.ID, connectionID); ClientWebSocketConnection newConn = new ClientWebSocketConnection { LocalEndPoint = localSIPEndPoint, ServerUri = serverUri, RemoteEndPoint = serverEndPoint, ConnectionID = connectionID, ReceiveBuffer = recvBuffer, ReceiveTask = receiveTask, Client = clientWebSocket }; if (!m_egressConnections.TryAdd(connectionID, newConn)) { logger.LogError( $"Could not add web socket client connected to {serverUri} to channel collection, closing."); await Close(connectionID, clientWebSocket).ConfigureAwait(false); } else { if (!m_isReceiveTaskRunning) { m_isReceiveTaskRunning = true; _ = Task.Factory.StartNew(MonitorReceiveTasks, TaskCreationOptions.LongRunning); } } return(SocketError.Success); } } catch (SocketException sockExcp) { return(sockExcp.SocketErrorCode); } }
private void UASInviteTransaction_TransactionResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { logger.LogWarning("UASInviteTransaction received unexpected response, " + sipResponse.ReasonPhrase + " from " + remoteEndPoint.ToString() + ", ignoring."); }
/// <summary> /// Attempts to parse a SIP message from a string containing a single SIP request or response. /// </summary> /// <param name="message">The string to parse.</param> /// <param name="localSIPEndPoint">The end point the message was received on.</param> /// <param name="remoteSIPEndPoint">The end point the message was received from.</param> /// <returns>If successfull a SIP message or null if not.</returns> public static SIPMessageBuffer ParseSIPMessage(string message, SIPEndPoint localSIPEndPoint, SIPEndPoint remoteSIPEndPoint) { try { SIPMessageBuffer sipMessage = new SIPMessageBuffer(); sipMessage.LocalSIPEndPoint = localSIPEndPoint; sipMessage.RemoteSIPEndPoint = remoteSIPEndPoint; // For connection oriented transports the same connection should be used for responses and subsequent requests. if (sipMessage.LocalSIPEndPoint != null && remoteSIPEndPoint.ConnectionID != null) { sipMessage.LocalSIPEndPoint.ConnectionID = remoteSIPEndPoint.ConnectionID; } sipMessage.RawMessage = message; int endFistLinePosn = message.IndexOf(m_CRLF); if (endFistLinePosn != -1) { sipMessage.FirstLine = message.Substring(0, endFistLinePosn); if (sipMessage.FirstLine.Substring(0, 3) == SIP_RESPONSE_PREFIX) { sipMessage.SIPMessageType = SIPMessageTypesEnum.Response; } else { sipMessage.SIPMessageType = SIPMessageTypesEnum.Request; } int endHeaderPosn = message.IndexOf(m_CRLF + m_CRLF); if (endHeaderPosn == -1) { // Assume flakey implementation if message does not contain the required CRLFCRLF sequence and treat the message as having no body. string headerString = message.Substring(endFistLinePosn + 2, message.Length - endFistLinePosn - 2); sipMessage.SIPHeaders = SIPHeader.SplitHeaders(headerString); } else { string headerString = message.Substring(endFistLinePosn + 2, endHeaderPosn - endFistLinePosn - 2); sipMessage.SIPHeaders = SIPHeader.SplitHeaders(headerString); if (message.Length > endHeaderPosn + 4) { sipMessage.Body = message.Substring(endHeaderPosn + 4); } } return(sipMessage); } else { logger.LogWarning("Error ParseSIPMessage, there were no end of line characters in the string being parsed."); return(null); } } catch (Exception excp) { logger.LogError("Exception ParseSIPMessage. " + excp.Message + "\nSIP Message=" + message + "."); return(null); } }
/// <summary> /// This method is not implemented for the SIP UDP channel. /// </summary> public override Task <SocketError> SendSecureAsync(SIPEndPoint dstEndPoint, byte[] buffer, string serverCertificateName, string connectionIDHint) { throw new NotImplementedException( "This Send method is not available in the SIP UDP channel, please use an alternative overload."); }
public SIPEndPoint LocalSIPEndPoint; // The local SIP socket the message was received on or sent from. /// <summary> /// Attempts to parse a SIP message from a single buffer that can only contain a single message. /// </summary> /// <param name="buffer">The buffer rhat will be parsed for a SIP message.</param> /// <param name="localSIPEndPoint">The end point the message was received on.</param> /// <param name="remoteSIPEndPoint">The end point the message was received from.</param> /// <returns>If successfull a SIP message or null if not.</returns> public static SIPMessageBuffer ParseSIPMessage(byte[] buffer, SIPEndPoint localSIPEndPoint, SIPEndPoint remoteSIPEndPoint) { string message = null; try { if (buffer == null || buffer.Length < m_minFirstLineLength) { // Ignore. return(null); } else if (buffer.Length > SIPConstants.SIP_MAXIMUM_RECEIVE_LENGTH) { throw new ApplicationException("SIP message received that exceeded the maximum allowed message length, ignoring."); } else if (!ByteBufferInfo.HasString(buffer, 0, buffer.Length, SIP_MESSAGE_IDENTIFIER, m_CRLF)) { // Message does not contain "SIP" anywhere on the first line, ignore. return(null); } else { message = Encoding.UTF8.GetString(buffer, 0, buffer.Length); SIPMessageBuffer sipMessageBuffer = ParseSIPMessage(message, localSIPEndPoint, remoteSIPEndPoint); if (sipMessageBuffer != null) { sipMessageBuffer.RawBuffer = buffer; return(sipMessageBuffer); } else { return(null); } } } catch (Exception excp) { message = message.Replace("\n", "LF"); message = message.Replace("\r", "CR"); logger.LogError("Exception ParseSIPMessage. " + excp.Message + "\nSIP Message=" + message + "."); return(null); } }
private void UACInviteTransaction_TransactionInformationResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { if (UACInviteTransactionInformationResponseReceived != null) { UACInviteTransactionInformationResponseReceived(localSIPEndPoint, remoteEndPoint, sipTransaction, sipResponse); } if (CDR != null) { SIPEndPoint localEP = SIPEndPoint.TryParse(sipResponse.Header.ProxyReceivedOn) ?? localSIPEndPoint; SIPEndPoint remoteEP = SIPEndPoint.TryParse(sipResponse.Header.ProxyReceivedFrom) ?? remoteEndPoint; CDR.Progress(sipResponse.Status, sipResponse.ReasonPhrase, localEP, remoteEP); } } catch (Exception excp) { logger.LogError("Exception UACInviteTransaction_TransactionInformationResponseReceived. " + excp.Message); } }
public bool IsSocketEqual(SIPEndPoint endPoint) { return(AreSocketsEqual(this, endPoint)); }
private void UACInviteTransaction_TransactionFinalResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { // BranchId for 2xx responses needs to be a new one, non-2xx final responses use same one as original request. if (sipResponse.StatusCode >= 200 && sipResponse.StatusCode < 299) { if (_sendOkAckManually == false) { Send2xxAckRequest(null, null); } } else { // ACK for non 2xx response is part of the INVITE transaction and gets routed to the same endpoint as the INVITE. var ackRequest = GetInTransactionACKRequest(sipResponse, m_transactionRequest.URI, LocalSIPEndPoint); base.SendRequest(RemoteEndPoint, ackRequest); } if (UACInviteTransactionFinalResponseReceived != null) { UACInviteTransactionFinalResponseReceived(localSIPEndPoint, remoteEndPoint, sipTransaction, sipResponse); } if (CDR != null) { SIPEndPoint localEP = SIPEndPoint.TryParse(sipResponse.Header.ProxyReceivedOn) ?? localSIPEndPoint; SIPEndPoint remoteEP = SIPEndPoint.TryParse(sipResponse.Header.ProxyReceivedFrom) ?? remoteEndPoint; CDR.Answered(sipResponse.StatusCode, sipResponse.Status, sipResponse.ReasonPhrase, localEP, remoteEP); } } catch (Exception excp) { logger.LogError("Exception UACInviteTransaction_TransactionFinalResponseReceived. " + excp.Message); } }
/// <summary> /// The contact SIP URI to be used for contacting this SIP channel WHEN sending to the destination IP address. /// The contact URI can change based on the destination. For example if the SIP channel is listening on IPAddress.Any /// a destination address of 127.0.0.1 will result in a contact of sip:127.0.0.1:X. Using the same channel to /// send to a destination address on the Internet will result in a different URI. /// </summary> /// <param name="scheme">The SIP scheme to use for the Contact URI.</param> /// <param name="dstEndPoint">The destination SIP end point the Contact URI is for. For a SIPChannel using /// IPAddress.Any the destination needs to be known so it can select the correct local address.</param> public SIPURI GetContactURI(SIPSchemesEnum scheme, SIPEndPoint dstEndPoint) { return(new SIPURI(scheme, GetLocalSIPEndPointForDestination(dstEndPoint))); }
/// <summary> /// New transaction ACK requests are for 2xx responses, i.e. INVITE accepted and dialogue being created. /// </summary> /// <remarks> /// From RFC 3261 Chapter 17.1.1.3 - ACK for non-2xx final responses /// /// IMPORTANT: /// an ACK for a non-2xx response will also have the same branch ID as the INVITE whose response it acknowledges. /// /// The ACK request constructed by the client transaction MUST contain /// values for the Call-ID, From, and Request-URI that are equal to the /// values of those header fields in the request passed to the transport /// by the client transaction (call this the "original request"). The To /// header field in the ACK MUST equal the To header field in the /// response being acknowledged, and therefore will usually differ from /// the To header field in the original request by the addition of the /// tag parameter. The ACK MUST contain a single Via header field, and /// this MUST be equal to the top Via header field of the original /// request. The CSeq header field in the ACK MUST contain the same /// value for the sequence number as was present in the original request, /// but the method parameter MUST be equal to "ACK". /// /// If the INVITE request whose response is being acknowledged had Route /// header fields, those header fields MUST appear in the ACK. This is /// to ensure that the ACK can be routed properly through any downstream /// stateless proxies. /// /// From RFC 3261 Chapter 13.2.2.4 - ACK for 2xx final responses /// /// IMPORTANT: /// an ACK for a 2xx final response is a new transaction and has a new branch ID. /// /// The UAC core MUST generate an ACK request for each 2xx received from /// the transaction layer. The header fields of the ACK are constructed /// in the same way as for any request sent within a dialog (see Section /// 12) with the exception of the CSeq and the header fields related to /// authentication. The sequence number of the CSeq header field MUST be /// the same as the INVITE being acknowledged, but the CSeq method MUST /// be ACK. The ACK MUST contain the same credentials as the INVITE. If /// the 2xx contains an offer (based on the rules above), the ACK MUST /// carry an answer in its body. If the offer in the 2xx response is not /// acceptable, the UAC core MUST generate a valid answer in the ACK and /// then send a BYE immediately. /// </remarks> private SIPRequest GetNewTransactionACKRequest(SIPResponse sipResponse, SIPURI ackURI, SIPEndPoint localSIPEndPoint) { SIPRequest ackRequest = new SIPRequest(SIPMethodsEnum.ACK, ackURI.ToString()); ackRequest.LocalSIPEndPoint = localSIPEndPoint; SIPHeader header = new SIPHeader(TransactionRequest.Header.From, sipResponse.Header.To, sipResponse.Header.CSeq, sipResponse.Header.CallId); header.CSeqMethod = SIPMethodsEnum.ACK; header.AuthenticationHeader = TransactionRequest.Header.AuthenticationHeader; header.ProxySendFrom = base.TransactionRequest.Header.ProxySendFrom; // If the UAS supplies a desired Record-Route list use that first. Otherwise fall back to any Route list used in the original transaction. if (sipResponse.Header.RecordRoutes != null) { header.Routes = sipResponse.Header.RecordRoutes.Reversed(); } else if (base.TransactionRequest.Header.Routes != null) { header.Routes = base.TransactionRequest.Header.Routes; } ackRequest.Header = header; SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, CallProperties.CreateBranchId()); ackRequest.Header.Vias.PushViaHeader(viaHeader); return(ackRequest); }
/// <summary> /// Asynchronous SIP message send over a secure TLS connection to a remote end point. /// </summary> /// <param name="dstEndPoint">The remote end point to send the message to.</param> /// <param name="buffer">The data to send.</param> /// <param name="serverCertificateName">If the send is over SSL the required common name of the server's X509 certificate.</param> /// <param name="canInitiateConnection">Indicates whether this send should initiate a connection if needed. /// The typical case is SIP requests can initiate new connections but responses should not. Responses should /// only be sent on the same TCP or TLS connection that the original request was received on.</param> /// <param name="connectionIDHint">Optional ID of the specific client connection that the message should be sent on. It's only /// a hint so if the connection has been closed a new one will be attempted.</param> /// <returns>If no errors SocketError.Success otherwise an error value.</returns> public abstract Task <SocketError> SendSecureAsync(SIPEndPoint dstEndPoint, byte[] buffer, string serverCertificateName, bool canInitiateConnection, string connectionIDHint = null);
/// <summary> /// In transaction ACK requests are for non-2xx responses, i.e. INVITE rejected and no dialogue being created. /// </summary> private SIPRequest GetInTransactionACKRequest(SIPResponse sipResponse, SIPURI ackURI, SIPEndPoint localSIPEndPoint) { SIPRequest ackRequest = new SIPRequest(SIPMethodsEnum.ACK, ackURI.ToString()); ackRequest.LocalSIPEndPoint = localSIPEndPoint; SIPHeader header = new SIPHeader(TransactionRequest.Header.From, sipResponse.Header.To, sipResponse.Header.CSeq, sipResponse.Header.CallId); header.CSeqMethod = SIPMethodsEnum.ACK; header.AuthenticationHeader = TransactionRequest.Header.AuthenticationHeader; header.Routes = base.TransactionRequest.Header.Routes; header.ProxySendFrom = base.TransactionRequest.Header.ProxySendFrom; ackRequest.Header = header; SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, sipResponse.Header.Vias.TopViaHeader.Branch); ackRequest.Header.Vias.PushViaHeader(viaHeader); return(ackRequest); }
public SIPEndPoint CopyOf() { SIPEndPoint copy = new SIPEndPoint(Protocol, new IPAddress(Address.GetAddressBytes()), Port); return(copy); }
/// <param name="sendOkAckManually">If set an ACK request for the 2xx response will NOT be sent and it will be up to the application to explicitly call the SendACK request.</param> internal UACInviteTransaction(SIPTransport sipTransport, SIPRequest sipRequest, SIPEndPoint dstEndPoint, SIPEndPoint localSIPEndPoint, SIPEndPoint outboundProxy, bool sendOkAckManually = false) : base(sipTransport, sipRequest, dstEndPoint, localSIPEndPoint, outboundProxy) { TransactionType = SIPTransactionTypesEnum.Invite; m_localTag = sipRequest.Header.From.FromTag; SIPEndPoint localEP = SIPEndPoint.TryParse(sipRequest.Header.ProxySendFrom) ?? localSIPEndPoint; CDR = new SIPCDR(SIPCallDirection.Out, sipRequest.URI, sipRequest.Header.From, sipRequest.Header.CallId, localEP, dstEndPoint); _sendOkAckManually = sendOkAckManually; TransactionFinalResponseReceived += UACInviteTransaction_TransactionFinalResponseReceived; TransactionInformationResponseReceived += UACInviteTransaction_TransactionInformationResponseReceived; TransactionTimedOut += UACInviteTransaction_TransactionTimedOut; TransactionRequestReceived += UACInviteTransaction_TransactionRequestReceived; TransactionRemoved += UACInviteTransaction_TransactionRemoved; }
/// <summary> /// Gets fired when a suspected SIP message is extracted from the TCP data stream. /// </summary> protected Task SIPTCPMessageReceived(SIPChannel channel, SIPEndPoint localEndPoint, SIPEndPoint remoteEndPoint, byte[] buffer) { return(SIPMessageReceived?.Invoke(channel, localEndPoint, remoteEndPoint, buffer)); }
public void GotRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { FireTransactionTraceMessage($"Transaction received Request {localSIPEndPoint.ToString()}<-{remoteEndPoint.ToString()}: {sipRequest.StatusLine}"); TransactionRequestReceived?.Invoke(localSIPEndPoint, remoteEndPoint, this, sipRequest); }
private QueueNewCallDelegate QueueNewCall_External; // Function delegate to allow new calls to be placed on the call manager and run through the dialplan logic. #endregion Fields #region Constructors /// <remarks> /// The ForkCall allows a SIP call to be forked to multiple destinations. To do this it utilises multiple /// simultaneous SIPCallDescriptor objects and consolidates their responses to work out what should and shouldn't /// be forwarded onto the client that initiated the call. The ForkCall acts as a classic SIP forking proxy. /// /// The ForkCall is capable of both multiple forwards and also of follow on forwarding in the event of a call /// leg of multiple forwards not succeeding. As an example: /// /// Dial(provider1&provider2|provider3&provider4|provider5&provider6) /// /// The handling of this call would be: /// 1. The call would be simultaneously forwarded to provider1 and provider2, /// 2. If the call was not successfully answered in step 1 the call would be simultaneously forwarded to provider3 and provider4, /// 3. If the call was not successfully answered in step 2 the call would be simultaneously forwarded to provider5 and provider6, /// 4. If the call was not successfully answered in step 3 the client call would be sent an error response. /// 5. If the client cancels the call at any time during the call all forwarding operations will halt. /// </remarks> /// <param name="sipTransport">The SIP transport layer that will handle the forked calls.</param> /// <param name="statefulProxyLogEvent">A delegate that allows the owning object to receive notifications from the ForkCall.</param> /// <param name="queueNewCall">A delegate that can be used to queue a new call with the SIP application server call manager. This /// delegate is used when a fork call generates a B2B call that requires the incoming dialplan for a called user to be processed.</param> /// <param name="dialStringParser">The dial string parser is used when a redirect response is received on a forked call leg. The /// parser can then be applied to the redirect SIP URI to generate new call legs to be added to the ForkCall.</param> /// <param name="username">The username of the call owner.</param> /// <param name="adminMemberId">The admin ID of the call owner.</param> /// <param name="outboundProxy">The outbound proxy to use for all SIP traffic originated. Can be null if an outbound proxy is not /// being used.</param> public ForkCall( SIPTransport sipTransport, SIPMonitorLogDelegate statefulProxyLogEvent, QueueNewCallDelegate queueNewCall, DialStringParser dialStringParser, string username, string adminMemberId, SIPEndPoint outboundProxy, ISIPCallManager callManager, DialPlanContext dialPlanContext) { m_sipTransport = sipTransport; m_statefulProxyLogEvent = statefulProxyLogEvent; QueueNewCall_External = queueNewCall; m_dialStringParser = dialStringParser; m_username = username; m_adminMemberId = adminMemberId; m_outboundProxySocket = outboundProxy; m_callManager = callManager; m_dialPlanContext = dialPlanContext; }
/// <summary> /// Checks whether there is an existing connection for a remote end point. Existing connections include /// connections that have been accepted by this channel's listener and connections that have been initiated /// due to sends from this channel. /// </summary> /// <param name="remoteEndPoint">The remote end point to check for an existing connection.</param> /// <returns>True if there is a connection or false if not.</returns> public override bool HasConnection(SIPEndPoint remoteEndPoint) { return(m_connections.Any(x => x.Value.RemoteEndPoint.Equals(remoteEndPoint.GetIPEndPoint()))); }
//private bool m_closed = false; public SIPUDPChannel(IPEndPoint endPoint) { m_localSIPEndPoint = new SIPEndPoint(SIPProtocolsEnum.udp, endPoint); Initialise(); }
public void Progress(SIPResponseStatusCodesEnum progressStatus, string progressReason, SIPEndPoint localEndPoint, SIPEndPoint remoteEndPoint) { InProgress = true; ProgressTime = DateTime.UtcNow; ProgressStatus = (int)progressStatus; ProgressReasonPhrase = progressReason; if (localEndPoint != null) { LocalSIPEndPoint = localEndPoint; } if (remoteEndPoint != null) { RemoteEndPoint = remoteEndPoint; } }