private SIPRequest GetCancelRequest(SIPRequest inviteRequest)
        {
            SIPRequest cancelRequest = new SIPRequest(SIPMethodsEnum.CANCEL, inviteRequest.URI);
            cancelRequest.LocalSIPEndPoint = inviteRequest.LocalSIPEndPoint;

            SIPHeader inviteHeader = inviteRequest.Header;
            SIPHeader cancelHeader = new SIPHeader(inviteHeader.From, inviteHeader.To, inviteHeader.CSeq, inviteHeader.CallId);
            cancelRequest.Header = cancelHeader;
            cancelHeader.CSeqMethod = SIPMethodsEnum.CANCEL;
            cancelHeader.Routes = inviteHeader.Routes;
            cancelHeader.ProxySendFrom = inviteHeader.ProxySendFrom;
            cancelHeader.Vias = inviteHeader.Vias;

            return cancelRequest;
        }
        /// <summary>
        /// 录像文件查询
        /// </summary>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        public int RecordFileQuery(DateTime startTime, DateTime endTime)
        {
            //lock (_msgCore.RemoteTrans)
            //{
            //    if (!_msgCore.RemoteTrans.ContainsKey(_remoteEndPoint.ToString()))
            //    {
            //        OnSIPServiceChange(_deviceName + "-" + _deviceId + _remoteEndPoint.ToString(), SipServiceStatus.Wait);
            //        return 0;
            //    }
            //}
            if (!_initComplate)
            {
                OnSIPServiceChange(_deviceName + "-" + _deviceId + _remoteEndPoint.ToString(), SipServiceStatus.Wait);
                return(0);
            }

            this.Stop();

            SIPURI           remoteUri     = new SIPURI(_deviceId, _remoteEndPoint.ToHost(), "");
            SIPURI           localUri      = new SIPURI(_msgCore.LocalSIPId, _msgCore.LocalEndPoint.ToHost(), "");
            SIPFromHeader    from          = new SIPFromHeader(null, localUri, CallProperties.CreateNewTag());
            SIPToHeader      to            = new SIPToHeader(null, remoteUri, CallProperties.CreateNewTag());
            SIPRequest       recordFileReq = _msgCore.Transport.GetRequest(SIPMethodsEnum.MESSAGE, remoteUri);
            SIPContactHeader contactHeader = new SIPContactHeader(null, localUri);

            recordFileReq.Header.Contact.Clear();
            recordFileReq.Header.Contact.Add(contactHeader);

            recordFileReq.Header.Allow       = null;
            recordFileReq.Header.From        = from;
            recordFileReq.Header.To          = to;
            recordFileReq.Header.UserAgent   = _msgCore.UserAgent;
            recordFileReq.Header.CSeq        = CallProperties.CreateNewCSeq();
            recordFileReq.Header.CallId      = CallProperties.CreateNewCallId();
            recordFileReq.Header.ContentType = "application/MANSCDP+xml";

            string      bTime  = startTime.ToString("yyyy-MM-ddTHH:mm:ss");
            string      eTime  = endTime.ToString("yyyy-MM-ddTHH:mm:ss");
            RecordQuery record = new RecordQuery()
            {
                DeviceID  = _deviceId,
                SN        = new Random().Next(1, 3000),
                CmdType   = CommandType.RecordInfo,
                Secrecy   = 0,
                StartTime = bTime,
                EndTime   = eTime,
                Type      = "time"
            };

            _recordTotal = -1;
            string xmlBody = RecordQuery.Instance.Save <RecordQuery>(record);

            recordFileReq.Body = xmlBody;
            _msgCore.Transport.SendRequest(_remoteEndPoint, recordFileReq);
            DateTime recordQueryTime = DateTime.Now;

            while (_recordTotal < 0)
            {
                Thread.Sleep(50);
                if (DateTime.Now.Subtract(recordQueryTime).TotalSeconds > 2)
                {
                    logger.Debug(_deviceName + "[" + _deviceId + "] 等待录像查询超时");
                    _recordTotal = 0;
                    break;
                }
            }

            return(_recordTotal);
        }
        private SIPRequest GetReferRequest(SIPEndPoint localSIPEndPoint, SIPURI referTo, ReplacesCallDescriptor sipReplacesCallDescriptor)
        {
            SIPRequest referRequest = new SIPRequest(SIPMethodsEnum.REFER, m_sipCallDescriptor.Uri);
            SIPFromHeader referFromHeader = SIPFromHeader.ParseFromHeader(m_sipCallDescriptor.From);
            SIPToHeader referToHeader = SIPToHeader.ParseToHeader(m_sipCallDescriptor.Uri);

            int cseq = ++CSeq;
            CallId = CallProperties.CreateNewCallId();

            SIPHeader referHeader = new SIPHeader(referFromHeader, referToHeader, cseq, CallId);
            referHeader.CSeqMethod = SIPMethodsEnum.REFER;
            referRequest.Header = referHeader;
            referRequest.Header.Routes = RouteSet;
            referRequest.Header.ProxySendFrom = m_sipCallDescriptor.ProxySendFrom;

            if (sipReplacesCallDescriptor != null)
            {
                referTo.Headers.Set("Replaces", sipReplacesCallDescriptor.GetUrlEncodedReplacesUriHeader());
                referRequest.Header.ReferTo = referTo.ToString();
            }
            else
            {
                referRequest.Header.ReferTo = referTo.ToString();
            }

            // "Requires" Header
            referRequest.Header.Require = (String.IsNullOrWhiteSpace(referRequest.Header.Require)) ? "replaces" : referRequest.Header.Require + ",replaces";

            SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, CallProperties.CreateBranchId());
            referRequest.Header.Vias.PushViaHeader(viaHeader);

            return referRequest;
        }
        public void SendSIPRequest(SIPRequest sipRequest, string dstSocket)
        {
            //ResetSIPResponse();

            if (sipRequest.Method == SIPMethodsEnum.INVITE)
            {
                //m_inviteRequest = sipRequest;
                UACInviteTransaction inviteTransaction = m_sipTransport.CreateUACTransaction(sipRequest, IPSocket.GetIPEndPoint(dstSocket), m_sipTransport.GetTransportContact(null), SIPProtocolsEnum.UDP);
                inviteTransaction.UACInviteTransactionInformationResponseReceived += new SIPTransactionResponseReceivedDelegate(TransactionInformationResponseReceived);
                inviteTransaction.UACInviteTransactionFinalResponseReceived += new SIPTransactionResponseReceivedDelegate(TransactionFinalResponseReceived);
                m_sipTransport.SendSIPReliable(inviteTransaction);
            }
            else
            {
                SIPNonInviteTransaction sipTransaction = m_sipTransport.CreateNonInviteTransaction(sipRequest, IPSocket.GetIPEndPoint(dstSocket), m_sipTransport.GetTransportContact(null), SIPProtocolsEnum.UDP);
                sipTransaction.NonInviteTransactionFinalResponseReceived += new SIPTransactionResponseReceivedDelegate(TransactionFinalResponseReceived);
                m_sipTransport.SendSIPReliable(sipTransaction);
            }
        }
        public SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum serverType, SIPMonitorEventTypesEnum eventType, string message, SIPRequest sipRequest, SIPResponse sipResponse, SIPEndPoint localEndPoint, SIPEndPoint remoteEndPoint, SIPCallDirection callDirection)
        {
            m_serialisationPrefix = SERIALISATION_PREFIX;
            ClientType = SIPMonitorClientTypesEnum.Console;

            ServerType = serverType;
            EventType = eventType;
            Message = message;
            RemoteEndPoint = remoteEndPoint;
            ServerEndPoint = localEndPoint;
            Created = DateTimeOffset.UtcNow;
            #if !SILVERLIGHT
            ProcessID = Process.GetCurrentProcess().Id;
            #endif

            string dirn = (callDirection == SIPCallDirection.In) ? CALLDIRECTION_IN_STRING : CALLDIRECTION_OUT_STRING;
            if (sipRequest != null)
            {
                Message = "REQUEST (" + Created.ToString("HH:mm:ss:fff") + "): " + localEndPoint + dirn + remoteEndPoint + "\r\n" + sipRequest.ToString();
            }
            else if (sipResponse != null)
            {
                Message = "RESPONSE (" + Created.ToString("HH:mm:ss:fff") + "): " + localEndPoint + dirn + remoteEndPoint + "\r\n" + sipResponse.ToString();
            }
        }
        public SIPRequest GetInviteRequest(string inviteURIStr, string fromURIStr, string body, int rtpPort)
        {
            SIPURI inviteURI = (inviteURIStr.StartsWith("sip:")) ? SIPURI.ParseSIPURI(inviteURIStr) : SIPURI.ParseSIPURI("sip:" + inviteURIStr);
            SIPFromHeader fromHeader = SIPFromHeader.ParseFromHeader(fromURIStr); // (fromURIStr.StartsWith("sip:")) ? SIPFromHeader.ParseFromHeader(fromURIStr) : SIPFromHeader.ParseFromHeader("sip:" + fromURIStr);
            SIPToHeader toHeader = new SIPToHeader(null, inviteURI, null);

            SIPRequest inviteRequest = new SIPRequest(SIPMethodsEnum.INVITE, inviteURI);

            IPEndPoint localSIPEndPoint = m_sipTransport.GetIPEndPointsList()[0];
            SIPHeader inviteHeader = new SIPHeader(fromHeader, toHeader, 1, CallProperties.CreateNewCallId());

            inviteHeader.From.FromTag = CallProperties.CreateNewTag();
            inviteHeader.Contact = SIPContactHeader.ParseContactHeader("sip:" + localSIPEndPoint.ToString());
            inviteHeader.CSeqMethod = SIPMethodsEnum.INVITE;
            //inviteHeader.UnknownHeaders.Add("BlueFace-Test: 12324");
            inviteRequest.Header = inviteHeader;

            SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint.Address.ToString(), localSIPEndPoint.Port, CallProperties.CreateBranchId());
            inviteRequest.Header.Via.PushViaHeader(viaHeader);

            rtpPort = (rtpPort != 0) ? rtpPort : Crypto.GetRandomInt(10000, 20000);
            string sessionId = Crypto.GetRandomInt(1000, 5000).ToString();

            if (body != null && body.Trim().Length > 0)
            {
                inviteRequest.Body = body;
            }
            else
            {
                inviteRequest.Body =
                   "v=0" + CRLF +
                    "o=- " + sessionId + " " + sessionId + " IN IP4 " + localSIPEndPoint.Address.ToString() + CRLF +
                    "s=session" + CRLF +
                    "c=IN IP4 " + localSIPEndPoint.Address.ToString() + CRLF +
                    "t=0 0" + CRLF +
                    "m=audio " + rtpPort + " RTP/AVP 0 101" + CRLF +
                    "a=rtpmap:0 PCMU/8000" + CRLF +
                    "a=rtpmap:101 telephone-event/8000" + CRLF +
                    "a=fmtp:101 0-16" + CRLF +
                    "a=sendrecv";
            }

            inviteRequest.Header.ContentLength = inviteRequest.Body.Length;
            inviteRequest.Header.ContentType = "application/sdp";

            return inviteRequest;
        }
        public SIPRequest GetReferRequest(SIPRequest inviteRequest, SIPResponse inviteResponse, string referToURI)
        {
            SIPRequest referRequest = new SIPRequest(SIPMethodsEnum.REFER, inviteRequest.URI);
            SIPHeader referHeader = new SIPHeader(inviteResponse.Header.From, inviteResponse.Header.To, inviteRequest.Header.CSeq + 1, inviteRequest.Header.CallId);
            referHeader.Contact = inviteRequest.Header.Contact;
            referHeader.CSeqMethod = SIPMethodsEnum.REFER;
            referHeader.ReferTo = referToURI;
            SIPFromHeader referredBy = new SIPFromHeader(inviteRequest.Header.From.FromName, inviteRequest.Header.From.FromURI, null);
            referHeader.ReferredBy = referredBy.ToString();
            referHeader.AuthenticationHeader = inviteRequest.Header.AuthenticationHeader;

            IPEndPoint localSIPEndPoint = m_sipTransport.GetIPEndPointsList()[0];
            SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint.Address.ToString(), localSIPEndPoint.Port, CallProperties.CreateBranchId());
            referHeader.Via.PushViaHeader(viaHeader);

            referRequest.Header = referHeader;

            return referRequest;
        }
Exemple #8
0
 private static void SIPRequestOutTraceEvent(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
 {
     logger.LogDebug("REQUEST OUT {0}->{1}", localSIPEndPoint.ToString(), remoteEndPoint.ToString());
     logger.LogDebug(sipRequest.ToString());
 }
        public async Task HangupUserAgentUnitTest()
        {
            logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name);
            logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name);

            SIPTransport   transport   = new SIPTransport();
            MockSIPChannel mockChannel = new MockSIPChannel(new System.Net.IPEndPoint(IPAddress.Any, 0));

            transport.AddSIPChannel(mockChannel);

            SIPUserAgent userAgent = new SIPUserAgent(transport, null);

            string inviteReqStr = "INVITE sip:192.168.11.50:5060 SIP/2.0" + m_CRLF +
                                  "Via: SIP/2.0/UDP 192.168.11.50:60163;rport;branch=z9hG4bKPj869f70960bdd4204b1352eaf242a3691" + m_CRLF +
                                  "To: <sip:[email protected]>;tag=ZUJSXRRGXQ" + m_CRLF +
                                  "From: <sip:[email protected]>;tag=4a60ce364b774258873ff199e5e39938" + m_CRLF +
                                  "Call-ID: 17324d6df8744d978008c8997bfd208d" + m_CRLF +
                                  "CSeq: 3532 INVITE" + m_CRLF +
                                  "Contact: <sip:[email protected]:60163;ob>" + m_CRLF +
                                  "Max-Forwards: 70" + m_CRLF +
                                  "User-Agent: MicroSIP/3.19.22" + m_CRLF +
                                  "Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS" + m_CRLF +
                                  "Supported: replaces, 100rel, timer, norefersub" + m_CRLF +
                                  "Content-Length: 343" + m_CRLF +
                                  "Content-Type: application/sdp" + m_CRLF +
                                  "Session-Expires: 1800" + m_CRLF +
                                  "Min-SE: 90" + m_CRLF +
                                  "" + m_CRLF +
                                  "v=0" + m_CRLF +
                                  "o=- 3785527268 3785527269 IN IP4 192.168.11.50" + m_CRLF +
                                  "s=pjmedia" + m_CRLF +
                                  "t=0 0" + m_CRLF +
                                  "m=audio 4032 RTP/AVP 0 101" + m_CRLF +
                                  "c=IN IP4 192.168.11.50" + m_CRLF +
                                  "a=rtpmap:0 PCMU/8000" + m_CRLF +
                                  "a=rtpmap:101 telephone-event/8000" + m_CRLF +
                                  "a=fmtp:101 0-16" + m_CRLF +
                                  "a=sendrecv";

            SIPEndPoint      dummySipEndPoint = new SIPEndPoint(new IPEndPoint(IPAddress.Loopback, 0));
            SIPMessageBuffer sipMessageBuffer = SIPMessageBuffer.ParseSIPMessage(inviteReqStr, dummySipEndPoint, dummySipEndPoint);
            SIPRequest       inviteReq        = SIPRequest.ParseSIPRequest(sipMessageBuffer);

            UASInviteTransaction uasTx   = new UASInviteTransaction(transport, inviteReq, null);
            SIPServerUserAgent   mockUas = new SIPServerUserAgent(transport, null, null, null, SIPCallDirection.In, null, null, uasTx);
            await userAgent.Answer(mockUas, CreateMediaSession());

            // Incremented Cseq and modified Via header from original request. Means the request is the same dialog but different tx.
            string inviteReqStr2 = "BYE sip:192.168.11.50:5060 SIP/2.0" + m_CRLF +
                                   "Via: SIP/2.0/UDP 192.168.11.50:60163;rport;branch=z9hG4bKPj869f70960bdd4204b1352eaf242a3700" + m_CRLF +
                                   "To: <sip:[email protected]>;tag=ZUJSXRRGXQ" + m_CRLF +
                                   "From: <sip:[email protected]>;tag=4a60ce364b774258873ff199e5e39938" + m_CRLF +
                                   "Call-ID: 17324d6df8744d978008c8997bfd208d" + m_CRLF +
                                   "CSeq: 3533 BYE" + m_CRLF +
                                   "Contact: <sip:[email protected]:60163;ob>" + m_CRLF +
                                   "Max-Forwards: 70" + m_CRLF +
                                   "User-Agent: MicroSIP/3.19.22" + m_CRLF +
                                   "Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS" + m_CRLF +
                                   "Supported: replaces, 100rel, timer, norefersub" + m_CRLF +
                                   "";

            mockChannel.FireMessageReceived(dummySipEndPoint, dummySipEndPoint, Encoding.UTF8.GetBytes(inviteReqStr2));
        }
Exemple #10
0
        private static Task OnSIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
        {
            if (sipRequest.Method == SIPMethodsEnum.INFO)
            {
                var notImplResp = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotImplemented, null);
                return(_sipTransport.SendResponseAsync(notImplResp));
            }

            return(Task.CompletedTask);
        }
Exemple #11
0
        /// <summary>
        /// Handler for processing incoming SIP requests.
        /// </summary>
        /// <param name="localSIPEndPoint">The end point the request was received on.</param>
        /// <param name="remoteEndPoint">The end point the request came from.</param>
        /// <param name="sipRequest">The SIP request received.</param>
        private static void SIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
        {
            try
            {
                if (sipRequest.Method == SIPMethodsEnum.BYE)
                {
                    throw new NotImplementedException();
                }
                else if (sipRequest.Method == SIPMethodsEnum.CANCEL)
                {
                    throw new NotImplementedException();
                }
                else if (sipRequest.Method == SIPMethodsEnum.INVITE)
                {
                    throw new NotImplementedException();
                }
                else if (sipRequest.Method == SIPMethodsEnum.OPTIONS)
                {
                    SIPNonInviteTransaction optionsTransaction = _sipTransport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null);
                    SIPResponse             optionsResponse    = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
                    optionsTransaction.SendFinalResponse(optionsResponse);
                }
                else if (sipRequest.Method == SIPMethodsEnum.REGISTER)
                {
                    SIPResponse tryingResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Trying, null);
                    _sipTransport.SendResponse(tryingResponse);

                    SIPResponseStatusCodesEnum registerResponse = SIPResponseStatusCodesEnum.Ok;

                    if (sipRequest.Header.Contact != null && sipRequest.Header.Contact.Count > 0)
                    {
                        int expiry                = sipRequest.Header.Contact[0].Expires > 0 ? sipRequest.Header.Contact[0].Expires : sipRequest.Header.Expires;
                        var sipAccount            = new SIPAccount(null, sipRequest.Header.From.FromURI.Host, sipRequest.Header.From.FromURI.User, null, null);
                        SIPAccountBinding binding = new SIPAccountBinding(sipAccount, sipRequest.Header.Contact[0].ContactURI, remoteEndPoint, localSIPEndPoint, expiry);

                        if (_sipRegistrations.ContainsKey(sipAccount.SIPUsername))
                        {
                            _sipRegistrations.Remove(sipAccount.SIPUsername);
                        }

                        _sipRegistrations.Add(sipAccount.SIPUsername, binding);

                        logger.LogDebug("Registered contact for " + sipAccount.SIPUsername + " as " + binding.RegisteredContact.ToString() + ".");
                    }
                    else
                    {
                        registerResponse = SIPResponseStatusCodesEnum.BadRequest;
                    }

                    SIPNonInviteTransaction registerTransaction = _sipTransport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null);
                    SIPResponse             okResponse          = SIPTransport.GetResponse(sipRequest, registerResponse, null);
                    registerTransaction.SendFinalResponse(okResponse);
                }
                else
                {
                    logger.LogDebug("SIP " + sipRequest.Method + " request received but no processing has been set up for it, rejecting.");
                }
            }
            catch (NotImplementedException)
            {
                logger.LogDebug(sipRequest.Method + " request processing not implemented for " + sipRequest.URI.ToParameterlessString() + " from " + remoteEndPoint + ".");

                SIPNonInviteTransaction notImplTransaction = _sipTransport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null);
                SIPResponse             notImplResponse    = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotImplemented, null);
                notImplTransaction.SendFinalResponse(notImplResponse);
            }
        }
        /// <summary>
        /// Because this is a server user agent the SIP transport must start listening for client user agents.
        /// </summary>
        private async Task OnRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
        {
            try
            {
                var banResult = _sipFail2Ban.IsBanned(remoteEndPoint);
                if (banResult == BanReasonsEnum.None)
                {
                    if (sipRequest.Header.From != null &&
                        sipRequest.Header.From.FromTag != null &&
                        sipRequest.Header.To != null &&
                        sipRequest.Header.To.ToTag != null)
                    {
                        _sipCallManager.ProcessInDialogueRequest(localSIPEndPoint, remoteEndPoint, sipRequest);
                    }
                    else
                    {
                        switch (sipRequest.Method)
                        {
                        case SIPMethodsEnum.BYE:
                        case SIPMethodsEnum.CANCEL:
                            // BYE's and CANCEL's should always have dialog fields set.
                            SIPResponse badResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.BadRequest, null);
                            await _sipTransport.SendResponseAsync(badResponse);

                            break;

                        case SIPMethodsEnum.INVITE:
                            if (!await WasRejected(sipRequest))
                            {
                                _logger.LogInformation($"Incoming call request: {localSIPEndPoint}<-{remoteEndPoint} {sipRequest.URI}.");
                                _b2bUserAgentCore.AddInviteRequest(sipRequest);
                            }
                            break;

                        case SIPMethodsEnum.OPTIONS:
                            SIPResponse optionsResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
                            optionsResponse.Header.Contact = new List <SIPContactHeader> {
                                SIPContactHeader.GetDefaultSIPContactHeader(sipRequest.URI.Scheme)
                            };
                            optionsResponse.Header.Server = SIPConstants.SIP_USERAGENT_STRING;
                            await _sipTransport.SendResponseAsync(optionsResponse);

                            break;

                        case SIPMethodsEnum.REGISTER:
                            if (!await WasRejected(sipRequest))
                            {
                                _registrarCore.AddRegisterRequest(localSIPEndPoint, remoteEndPoint, sipRequest);
                            }
                            break;

                        case SIPMethodsEnum.SUBSCRIBE:
                            if (!await WasRejected(sipRequest))
                            {
                                _subscriberCore.AddSubscribeRequest(localSIPEndPoint, remoteEndPoint, sipRequest);
                            }
                            break;

                        default:
                            var notAllowedResp = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null);
                            await _sipTransport.SendResponseAsync(notAllowedResp);

                            break;
                        }
                    }
                }
                else
                {
                    _logger.LogWarning($"Ban list hit for {remoteEndPoint} and {banResult} dropped request {sipRequest.StatusLine}, user agent {sipRequest.Header.UserAgent}.");
                }
            }
            catch (Exception reqExcp)
            {
                _logger.LogWarning($"Exception handling {sipRequest.Method}. {reqExcp.Message}");
            }
        }
Exemple #13
0
        private SIPRequest GetRequest(SIPMethodsEnum method)
        {
            try
            {
                SIPURI uri = SIPURI.ParseSIPURIRelaxed(m_callDescriptor.Uri);

                SIPRequest    request    = new SIPRequest(method, uri);
                SIPFromHeader fromHeader = m_callDescriptor.GetFromHeader();
                fromHeader.FromTag = CallProperties.CreateNewTag();
                SIPToHeader toHeader = new SIPToHeader(null, uri, null);
                int         cseq     = Crypto.GetRandomInt(10000, 20000);

                SIPHeader header = new SIPHeader(fromHeader, toHeader, cseq, CallProperties.CreateNewCallId());
                header.CSeqMethod = method;
                header.UserAgent  = m_userAgent;
                request.Header    = header;

                SIPViaHeader viaHeader = new SIPViaHeader(m_sipTransport.GetDefaultSIPEndPoint(), CallProperties.CreateBranchId());
                request.Header.Vias.PushViaHeader(viaHeader);

                try
                {
                    if (m_callDescriptor.CustomHeaders != null && m_callDescriptor.CustomHeaders.Count > 0)
                    {
                        foreach (string customHeader in m_callDescriptor.CustomHeaders)
                        {
                            if (customHeader.IsNullOrBlank())
                            {
                                continue;
                            }
                            else if (customHeader.Trim().StartsWith(SIPHeaders.SIP_HEADER_USERAGENT))
                            {
                                request.Header.UserAgent = customHeader.Substring(customHeader.IndexOf(":") + 1).Trim();
                            }
                            else
                            {
                                request.Header.UnknownHeaders.Add(customHeader);
                            }
                        }
                    }
                }
                catch (Exception excp)
                {
                    logger.Error("Exception Parsing CustomHeader for SIPNonInviteClientUserAgent GetRequest. " + excp.Message + m_callDescriptor.CustomHeaders);
                }

                if (!m_callDescriptor.Content.IsNullOrBlank())
                {
                    request.Body = m_callDescriptor.Content;
                    request.Header.ContentType   = m_callDescriptor.ContentType;
                    request.Header.ContentLength = request.Body.Length;
                }

                return(request);
            }
            catch (Exception excp)
            {
                logger.Error("Exception SIPNonInviteClientUserAgent GetRequest. " + excp.Message);
                throw excp;
            }
        }
Exemple #14
0
        private void SIPRequestOutTraceEvent(SIPEndPoint localEP, SIPEndPoint remoteEP, SIPRequest sipRequest)
        {
            logger.LogDebug($"Request Sent {localEP}<-{remoteEP}: {sipRequest.StatusLine}.");

            if (_homerSIPClient != null)
            {
                var hepBuffer = HepPacket.GetBytes(localEP, remoteEP, DateTime.Now, 333, "myHep", sipRequest.ToString());
                _homerSIPClient.SendAsync(hepBuffer, hepBuffer.Length, HOMER_SERVER_ADDRESS, HOMER_SERVER_PORT);
            }
        }
        private SIPRequest GetUpdateRequest(SIPRequest inviteRequest, CRMHeaders crmHeaders)
        {
            SIPRequest updateRequest = new SIPRequest(SIPMethodsEnum.UPDATE, inviteRequest.URI);
            updateRequest.LocalSIPEndPoint = inviteRequest.LocalSIPEndPoint;

            SIPHeader inviteHeader = inviteRequest.Header;
            SIPHeader updateHeader = new SIPHeader(inviteHeader.From, inviteHeader.To, inviteHeader.CSeq + 1, inviteHeader.CallId);
            inviteRequest.Header.CSeq++;
            updateRequest.Header = updateHeader;
            updateHeader.CSeqMethod = SIPMethodsEnum.UPDATE;
            updateHeader.Routes = inviteHeader.Routes;
            updateHeader.ProxySendFrom = inviteHeader.ProxySendFrom;

            SIPViaHeader viaHeader = new SIPViaHeader(inviteRequest.LocalSIPEndPoint, CallProperties.CreateBranchId());
            updateHeader.Vias.PushViaHeader(viaHeader);

            // Add custom CRM headers.
            if (crmHeaders != null)
            {
                updateHeader.CRMPersonName = crmHeaders.PersonName;
                updateHeader.CRMCompanyName = crmHeaders.CompanyName;
                updateHeader.CRMPictureURL = crmHeaders.AvatarURL;
            }

            return updateRequest;
        }
        public async Task IncomingCallNoSdpWithACKUnitTest()
        {
            logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name);
            logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name);

            SIPTransport transport = new SIPTransport();

            transport.AddSIPChannel(new MockSIPChannel(new System.Net.IPEndPoint(IPAddress.Any, 0)));
            var dummySep = SIPEndPoint.ParseSIPEndPoint("udp:127.0.0.1:5060");

            SIPUserAgent userAgent = new SIPUserAgent(transport, null);

            string inviteReqStr = @"INVITE sip:[email protected] SIP/2.0
Via: SIP/2.0/UDP 127.0.0.1:51200;branch=z9hG4bKbeed9b0cde8d43cc8a2aae91526b6a1d;rport
To: <sip:[email protected]>
From: <sip:[email protected]>;tag=GCLNRILCDU
Call-ID: 7265e19f53a146a1bacdf4f4f8ea70b2
CSeq: 1 INVITE
Contact: <sip:127.0.0.1:51200>
Max-Forwards: 70
User-Agent: www.sipsorcery.com
Content-Length: 0
Content-Type: application/sdp" + m_CRLF + m_CRLF;

            SIPEndPoint      dummySipEndPoint = new SIPEndPoint(new IPEndPoint(IPAddress.Loopback, 0));
            SIPMessageBuffer sipMessageBuffer = SIPMessageBuffer.ParseSIPMessage(inviteReqStr, dummySipEndPoint, dummySipEndPoint);
            SIPRequest       inviteReq        = SIPRequest.ParseSIPRequest(sipMessageBuffer);

            var uas          = userAgent.AcceptCall(inviteReq);
            var mediaSession = CreateMediaSession();

            _ = Task.Run(() =>
            {
                Task.Delay(2000).Wait();

                string ackReqStr = @"ACK sip:127.0.0.1:5060 SIP/2.0
Via: SIP/2.0/UDP 127.0.0.1:51200;branch=z9hG4bK76dfb1480ea14f778bd24afed1c8ded0;rport
To: <sip:[email protected]>;tag=YWPNZPMLPB
From: <sip:[email protected]>;tag=GCLNRILCDU
Call-ID: 7265e19f53a146a1bacdf4f4f8ea70b2
CSeq: 1 ACK
Max-Forwards: 70
Content-Length: 160

v=0
o=- 67424 0 IN IP4 127.0.0.1
s=-
c=IN IP4 127.0.0.1
t=0 0
m=audio 16976 RTP/AVP 8 101
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=sendrecv" + m_CRLF + m_CRLF;


                uas.ClientTransaction.ACKReceived(dummySep, dummySep, SIPRequest.ParseSIPRequest(ackReqStr));
            });

            await userAgent.Answer(uas, mediaSession);

            Assert.True(userAgent.IsCallActive);
        }
 public SIPTransferServerUserAgent(            
     SIPMonitorLogDelegate logDelegate,
     BlindTransferDelegate blindTransfer,
     SIPTransport sipTransport,
     SIPEndPoint outboundProxy,
     SIPDialogue dialogueToReplace,
     SIPDialogue oppositeDialogue,
     string callDestination,
     string owner,
     string adminID)
 {
     Log_External = logDelegate;
     BlindTransfer_External = blindTransfer;
     m_sipTransport = sipTransport;
     m_outboundProxy = outboundProxy;
     m_dialogueToReplace = dialogueToReplace;
     m_oppositeDialogue = oppositeDialogue;
     m_callDestination = callDestination;
     m_owner = owner;
     m_adminID = adminID;
     m_dummyRequest = CreateDummyRequest(m_dialogueToReplace, m_callDestination);
 }
        private Task <SocketError> OnAckAnswerReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPRequest sipRequest)
        {
            SIPDialogue = new SIPDialogue(m_uasTransaction, m_owner, m_adminMemberId);
            SIPDialogue.TransferMode = m_transferMode;

            OnDialogueCreated?.Invoke(SIPDialogue);

            return(Task.FromResult(SocketError.Success));
        }
        public SIPRequest GetCancelRequest(SIPRequest inviteRequest)
        {
            SIPRequest cancelRequest = new SIPRequest(SIPMethodsEnum.CANCEL, inviteRequest.URI);
            SIPHeader cancelHeader = new SIPHeader(inviteRequest.Header.From, inviteRequest.Header.To, inviteRequest.Header.CSeq, inviteRequest.Header.CallId);
            cancelHeader.Via = inviteRequest.Header.Via;
            cancelHeader.CSeqMethod = SIPMethodsEnum.CANCEL;

            cancelRequest.Header = cancelHeader;

            return cancelRequest;
        }
        public bool AuthenticateCall()
        {
            m_isAuthenticated = false;

            try
            {
                if (SIPAuthenticateRequest_External == null)
                {
                    // No point trying to authenticate if we haven't been given an authentication delegate.
                    Reject(SIPResponseStatusCodesEnum.InternalServerError, null, null);
                }
                else if (GetSIPAccount_External == null)
                {
                    // No point trying to authenticate if we haven't been given a  delegate to load the SIP account.
                    Reject(SIPResponseStatusCodesEnum.InternalServerError, null, null);
                }
                else
                {
                    m_sipAccount = GetSIPAccount_External(m_sipUsername, m_sipDomain);

                    if (m_sipAccount == null)
                    {
                        Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Rejecting authentication required call for " + m_sipUsername + "@" + m_sipDomain + ", SIP account not found.", null));
                        Reject(SIPResponseStatusCodesEnum.Forbidden, null, null);
                    }
                    else
                    {
                        SIPRequest  sipRequest       = m_uasTransaction.TransactionRequest;
                        SIPEndPoint localSIPEndPoint = (!sipRequest.Header.ProxyReceivedOn.IsNullOrBlank()) ? SIPEndPoint.ParseSIPEndPoint(sipRequest.Header.ProxyReceivedOn) : sipRequest.LocalSIPEndPoint;
                        SIPEndPoint remoteEndPoint   = (!sipRequest.Header.ProxyReceivedFrom.IsNullOrBlank()) ? SIPEndPoint.ParseSIPEndPoint(sipRequest.Header.ProxyReceivedFrom) : sipRequest.RemoteSIPEndPoint;

                        SIPRequestAuthenticationResult authenticationResult = SIPAuthenticateRequest_External(localSIPEndPoint, remoteEndPoint, sipRequest, m_sipAccount, Log_External);
                        if (authenticationResult.Authenticated)
                        {
                            if (authenticationResult.WasAuthenticatedByIP)
                            {
                                Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "New call from " + remoteEndPoint.ToString() + " successfully authenticated by IP address.", m_sipAccount.Owner));
                            }
                            else
                            {
                                Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "New call from " + remoteEndPoint.ToString() + " successfully authenticated by digest.", m_sipAccount.Owner));
                            }

                            SetOwner(m_sipAccount.Owner, m_sipAccount.AdminMemberId);
                            m_isAuthenticated = true;
                        }
                        else
                        {
                            // Send authorisation failure or required response
                            SIPResponse authReqdResponse = SIPTransport.GetResponse(sipRequest, authenticationResult.ErrorResponse, null);
                            authReqdResponse.Header.AuthenticationHeader = authenticationResult.AuthenticationRequiredHeader;
                            Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Call not authenticated for " + m_sipUsername + "@" + m_sipDomain + ", responding with " + authenticationResult.ErrorResponse + ".", null));
                            m_uasTransaction.SendFinalResponse(authReqdResponse);
                        }
                    }
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception SIPServerUserAgent AuthenticateCall. " + excp.Message);
                Reject(SIPResponseStatusCodesEnum.InternalServerError, null, null);
            }

            return(m_isAuthenticated);
        }
        public SIPRequest GetSIPRequest(SIPMethodsEnum sipMethod, string requestURIStr, string fromURIStr, int cseq, string callId, string contentType, string body)
        {
            SIPURI requestURI = (requestURIStr.StartsWith("sip:")) ? SIPURI.ParseSIPURI(requestURIStr) : SIPURI.ParseSIPURI("sip:" + requestURIStr);
            SIPURI fromURI = (fromURIStr.StartsWith("sip:")) ? SIPURI.ParseSIPURI(fromURIStr) : SIPURI.ParseSIPURI("sip:" + fromURIStr);

            SIPFromHeader fromHeader = new SIPFromHeader(null, fromURI, CallProperties.CreateNewTag());
            SIPToHeader toHeader = new SIPToHeader(null, requestURI, null);

            SIPRequest sipRequest = new SIPRequest(sipMethod, requestURI);

            IPEndPoint localSIPEndPoint = m_sipTransport.GetIPEndPointsList()[0];
            SIPHeader sipHeader = new SIPHeader(fromHeader, toHeader, cseq, callId);

            sipHeader.Contact = SIPContactHeader.ParseContactHeader("sip:" + localSIPEndPoint.ToString());
            sipHeader.CSeqMethod = sipMethod;
            sipRequest.Header = sipHeader;

            SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint.Address.ToString(), localSIPEndPoint.Port, CallProperties.CreateBranchId());
            sipRequest.Header.Via.PushViaHeader(viaHeader);

            if (body != null && body.Trim().Length > 0)
            {
                sipRequest.Body = body;
                //sipRequest.Body = "Signal=5\r\nDuration=250";
                //sipRequest.Body = "<rtcp>blah blah blah</rtcp>";
                sipRequest.Header.ContentLength = sipRequest.Body.Length;
                sipRequest.Header.ContentType = contentType;
            }

            return sipRequest;
        }
Exemple #22
0
        public void AddSubscribeRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest subscribeRequest)
        {
            try
            {
                if (subscribeRequest.Method != SIPMethodsEnum.SUBSCRIBE)
                {
                    SIPResponse notSupportedResponse = SIPTransport.GetResponse(subscribeRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, "Subscribe requests only");
                    m_sipTransport.SendResponse(notSupportedResponse);
                }
                else
                {
                    #region Do as many validation checks as possible on the request before adding it to the queue.

                    if (subscribeRequest.Header.Event.IsNullOrBlank() ||
                        !(subscribeRequest.Header.Event.ToLower() == SIPEventPackage.Dialog.ToString().ToLower() || subscribeRequest.Header.Event.ToLower() == SIPEventPackage.Presence.ToString().ToLower()))
                    {
                        SIPResponse badEventResponse = SIPTransport.GetResponse(subscribeRequest, SIPResponseStatusCodesEnum.BadEvent, null);
                        m_sipTransport.SendResponse(badEventResponse);
                        FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Warn, "Event type " + subscribeRequest.Header.Event + " not supported for " + subscribeRequest.URI.ToString() + ".", null));
                    }
                    else if (subscribeRequest.Header.Expires > 0 && subscribeRequest.Header.Expires < MIN_SUBSCRIPTION_EXPIRY)
                    {
                        SIPResponse tooBriefResponse = SIPTransport.GetResponse(subscribeRequest, SIPResponseStatusCodesEnum.IntervalTooBrief, null);
                        tooBriefResponse.Header.MinExpires = MIN_SUBSCRIPTION_EXPIRY;
                        m_sipTransport.SendResponse(tooBriefResponse);
                        FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Warn, "Subscribe request was rejected as interval too brief " + subscribeRequest.Header.Expires + ".", null));
                    }
                    else if (subscribeRequest.Header.Contact == null || subscribeRequest.Header.Contact.Count == 0)
                    {
                        SIPResponse noContactResponse = SIPTransport.GetResponse(subscribeRequest, SIPResponseStatusCodesEnum.BadRequest, "Missing Contact header");
                        m_sipTransport.SendResponse(noContactResponse);
                        FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Warn, "Subscribe request was rejected due to no Contact header.", null));
                    }

                    #endregion

                    else
                    {
                        if (m_notifierQueue.Count < MAX_NOTIFIER_QUEUE_SIZE)
                        {
                            SIPNonInviteTransaction subscribeTransaction = m_sipTransport.CreateNonInviteTransaction(subscribeRequest, remoteEndPoint, localSIPEndPoint, m_outboundProxy);
                            lock (m_notifierQueue)
                            {
                                m_notifierQueue.Enqueue(subscribeTransaction);
                            }
                            FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeQueued, "Subscribe queued for " + subscribeRequest.Header.To.ToURI.ToString() + ".", null));
                        }
                        else
                        {
                            logger.Error("Subscribe queue exceeded max queue size " + MAX_NOTIFIER_QUEUE_SIZE + ", overloaded response sent.");
                            SIPResponse overloadedResponse = SIPTransport.GetResponse(subscribeRequest, SIPResponseStatusCodesEnum.TemporarilyUnavailable, "Notifier overloaded, please try again shortly");
                            m_sipTransport.SendResponse(overloadedResponse);
                        }

                        m_notifierARE.Set();
                    }
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception AddNotifierRequest (" + remoteEndPoint.ToString() + "). " + excp.Message);
            }
        }
        public SIPResponse WaitForFinalResponse(int waitSeconds, SIPRequest sipRequest)
        {
            DateTime startWaitTime = DateTime.Now;
            m_waitForSIPFinalResponse.Reset();
            m_lastFinalResponse = null;

            while (m_lastFinalResponse == null && DateTime.Now.Subtract(startWaitTime).TotalSeconds < waitSeconds)
            {
                m_waitForSIPFinalResponse.WaitOne(Convert.ToInt32((waitSeconds - DateTime.Now.Subtract(startWaitTime).TotalSeconds) * 1000), false);

                if (m_lastFinalResponse != null && m_lastFinalResponse.Header.CallId == sipRequest.Header.CallId)
                {
                    break;
                }
                else
                {
                    m_lastFinalResponse = null;
                }
            }

            return m_lastFinalResponse;
        }
Exemple #24
0
        private void Subscribe(SIPTransaction subscribeTransaction)
        {
            try
            {
                SIPRequest sipRequest      = subscribeTransaction.TransactionRequest;
                string     fromUser        = sipRequest.Header.From.FromURI.User;
                string     fromHost        = sipRequest.Header.From.FromURI.Host;
                string     canonicalDomain = GetCanonicalDomain_External(fromHost, true);

                if (canonicalDomain == null)
                {
                    FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Warn, "Subscribe request for " + fromHost + " rejected as no matching domain found.", null));
                    SIPResponse noDomainResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, "Domain not serviced");
                    subscribeTransaction.SendFinalResponse(noDomainResponse);
                    return;
                }
                SIPAccountAsset sipAccountAsset = m_sipAssetPersistor.Get(s => s.SIPUsername == fromUser && s.SIPDomain == canonicalDomain);
                SIPRequestAuthenticationResult authenticationResult = SIPRequestAuthenticator_External(subscribeTransaction.LocalSIPEndPoint, subscribeTransaction.RemoteEndPoint, sipRequest, sipAccountAsset.SIPAccount, FireProxyLogEvent);

                if (!authenticationResult.Authenticated)
                {
                    // 401 Response with a fresh nonce needs to be sent.
                    SIPResponse authReqdResponse = SIPTransport.GetResponse(sipRequest, authenticationResult.ErrorResponse, null);
                    authReqdResponse.Header.AuthenticationHeader = authenticationResult.AuthenticationRequiredHeader;
                    subscribeTransaction.SendFinalResponse(authReqdResponse);

                    if (authenticationResult.ErrorResponse == SIPResponseStatusCodesEnum.Forbidden)
                    {
                        FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Warn, "Forbidden " + fromUser + "@" + canonicalDomain + " does not exist, " + sipRequest.Header.ProxyReceivedFrom.ToString() + ", " + sipRequest.Header.UserAgent + ".", null));
                    }
                    else
                    {
                        FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAuth, "Authentication required for " + fromUser + "@" + canonicalDomain + " from " + subscribeTransaction.RemoteEndPoint + ".", sipAccountAsset.Owner));
                    }
                    return;
                }
                else
                {
                    if (sipRequest.Header.To.ToTag != null)
                    {
                        // Request is to renew an existing subscription.
                        SIPResponseStatusCodesEnum errorResponse = SIPResponseStatusCodesEnum.None;
                        string errorResponseReason = null;

                        string sessionID = m_subscriptionsManager.RenewSubscription(sipRequest, out errorResponse, out errorResponseReason);
                        if (errorResponse != SIPResponseStatusCodesEnum.None)
                        {
                            // A subscription renewal attempt failed
                            SIPResponse renewalErrorResponse = SIPTransport.GetResponse(sipRequest, errorResponse, errorResponseReason);
                            subscribeTransaction.SendFinalResponse(renewalErrorResponse);
                            FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeFailed, "Subscription renewal failed for event type " + sipRequest.Header.Event + " " + sipRequest.URI.ToString() + ", " + errorResponse + " " + errorResponseReason + ".", sipAccountAsset.Owner));
                        }
                        else if (sipRequest.Header.Expires == 0)
                        {
                            // Existing subscription was closed.
                            SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
                            subscribeTransaction.SendFinalResponse(okResponse);
                        }
                        else
                        {
                            // Existing subscription was found.
                            SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
                            subscribeTransaction.SendFinalResponse(okResponse);
                            FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeRenew, "Subscription renewal for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + " and expiry " + sipRequest.Header.Expires + ".", sipAccountAsset.Owner));
                            m_subscriptionsManager.SendFullStateNotify(sessionID);
                        }
                    }
                    else
                    {
                        // Authenticated but the this is a new subscription request and authorisation to subscribe to the requested resource also needs to be checked.
                        SIPURI canonicalResourceURI    = sipRequest.URI.CopyOf();
                        string resourceCanonicalDomain = GetCanonicalDomain_External(canonicalResourceURI.Host, true);
                        canonicalResourceURI.Host = resourceCanonicalDomain;
                        SIPAccountAsset resourceSIPAccount = null;

                        if (resourceCanonicalDomain == null)
                        {
                            SIPResponse notFoundResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotFound, "Domain " + resourceCanonicalDomain + " not serviced");
                            subscribeTransaction.SendFinalResponse(notFoundResponse);
                            FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeFailed, "Subscription failed for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + ", domain not serviced.", sipAccountAsset.Owner));
                            return;
                        }

                        if (canonicalResourceURI.User != m_wildcardUser)
                        {
                            resourceSIPAccount = m_sipAssetPersistor.Get(s => s.SIPUsername == canonicalResourceURI.User && s.SIPDomain == canonicalResourceURI.Host);

                            if (resourceSIPAccount == null)
                            {
                                SIPResponse notFoundResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotFound, "Requested resource does not exist");
                                subscribeTransaction.SendFinalResponse(notFoundResponse);
                                FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeFailed, "Subscription failed for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + ", SIP account does not exist.", sipAccountAsset.Owner));
                                return;
                            }
                        }

                        // Check the owner permissions on the requesting and subscribed resources.
                        bool   authorised = false;
                        string adminID    = null;

                        if (canonicalResourceURI.User == m_wildcardUser || sipAccountAsset.Owner == resourceSIPAccount.Owner)
                        {
                            authorised = true;
                            FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAuth, "Subscription to " + canonicalResourceURI.ToString() + " authorised due to common owner.", sipAccountAsset.Owner));
                        }
                        else
                        {
                            // Lookup the customer record for the requestor and check the administrative level on it.
                            Customer requestingCustomer = GetCustomer_External(c => c.CustomerUsername == sipAccountAsset.Owner);
                            adminID = requestingCustomer.AdminId;
                            if (!resourceSIPAccount.AdminMemberId.IsNullOrBlank() && requestingCustomer.AdminId == resourceSIPAccount.AdminMemberId)
                            {
                                authorised = true;
                                FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAuth, "Subscription to " + canonicalResourceURI.ToString() + " authorised due to requestor admin permissions for domain " + resourceSIPAccount.AdminMemberId + ".", sipAccountAsset.Owner));
                            }
                            else if (requestingCustomer.AdminId == m_topLevelAdminID)
                            {
                                authorised = true;
                                FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAuth, "Subscription to " + canonicalResourceURI.ToString() + " authorised due to requestor having top level admin permissions.", sipAccountAsset.Owner));
                            }
                        }

                        if (authorised)
                        {
                            // Request is to create a new subscription.
                            SIPResponseStatusCodesEnum errorResponse = SIPResponseStatusCodesEnum.None;
                            string errorResponseReason = null;
                            string toTag     = CallProperties.CreateNewTag();
                            string sessionID = m_subscriptionsManager.SubscribeClient(sipAccountAsset.Owner, adminID, sipRequest, toTag, canonicalResourceURI, out errorResponse, out errorResponseReason);

                            if (errorResponse != SIPResponseStatusCodesEnum.None)
                            {
                                SIPResponse subscribeErrorResponse = SIPTransport.GetResponse(sipRequest, errorResponse, errorResponseReason);
                                subscribeTransaction.SendFinalResponse(subscribeErrorResponse);
                                FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAccept, "Subscription failed for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + ", " + errorResponse + " " + errorResponseReason + ".", sipAccountAsset.Owner));
                            }
                            else
                            {
                                SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
                                okResponse.Header.To.ToTag = toTag;
                                okResponse.Header.Expires  = sipRequest.Header.Expires;
                                okResponse.Header.Contact  = new List <SIPContactHeader>()
                                {
                                    new SIPContactHeader(null, new SIPURI(SIPSchemesEnum.sip, subscribeTransaction.LocalSIPEndPoint))
                                };
                                subscribeTransaction.SendFinalResponse(okResponse);
                                FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAccept, "Subscription accepted for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + " and expiry " + sipRequest.Header.Expires + ".", sipAccountAsset.Owner));

                                if (sessionID != null)
                                {
                                    m_subscriptionsManager.SendFullStateNotify(sessionID);
                                }
                            }
                        }
                        else
                        {
                            SIPResponse forbiddenResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, "Requested resource not authorised");
                            subscribeTransaction.SendFinalResponse(forbiddenResponse);
                            FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeFailed, "Subscription failed for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + ", requesting account " + sipAccountAsset.Owner + " was not authorised.", sipAccountAsset.Owner));
                        }
                    }
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception notifiercore subscribing. " + excp.Message + "\r\n" + subscribeTransaction.TransactionRequest.ToString());
                FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Error, "Exception notifiercore subscribing. " + excp.Message, null));
                SIPResponse errorResponse = SIPTransport.GetResponse(subscribeTransaction.TransactionRequest, SIPResponseStatusCodesEnum.InternalServerError, null);
                subscribeTransaction.SendFinalResponse(errorResponse);
            }
        }
Exemple #25
0
        /// <summary>
        /// Handler for processing incoming SIP requests.
        /// </summary>
        /// <param name="localSIPEndPoint">The end point the request was received on.</param>
        /// <param name="remoteEndPoint">The end point the request came from.</param>
        /// <param name="sipRequest">The SIP request received.</param>
        private Task SIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
        {
            if (sipRequest.Method == SIPMethodsEnum.INFO)
            {
                logger.LogDebug("SIP " + sipRequest.Method + " request received but no processing has been set up for it, rejecting.");
                SIPResponse notAllowedResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null);
                return(SIPTransport.SendResponseAsync(notAllowedResponse));
            }
            else if (sipRequest.Header.From != null &&
                     sipRequest.Header.From.FromTag != null &&
                     sipRequest.Header.To != null &&
                     sipRequest.Header.To.ToTag != null)
            {
                // This is an in-dialog request that will be handled directly by a user agent instance.
            }
            else if (sipRequest.Method == SIPMethodsEnum.INVITE)
            {
                bool?callAccepted = IncomingCall?.Invoke(sipRequest);

                if (callAccepted == false)
                {
                    // All user agents were already on a call return a busy response.
                    UASInviteTransaction uasTransaction = new UASInviteTransaction(SIPTransport, sipRequest, null);
                    SIPResponse          busyResponse   = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.BusyHere, null);
                    uasTransaction.SendFinalResponse(busyResponse);
                }
            }
            else
            {
                logger.LogDebug("SIP " + sipRequest.Method + " request received but no processing has been set up for it, rejecting.");
                SIPResponse notAllowedResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null);
                return(SIPTransport.SendResponseAsync(notAllowedResponse));
            }

            return(Task.FromResult(0));
        }
        public void AddRegisterRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest registerRequest)
        {
            if (registerRequest.Method != SIPMethodsEnum.REGISTER)
            {
                SIPResponse notSupportedResponse = SIPResponse.GetResponse(registerRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, "Registration requests only");
                m_sipTransport.SendResponseAsync(notSupportedResponse).Wait();
            }
            else
            {
                int requestedExpiry = GetRequestedExpiry(registerRequest);

                if (requestedExpiry > 0 && requestedExpiry < m_minimumBindingExpiry)
                {
                    Logger.LogDebug("Bad register request, no expiry of " + requestedExpiry + " to small from " + remoteEndPoint + ".");
                    SIPResponse tooFrequentResponse = SIPResponse.GetResponse(registerRequest, SIPResponseStatusCodesEnum.IntervalTooBrief, null);
                    tooFrequentResponse.Header.MinExpires = m_minimumBindingExpiry;
                    m_sipTransport.SendResponseAsync(tooFrequentResponse).Wait();
                }
                else
                {
                    if (m_registerQueue.Count < MAX_REGISTER_QUEUE_SIZE)
                    {
                        SIPNonInviteTransaction regTx = new SIPNonInviteTransaction(m_sipTransport, registerRequest, null);
                        m_registerQueue.Enqueue(regTx);
                    }
                    else
                    {
                        Logger.LogError("Register queue exceeded maximum queue size " + MAX_REGISTER_QUEUE_SIZE + ", overloaded response sent.");
                        SIPResponse overloadedResponse = SIPResponse.GetResponse(registerRequest, SIPResponseStatusCodesEnum.TemporarilyUnavailable, "Registrar overloaded, please try again shortly");
                        m_sipTransport.SendResponseAsync(overloadedResponse).Wait();
                    }

                    m_registerARE.Set();
                }
            }
        }
        public SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum serverType, SIPMonitorEventTypesEnum eventType, string message, SIPRequest sipRequest, SIPResponse sipResponse, SIPEndPoint localEndPoint, SIPEndPoint remoteEndPoint, SIPCallDirection callDirection)
        {
            m_serialisationPrefix = SERIALISATION_PREFIX;
            ClientType            = SIPMonitorClientTypesEnum.Console;

            ServerType     = serverType;
            EventType      = eventType;
            Message        = message;
            RemoteEndPoint = remoteEndPoint;
            ServerEndPoint = localEndPoint;
            Created        = DateTimeOffset.UtcNow;
#if !SILVERLIGHT
            ProcessID = Process.GetCurrentProcess().Id;
#endif

            string dirn = (callDirection == SIPCallDirection.In) ? CALLDIRECTION_IN_STRING : CALLDIRECTION_OUT_STRING;
            if (sipRequest != null)
            {
                Message = "REQUEST (" + Created.ToString("HH:mm:ss:fff") + "): " + localEndPoint + dirn + remoteEndPoint + "\r\n" + sipRequest.ToString();
            }
            else if (sipResponse != null)
            {
                Message = "RESPONSE (" + Created.ToString("HH:mm:ss:fff") + "): " + localEndPoint + dirn + remoteEndPoint + "\r\n" + sipResponse.ToString();
            }
        }
Exemple #28
0
        private void DeviceDmsRegister(SIPTransaction sipTransaction, string gbname)
        {
            try
            {
                //Device insert into database
                Device     _device    = new Device();
                SIPRequest sipRequest = sipTransaction.TransactionRequest;
                _device.Guid = Guid.NewGuid().ToString();
                _device.IP   = sipTransaction.TransactionRequest.RemoteSIPEndPoint.Address.ToString();//IPC
                _device.Name = gbname;
                _device.LoginUser.Add(new LoginUser()
                {
                    LoginName = _SIPAccount.SIPUsername ?? "admin", LoginPwd = _SIPAccount.SIPPassword ?? "123456"
                });                                                                                                //same to GB config service
                _device.Port         = Convert.ToUInt32(sipTransaction.TransactionRequest.RemoteSIPEndPoint.Port); //5060
                _device.GBID         = sipTransaction.TransactionRequestFrom.URI.User;                             //42010000001180000184
                _device.PtzType      = 0;
                _device.ProtocolType = 0;
                _device.ShapeType    = ShapeType.Dome;
                //var options = new List<ChannelOption> { new ChannelOption(ChannelOptions.MaxMessageLength, int.MaxValue) };

                //devicemanagementservice 是预留的服务标识(暂命名为设备管理服务).目前没有这个服务.
                //需要你的微服务架构中实现一个设备资产以及一个配置管理服务(或者二合一的资源管服务)
                //以达到两个目的:1、用来为当前GB服务提供启动配置,2、为GB收到注册的设备/平台信息,提供全平台的统一的存储服务.
                var channel = GrpcChannel.ForAddress(EnvironmentVariables.DeviceManagementServiceAddress ?? "devicemanagementservice:8080"); //, ChannelCredentials.Insecure);
                logger.Debug("Device Management Service Address: " + (EnvironmentVariables.DeviceManagementServiceAddress ?? "devicemanagementservice:8080"));
                var client = new DevicesManager.DevicesManagerClient(channel);
                //if (!_sipCoreMessageService.NodeMonitorService.ContainsKey(_device.GBID))
                //{
                //    AddDeviceRequest _AddDeviceRequest = new AddDeviceRequest();
                //    _AddDeviceRequest.Device.Add(_device);
                //    _AddDeviceRequest.LoginRoleId = "XXXX";
                //    var reply = client.AddDevice(_AddDeviceRequest);
                //    if (reply.Status == OP_RESULT_STATUS.OpSuccess)
                //    {
                //        logger.Debug("Device[" + sipTransaction.TransactionRequest.RemoteSIPEndPoint + "] have added registering DMS service.");
                //        DeviceEditEvent(_device.GBID, "add");
                //    }
                //    else
                //    {
                //        logger.Error("_sipRegistrarCore_RPCDmsRegisterReceived.AddDevice: " + reply.Status.ToString());
                //    }
                //}
                //else
                //{
                //    UpdateDeviceRequest _UpdateDeviceRequest = new UpdateDeviceRequest();
                //    _UpdateDeviceRequest.DeviceItem.Add(_device);
                //    _UpdateDeviceRequest.LoginRoleId = "XXXX";
                //    var reply = client.UpdateDevice(_UpdateDeviceRequest);
                //    if (reply.Status == OP_RESULT_STATUS.OpSuccess)
                //    {
                //        logger.Debug("Device[" + sipTransaction.TransactionRequest.RemoteSIPEndPoint + "] have updated registering DMS service.");
                //    }
                //    else
                //    {
                //        logger.Error("_sipRegistrarCore_RPCDmsRegisterReceived.UpdateDevice: " + reply.Status.ToString());
                //    }
                //}

                //add & update device
                AddDeviceRequest _AddDeviceRequest = new AddDeviceRequest();
                _AddDeviceRequest.Device.Add(_device);
                _AddDeviceRequest.LoginRoleId = "XXXX";
                var reply = client.AddDevice(_AddDeviceRequest);
                if (reply.Status == OP_RESULT_STATUS.OpSuccess)
                {
                    logger.Debug("Device added into DMS service: " + JsonConvert.SerializeObject(_device));
                }
                else
                {
                    logger.Warn("DeviceDmsRegister.AddDevice: " + reply.Status.ToString());
                }
            }
            catch (Exception ex)
            {
                logger.Error("DeviceDmsRegister Exception: " + ex.Message);
            }
        }
        private SIPRequest GetByeRequest(SIPResponse inviteResponse, SIPURI byeURI, SIPEndPoint localSIPEndPoint)
        {
            SIPRequest byeRequest = new SIPRequest(SIPMethodsEnum.BYE, byeURI);
            byeRequest.LocalSIPEndPoint = localSIPEndPoint;

            SIPFromHeader byeFromHeader = inviteResponse.Header.From;
            SIPToHeader byeToHeader = inviteResponse.Header.To;
            int cseq = inviteResponse.Header.CSeq + 1;

            SIPHeader byeHeader = new SIPHeader(byeFromHeader, byeToHeader, cseq, inviteResponse.Header.CallId);
            byeHeader.CSeqMethod = SIPMethodsEnum.BYE;
            byeHeader.ProxySendFrom = m_serverTransaction.TransactionRequest.Header.ProxySendFrom;
            byeRequest.Header = byeHeader;

            byeRequest.Header.Routes = (inviteResponse.Header.RecordRoutes != null) ? inviteResponse.Header.RecordRoutes.Reversed() : null;

            SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, CallProperties.CreateBranchId());
            byeRequest.Header.Vias.PushViaHeader(viaHeader);

            return byeRequest;
        }
 public void GotRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
 {
     try
     {
         if (sipRequest.Method == SIPMethodsEnum.NOTIFY)
         {
             if (sipRequest.Header.UnknownHeaders.Exists(s => s.Contains("Event: keep-alive")))
             {
                 // If this is a NOTIFY request that's being sent for NAT keep-alive purposes repond with Ok.
                 SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
                 m_sipTransport.SendResponse(okResponse);
             }
             if (GetCanonicalDomain_External(sipRequest.URI.Host, true) != null && !sipRequest.URI.User.IsNullOrBlank())
             {
                 m_notifyManager.QueueNotification(sipRequest);
             }
             else
             {
                 // Send Not Serviced response to server.
                 SIPResponse notServicedResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotFound, "Domain not serviced");
                 m_sipTransport.SendResponse(notServicedResponse);
             }
         }
         else if (sipRequest.Method == SIPMethodsEnum.SUBSCRIBE)
         {
             m_notifierCore.AddSubscribeRequest(localSIPEndPoint, remoteEndPoint, sipRequest);
         }
         else
         {
             SIPResponse methodNotSupportedResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null);
             m_sipTransport.SendResponse(methodNotSupportedResponse);
         }
     }
     catch (Exception excp)
     {
         logger.Error("Exception SIPNotifierDaemon GotRequest. " + excp.Message);
     }
 }
        //private void ByeFinalResponseReceived(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse)
        //{
        //    Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "BYE response " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + ".", Owner));
        //}
        private SIPRequest GetInviteRequest(SIPCallDescriptor sipCallDescriptor, string branchId, string callId, SIPEndPoint localSIPEndPoint, SIPRouteSet routeSet, string content, string contentType)
        {
            SIPRequest inviteRequest = new SIPRequest(SIPMethodsEnum.INVITE, sipCallDescriptor.Uri);
            inviteRequest.LocalSIPEndPoint = localSIPEndPoint;

            SIPHeader inviteHeader = new SIPHeader(sipCallDescriptor.GetFromHeader(), SIPToHeader.ParseToHeader(sipCallDescriptor.To), 1, callId);

            inviteHeader.From.FromTag = CallProperties.CreateNewTag();

            // For incoming calls forwarded via the dial plan the username needs to go into the Contact header.
            inviteHeader.Contact = new List<SIPContactHeader>() { new SIPContactHeader(null, new SIPURI(inviteRequest.URI.Scheme, localSIPEndPoint)) };
            inviteHeader.Contact[0].ContactURI.User = sipCallDescriptor.Username;
            inviteHeader.CSeqMethod = SIPMethodsEnum.INVITE;
            inviteHeader.UserAgent = m_userAgent;
            inviteHeader.Routes = routeSet;
            inviteRequest.Header = inviteHeader;

            if (!sipCallDescriptor.ProxySendFrom.IsNullOrBlank())
            {
                inviteHeader.ProxySendFrom = sipCallDescriptor.ProxySendFrom;
            }

            SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, branchId);
            inviteRequest.Header.Vias.PushViaHeader(viaHeader);

            inviteRequest.Body = content;
            inviteRequest.Header.ContentLength = (inviteRequest.Body != null) ? inviteRequest.Body.Length : 0;
            inviteRequest.Header.ContentType = contentType;

            // Add custom switchboard headers.
            if (CallDescriptor.SwitchboardHeaders != null)
            {
                inviteHeader.SwitchboardOriginalCallID = CallDescriptor.SwitchboardHeaders.SwitchboardOriginalCallID;
                //inviteHeader.SwitchboardCallerDescription = CallDescriptor.SwitchboardHeaders.SwitchboardCallerDescription;
                inviteHeader.SwitchboardLineName = CallDescriptor.SwitchboardHeaders.SwitchboardLineName;
                //inviteHeader.SwitchboardOwner = CallDescriptor.SwitchboardHeaders.SwitchboardOwner;
                //inviteHeader.SwitchboardOriginalFrom = CallDescriptor.SwitchboardHeaders.SwitchboardOriginalFrom;
            }

            // Add custom CRM headers.
            if (CallDescriptor.CRMHeaders != null)
            {
                inviteHeader.CRMPersonName = CallDescriptor.CRMHeaders.PersonName;
                inviteHeader.CRMCompanyName = CallDescriptor.CRMHeaders.CompanyName;
                inviteHeader.CRMPictureURL = CallDescriptor.CRMHeaders.AvatarURL;
            }

            try
            {
                if (sipCallDescriptor.CustomHeaders != null && sipCallDescriptor.CustomHeaders.Count > 0)
                {
                    foreach (string customHeader in sipCallDescriptor.CustomHeaders)
                    {
                        if (customHeader.IsNullOrBlank())
                        {
                            continue;
                        }
                        else if (customHeader.Trim().StartsWith(SIPHeaders.SIP_HEADER_USERAGENT))
                        {
                            inviteRequest.Header.UserAgent = customHeader.Substring(customHeader.IndexOf(":") + 1).Trim();
                        }
                        else
                        {
                            inviteRequest.Header.UnknownHeaders.Add(customHeader);
                        }
                    }
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception Parsing CustomHeader for GetInviteRequest. " + excp.Message + sipCallDescriptor.CustomHeaders);
            }

            return inviteRequest;
        }
Exemple #32
0
        private void SendInitialRegister()
        {
            try
            {
                if (m_attempts >= m_maxRegisterAttempts)
                {
                    Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient,
                                                            SIPMonitorEventTypesEnum.ContactRegisterFailed,
                                                            "Registration to " + m_sipAccountAOR.ToString() +
                                                            " reached the maximum number of allowed attempts without a failure condition.", null));
                    m_isRegistered = false;
                    RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR,
                                                         "Registration reached the maximum number of allowed attempts.");
                    m_waitForRegistrationMRE.Set();
                }
                else
                {
                    m_attempts++;

                    SIPEndPoint registrarSIPEndPoint = m_outboundProxy;
                    if (registrarSIPEndPoint == null)
                    {
                        SIPDNSLookupResult lookupResult = m_sipTransport.GetHostEndPoint(m_registrarHost, false);
                        if (lookupResult.LookupError != null)
                        {
                            Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient,
                                                                    SIPMonitorEventTypesEnum.ContactRegisterFailed,
                                                                    "Could not resolve " + m_registrarHost + ", " + lookupResult.LookupError, null));
                        }
                        else
                        {
                            registrarSIPEndPoint = lookupResult.GetSIPEndPoint();
                        }
                    }

                    if (registrarSIPEndPoint == null)
                    {
                        logger.LogWarning("SIPRegistrationAgent could not resolve " + m_registrarHost + ".");

                        RegistrationFailed?.Invoke(m_sipAccountAOR, "Could not resolve " + m_registrarHost + ".");
                    }
                    else
                    {
                        Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient,
                                                                SIPMonitorEventTypesEnum.ContactRegisterInProgress,
                                                                "Initiating registration to " + m_registrarHost + " at " + registrarSIPEndPoint.ToString() +
                                                                " for " + m_sipAccountAOR.ToString() + ".", null));
                        SIPRequest regRequest = GetRegistrationRequest();

                        SIPNonInviteTransaction regTransaction =
                            new SIPNonInviteTransaction(m_sipTransport, regRequest, registrarSIPEndPoint);
                        // These handlers need to be on their own threads to take the processing off the SIP transport layer.
                        regTransaction.NonInviteTransactionFinalResponseReceived += (lep, rep, tn, rsp) =>
                        {
                            ThreadPool.QueueUserWorkItem(delegate { ServerResponseReceived(lep, rep, tn, rsp); });
                            return(Task.FromResult(SocketError.Success));
                        };
                        regTransaction.NonInviteTransactionTimedOut += (tn) =>
                        {
                            ThreadPool.QueueUserWorkItem(delegate { RegistrationTimedOut(tn); });
                        };

                        m_sipTransport.SendTransaction(regTransaction);
                    }
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception SendInitialRegister to " + m_registrarHost + ". " + excp.Message);
                RegistrationFailed?.Invoke(m_sipAccountAOR,
                                           "Exception SendInitialRegister to " + m_registrarHost + ". " + excp.Message);
            }
        }
        private SIPRequest CreateDummyRequest(SIPDialogue dialogueToReplace, string callDestination)
        {
            SIPRequest dummyInvite = new SIPRequest(SIPMethodsEnum.INVITE, SIPURI.ParseSIPURIRelaxed(callDestination + "@sipsorcery.com"));
            SIPHeader dummyHeader = new SIPHeader("<sip:[email protected]>", "<sip:[email protected]>", 1, CallProperties.CreateNewCallId());
            dummyHeader.CSeqMethod = SIPMethodsEnum.INVITE;
            dummyHeader.Vias.PushViaHeader(new SIPViaHeader(new IPEndPoint(SIPTransport.BlackholeAddress, 0), CallProperties.CreateBranchId()));
            dummyInvite.Header = dummyHeader;
            dummyInvite.Header.ContentType = "application/sdp";
            dummyInvite.Body = dialogueToReplace.SDP;

            return dummyInvite;
        }
Exemple #34
0
        /// <summary>
        /// The event handler for responses to the initial register request.
        /// </summary>
        private void ServerResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint,
                                            SIPTransaction sipTransaction, SIPResponse sipResponse)
        {
            try
            {
                Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient,
                                                        SIPMonitorEventTypesEnum.ContactRegisterInProgress,
                                                        "Server response " + sipResponse.Status + " received for " + m_sipAccountAOR.ToString() + ".",
                                                        null));

                if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired ||
                    sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised)
                {
                    if (sipResponse.Header.AuthenticationHeader != null)
                    {
                        if (m_attempts >= m_maxRegisterAttempts)
                        {
                            Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient,
                                                                    SIPMonitorEventTypesEnum.ContactRegisterFailed,
                                                                    "Registration to " + m_sipAccountAOR.ToString() +
                                                                    " reached the maximum number of allowed attempts without a failure condition.", null));
                            m_isRegistered = false;
                            RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR,
                                                                 "Registration reached the maximum number of allowed attempts.");
                            m_waitForRegistrationMRE.Set();
                        }
                        else
                        {
                            m_attempts++;
                            SIPRequest authenticatedRequest =
                                GetAuthenticatedRegistrationRequest(sipTransaction.TransactionRequest, sipResponse);
                            SIPEndPoint registrarSIPEndPoint = m_outboundProxy;
                            if (registrarSIPEndPoint == null)
                            {
                                SIPDNSLookupResult lookupResult =
                                    m_sipTransport.GetHostEndPoint(m_registrarHost, false);
                                if (lookupResult.LookupError != null)
                                {
                                    Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient,
                                                                            SIPMonitorEventTypesEnum.ContactRegisterFailed,
                                                                            "Could not resolve " + m_registrarHost + ", " + lookupResult.LookupError,
                                                                            null));
                                }
                                else
                                {
                                    registrarSIPEndPoint = lookupResult.GetSIPEndPoint();
                                }
                            }

                            if (registrarSIPEndPoint == null)
                            {
                                logger.LogWarning("SIPRegistrationAgent could not resolve " + m_registrarHost + ".");

                                RegistrationFailed?.Invoke(m_sipAccountAOR,
                                                           "Could not resolve " + m_registrarHost + ".");
                            }
                            else
                            {
                                SIPNonInviteTransaction regAuthTransaction = new SIPNonInviteTransaction(m_sipTransport,
                                                                                                         authenticatedRequest, registrarSIPEndPoint);
                                regAuthTransaction.NonInviteTransactionFinalResponseReceived += (lep, rep, tn, rsp) =>
                                {
                                    ThreadPool.QueueUserWorkItem(delegate { AuthResponseReceived(lep, rep, tn, rsp); });
                                    return(Task.FromResult(SocketError.Success));
                                };
                                regAuthTransaction.NonInviteTransactionTimedOut += (tn) =>
                                {
                                    ThreadPool.QueueUserWorkItem(delegate { RegistrationTimedOut(tn); });
                                };
                                m_sipTransport.SendTransaction(regAuthTransaction);
                            }
                        }
                    }
                    else
                    {
                        Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient,
                                                                SIPMonitorEventTypesEnum.ContactRegisterFailed,
                                                                "Registration failed with " + sipResponse.Status +
                                                                " but no authentication header was supplied for " + m_sipAccountAOR.ToString() + ".",
                                                                null));
                        m_isRegistered = false;
                        RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR,
                                                             "Registration failed with " + sipResponse.Status +
                                                             " but no authentication header was supplied.");
                        m_waitForRegistrationMRE.Set();
                    }
                }
                else
                {
                    if (sipResponse.Status == SIPResponseStatusCodesEnum.Ok)
                    {
                        if (m_expiry > 0)
                        {
                            m_isRegistered = true;
                            m_expiry       = GetUpdatedExpiry(sipResponse);
                            RegistrationSuccessful?.Invoke(m_sipAccountAOR);
                        }
                        else
                        {
                            m_isRegistered = false;
                            RegistrationRemoved?.Invoke(m_sipAccountAOR);
                        }

                        m_waitForRegistrationMRE.Set();
                    }
                    else if (sipResponse.Status == SIPResponseStatusCodesEnum.Forbidden ||
                             sipResponse.Status == SIPResponseStatusCodesEnum.NotFound)
                    {
                        // SIP account does not appear to exist.
                        Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient,
                                                                SIPMonitorEventTypesEnum.ContactRegisterFailed,
                                                                "Registration failed with " + sipResponse.Status + " for " + m_sipAccountAOR.ToString() +
                                                                ", no further registration attempts will be made.", null));
                        string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank())
                            ? sipResponse.Status.ToString()
                            : sipResponse.ReasonPhrase;
                        RegistrationFailed?.Invoke(m_sipAccountAOR,
                                                   "Registration failed with " + (int)sipResponse.Status + " " + reasonPhrase + ".");
                        m_exit = true;
                        m_waitForRegistrationMRE.Set();
                    }
                    else if (sipResponse.Status == SIPResponseStatusCodesEnum.IntervalTooBrief && m_expiry != 0)
                    {
                        m_expiry = GetUpdatedExpiryForIntervalTooBrief(sipResponse);
                        Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient,
                                                                SIPMonitorEventTypesEnum.ContactRegisterInProgress,
                                                                "Registration for " + m_sipAccountAOR.ToString() + " had a too short expiry, updated to +" +
                                                                m_expiry + " and trying again.", null));
                        SendInitialRegister();
                    }
                    else
                    {
                        Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient,
                                                                SIPMonitorEventTypesEnum.ContactRegisterFailed,
                                                                "Registration failed with " + sipResponse.Status + " for " + m_sipAccountAOR.ToString() +
                                                                ".", null));
                        m_isRegistered = false;
                        RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR,
                                                             "Registration failed with " + sipResponse.Status + ".");
                        m_waitForRegistrationMRE.Set();
                    }
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception SIPRegistrationUserAgent ServerResponseReceived (" + remoteEndPoint + "). " +
                                excp.Message);
            }
        }
        private SIPRequest GetInviteRequest(string callURI, SIPCallDescriptor sipCallDescriptor)
        {
            SIPFromHeader fromHeader = sipCallDescriptor.GetFromHeader();

            SIPRequest inviteRequest = new SIPRequest(SIPMethodsEnum.INVITE, SIPURI.ParseSIPURI(callURI));
            inviteRequest.LocalSIPEndPoint = m_blackhole;

            SIPHeader inviteHeader = new SIPHeader(fromHeader, new SIPToHeader(null, inviteRequest.URI, null), 1, CallProperties.CreateNewCallId());

            inviteHeader.From.FromTag = CallProperties.CreateNewTag();

            // For incoming calls forwarded via the dial plan the username needs to go into the Contact header.
            inviteHeader.Contact = new List<SIPContactHeader>() { new SIPContactHeader(null, new SIPURI(inviteRequest.URI.Scheme, m_blackhole)) };
            inviteHeader.CSeqMethod = SIPMethodsEnum.INVITE;
            inviteRequest.Header = inviteHeader;

            SIPViaHeader viaHeader = new SIPViaHeader(m_blackhole, CallProperties.CreateBranchId());
            inviteRequest.Header.Vias.PushViaHeader(viaHeader);

            try
            {
                if (sipCallDescriptor.CustomHeaders != null && sipCallDescriptor.CustomHeaders.Count > 0)
                {
                    foreach (string customHeader in sipCallDescriptor.CustomHeaders)
                    {
                        if (customHeader.IsNullOrBlank())
                        {
                            continue;
                        }
                        else if (customHeader.Trim().StartsWith(SIPHeaders.SIP_HEADER_USERAGENT))
                        {
                            inviteRequest.Header.UserAgent = customHeader.Substring(customHeader.IndexOf(":") + 1).Trim();
                        }
                        else
                        {
                            inviteRequest.Header.UnknownHeaders.Add(customHeader);
                        }
                    }
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception Parsing CustomHeader for GetInviteRequest. " + excp.Message + sipCallDescriptor.CustomHeaders);
            }

            return inviteRequest;
        }
Exemple #36
0
        private void LogSIPRequestOut(SIPEndPoint localSIPEndPoint, SIPEndPoint endPoint, SIPRequest sipRequest)
        {
            string message = "App Svr Sent: " + localSIPEndPoint.ToString() + "->" + endPoint.ToString() + "\r\n" + sipRequest.ToString();
            //logger.Debug("as: request out " + sipRequest.Method + " " + localSIPEndPoint.ToString() + "->" + endPoint.ToString() + ", callid=" + sipRequest.Header.CallId + ".");
            string fromUser = (sipRequest.Header.From != null && sipRequest.Header.From.FromURI != null) ? sipRequest.Header.From.FromURI.User : "******";

            FireSIPMonitorEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.FullSIPTrace, message, fromUser, localSIPEndPoint, endPoint));
        }
        public SIPRequest GetAuthenticatedRequest(SIPRequest origRequest, SIPResponse authReqdResponse, string username, string password)
        {
            SIPRequest authRequest = origRequest;
            authRequest.Header.Via.TopViaHeader.Branch = CallProperties.CreateBranchId();
            authRequest.Header.From.FromTag = CallProperties.CreateNewTag();
            authRequest.Header.CSeq = origRequest.Header.CSeq + 1;

            AuthorizationRequest authorizationRequest = authReqdResponse.Header.AuthenticationHeader.AuthRequest;
            authorizationRequest.SetCredentials(username, password, origRequest.URI.ToString(), origRequest.Method.ToString());

            authRequest.Header.AuthenticationHeader = new SIPAuthenticationHeader(authorizationRequest);
            authRequest.Header.AuthenticationHeader.AuthRequest.Response = authorizationRequest.Digest;

            return authRequest;
        }
Exemple #38
0
        /// <summary>
        /// Because this is a server user agent the SIP transport must start listening for client user agents.
        /// </summary>
        private static async Task OnRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
        {
            try
            {
                if (sipRequest.Header.From != null &&
                    sipRequest.Header.From.FromTag != null &&
                    sipRequest.Header.To != null &&
                    sipRequest.Header.To.ToTag != null)
                {
                    // This is an in-dialog request that will be handled directly by a user agent instance.
                }
                else if (sipRequest.Method == SIPMethodsEnum.INVITE)
                {
                    Log.LogInformation($"Incoming call request: {localSIPEndPoint}<-{remoteEndPoint} {sipRequest.URI}.");

                    SIPUserAgent ua = new SIPUserAgent(_sipTransport, null);
                    ua.OnCallHungup              += OnHangup;
                    ua.ServerCallCancelled       += (uas) => Log.LogDebug("Incoming call cancelled by remote party.");
                    ua.OnDtmfTone                += (key, duration) => OnDtmfTone(ua, key, duration);
                    ua.OnRtpEvent                += (evt, hdr) => Log.LogDebug($"rtp event {evt.EventID}, duration {evt.Duration}, end of event {evt.EndOfEvent}, timestamp {hdr.Timestamp}, marker {hdr.MarkerBit}.");
                    ua.OnTransactionTraceMessage += (tx, msg) => Log.LogDebug($"uas tx {tx.TransactionId}: {msg}");
                    ua.ServerCallRingTimeout     += (uas) =>
                    {
                        Log.LogWarning($"Incoming call timed out in {uas.ClientTransaction.TransactionState} state waiting for client ACK, terminating.");
                        ua.Hangup();
                    };

                    var uas        = ua.AcceptCall(sipRequest);
                    var rtpSession = CreateRtpSession(ua, sipRequest.URI.User);

                    // Insert a brief delay to allow testing of the "Ringing" progress response.
                    // Without the delay the call gets answered before it can be sent.
                    await Task.Delay(500);

                    await ua.Answer(uas, rtpSession);

                    if (ua.IsCallActive)
                    {
                        await rtpSession.Start();

                        _calls.TryAdd(ua.Dialogue.CallId, ua);
                    }
                }
                else if (sipRequest.Method == SIPMethodsEnum.BYE)
                {
                    SIPResponse byeResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist, null);
                    await _sipTransport.SendResponseAsync(byeResponse);
                }
                else if (sipRequest.Method == SIPMethodsEnum.SUBSCRIBE)
                {
                    SIPResponse notAllowededResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null);
                    await _sipTransport.SendResponseAsync(notAllowededResponse);
                }
                else if (sipRequest.Method == SIPMethodsEnum.OPTIONS || sipRequest.Method == SIPMethodsEnum.REGISTER)
                {
                    SIPResponse optionsResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
                    await _sipTransport.SendResponseAsync(optionsResponse);
                }
            }
            catch (Exception reqExcp)
            {
                Log.LogWarning($"Exception handling {sipRequest.Method}. {reqExcp.Message}");
            }
        }
        public SIPRequest GetByeRequest(SIPResponse inviteResponse)
        {
            SIPRequest byeRequest = new SIPRequest(SIPMethodsEnum.BYE, inviteResponse.Header.Contact[0].ContactURI);
            SIPHeader byeHeader = new SIPHeader(inviteResponse.Header.From, inviteResponse.Header.To, inviteResponse.Header.CSeq + 1, inviteResponse.Header.CallId);
            byeHeader.CSeqMethod = SIPMethodsEnum.BYE;

            IPEndPoint localSIPEndPoint = m_sipTransport.GetIPEndPointsList()[0];
            SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint.Address.ToString(), localSIPEndPoint.Port, CallProperties.CreateBranchId());
            byeHeader.Via.PushViaHeader(viaHeader);

            byeRequest.Header = byeHeader;

            return byeRequest;
        }
Exemple #40
0
        public void AddRegisterRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest registerRequest)
        {
            try
            {
                if (registerRequest.Method != SIPMethodsEnum.REGISTER)
                {
                    SIPResponse notSupportedResponse = SIPResponse.GetResponse(registerRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, "Registration requests only");
                    m_sipTransport.SendResponseAsync(notSupportedResponse).Wait();
                }
                else
                {
                    int requestedExpiry = GetRequestedExpiry(registerRequest);

                    if (registerRequest.Header.To == null)
                    {
                        Logger.LogDebug("Bad register request, no To header from " + remoteEndPoint + ".");
                        SIPResponse badReqResponse = SIPResponse.GetResponse(registerRequest, SIPResponseStatusCodesEnum.BadRequest, "Missing To header");
                        m_sipTransport.SendResponseAsync(badReqResponse).Wait();
                    }
                    else if (registerRequest.Header.To.ToURI.User.IsNullOrBlank())
                    {
                        Logger.LogDebug("Bad register request, no To user from " + remoteEndPoint + ".");
                        SIPResponse badReqResponse = SIPResponse.GetResponse(registerRequest, SIPResponseStatusCodesEnum.BadRequest, "Missing username on To header");
                        m_sipTransport.SendResponseAsync(badReqResponse).Wait();
                    }
                    else if (registerRequest.Header.Contact == null || registerRequest.Header.Contact.Count == 0)
                    {
                        Logger.LogDebug("Bad register request, no Contact header from " + remoteEndPoint + ".");
                        SIPResponse badReqResponse = SIPResponse.GetResponse(registerRequest, SIPResponseStatusCodesEnum.BadRequest, "Missing Contact header");
                        m_sipTransport.SendResponseAsync(badReqResponse).Wait();
                    }
                    else if (requestedExpiry > 0 && requestedExpiry < m_minimumBindingExpiry)
                    {
                        Logger.LogDebug("Bad register request, no expiry of " + requestedExpiry + " to small from " + remoteEndPoint + ".");
                        SIPResponse tooFrequentResponse = SIPResponse.GetResponse(registerRequest, SIPResponseStatusCodesEnum.IntervalTooBrief, null);
                        tooFrequentResponse.Header.MinExpires = m_minimumBindingExpiry;
                        m_sipTransport.SendResponseAsync(tooFrequentResponse).Wait();
                    }
                    else
                    {
                        if (m_registerQueue.Count < MAX_REGISTER_QUEUE_SIZE)
                        {
                            SIPNonInviteTransaction regTx = new SIPNonInviteTransaction(m_sipTransport, registerRequest, null);
                            m_registerQueue.Enqueue(regTx);
                        }
                        else
                        {
                            Logger.LogError("Register queue exceeded max queue size " + MAX_REGISTER_QUEUE_SIZE + ", overloaded response sent.");
                            SIPResponse overloadedResponse = SIPResponse.GetResponse(registerRequest, SIPResponseStatusCodesEnum.TemporarilyUnavailable, "Registrar overloaded, please try again shortly");
                            m_sipTransport.SendResponseAsync(overloadedResponse).Wait();
                        }

                        m_registerARE.Set();
                    }
                }
            }
            catch (Exception excp)
            {
                Logger.LogError("Exception AddRegisterRequest (" + remoteEndPoint.ToString() + "). " + excp.Message);
            }
        }
        public SIPRequest GetRegisterRequest(string server, string toURIStr, string contactStr)
        {
            try
            {
                IPEndPoint localSIPEndPoint = m_sipTransport.GetDefaultTransportContact(SIPProtocolsEnum.UDP);

                SIPRequest registerRequest = new SIPRequest(SIPMethodsEnum.REGISTER, "sip:" + server);
                SIPHeader registerHeader = new SIPHeader(SIPFromHeader.ParseFromHeader(toURIStr), SIPToHeader.ParseToHeader(toURIStr), 1, CallProperties.CreateNewCallId());
                registerHeader.From.FromTag = CallProperties.CreateNewTag();
                registerHeader.Contact = SIPContactHeader.ParseContactHeader(contactStr);
                SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint.Address.ToString(), localSIPEndPoint.Port, CallProperties.CreateBranchId());
                registerHeader.Via.PushViaHeader(viaHeader);
                registerHeader.CSeqMethod = SIPMethodsEnum.REGISTER;
                registerHeader.Expires = SIPConstants.DEFAULT_REGISTEREXPIRY_SECONDS;

                registerRequest.Header = registerHeader;

                return registerRequest;
            }
            catch (Exception excp)
            {
                logger.Error("Exception GetRegisterRequest. " + excp.Message);
                throw new ApplicationException("GetRegisterRequest " + excp.GetType().ToString() + ".  " + excp.Message);
            }
        }
Exemple #42
0
        private int GetRequestedExpiry(SIPRequest registerRequest)
        {
            int contactHeaderExpiry = (registerRequest.Header.Contact != null && registerRequest.Header.Contact.Count > 0) ? registerRequest.Header.Contact[0].Expires : -1;

            return((contactHeaderExpiry == -1) ? registerRequest.Header.Expires : contactHeaderExpiry);
        }
 public void SendSIPRequest(SIPRequest sipRequest)
 {
     SendSIPRequest(sipRequest, sipRequest.URI.GetURIEndPoint().ToString());
 }
Exemple #44
0
        private RegisterResultEnum Register(SIPNonInviteTransaction registerTransaction)
        {
            try
            {
                SIPRequest  sipRequest      = registerTransaction.TransactionRequest;
                SIPURI      registerURI     = sipRequest.URI;
                SIPToHeader toHeader        = sipRequest.Header.To;
                string      toUser          = toHeader.ToURI.User;
                string      canonicalDomain = (!m_strictRealmHandling) ? m_sipDomainDataLayer.GetCanonicalDomain(toHeader.ToURI.Host, true) : toHeader.ToURI.Host;
                int         requestedExpiry = GetRequestedExpiry(sipRequest);

                if (canonicalDomain == null)
                {
                    Logger.LogWarning("Register request for " + toHeader.ToURI.Host + " rejected as no matching domain found.");
                    SIPResponse noDomainResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, "Domain not serviced");
                    registerTransaction.SendResponse(noDomainResponse);
                    return(RegisterResultEnum.DomainNotServiced);
                }
                else
                {
                    SIPAccount sipAccount = m_sipAccountsDataLayer.GetSIPAccount(toUser, canonicalDomain);

                    if (sipAccount == null)
                    {
                        Logger.LogWarning($"RegistrarCore SIP account {toUser}@{canonicalDomain} does not exist.");
                        SIPResponse forbiddenResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, null);
                        registerTransaction.SendResponse(forbiddenResponse);
                        return(RegisterResultEnum.Forbidden);
                    }
                    else
                    {
                        SIPRequestAuthenticationResult authenticationResult = SIPRequestAuthenticator.AuthenticateSIPRequest(registerTransaction.TransactionRequest.LocalSIPEndPoint, registerTransaction.TransactionRequest.RemoteSIPEndPoint, sipRequest, sipAccount);

                        if (!authenticationResult.Authenticated)
                        {
                            // 401 Response with a fresh nonce needs to be sent.
                            SIPResponse authReqdResponse = SIPResponse.GetResponse(sipRequest, authenticationResult.ErrorResponse, null);
                            authReqdResponse.Header.AuthenticationHeader = authenticationResult.AuthenticationRequiredHeader;
                            registerTransaction.SendResponse(authReqdResponse);

                            if (authenticationResult.ErrorResponse == SIPResponseStatusCodesEnum.Forbidden)
                            {
                                Logger.LogWarning($"Forbidden {sipAccount.AOR} does not exist, {sipRequest.Header.ProxyReceivedFrom}, {sipRequest.Header.UserAgent}.");
                                return(RegisterResultEnum.Forbidden);
                            }
                            else
                            {
                                return(RegisterResultEnum.AuthenticationRequired);
                            }
                        }
                        else
                        {
                            if (sipRequest.Header.Contact == null || sipRequest.Header.Contact.Count == 0)
                            {
                                // No contacts header to update bindings with, return a list of the current bindings.
                                //List<SIPRegistrarBinding> bindings = m_registrarBindingsManager.GetBindings(sipAccount.ID);
                                List <SIPRegistrarBinding> bindings = m_SIPRegistrarBindingDataLayer.GetForSIPAccount(sipAccount.ID).ToList();
                                //List<SIPContactHeader> contactsList = m_registrarBindingsManager.GetContactHeader(); // registration.GetContactHeader(true, null);
                                if (bindings != null)
                                {
                                    sipRequest.Header.Contact = GetContactHeader(bindings);
                                }

                                SIPResponse okResponse = GetOkResponse(sipRequest);
                                registerTransaction.SendResponse(okResponse);
                                Logger.LogDebug($"Empty registration request successful for {sipAccount.AOR} from {sipRequest.Header.ProxyReceivedFrom}.");
                            }
                            else
                            {
                                SIPEndPoint uacRemoteEndPoint = SIPEndPoint.TryParse(sipRequest.Header.ProxyReceivedFrom) ?? registerTransaction.TransactionRequest.RemoteSIPEndPoint;
                                SIPEndPoint proxySIPEndPoint  = SIPEndPoint.TryParse(sipRequest.Header.ProxyReceivedOn);
                                SIPEndPoint registrarEndPoint = registerTransaction.TransactionRequest.LocalSIPEndPoint;

                                SIPResponseStatusCodesEnum updateResult = SIPResponseStatusCodesEnum.Ok;
                                string updateMessage = null;

                                DateTime startTime = DateTime.Now;

                                List <SIPRegistrarBinding> bindingsList = m_registrarBindingsManager.UpdateBindings(
                                    sipAccount,
                                    proxySIPEndPoint,
                                    uacRemoteEndPoint,
                                    registrarEndPoint,
                                    sipRequest.Header.Contact,
                                    sipRequest.Header.CallId,
                                    sipRequest.Header.CSeq,
                                    sipRequest.Header.Expires,
                                    sipRequest.Header.UserAgent,
                                    out updateResult,
                                    out updateMessage);

                                TimeSpan duration = DateTime.Now.Subtract(startTime);
                                Logger.LogDebug($"Binding update time for {sipAccount.AOR} took {duration.TotalMilliseconds}ms.");

                                if (updateResult == SIPResponseStatusCodesEnum.Ok)
                                {
                                    string proxySocketStr = (proxySIPEndPoint != null) ? " (proxy=" + proxySIPEndPoint.ToString() + ")" : null;

                                    Logger.LogDebug($"Bindings for {sipAccount.AOR}:");
                                    for (int i = 0; i < bindingsList.Count(); i++)
                                    {
                                        var binding = bindingsList[i];
                                        Logger.LogDebug($" {i}: {binding.ContactURI}, expiry {binding.Expiry}s.");
                                    }

                                    sipRequest.Header.Contact = GetContactHeader(bindingsList);
                                    SIPResponse okResponse = GetOkResponse(sipRequest);
                                    registerTransaction.SendResponse(okResponse);
                                }
                                else
                                {
                                    // The binding update failed even though the REGISTER request was authorised. This is probably due to a
                                    // temporary problem connecting to the bindings data store. Send Ok but set the binding expiry to the minimum so
                                    // that the UA will try again as soon as possible.
                                    Logger.LogError($"Registration request successful but binding update failed for {sipAccount.AOR} from {registerTransaction.TransactionRequest.RemoteSIPEndPoint}.");
                                    sipRequest.Header.Contact[0].Expires = m_minimumBindingExpiry;
                                    SIPResponse okResponse = GetOkResponse(sipRequest);
                                    registerTransaction.SendResponse(okResponse);
                                }
                            }

                            return(RegisterResultEnum.Authenticated);
                        }
                    }
                }
            }
            catch (Exception excp)
            {
                string regErrorMessage = "Exception registrarcore registering. " + excp.Message + "\r\n" + registerTransaction.TransactionRequest.ToString();
                Logger.LogError(regErrorMessage);

                SIPResponse errorResponse = SIPResponse.GetResponse(registerTransaction.TransactionRequest, SIPResponseStatusCodesEnum.InternalServerError, null);
                registerTransaction.SendResponse(errorResponse);

                return(RegisterResultEnum.Error);
            }
        }
 public void SIPTransportRequestReceived(SIPProtocolsEnum protocol, IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, SIPRequest sipRequest)
 {
     if (sipRequest.Method == SIPMethodsEnum.BYE)
     {
         // Send an Ok response.
         SIPResponse okResponse = GetResponse(sipRequest.Header, SIPResponseStatusCodesEnum.Ok);
         m_sipTransport.SendResponseFrom(localEndPoint, remoteEndPoint, protocol, okResponse);
     }
     else if (sipRequest.Method == SIPMethodsEnum.NOTIFY)
     {
         // Send an not supported response.
         //SIPResponse notSupportedResponse = GetResponse(sipRequest.Header, SIPResponseStatusCodesEnum.MethodNotAllowed);
         //SIPTransport.SendResponseFrom(localEndPoint, remoteEndPoint, notSupportedResponse);
         // Send an Ok response.
         SIPResponse okResponse = GetResponse(sipRequest.Header, SIPResponseStatusCodesEnum.Ok);
         okResponse.Header.Contact = null;
         m_sipTransport.SendResponseFrom(localEndPoint, remoteEndPoint, protocol, okResponse);
     }
     else
     {
         m_lastRequest = sipRequest;
         m_waitForSIPRequest.Set();
     }
 }
Exemple #46
0
        private void SendInitialRegister()
        {
            try
            {
                if (m_attempts >= MAX_REGISTER_ATTEMPTS)
                {
                    m_isRegistered = false;
                    if (RegistrationTemporaryFailure != null)
                    {
                        RegistrationTemporaryFailure(m_sipAccountAOR,
                                                     "Registration reached the maximum number of allowed attempts.");
                    }

                    m_waitForRegistrationMRE.Set();
                }
                else
                {
                    m_attempts++;

                    SIPEndPoint registrarSIPEndPoint = m_outboundProxy;
                    if (registrarSIPEndPoint == null)
                    {
                        SIPDNSLookupResult lookupResult = m_sipTransport.GetHostEndPoint(m_registrarHost, false);
                        if (lookupResult.LookupError != null)
                        {
                        }
                        else
                        {
                            registrarSIPEndPoint = lookupResult.GetSIPEndPoint();
                        }
                    }

                    if (registrarSIPEndPoint == null && RegistrationFailed != null)
                    {
                        RegistrationFailed(m_sipAccountAOR, "Could not resolve " + m_registrarHost + ".");
                    }
                    else
                    {
                        SIPRequest regRequest = GetRegistrationRequest(m_localEndPoint);

                        SIPNonInviteTransaction regTransaction = m_sipTransport.CreateNonInviteTransaction(regRequest,
                                                                                                           registrarSIPEndPoint, m_localEndPoint, m_outboundProxy);
                        // These handlers need to be on their own threads to take the processing off the SIP transport layer.
                        regTransaction.NonInviteTransactionFinalResponseReceived += (lep, rep, tn, rsp) =>
                        {
                            ThreadPool.QueueUserWorkItem(delegate { ServerResponseReceived(lep, rep, tn, rsp); });
                        };
                        regTransaction.NonInviteTransactionTimedOut += (tn) =>
                        {
                            ThreadPool.QueueUserWorkItem(delegate { RegistrationTimedOut(tn); });
                        };

                        m_sipTransport.SendSIPReliable(regTransaction);
                    }
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception SendInitialRegister to " + m_registrarHost + ". " + excp.Message);
                if (RegistrationFailed != null)
                {
                    RegistrationFailed(m_sipAccountAOR,
                                       "Exception SendInitialRegister to " + m_registrarHost + ". " + excp.Message);
                }
            }
        }
        private SIPRequest GetInviteRequest(string callURI, SIPFromHeader fromHeader)
        {
            SIPRequest inviteRequest = new SIPRequest(SIPMethodsEnum.INVITE, SIPURI.ParseSIPURI(callURI));
            inviteRequest.LocalSIPEndPoint = m_blackhole;

            SIPHeader inviteHeader = new SIPHeader(fromHeader, new SIPToHeader(null, inviteRequest.URI, null), 1, CallProperties.CreateNewCallId());

            inviteHeader.From.FromTag = CallProperties.CreateNewTag();

            // For incoming calls forwarded via the dial plan the username needs to go into the Contact header.
            inviteHeader.Contact = new List<SIPContactHeader>() { new SIPContactHeader(null, new SIPURI(inviteRequest.URI.Scheme, m_blackhole)) };
            inviteHeader.CSeqMethod = SIPMethodsEnum.INVITE;
            inviteRequest.Header = inviteHeader;

            SIPViaHeader viaHeader = new SIPViaHeader(m_blackhole, CallProperties.CreateBranchId());
            inviteRequest.Header.Vias.PushViaHeader(viaHeader);

            return inviteRequest;
        }
Exemple #48
0
        /// <summary>
        /// The event handler for responses to the initial register request.
        /// </summary>
        private void ServerResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint,
                                            SIPTransaction sipTransaction, SIPResponse sipResponse)
        {
            try
            {
                if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired ||
                    sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised)
                {
                    if (sipResponse.Header.AuthenticationHeader != null)
                    {
                        if (m_attempts >= MAX_REGISTER_ATTEMPTS)
                        {
                            m_isRegistered = false;
                            if (RegistrationTemporaryFailure != null)
                            {
                                RegistrationTemporaryFailure(m_sipAccountAOR,
                                                             "Registration reached the maximum number of allowed attempts.");
                            }

                            m_waitForRegistrationMRE.Set();
                        }
                        else
                        {
                            m_attempts++;
                            SIPRequest authenticatedRequest =
                                GetAuthenticatedRegistrationRequest(sipTransaction.TransactionRequest, sipResponse);
                            SIPNonInviteTransaction regAuthTransaction =
                                m_sipTransport.CreateNonInviteTransaction(authenticatedRequest,
                                                                          sipTransaction.RemoteEndPoint, localSIPEndPoint, m_outboundProxy);
                            regAuthTransaction.NonInviteTransactionFinalResponseReceived += (lep, rep, tn, rsp) =>
                            {
                                ThreadPool.QueueUserWorkItem(delegate { AuthResponseReceived(lep, rep, tn, rsp); });
                            };
                            regAuthTransaction.NonInviteTransactionTimedOut += (tn) =>
                            {
                                ThreadPool.QueueUserWorkItem(delegate { RegistrationTimedOut(tn); });
                            };
                            m_sipTransport.SendSIPReliable(regAuthTransaction);
                        }
                    }
                    else
                    {
                        m_isRegistered = false;
                        if (RegistrationTemporaryFailure != null)
                        {
                            RegistrationTemporaryFailure(m_sipAccountAOR,
                                                         "Registration failed with " + sipResponse.Status +
                                                         " but no authentication header was supplied.");
                        }

                        m_waitForRegistrationMRE.Set();
                    }
                }
                else
                {
                    if (sipResponse.Status == SIPResponseStatusCodesEnum.Ok)
                    {
                        if (m_expiry > 0)
                        {
                            m_isRegistered = true;
                            m_expiry       = GetUpdatedExpiry(sipResponse);
                            //if (sipResponse.Header.SwitchboardToken != null && m_lastServerNonce != null)
                            //{
                            //    SwitchboardToken = Crypto.SymmetricDecrypt(m_password, m_lastServerNonce, sipResponse.Header.SwitchboardToken);
                            //}
                            RegistrationSuccessful(m_sipAccountAOR);
                        }
                        else
                        {
                            m_isRegistered = false;
                            RegistrationRemoved(m_sipAccountAOR);
                        }

                        m_waitForRegistrationMRE.Set();
                    }
                    else if (sipResponse.Status == SIPResponseStatusCodesEnum.Forbidden ||
                             sipResponse.Status == SIPResponseStatusCodesEnum.NotFound)
                    {
                        // SIP account does not appear to exist.
                        string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank())
                            ? sipResponse.Status.ToString()
                            : sipResponse.ReasonPhrase;
                        if (RegistrationFailed != null)
                        {
                            RegistrationFailed(m_sipAccountAOR,
                                               "Registration failed with " + (int)sipResponse.Status + " " + reasonPhrase + ".");
                        }

                        m_exit = true;
                        m_waitForRegistrationMRE.Set();
                    }
                    else if (sipResponse.Status == SIPResponseStatusCodesEnum.IntervalTooBrief && m_expiry != 0)
                    {
                        m_expiry = GetUpdatedExpiryForIntervalTooBrief(sipResponse);
                        SendInitialRegister();
                    }
                    else
                    {
                        m_isRegistered = false;
                        if (RegistrationTemporaryFailure != null)
                        {
                            RegistrationTemporaryFailure(m_sipAccountAOR,
                                                         "Registration failed with " + sipResponse.Status + ".");
                        }

                        m_waitForRegistrationMRE.Set();
                    }
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception SIPRegistrationUserAgent ServerResponseReceived (" + remoteEndPoint + "). " +
                             excp.Message);
            }
        }
        /// <summary>
        /// Authenticates a SIP request.
        /// </summary>
        public static SIPRequestAuthenticationResult AuthenticateSIPRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest, SIPAccount sipAccount, SIPMonitorLogDelegate logSIPMonitorEvent)
        {
            try
            {
                if (sipAccount == null)
                {
                    return new SIPRequestAuthenticationResult(SIPResponseStatusCodesEnum.Forbidden, null);
                }
                else if (sipAccount.IsDisabled)
                {
                    if (logSIPMonitorEvent != null)
                    {
                        logSIPMonitorEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Authoriser, SIPMonitorEventTypesEnum.DialPlan, "SIP account " + sipAccount.SIPUsername + "@" + sipAccount.SIPDomain + " is disabled for " + sipRequest.Method + ".", sipAccount.Owner));
                    }
                    return new SIPRequestAuthenticationResult(SIPResponseStatusCodesEnum.Forbidden, null);
                }
                else
                {
                    SIPAuthenticationHeader reqAuthHeader = sipRequest.Header.AuthenticationHeader;
                    if (reqAuthHeader == null)
                    {
                        // Check for IP address authentication.
                        if (!sipAccount.IPAddressACL.IsNullOrBlank())
                        {
                            SIPEndPoint uaEndPoint = (!sipRequest.Header.ProxyReceivedFrom.IsNullOrBlank()) ? SIPEndPoint.ParseSIPEndPoint(sipRequest.Header.ProxyReceivedFrom) : remoteEndPoint;
                            if (Regex.Match(uaEndPoint.GetIPEndPoint().ToString(), sipAccount.IPAddressACL).Success)
                            {
                                // Successfully authenticated
                                return new SIPRequestAuthenticationResult(true, true);
                            }
                        }

                        SIPAuthenticationHeader authHeader = new SIPAuthenticationHeader(SIPAuthorisationHeadersEnum.WWWAuthenticate, sipAccount.SIPDomain, GetNonce());
                        return new SIPRequestAuthenticationResult(SIPResponseStatusCodesEnum.Unauthorised, authHeader);
                    }
                    else
                    {
                        // Check for IP address authentication.
                        if (!sipAccount.IPAddressACL.IsNullOrBlank())
                        {
                            SIPEndPoint uaEndPoint = (!sipRequest.Header.ProxyReceivedFrom.IsNullOrBlank()) ? SIPEndPoint.ParseSIPEndPoint(sipRequest.Header.ProxyReceivedFrom) : remoteEndPoint;
                            if (Regex.Match(uaEndPoint.GetIPEndPoint().ToString(), sipAccount.IPAddressACL).Success)
                            {
                                // Successfully authenticated
                                return new SIPRequestAuthenticationResult(true, true);
                            }
                        }

                        string requestNonce = reqAuthHeader.SIPDigest.Nonce;
                        string uri = reqAuthHeader.SIPDigest.URI;
                        string response = reqAuthHeader.SIPDigest.Response;

                        // Check for stale nonces.
                        if (IsNonceStale(requestNonce))
                        {
                            if (logSIPMonitorEvent != null)
                            {
                                logSIPMonitorEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Authoriser, SIPMonitorEventTypesEnum.Warn, "Authentication failed stale nonce for realm=" + sipAccount.SIPDomain + ", username="******", uri=" + uri + ", nonce=" + requestNonce + ", method=" + sipRequest.Method + ".", null));
                            }
                            SIPAuthenticationHeader authHeader = new SIPAuthenticationHeader(SIPAuthorisationHeadersEnum.WWWAuthenticate, sipAccount.SIPDomain, GetNonce());
                            return new SIPRequestAuthenticationResult(SIPResponseStatusCodesEnum.Unauthorised, authHeader);
                        }
                        else
                        {
                            SIPAuthorisationDigest checkAuthReq = reqAuthHeader.SIPDigest;
                            checkAuthReq.SetCredentials(sipAccount.SIPUsername, sipAccount.SIPPassword, uri, sipRequest.Method.ToString());
                            string digest = checkAuthReq.Digest;

                            if (digest == response)
                            {
                                // Successfully authenticated
                                return new SIPRequestAuthenticationResult(true, false);
                            }
                            else
                            {
                                if (logSIPMonitorEvent != null)
                                {
                                    logSIPMonitorEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Authoriser, SIPMonitorEventTypesEnum.Warn, "Authentication token check failed for realm=" + sipAccount.SIPDomain + ", username="******", uri=" + uri + ", nonce=" + requestNonce + ", method=" + sipRequest.Method + ".", sipAccount.Owner));
                                }
                                SIPAuthenticationHeader authHeader = new SIPAuthenticationHeader(SIPAuthorisationHeadersEnum.WWWAuthenticate, sipAccount.SIPDomain, GetNonce());
                                return new SIPRequestAuthenticationResult(SIPResponseStatusCodesEnum.Unauthorised, authHeader);
                            }
                        }
                    }
                }
            }
            catch (Exception excp)
            {
                if (logSIPMonitorEvent != null)
                {
                    logSIPMonitorEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Authoriser, SIPMonitorEventTypesEnum.Error, "Exception AuthoriseSIPRequest. " + excp.Message, null));
                }
                return new SIPRequestAuthenticationResult(SIPResponseStatusCodesEnum.InternalServerError, null);
            }
        }
        private void Transport_SIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
        {
            var endpoint = new SIPEndPoint(SIPProtocolsEnum.udp, publicIPAddress, localSIPEndPoint.Port);

            if (sipRequest.Method == SIPMethodsEnum.INVITE)
            {
                if (transaction != null)
                {
                    return;
                }

                logger.DebugFormat("{0} Incoming call from {1}", prefix, sipRequest.Header.From.FromURI.User);

                transaction = transport.CreateUASTransaction(sipRequest, remoteEndPoint, endpoint, null);
                agent       = new SIPServerUserAgent(
                    transport,
                    null,
                    sipRequest.Header.From.FromURI.User,
                    null,
                    SIPCallDirection.In,
                    null,
                    null,
                    null,
                    transaction);

                agent.CallCancelled       += Agent_CallCancelled;
                agent.TransactionComplete += Agent_TransactionComplete;

                agent.Progress(SIPResponseStatusCodesEnum.Trying, null, null, null, null);
                agent.Progress(SIPResponseStatusCodesEnum.Ringing, null, null, null, null);

                var answer  = SDP.ParseSDPDescription(agent.CallRequest.Body);
                var address = IPAddress.Parse(answer.Connection.ConnectionAddress);
                var port    = answer.Media.FirstOrDefault(m => m.Media == SDPMediaTypesEnum.audio).Port;
                var random  = Crypto.GetRandomInt(5).ToString();
                var sdp     = new SDP
                {
                    Version     = 2,
                    Username    = "******",
                    SessionId   = random,
                    Address     = localIPEndPoint.Address.ToString(),
                    SessionName = "redfox_" + random,
                    Timing      = "0 0",
                    Connection  = new SDPConnectionInformation(publicIPAddress.ToString())
                };

                rtpChannel = new RTPChannel
                {
                    DontTimeout    = true,
                    RemoteEndPoint = new IPEndPoint(address, port)
                };

                rtpChannel.SetFrameType(FrameTypesEnum.Audio);
                // TODO Fix hardcoded ports
                rtpChannel.ReservePorts(15000, 15090);
                rtpChannel.OnFrameReady += Channel_OnFrameReady;
                rtpChannel.Start();

                // Send some setup parameters to punch a hole in the firewall/router
                rtpChannel.SendRTPRaw(new byte[] { 80, 95, 198, 88, 55, 96, 225, 141, 215, 205, 185, 242, 00 });

                rtpChannel.OnControlDataReceived       += (b) => { logger.Debug($"{prefix} Control Data Received; {b.Length} bytes"); };
                rtpChannel.OnControlSocketDisconnected += () => { logger.Debug($"{prefix} Control Socket Disconnected"); };

                var announcement = new SDPMediaAnnouncement
                {
                    Media        = SDPMediaTypesEnum.audio,
                    MediaFormats = new List <SDPMediaFormat>()
                    {
                        new SDPMediaFormat((int)SDPMediaFormatsEnum.PCMU, "PCMU", 8000)
                    },
                    Port = rtpChannel.RTPPort
                };

                sdp.Media.Add(announcement);

                SetState(State.Listening, sipRequest.Header.From.FromURI.User);

                agent.Progress(SIPResponseStatusCodesEnum.Accepted, null, null, null, null);
                agent.Answer(SDP.SDP_MIME_CONTENTTYPE, sdp.ToString(), null, SIPDialogueTransferModesEnum.NotAllowed);

                SetState(State.Busy, "");
                return;
            }
            if (sipRequest.Method == SIPMethodsEnum.BYE)
            {
                if (State != State.Busy)
                {
                    return;
                }

                logger.DebugFormat("{0} Hangup from {1}", prefix, sipRequest.Header.From.FromURI.User);

                var noninvite = transport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, endpoint, null);
                var response  = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);

                noninvite.SendFinalResponse(response);

                SetState(State.Finished, Endpoint);

                rtpChannel.OnFrameReady -= Channel_OnFrameReady;
                rtpChannel.Close();

                agent.TransactionComplete -= Agent_TransactionComplete;
                agent.CallCancelled       -= Agent_CallCancelled;
                agent       = null;
                transaction = null;

                SetState(State.Ready, Endpoint);

                return;
            }
            if (sipRequest.Method == SIPMethodsEnum.ACK)
            {
            }
            if (sipRequest.Method == SIPMethodsEnum.CANCEL)
            {
            }
        }