This class must remain immutable otherwise the SIP stack can develop problems. SIP end points can get passed amongst different servers for logging and forwarding SIP messages and a modification of the end point by one server can result in a problem for a different server. Instead a new SIP end point should be created wherever a modification is required.
 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();
        }
Example #27
0
 /// <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);
Example #28
0
 /// <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);
Example #29
0
 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);
        }
Example #32
0
 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));
 }
Example #34
0
 /// <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() + "."); };
        }
Example #36
0
 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));
 }
Example #38
0
        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);
            }
        }
Example #39
0
 public void SendInviteRequest(SIPEndPoint dstEndPoint, SIPRequest inviteRequest)
 {
     this.RemoteEndPoint = dstEndPoint;
     base.SendReliableRequest();
 }
Example #40
0
        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);
            }
        }
Example #41
0
        /// <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);
            }
        }
Example #42
0
 private void UASInviteTransaction_TransactionResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse)
 {
     logger.LogWarning("UASInviteTransaction received unexpected response, " + sipResponse.ReasonPhrase + " from " + remoteEndPoint.ToString() + ", ignoring.");
 }
Example #43
0
        /// <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.");
 }
Example #45
0
        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);
            }
        }
Example #46
0
        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);
            }
        }
Example #47
0
 public bool IsSocketEqual(SIPEndPoint endPoint)
 {
     return(AreSocketsEqual(this, endPoint));
 }
Example #48
0
        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);
            }
        }
Example #49
0
 /// <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)));
 }
Example #50
0
        /// <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);
        }
Example #51
0
 /// <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);
Example #52
0
        /// <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);
        }
Example #53
0
        public SIPEndPoint CopyOf()
        {
            SIPEndPoint copy = new SIPEndPoint(Protocol, new IPAddress(Address.GetAddressBytes()), Port);

            return(copy);
        }
Example #54
0
        /// <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;
        }
Example #55
0
 /// <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));
 }
Example #56
0
 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);
 }
Example #57
0
        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;
        }
Example #58
0
 /// <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();
 }
Example #60
0
        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;
            }
        }