public SIPEventSubscription(
     SIPMonitorLogDelegate log,
     string sessionID,
     SIPURI resourceURI,
     SIPURI canonicalResourceURI,
     string filter,
     SIPDialogue subscriptionDialogue,
     int expiry)
 {
     MonitorLogEvent_External = log;
     SessionID = sessionID;
     ResourceURI = resourceURI;
     CanonicalResourceURI = canonicalResourceURI;
     Filter = filter;
     SubscriptionDialogue = subscriptionDialogue;
     Expiry = expiry;
 }
 public SIPDialogEventSubscription(
     SIPMonitorLogDelegate log,
     string sessionID,
     SIPURI resourceURI,
     SIPURI canonincalResourceURI,
     string filter,
     SIPDialogue subscriptionDialogue,
     int expiry,
     SIPAssetGetListDelegate<SIPDialogueAsset> getDialogues,
     SIPAssetGetByIdDelegate<SIPDialogueAsset> getDialogue
     )
     : base(log, sessionID, resourceURI, canonincalResourceURI, filter, subscriptionDialogue, expiry)
 {
     GetDialogues_External = getDialogues;
     GetDialogue_External = getDialogue;
     DialogInfo = new SIPEventDialogInfo(0, SIPEventDialogInfoStateEnum.full, resourceURI);
 }
 public SIPPresenceEventSubscription(
     SIPMonitorLogDelegate log,
     string sessionID,
     SIPURI resourceURI,
     SIPURI canonincalResourceURI,
     string filter,
     SIPDialogue subscriptionDialogue,
     int expiry,
     SIPAssetPersistor<SIPAccount> sipAccountPersistor,
     SIPAssetCountDelegate<SIPRegistrarBinding> getBindingsCount,
     bool switchboardSIPAccountsOnly
     )
     : base(log, sessionID, resourceURI, canonincalResourceURI, filter, subscriptionDialogue, expiry)
 {
     m_sipAccountPersistor = sipAccountPersistor;
     GetSIPRegistrarBindingsCount_External = getBindingsCount;
     Presence = new SIPEventPresence(resourceURI);
     m_switchboardSIPAccountsOnly = switchboardSIPAccountsOnly;
 }
        void ProcessRegister(PreprocessSipRequestEventArgs e)
        {
            e.Handled = true;
            bool isNewRegistration = false;

            // Remove the Record-Route field as per RFC-3261 10.3
            if (e.Request.HeaderFields.Contains("Record-Route", null))
                e.Request.HeaderFields.Remove("Record-Route");

            try
            {
                SIPURI addressOfRecord = new SIPURI(e.Request.HeaderFields["To", "t"].FieldValue);

                // Make sure the request is authorized
                if (ProcessRequestAuthorization(e, addressOfRecord, false))
                {
                    int extensionNumber = 0;

                    try
                    {
                        extensionNumber = Convert.ToInt32(addressOfRecord.User);
                    }
                    catch
                    {
                        ipClient.SendSipResponse(e.Request.CreateResponse(404, "Not Found"));
                        return;
                    }

                    PBXPresenceInfo presenceInfo = FindPresenceInfo(extensionNumber, e.Request.SentFrom, e.Request.SentFromPort, true);

                    if (e.Request.HeaderFields.Contains("Contact", "m"))
                    {
                        HeaderField[] contactFields = e.Request.HeaderFields.GetMultiHeaderFields("Contact", "m");

                        bool containsStar = false;

                        foreach (HeaderField contactField in contactFields)
                        {
                            if (contactField.FieldValue == "*")
                            {
                                containsStar = true;
                            }
                        }

                        if (containsStar)
                        {
                            if (contactFields.Length > 1 || !e.Request.HeaderFields.Contains("Expires", null) || e.Request.HeaderFields["Expires", null].FieldValue.Trim() != "0")
                            {
                                ipClient.SendSipResponse(e.Request.CreateResponse(400, "Invalid Request"));
                                return;
                            }
                        }

                        int requestedExpiration = 0;

                        if (contactFields[0].ContainsParameter("Expires"))
                            requestedExpiration = Convert.ToInt32(contactFields[0].Parameters["Expires"]);
                        else if (e.Request.HeaderFields.Contains("Expires", null))
                            requestedExpiration = Convert.ToInt32(e.Request.HeaderFields["Expires", null].FieldValue);
                        else
                            requestedExpiration = Properties.Settings.Default.PresenceTimeout;

                        if (presenceInfo != null)
                        {
                            // Check the Call-ID
                            string callID = e.Request.HeaderFields["Call-ID", "i"].FieldValue;

                            if (callID == presenceInfo.SessionID)
                            {
                                // Parse our CSeq
                                int cSeq = Convert.ToInt32(e.Request.HeaderFields["CSeq", null].FieldValue.Split(' ')[0]);

                                if (cSeq < presenceInfo.CSeq)
                                {
                                    RemovePresenceInfo(presenceInfo);

                                    ipClient.SendSipResponse(e.Request.CreateResponse(400, "Invalid Request"));

                                    return;
                                }
                            }

                            if (requestedExpiration == 0)
                            {
                                RemovePresenceInfo(presenceInfo);
                                ipClient.SendSipResponse(e.Request.CreateResponse(200, "OK"));
                                return;
                            }
                        }
                        else
                        {
                            presenceInfo = new PBXPresenceInfo();
                            isNewRegistration = true;
                        }

                        presenceInfo.AddressOfRecord = new SIPURI(e.Request.HeaderFields["To", "t"].FieldValue).BasicURIStringWithoutParameters;
                        presenceInfo.CSeq = Convert.ToInt32(e.Request.HeaderFields["CSeq", null].FieldValue.Split(' ')[0]);
                        presenceInfo.ExpiresInSeconds = requestedExpiration;
                        presenceInfo.ExtensionNumber = extensionNumber;
                        presenceInfo.LastRegistration = DateTime.Now;
                        presenceInfo.Name = addressOfRecord.DisplayName;
                        presenceInfo.RemoteAddress = e.Request.SentFrom;
                        presenceInfo.RemotePort = e.Request.SentFromPort;
                        presenceInfo.SessionID = e.Request.HeaderFields["Call-ID", "i"].FieldValue;
                        presenceInfo.Status = PBXPresenceStatus.Online;

                        if (isNewRegistration)
                        {
                            lock (presenceDataLock)
                            {
                                presenceData.Add(presenceInfo);
                                LoggingService.AddLogEntry(WOSI.CallButler.ManagementInterface.LogLevel.Extended, "Extension " + presenceInfo.ExtensionNumber + " registered for " + presenceInfo.RemoteAddress, false);

                                UpdateExtensionState(presenceInfo);
                            }
                        }
                    }

                    if (presenceInfo != null)
                    {
                        SipResponse response = e.Request.CreateResponse(200, "OK");

                        response.HeaderFields.InsertAfter("CSeq", e.Request.HeaderFields["Contact", "m"]);
                        response.HeaderFields["Contact", "m"].Parameters["expires"] = presenceInfo.ExpiresInSeconds.ToString();
                        response.HeaderFields.InsertAfter("Contact", "Date", DateTime.Now.ToUniversalTime().ToString("ddd, d MMM yyyy HH:mm:ss G\\MT"));

                        ipClient.SendSipResponse(response);

                        // Send our message waiting notification
                        if(isNewRegistration)
                            SendMessageWaitingNotification(extensionNumber);

                        PerformanceCounterService.PhonesRegistered = presenceData.Count;
                    }
                    else
                    {
                        ipClient.SendSipResponse(e.Request.CreateResponse(404, "Not Found"));
                    }

                    return;
                }
            }
            catch (Exception ex)
            {
                ipClient.SendSipResponse(e.Request.CreateResponse(500, "Server Error"));
                LoggingService.AddLogEntry(WOSI.CallButler.ManagementInterface.LogLevel.ErrorsOnly, Utils.ErrorUtils.FormatErrorString(ex), true);
            }
        }
 public void Redirect(SIPResponseStatusCodesEnum redirectCode, SIPURI redirectURI)
 {
     throw new NotImplementedException("SIPTransferServerUserAgent Redirect");
 }
Exemple #6
0
 public static SIPDNSLookupResult Resolve(SIPURI sipURI, bool async)
 {
     // This assumes the input SIP URI has an IP address as the host!
     return(new SIPDNSLookupResult(sipURI, new SIPEndPoint(IPSocket.ParseSocketString(sipURI.Host))));
 }
Exemple #7
0
        public SIPProvider(
            ProviderTypes providerType,
            string owner,
            string name,
            string username,
            string password,
            SIPURI server,
            string outboundProxy,
            string from,
            string custom,
            SIPURI registerContact,
            int registerExpiry,
            SIPURI registerServer,
            string authUsername,
            string registerRealm,
            bool registerEnabled,
            bool registerEnabledAdmin,
            string gvCallbackNumber,
            string gvCallbackPattern,
            GoogleVoiceCallbackTypes? gvCallbackType)
        {
            m_providerType = providerType;
            m_owner = owner;
            m_id = Guid.NewGuid();
            m_providerName = name;
            m_providerUsername = username;
            m_providerPassword = password;
            m_providerServer = server;
            m_providerOutboundProxy = outboundProxy;
            m_providerFrom = from;
            m_customHeaders = custom;
            m_registerContact = registerContact;
            m_registerExpiry = (registerExpiry < REGISTER_MINIMUM_EXPIRY) ? REGISTER_MINIMUM_EXPIRY : registerExpiry;
            m_registerServer = registerServer;
            m_providerAuthUsername = authUsername;
            m_registerRealm = registerRealm;
            m_registerEnabled = registerEnabled;
            m_registerAdminEnabled = registerEnabledAdmin;
            m_gvCallbackNumber = gvCallbackNumber;
            m_gvCallbackPattern = gvCallbackPattern;
            m_gvCallbackType = gvCallbackType;
            Inserted = DateTimeOffset.UtcNow;
            LastUpdate = DateTimeOffset.UtcNow;

            //if (m_registerContact != null)
            //{
            //    m_registerContact.Parameters.Set(CONTACT_ID_KEY, Crypto.GetRandomString(6));
            //}

            //if (m_registerContact == null && m_registerEnabled)
            //{
            //    m_registerEnabled = false;
            //    m_registerDisabledReason = "No Contact URI was specified for the registration.";
            //    logger.Warn("Registrations for provider " + m_providerName + " owned by " + m_owner + " have been disabled due to an empty or invalid Contact URI.");
            //}
        }
        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 SetProviderFields(SIPProvider sipProvider)
        {
            m_providerId = sipProvider.Id;
            m_owner = sipProvider.Owner;
            AdminMemberId = sipProvider.AdminMemberId;
            ProviderName = sipProvider.ProviderName;
            ProviderAuthUsername = (!sipProvider.ProviderAuthUsername.IsNullOrBlank()) ? sipProvider.ProviderAuthUsername : sipProvider.ProviderUsername;
            ProviderPassword = sipProvider.ProviderPassword;
            RegistrarServer = sipProvider.Registrar.CopyOf();
            RegistrarRealm = (!sipProvider.RegisterRealm.IsNullOrBlank()) ? sipProvider.RegisterRealm : RegistrarServer.Host;
            ProviderOutboundProxy = sipProvider.ProviderOutboundProxy;
            SendMWISubscribe = sipProvider.SendMWISubscribe;

            if (sipProvider.RegisterEnabled) {
                BindingExpiry = sipProvider.RegisterExpiry;
            }
            else {
                BindingExpiry = 0;
            }

            string bindingId = null;
            if (m_bindingURI != null && m_bindingURI.Parameters.Has(REGAGENT_CONTACT_ID_KEY)) {
                bindingId = m_bindingURI.Parameters.Get(REGAGENT_CONTACT_ID_KEY);
            }

            if (!sipProvider.RegisterContact.IsNullOrBlank()) {
                m_bindingURI = SIPURI.ParseSIPURI(sipProvider.RegisterContact);
                if (!bindingId.IsNullOrBlank()) {
                    m_bindingURI.Parameters.Set(REGAGENT_CONTACT_ID_KEY, bindingId);
                }
            }
            else {
                // The register contact field on the SIP Provider is empty.
                // This condition needs to be trearted as the binding being disabled and it needs to be removed.
                BindingExpiry = 0;
            }
        }
        public bool Pending;                // If an aysnc lookup request is made this will be set to true if no immediate result is available.

        public SIPDNSLookupResult(SIPURI uri)
        {
            URI = uri;
        }
        /// <summary>
        /// The event handler for responses to the initial register request.
        /// </summary>
        private void ServerResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse)
        {
            try
            {
                logger.LogDebug($"Server response {sipResponse.Status} received for {m_sipAccountAOR}.");

                if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised)
                {
                    if (sipResponse.Header.HasAuthenticationHeader)
                    {
                        if (m_attempts >= m_maxRegisterAttempts)
                        {
                            logger.LogDebug("Registration to " + m_sipAccountAOR.ToString() + " reached the maximum number of allowed attempts without a failure condition.");
                            m_isRegistered = false;
                            RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR, "Registration reached the maximum number of allowed attempts.");
                            m_waitForRegistrationMRE.Set();
                        }
                        else
                        {
                            m_attempts++;

                            string username             = (m_authUsername != null) ? m_authUsername : m_sipAccountAOR.User;
                            var    authenticatedRequest = sipTransaction.TransactionRequest.DuplicateAndAuthenticate(
                                sipResponse.Header.AuthenticationHeaders, username, m_password);

                            SIPEndPoint registrarSIPEndPoint = m_outboundProxy;
                            if (registrarSIPEndPoint == null)
                            {
                                SIPURI uri          = SIPURI.ParseSIPURIRelaxed(m_registrarHost);
                                var    lookupResult = m_sipTransport.ResolveSIPUriAsync(uri).Result;
                                if (lookupResult == null)
                                {
                                    logger.LogWarning("Could not resolve " + m_registrarHost + ".");
                                }
                                else
                                {
                                    registrarSIPEndPoint = lookupResult;
                                }
                            }
                            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) =>
                                {
                                    AuthResponseReceived(lep, rep, tn, rsp);
                                    return(Task.FromResult(SocketError.Success));
                                };
                                regAuthTransaction.NonInviteTransactionFailed += RegistrationTransactionFailed;
                                regAuthTransaction.SendRequest();
                            }
                        }
                    }
                    else
                    {
                        logger.LogWarning($"Registration failed with {sipResponse.Status} but no authentication header was supplied for {m_sipAccountAOR}.");
                        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.
                        m_exit = m_exitOnUnequivocalFailure;

                        logger.LogWarning($"Registration unequivocal failure with {sipResponse.Status} for {m_sipAccountAOR}{(m_exit ? ", no further registration attempts will be made" : "")}.");
                        string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank()) ? sipResponse.Status.ToString() : sipResponse.ReasonPhrase;
                        RegistrationFailed?.Invoke(m_sipAccountAOR, "Registration failed with " + (int)sipResponse.Status + " " + reasonPhrase + ".");

                        m_waitForRegistrationMRE.Set();
                    }
                    else if (sipResponse.Status == SIPResponseStatusCodesEnum.IntervalTooBrief && m_expiry != 0)
                    {
                        m_expiry = GetUpdatedExpiryForIntervalTooBrief(sipResponse);
                        logger.LogWarning("Registration for " + m_sipAccountAOR.ToString() + " had a too short expiry, updated to +" + m_expiry + " and trying again.");
                        SendInitialRegister();
                    }
                    else
                    {
                        logger.LogWarning($"Registration failed with {sipResponse.Status} for {m_sipAccountAOR}.");
                        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}");
            }
        }
Exemple #12
0
 /// <summary>
 /// Redirects an incoming SIP call.
 /// </summary>
 public void Redirect(string destination)
 {
     m_pendingIncomingCall?.Redirect(SIPResponseStatusCodesEnum.MovedTemporarily, SIPURI.ParseSIPURIRelaxed(destination));
 }
Exemple #13
0
        /// <summary>
        /// Parses the input string into a SIP message object.
        /// </summary>
        /// <param name="value">The value.</param>
        public void Parse(string value)
        {
            int index = 0;

            index = value.IndexOf("\r\n\r\n");
            string body         = "";
            string firstheaders = "";

            if (index == -1)
            {
                firstheaders = value;
                Debug.Assert(false, String.Format("No message body, assuming empty\n{0}\n", value));
            }
            else
            {
                firstheaders = value.Substring(0, index);
                body         = value.Substring(index + 1).Trim();
            }
            index = firstheaders.IndexOf("\r\n");
            string firstline = firstheaders.Substring(0, index);
            string headers   = firstheaders.Substring(index + 2);

            string[] parts = firstline.Split(" ".ToCharArray(), 3);
            if (parts.Length < 3)
            {
                Debug.Assert(false, String.Format("First line has less than 3 parts \n{0}\n", firstline));
            }
            int tempResponseCode = 0;

            if (int.TryParse(parts[1], out tempResponseCode))
            {
                ResponseCode   = tempResponseCode;
                ResponseText   = parts[2];
                Protocol       = parts[0];
                StatusCodeType = Types.GetStatusType(ResponseCode);
            }
            else
            {
                Method   = parts[0];
                Uri      = new SIPURI(parts[1]);
                Protocol = parts[2];
            }
            string[] stringSeparators = new[] { "\r\n" };
            foreach (string bh in headers.Split(stringSeparators, StringSplitOptions.None))
            {
                string h = bh.Trim();
                if (Regex.IsMatch(h, @"^\s"))
                {
                    break;
                }
                try
                {
                    if (!h.StartsWith("Warning:"))
                    {
                        List <Header> createdHeaders = Header.CreateHeaders(h);
                        string        name           = createdHeaders[0].Name;
                        if (Headers.ContainsKey(name))
                        {
                            Headers[name].AddRange(createdHeaders);
                        }
                        else
                        {
                            Headers.Add(name, createdHeaders);
                        }
                    }
                }
                catch (Exception exp)
                {
                    Debug.Assert(false, String.Format("Error parsing header {0}\n with error\n{1}", h, exp.Message));
                    break;
                }
            }
            int bodylength = 0;

            if (Headers.ContainsKey("Content-Length"))
            {
                bodylength = Convert.ToInt32(First("Content-Length").Value);
            }
            if (body.Length > 0)
            {
                Body = body;
            }
            Debug.Assert(Math.Abs(body.Length - bodylength) < 3,
                         String.Format("Invalid content-length {0} != {1}\n", body.Length, bodylength));
            string[] mandatoryHeaders = { "To", "From", "CSeq", "Call-ID" };
            foreach (string s in mandatoryHeaders)
            {
                if (!Headers.ContainsKey(s))
                {
                    Debug.Assert(false, String.Format("Mandatory header missing {0}\n", s));
                }
            }
        }
Exemple #14
0
        static void Main()
        {
            Console.WriteLine("SIPSorcery call hold example.");
            Console.WriteLine("Press ctrl-c to exit.");

            // Plumbing code to facilitate a graceful exit.
            CancellationTokenSource exitCts = new CancellationTokenSource(); // Cancellation token to stop the SIP trnasport and RTP stream.
            bool isCallHungup  = false;
            bool hasCallFailed = false;

            AddConsoleLogger();

            SIPURI callUri = SIPURI.ParseSIPURI(DEFAULT_DESTINATION_SIP_URI);

            Log.LogInformation($"Call destination {callUri}.");

            // Set up a default SIP transport.
            var sipTransport = new SIPTransport();

            sipTransport.AddSIPChannel(new SIPUDPChannel(new IPEndPoint(IPAddress.Any, 0)));

            EnableTraceLogs(sipTransport);

            var lookupResult = SIPDNSManager.ResolveSIPService(callUri, false);

            Log.LogDebug($"DNS lookup result for {callUri}: {lookupResult?.GetSIPEndPoint()}.");
            var dstAddress = lookupResult.GetSIPEndPoint().Address;

            IPAddress localIPAddress = NetServices.GetLocalAddressForRemote(dstAddress);

            // Initialise an RTP session to receive the RTP packets from the remote SIP server.
            Socket rtpSocket     = null;
            Socket controlSocket = null;

            NetServices.CreateRtpSocket(localIPAddress, 48000, 48100, false, out rtpSocket, out controlSocket);
            var rtpRecvSession = new RTPSession((int)RTPPayloadTypesEnum.PCMU, null, null);
            var rtpSendSession = new RTPSession((int)RTPPayloadTypesEnum.PCMU, null, null);

            // Create a client user agent to place a call to a remote SIP server along with event handlers for the different stages of the call.
            var uac = new SIPClientUserAgent(sipTransport);

            uac.CallTrying += (uac, resp) =>
            {
                Log.LogInformation($"{uac.CallDescriptor.To} Trying: {resp.StatusCode} {resp.ReasonPhrase}.");
            };
            uac.CallRinging += (uac, resp) => Log.LogInformation($"{uac.CallDescriptor.To} Ringing: {resp.StatusCode} {resp.ReasonPhrase}.");
            uac.CallFailed  += (uac, err) =>
            {
                Log.LogWarning($"{uac.CallDescriptor.To} Failed: {err}");
                hasCallFailed = true;
            };
            uac.CallAnswered += (uac, resp) =>
            {
                if (resp.Status == SIPResponseStatusCodesEnum.Ok)
                {
                    Log.LogInformation($"{uac.CallDescriptor.To} Answered: {resp.StatusCode} {resp.ReasonPhrase}.");

                    // Only set the remote RTP end point if there hasn't already been a packet received on it.
                    if (_remoteRtpEndPoint == null)
                    {
                        _remoteRtpEndPoint = SDP.GetSDPRTPEndPoint(resp.Body);
                        Log.LogDebug($"Remote RTP socket {_remoteRtpEndPoint}.");
                    }
                }
                else
                {
                    Log.LogWarning($"{uac.CallDescriptor.To} Answered: {resp.StatusCode} {resp.ReasonPhrase}.");
                }
            };

            // The only incoming request that needs to be explicitly handled for this example is if the remote end hangs up the call.
            sipTransport.SIPTransportRequestReceived += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) =>
            {
                if (sipRequest.Method == SIPMethodsEnum.BYE)
                {
                    SIPNonInviteTransaction byeTransaction = sipTransport.CreateNonInviteTransaction(sipRequest, null);
                    SIPResponse             byeResponse    = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
                    byeTransaction.SendFinalResponse(byeResponse);

                    if (uac.IsUACAnswered)
                    {
                        Log.LogInformation("Call was hungup by remote server.");
                        isCallHungup = true;
                        exitCts.Cancel();
                    }
                }
            };

            // It's a good idea to start the RTP receiving socket before the call request is sent.
            // A SIP server will generally start sending RTP as soon as it has processed the incoming call request and
            // being ready to receive will stop any ICMP error response being generated.
            Task.Run(() => RecvRtp(rtpSocket, rtpRecvSession, exitCts));
            Task.Run(() => SendRtp(rtpSocket, rtpSendSession, exitCts));

            // Start the thread that places the call.
            SIPCallDescriptor callDescriptor = new SIPCallDescriptor(
                SIP_USERNAME,
                SIP_PASSWORD,
                callUri.ToString(),
                $"sip:{SIP_USERNAME}@localhost",
                callUri.CanonicalAddress,
                null, null, null,
                SIPCallDirection.Out,
                SDP.SDP_MIME_CONTENTTYPE,
                GetSDP(rtpSocket.LocalEndPoint as IPEndPoint).ToString(),
                null);

            uac.Call(callDescriptor);

            // Ctrl-c will gracefully exit the call at any point.
            Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
            {
                e.Cancel = true;
                exitCts.Cancel();
            };

            // At this point the call has been initiated and everything will be handled in an event handler.

            Task.Run(() =>
            {
                try
                {
                    while (!exitCts.Token.WaitHandle.WaitOne(0))
                    {
                        var keyProps = Console.ReadKey();
                        if (keyProps.KeyChar == 'h')
                        {
                        }
                        else if (keyProps.KeyChar == 'q')
                        {
                            Console.WriteLine();
                            Console.WriteLine("Hangup requested by user...");

                            uac.Hangup();

                            exitCts.Cancel();
                            rtpSocket?.Close();
                            controlSocket?.Close();

                            SIPSorcery.Sys.Log.Logger.LogInformation("Quitting...");

                            if (sipTransport != null)
                            {
                                SIPSorcery.Sys.Log.Logger.LogInformation("Shutting down SIP transport...");
                                sipTransport.Shutdown();
                            }
                        }
                    }
                }
                catch (Exception excp)
                {
                    SIPSorcery.Sys.Log.Logger.LogError($"Exception Key Press listener. {excp.Message}.");
                }
            });

            // Wait for a signal saying the call failed, was cancelled with ctrl-c or completed.
            exitCts.Token.WaitHandle.WaitOne();

            Log.LogInformation("Exiting...");

            rtpSocket?.Close();
            controlSocket?.Close();

            if (!isCallHungup && uac != null)
            {
                if (uac.IsUACAnswered)
                {
                    Log.LogInformation($"Hanging up call to {uac.CallDescriptor.To}.");
                    uac.Hangup();
                }
                else if (!hasCallFailed)
                {
                    Log.LogInformation($"Cancelling call to {uac.CallDescriptor.To}.");
                    uac.Cancel();
                }

                // Give the BYE or CANCEL request time to be transmitted.
                Log.LogInformation("Waiting 1s for call to clean up...");
                Task.Delay(1000).Wait();
            }

            SIPSorcery.Net.DNSManager.Stop();

            if (sipTransport != null)
            {
                Log.LogInformation("Shutting down SIP transport...");
                sipTransport.Shutdown();
            }
        }
Exemple #15
0
        public void Load(DataRow providerRow)
        {
            try
            {
                m_id                     = (providerRow.Table.Columns.Contains("id") && providerRow["id"] != DBNull.Value && providerRow["id"] != null) ? new Guid(providerRow["id"] as string) : Guid.NewGuid();
                m_providerType           = (ProviderTypes)Enum.Parse(typeof(ProviderTypes), providerRow["providertype"] as string, true);
                m_owner                  = providerRow["owner"] as string;
                AdminMemberId            = (providerRow.Table.Columns.Contains("adminmemberid") && providerRow["adminmemberid"] != null) ? providerRow["adminmemberid"] as string : null;
                m_providerName           = providerRow["providername"] as string;
                m_providerUsername       = providerRow["providerusername"] as string;
                m_providerPassword       = providerRow["providerpassword"] as string;
                m_providerServer         = SIPURI.ParseSIPURIRelaxed(providerRow["providerserver"] as string);
                m_providerAuthUsername   = (providerRow.Table.Columns.Contains("providerauthusername") && providerRow["providerauthusername"] != null) ? providerRow["providerauthusername"] as string : null;
                m_providerOutboundProxy  = (providerRow.Table.Columns.Contains("provideroutboundproxy") && providerRow["provideroutboundproxy"] != null) ? providerRow["provideroutboundproxy"] as string : null;
                m_providerFrom           = (providerRow.Table.Columns.Contains("providerfrom") && providerRow["providerfrom"] != null) ? providerRow["providerfrom"] as string : null;
                m_customHeaders          = (providerRow.Table.Columns.Contains("customheaders") && providerRow["customheaders"] != null) ? providerRow["customheaders"] as string : null;
                m_registerContact        = (providerRow.Table.Columns.Contains("registercontact") && providerRow["registercontact"] != DBNull.Value && providerRow["registercontact"] != null && providerRow["registercontact"].ToString().Length > 0) ? SIPURI.ParseSIPURIRelaxed(providerRow["registercontact"] as string) : null;
                m_registerExpiry         = (providerRow.Table.Columns.Contains("registerexpiry") && providerRow["registerexpiry"] != DBNull.Value && providerRow["registerexpiry"] != null) ? Convert.ToInt32(providerRow["registerexpiry"]) : REGISTER_DEFAULT_EXPIRY;
                m_registerServer         = (providerRow.Table.Columns.Contains("registerserver") && providerRow["registerserver"] != null) ? SIPURI.ParseSIPURIRelaxed(providerRow["registerserver"] as string) : null;
                m_registerRealm          = (providerRow.Table.Columns.Contains("registerrealm") && providerRow["registerrealm"] != null) ? providerRow["registerrealm"] as string : null;
                m_registerEnabled        = (providerRow.Table.Columns.Contains("registerenabled") && providerRow["registerenabled"] != DBNull.Value && providerRow["registerenabled"] != null) ? Convert.ToBoolean(providerRow["registerenabled"]) : false;
                m_registerAdminEnabled   = (providerRow.Table.Columns.Contains("registeradminenabled") && providerRow["registeradminenabled"] != DBNull.Value && providerRow["registeradminenabled"] != null) ? Convert.ToBoolean(providerRow["registeradminenabled"]) : true;
                m_registerDisabledReason = (providerRow.Table.Columns.Contains("registerdisabledreason") && providerRow["registerdisabledreason"] != DBNull.Value && providerRow["registerdisabledreason"] != null) ? providerRow["registerdisabledreason"] as string : null;
                m_gvCallbackNumber       = (providerRow.Table.Columns.Contains("gvcallbacknumber") && providerRow["gvcallbacknumber"] != null) ? providerRow["gvcallbacknumber"] as string : null;
                m_gvCallbackPattern      = (providerRow.Table.Columns.Contains("gvcallbackpattern") && providerRow["gvcallbackpattern"] != null) ? providerRow["gvcallbackpattern"] as string : null;
                m_gvCallbackType         = (providerRow.Table.Columns.Contains("gvcallbacktype") && providerRow["gvcallbacktype"] != DBNull.Value && providerRow["gvcallbacktype"] != null && (providerRow["gvcallbacktype"] as string).NotNullOrBlank()) ? (GoogleVoiceCallbackTypes)Enum.Parse(typeof(GoogleVoiceCallbackTypes), providerRow["gvcallbacktype"] as string, true) : (GoogleVoiceCallbackTypes?)null;
                LastUpdate               = (providerRow.Table.Columns.Contains("lastupdate") && providerRow["lastupdate"] != DBNull.Value && providerRow["lastupdate"] != null) ? DateTimeOffset.Parse(providerRow["lastupdate"] as string) : DateTimeOffset.UtcNow;
                Inserted                 = (providerRow.Table.Columns.Contains("inserted") && providerRow["inserted"] != DBNull.Value && providerRow["inserted"] != null) ? DateTimeOffset.Parse(providerRow["inserted"] as string) : DateTimeOffset.UtcNow;
                m_isReadOnly             = (providerRow.Table.Columns.Contains("isreadonly") && providerRow["isreadonly"] != DBNull.Value && providerRow["isreadonly"] != null) ? Convert.ToBoolean(providerRow["isreadonly"]) : false;
                m_sendMWISubscribe       = (providerRow.Table.Columns.Contains("sendmwisubscribe") && providerRow["sendmwisubscribe"] != DBNull.Value && providerRow["sendmwisubscribe"] != null) ? Convert.ToBoolean(providerRow["sendmwisubscribe"]) : false;

                if (m_registerContact == null && m_registerEnabled)
                {
                    m_registerEnabled        = false;
                    m_registerDisabledReason = "No Contact URI was specified for the registration.";
                    logger.Warn("Registrations for provider " + m_providerName + " owned by " + m_owner + " have been disabled due to an empty or invalid Contact URI.");
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception SIPProvider Load. " + excp.Message);
                throw;
            }
        }
        /// <summary>
        /// Checks and where required adds a presence related monitor event to the list of pending notifications.
        /// </summary>
        /// <param name="machineEvent">The monitor event that has been received.</param>
        /// <returns>True if a notification needs to be sent as a result of this monitor event, false otherwise.</returns>
        public override bool AddMonitorEvent(SIPMonitorMachineEvent machineEvent)
        {
            try
            {
                MonitorLogEvent_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Monitor, "Monitor event " + machineEvent.MachineEventType + " presence " + machineEvent.ResourceURI.ToString() + " for subscription to " + ResourceURI.ToString() + ".", SubscriptionDialogue.Owner));

                string safeSIPAccountID         = machineEvent.ResourceID;
                SIPURI sipAccountURI            = machineEvent.ResourceURI;
                bool   sendNotificationForEvent = true;
                string avatarURL = null;

                if (m_switchboardSIPAccountsOnly)
                {
                    // Need to check whether the SIP account is switchboard enabled before forwarding the notification.
                    Guid sipAccountID = new Guid(machineEvent.ResourceID);
                    //sendNotificationForEvent = Convert.ToBoolean(m_sipAccountPersistor.GetProperty(sipAccountID, "IsSwitchboardEnabled"));
                    sendNotificationForEvent = Convert.ToBoolean(GetSipAccountProperty_External(sipAccountID, "IsSwitchboardEnabled"));

                    if (sendNotificationForEvent)
                    {
                        //avatarURL = m_sipAccountPersistor.GetProperty(sipAccountID, "AvatarURL") as string;
                        avatarURL = GetSipAccountProperty_External(sipAccountID, "AvatarURL") as string;
                    }
                }

                if (sendNotificationForEvent)
                {
                    if (machineEvent.MachineEventType == SIPMonitorMachineEventTypesEnum.SIPRegistrarBindingUpdate)
                    {
                        // A binding has been updated so there is at least one device online for the SIP account.
                        Presence.Tuples.Add(new SIPEventPresenceTuple(safeSIPAccountID, SIPEventPresenceStateEnum.open, sipAccountURI, Decimal.Zero, avatarURL));
                        //logger.Debug(" single presence open.");
                    }
                    else
                    {
                        // A binding has been removed but there could still be others.
                        Guid sipAccountID  = new Guid(machineEvent.ResourceID);
                        int  bindingsCount = GetSIPRegistrarBindingsCount_External(b => b.SIPAccountId == sipAccountID);
                        if (bindingsCount > 0)
                        {
                            Presence.Tuples.Add(new SIPEventPresenceTuple(safeSIPAccountID, SIPEventPresenceStateEnum.open, sipAccountURI, Decimal.Zero, avatarURL));
                        }
                        else
                        {
                            Presence.Tuples.Add(new SIPEventPresenceTuple(safeSIPAccountID, SIPEventPresenceStateEnum.closed, sipAccountURI, Decimal.Zero, avatarURL));
                        }
                    }

                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception SIPresenceEventSubscription AddMonitorEvent. " + excp.Message);
                throw;
            }
        }
 public void Redirect(SIPResponseStatusCodesEnum redirectCode, SIPURI redirectURI)
 {
     try
     {
         if (m_uasTransaction.TransactionFinalResponse == null)
         {
             SIPResponse redirectResponse = SIPTransport.GetResponse(m_uasTransaction.TransactionRequest, redirectCode, null);
             redirectResponse.Header.Contact = SIPContactHeader.CreateSIPContactList(redirectURI);
             m_uasTransaction.SendFinalResponse(redirectResponse);
         }
     }
     catch (Exception excp)
     {
         logger.Error("Exception SIPServerUserAgent Redirect. " + excp.Message);
     }
 }
        private void SendMessageWaitingNotification(WOSI.CallButler.Data.CallButlerDataset.ExtensionsRow extension)
        {
            PBXPresenceInfo[] presenceInfos = GetPresenceInfoForExtension(extension.ExtensionNumber);

            if (presenceInfos != null)
            {
                foreach (PBXPresenceInfo presenceInfo in presenceInfos)
                {
                    if (presenceInfo.Status == PBXPresenceStatus.Online)
                    {
                        // Create our notify message
                        SipRequest request = new SipRequest(SIPMethodType.NOTIFY);

                        SIPURI requestURI = new SIPURI(presenceInfo.AddressOfRecord);

                        request.BranchID = "z9hG4bK" + Guid.NewGuid().ToString();
                        request.RequestURI = new SIPURI(presenceInfo.AddressOfRecord);
                        request.HeaderFields["To", "t"].FieldValue = requestURI.ExtendedURIStringWithParameters;
                        request.HeaderFields["From", "f"].FieldValue = requestURI.ExtendedURIStringWithParameters;
                        request.HeaderFields.Add("Event", "message-summary");
                        request.HeaderFields.Add("Content-Type", "application/simple-message-summary");

                        StringBuilder sb = new StringBuilder();

                        int newVoicemailCount = dataProvider.GetNewVoicemailCount(extension.ExtensionID);
                        int totalVoicemailCount = dataProvider.GetVoicemails(extension.ExtensionID).Count;

                        string vmStatus = "no";

                        if (newVoicemailCount > 0)
                            vmStatus = "yes";

                        sb.AppendFormat("Messages-Waiting: {0}\r\n", vmStatus);
                        sb.AppendFormat("Voice-Message: {0}/{1}", newVoicemailCount, totalVoicemailCount);

                        request.MessageBody = sb.ToString();

                        ipClient.SendSipRequest(request, presenceInfo.RemoteAddress, presenceInfo.RemotePort);
                    }
                }
            }
        }
        public static SIPDNSLookupResult DNSARecordLookup(string host, int port, bool async, SIPURI uri)
        {
            SIPDNSLookupResult result = new SIPDNSLookupResult(uri);


            return(result);
        }
Exemple #20
0
        public void TcpTrickleReceiveTest()
        {
            TaskCompletionSource <bool> testComplete = new TaskCompletionSource <bool>();

            IPEndPoint listenEP   = new IPEndPoint(IPAddress.Loopback, 9066);
            var        transport  = new SIPTransport();
            var        tcpChannel = new SIPTCPChannel(new IPEndPoint(IPAddress.Loopback, 9067));

            tcpChannel.DisableLocalTCPSocketsCheck = true;
            transport.AddSIPChannel(tcpChannel);

            int requestCount  = 10;
            int recvdReqCount = 0;

            Task.Run(() =>
            {
                TcpListener listener = new TcpListener(listenEP);
                listener.Start();
                var tcpClient = listener.AcceptTcpClient();
                logger.LogDebug($"TCP listener accepted client with remote end point {tcpClient.Client.RemoteEndPoint}.");
                for (int i = 0; i < requestCount; i++)
                {
                    logger.LogDebug($"Sending request {i}.");

                    var req         = transport.GetRequest(SIPMethodsEnum.OPTIONS, SIPURI.ParseSIPURIRelaxed($"{i}@sipsorcery.com"));
                    byte[] reqBytes = Encoding.UTF8.GetBytes(req.ToString());

                    tcpClient.GetStream().Write(reqBytes, 0, reqBytes.Length);
                    tcpClient.GetStream().Flush();

                    Task.Delay(30).Wait();
                }
                tcpClient.GetStream().Close();
            });

            transport.SIPTransportRequestReceived += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) =>
            {
                logger.LogDebug($"Request received {localSIPEndPoint.ToString()}<-{remoteEndPoint.ToString()}: {sipRequest.StatusLine}");
                logger.LogDebug(sipRequest.ToString());
                Interlocked.Increment(ref recvdReqCount);

                if (recvdReqCount == requestCount)
                {
                    testComplete.SetResult(true);
                }
            };

            transport.SIPTransportResponseReceived += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPResponse sipResponse) =>
            {
                logger.LogDebug($"Response received {localSIPEndPoint.ToString()}<-{remoteEndPoint.ToString()}: {sipResponse.ShortDescription}");
                logger.LogDebug(sipResponse.ToString());
            };

            tcpChannel.ConnectClientAsync(listenEP, null, null).Wait();

            Task.WhenAny(new Task[] { testComplete.Task, Task.Delay(5000) }).Wait();

            transport.Shutdown();

            Assert.IsTrue(testComplete.Task.IsCompleted);
            Assert.IsTrue(testComplete.Task.Result);
            Assert.AreEqual(requestCount, recvdReqCount, $"The count of {recvdReqCount} for the requests received did not match what was expected.");
        }
 public void Load(DataRow row)
 {
     try
     {
         Id = new Guid(row["id"] as string);
         SIPAccountId = new Guid(row["sipaccountid"] as string);
         SIPAccountName = row["sipaccountname"] as string;
         Owner = row["owner"] as string;
         AdminMemberId = row["adminmemberid"] as string;
         UserAgent = row["useragent"] as string;
         m_contactURI = SIPURI.ParseSIPURI(row["contacturi"] as string);
         m_mangledContactURI = (!(row["mangledcontacturi"] as string).IsNullOrBlank()) ? SIPURI.ParseSIPURI(row["mangledcontacturi"] as string) : null;
         Expiry = Convert.ToInt32(row["expiry"]);
         RemoteSIPEndPoint = (!(row["remotesipsocket"] as string).IsNullOrBlank()) ? SIPEndPoint.ParseSIPEndPoint(row["remotesipsocket"] as string) : null;
         m_proxySIPEndPoint = (!(row["proxysipsocket"] as string).IsNullOrBlank()) ? SIPEndPoint.ParseSIPEndPoint(row["proxysipsocket"] as string) : null;
         m_registrarSIPEndPoint = (!(row["registrarsipsocket"] as string).IsNullOrBlank()) ? SIPEndPoint.ParseSIPEndPoint(row["registrarsipsocket"] as string) : null;
         LastUpdate = DateTimeOffset.Parse(row["lastupdate"] as string);
     }
     catch (Exception excp)
     {
         logger.Error("Exception SIPRegistrarBinding Load. " + excp.Message);
         throw;
     }
 }
 public void Redirect(SIPResponseStatusCodesEnum redirectCode, SIPURI redirectURI)
 {
     throw new NotImplementedException();
 }
Exemple #23
0
        public static SIPDNSLookupResult DNSNameRecordLookup(string host, int port, bool async, SIPURI lookupURI, ref SIPDNSLookupResult lookupResult, bool?preferIPv6 = null)
        {
            SIPDNSLookupResult result = null;

            if (lookupResult.SIPSRVResults != null)
            {
                foreach (SIPDNSServiceResult nextSRVRecord in lookupResult.SIPSRVResults)
                {
                    if (nextSRVRecord != null && nextSRVRecord.Data != null)
                    {
                        result = DNSNameRecordLookup(nextSRVRecord.Data, nextSRVRecord.Port, async, lookupResult.URI, lookupResult, preferIPv6);
                        if (result.LookupError == null)
                        {
                            return(result);
                        }
                    }
                }
            }

            result = DNSNameRecordLookup(host, port, async, lookupResult.URI, lookupResult, preferIPv6);
            return(result);
        }
 public static SIPDNSLookupResult DNSARecordLookup(SIPDNSServiceResult nextSRVRecord, string host, int port, bool async, SIPURI lookupURI)
 {
     if (nextSRVRecord != null && nextSRVRecord.Data != null)
     {
         return DNSARecordLookup(nextSRVRecord.Data, port, async, lookupURI);
         //nextSRVRecord.ResolvedAt = DateTime.Now;
     }
     else
     {
         return DNSARecordLookup(host, port, async, lookupURI);
     }
 }
 public SIPParameterlessURI(SIPURI sipURI)
 {
     m_uri = sipURI;
 }
Exemple #26
0
        static void Main()
        {
            Console.WriteLine("SIPSorcery call hold example.");
            Console.WriteLine("Press ctrl-c to exit.");

            // Plumbing code to facilitate a graceful exit.
            CancellationTokenSource exitCts = new CancellationTokenSource(); // Cancellation token to stop the SIP transport and RTP stream.
            bool isCallHungup  = false;
            bool hasCallFailed = false;

            AddConsoleLogger();

            // Set up a default SIP transport.
            var sipTransport = new SIPTransport();

            sipTransport.AddSIPChannel(new SIPUDPChannel(new IPEndPoint(IPAddress.Any, SIP_LISTEN_PORT)));

            //EnableTraceLogs(sipTransport);

            // Get the default speaker.
            var(audioOutEvent, audioOutProvider) = GetAudioOutputDevice();
            WaveInEvent waveInEvent = GetAudioInputDevice();

            RTPMediaSession RtpMediaSession = null;

            // Create a client/server user agent to place a call to a remote SIP server along with event handlers for the different stages of the call.
            var userAgent = new SIPUserAgent(sipTransport, null);

            userAgent.ClientCallTrying  += (uac, resp) => Log.LogInformation($"{uac.CallDescriptor.To} Trying: {resp.StatusCode} {resp.ReasonPhrase}.");
            userAgent.ClientCallRinging += (uac, resp) => Log.LogInformation($"{uac.CallDescriptor.To} Ringing: {resp.StatusCode} {resp.ReasonPhrase}.");
            userAgent.ClientCallFailed  += (uac, err) =>
            {
                Log.LogWarning($"{uac.CallDescriptor.To} Failed: {err}");
                hasCallFailed = true;
                exitCts.Cancel();
            };
            userAgent.ClientCallAnswered += (uac, resp) =>
            {
                if (resp.Status == SIPResponseStatusCodesEnum.Ok)
                {
                    Log.LogInformation($"{uac.CallDescriptor.To} Answered: {resp.StatusCode} {resp.ReasonPhrase}.");
                    PlayRemoteMedia(RtpMediaSession, audioOutProvider);
                }
                else
                {
                    Log.LogWarning($"{uac.CallDescriptor.To} Answered: {resp.StatusCode} {resp.ReasonPhrase}.");
                    hasCallFailed = true;
                    exitCts.Cancel();
                }
            };
            userAgent.OnCallHungup += () =>
            {
                Log.LogInformation($"Call hungup by remote party.");
                exitCts.Cancel();
            };
            userAgent.ServerCallCancelled += (uas) => Log.LogInformation("Incoming call cancelled by caller.");

            sipTransport.SIPTransportRequestReceived += async(localEndPoint, remoteEndPoint, sipRequest) =>
            {
                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)
                {
                    if (userAgent?.IsCallActive == true)
                    {
                        Log.LogWarning($"Busy response returned for incoming call request from {remoteEndPoint}: {sipRequest.StatusLine}.");
                        // If we are 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
                    {
                        Log.LogInformation($"Incoming call request from {remoteEndPoint}: {sipRequest.StatusLine}.");
                        var incomingCall = userAgent.AcceptCall(sipRequest);

                        RtpMediaSession = new RTPMediaSession(SDPMediaTypesEnum.audio, new SDPMediaFormat(SDPMediaFormatsEnum.PCMU), AddressFamily.InterNetwork);
                        RtpMediaSession.RemotePutOnHold   += () => Log.LogInformation("Remote call party has placed us on hold.");
                        RtpMediaSession.RemoteTookOffHold += () => Log.LogInformation("Remote call party took us off hold.");
                        await userAgent.Answer(incomingCall, RtpMediaSession);

                        PlayRemoteMedia(RtpMediaSession, audioOutProvider);
                        waveInEvent.StartRecording();

                        Log.LogInformation($"Answered incoming call from {sipRequest.Header.From.FriendlyDescription()} at {remoteEndPoint}.");
                    }
                }
                else
                {
                    Log.LogDebug($"SIP {sipRequest.Method} request received but no processing has been set up for it, rejecting.");
                    SIPResponse notAllowedResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null);
                    await sipTransport.SendResponseAsync(notAllowedResponse);
                }
            };

            // Wire up the RTP send session to the audio output device.
            uint rtpSendTimestamp = 0;

            waveInEvent.DataAvailable += (object sender, WaveInEventArgs args) =>
            {
                byte[] sample      = new byte[args.Buffer.Length / 2];
                int    sampleIndex = 0;

                for (int index = 0; index < args.BytesRecorded; index += 2)
                {
                    var ulawByte = NAudio.Codecs.MuLawEncoder.LinearToMuLawSample(BitConverter.ToInt16(args.Buffer, index));
                    sample[sampleIndex++] = ulawByte;
                }

                if (RtpMediaSession != null)
                {
                    RtpMediaSession.SendAudioFrame(rtpSendTimestamp, (int)SDPMediaFormatsEnum.PCMU, sample);
                    rtpSendTimestamp += (uint)(8000 / waveInEvent.BufferMilliseconds);
                }
            };

            // At this point the call has been initiated and everything will be handled in an event handler.
            Task.Run(async() =>
            {
                try
                {
                    while (!exitCts.Token.WaitHandle.WaitOne(0))
                    {
                        var keyProps = Console.ReadKey();

                        if (keyProps.KeyChar == 'c')
                        {
                            if (!userAgent.IsCallActive)
                            {
                                RtpMediaSession = new RTPMediaSession(SDPMediaTypesEnum.audio, new SDPMediaFormat(SDPMediaFormatsEnum.PCMU), AddressFamily.InterNetwork);
                                RtpMediaSession.RemotePutOnHold   += () => Log.LogInformation("Remote call party has placed us on hold.");
                                RtpMediaSession.RemoteTookOffHold += () => Log.LogInformation("Remote call party took us off hold.");

                                var callDescriptor = GetCallDescriptor(DEFAULT_DESTINATION_SIP_URI);
                                await userAgent.InitiateCall(callDescriptor, RtpMediaSession);
                            }
                            else
                            {
                                Log.LogWarning("There is already an active call.");
                            }
                        }
                        else if (keyProps.KeyChar == 'h')
                        {
                            // Place call on/off hold.
                            if (userAgent.IsCallActive)
                            {
                                if (RtpMediaSession.LocalOnHold)
                                {
                                    Log.LogInformation("Taking the remote call party off hold.");
                                    RtpMediaSession.TakeOffHold();
                                }
                                else
                                {
                                    Log.LogInformation("Placing the remote call party on hold.");
                                    RtpMediaSession.PutOnHold();
                                }
                            }
                            else
                            {
                                Log.LogWarning("There is no active call to put on hold.");
                            }
                        }
                        else if (keyProps.KeyChar == 't')
                        {
                            if (userAgent.IsCallActive)
                            {
                                var transferURI = SIPURI.ParseSIPURI(TRANSFER_DESTINATION_SIP_URI);
                                bool result     = await userAgent.BlindTransfer(transferURI, TimeSpan.FromSeconds(TRANSFER_TIMEOUT_SECONDS), exitCts.Token);
                                if (result)
                                {
                                    // If the transfer was accepted the original call will already have been hungup.
                                    // Wait a second for the transfer NOTIFY request to arrive.
                                    await Task.Delay(1000);
                                    exitCts.Cancel();
                                }
                                else
                                {
                                    Log.LogWarning($"Transfer to {TRANSFER_DESTINATION_SIP_URI} failed.");
                                }
                            }
                            else
                            {
                                Log.LogWarning("There is no active call to transfer.");
                            }
                        }
                        else if (keyProps.KeyChar == 'q')
                        {
                            // Quit application.
                            exitCts.Cancel();
                        }
                    }
                }
                catch (Exception excp)
                {
                    SIPSorcery.Sys.Log.Logger.LogError($"Exception Key Press listener. {excp.Message}.");
                }
            });

            // Ctrl-c will gracefully exit the call at any point.
            Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
            {
                e.Cancel = true;
                exitCts.Cancel();
            };

            // Wait for a signal saying the call failed, was cancelled with ctrl-c or completed.
            exitCts.Token.WaitHandle.WaitOne();

            #region Cleanup.

            Log.LogInformation("Exiting...");

            RtpMediaSession?.Close();
            waveInEvent?.StopRecording();
            audioOutEvent?.Stop();

            if (!isCallHungup && userAgent != null)
            {
                if (userAgent.IsCallActive)
                {
                    Log.LogInformation($"Hanging up call to {userAgent?.CallDescriptor?.To}.");
                    userAgent.Hangup();
                }
                else if (!hasCallFailed)
                {
                    Log.LogInformation($"Cancelling call to {userAgent?.CallDescriptor?.To}.");
                    userAgent.Cancel();
                }

                // Give the BYE or CANCEL request time to be transmitted.
                Log.LogInformation("Waiting 1s for call to clean up...");
                Task.Delay(1000).Wait();
            }

            SIPSorcery.Net.DNSManager.Stop();

            if (sipTransport != null)
            {
                Log.LogInformation("Shutting down SIP transport...");
                sipTransport.Shutdown();
            }

            #endregion
        }
 public SIPDNSLookupResult(SIPURI uri, string lookupError)
 {
     URI = uri;
     LookupError = lookupError;
 }
        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;
        }
Exemple #29
0
 public void Redirect(SIPResponseStatusCodesEnum redirectCode, SIPURI redirectURI)
 {
     Redirect(redirectCode, redirectURI, null);
 }
 public void Redirect(SIPResponseStatusCodesEnum redirectCode, SIPURI redirectURI)
 {
     NoRingTimeout.Invoke(this);
     logger.Debug("SIPB2BUserAgent Redirect.");
     //m_uas.Redirect(redirectCode, redirectURI);
 }
Exemple #31
0
        private void ExpireBindings()
        {
            try
            {
                Thread.CurrentThread.Name = EXPIRE_BINDINGS_THREAD_NAME;

                while (!m_stop)
                {
                    try
                    {
                        DateTimeOffset      expiryTime     = DateTimeOffset.UtcNow.AddSeconds(BINDING_EXPIRY_GRACE_PERIOD * -1);
                        SIPRegistrarBinding expiredBinding = GetNextExpiredBinding(expiryTime);

                        while (expiredBinding != null)
                        {
                            FireSIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar,
                                                                              SIPMonitorEventTypesEnum.BindingExpired, "Expired binding deleted for " +
                                                                              expiredBinding.SIPAccountName + " and " +
                                                                              expiredBinding.MangledContactURI +
                                                                              ", last register " +
                                                                              expiredBinding.LastUpdate
                                                                              .ToString("HH:mm:ss") + ", expiry " +
                                                                              expiredBinding.Expiry + ", expiry time " +
                                                                              expiredBinding.ExpiryTime
                                                                              .ToString("HH:mm:ss") + ", now " +
                                                                              expiryTime.ToString("HH:mm:ss") + ".",
                                                                              expiredBinding.Owner));

                            FireSIPMonitorLogEvent(new SIPMonitorMachineEvent(
                                                       SIPMonitorMachineEventTypesEnum.SIPRegistrarBindingRemoval, expiredBinding.Owner,
                                                       expiredBinding.SIPAccountId.ToString(),
                                                       SIPURI.ParseSIPURIRelaxed(expiredBinding.SIPAccountName + "@sipsorcery.com")));

                            lock (m_natKeepAliveJobs)
                            {
                                if (m_natKeepAliveJobs.ContainsKey(expiredBinding.RemoteSIPSocket))
                                {
                                    m_natKeepAliveJobs[expiredBinding.RemoteSIPSocket].CancelJob();
                                }
                            }

                            expiryTime     = DateTimeOffset.UtcNow.AddSeconds(BINDING_EXPIRY_GRACE_PERIOD * -1);
                            expiredBinding = GetNextExpiredBinding(expiryTime);
                        }
                    }
                    catch (Exception expireExcp)
                    {
                        Logger.Logger.Error("Exception ExpireBindings Delete. ->" + expireExcp.Message);
                    }

                    Thread.Sleep(REMOVE_EXPIRED_BINDINGS_INTERVAL);
                }
            }
            catch (Exception excp)
            {
                Logger.Logger.Error("Exception ExpireBindings. ->" + excp.Message);
            }
            finally
            {
                Logger.Logger.Warn("Thread " + EXPIRE_BINDINGS_THREAD_NAME + " stopped!");
            }
        }
 public SIPParameterlessURI(SIPSchemesEnum scheme, string host, string user)
 {
     m_uri        = new SIPURI(user, host, null);
     m_uri.Scheme = scheme;
 }
Exemple #33
0
        /// <summary>
        /// Updates the bindings list for a registrar's address-of-records.
        /// </summary>
        /// <param name="proxyEndPoint">If the request arrived at this registrar via a proxy then this will contain the end point of the proxy.</param>
        /// <param name="uacRecvdEndPoint">The public end point the UAC REGISTER request was deemded to have originated from.</param>
        /// <param name="registrarEndPoint">The registrar end point the registration request was received on.</param>
        /// <param name="maxAllowedExpiry">The maximum allowed expiry that can be granted to this binding request.</param>
        /// <returns>If the binding update was successful the expiry time for it is returned otherwise 0.</returns>
        public List <SIPRegistrarBinding> UpdateBindings(
            SIPAccount sipAccount,
            SIPEndPoint proxySIPEndPoint,
            SIPEndPoint remoteSIPEndPoint,
            SIPEndPoint registrarSIPEndPoint,
            List <SIPContactHeader> contactHeaders,
            string callId,
            int cseq,
            //int contactHeaderExpiresValue,
            int expiresHeaderValue,
            string userAgent,
            out SIPResponseStatusCodesEnum responseStatus,
            out string responseMessage)
        {
            //logger.Debug("UpdateBinding " + bindingURI.ToString() + ".");

            int maxAllowedExpiry = (m_userAgentConfigs != null)
                ? m_userAgentConfigs.GetMaxAllowedExpiry(userAgent)
                : SIPUserAgentConfiguration.DEFAULT_MAX_EXPIRY_SECONDS;

            responseMessage = null;
            string sipAccountAOR = sipAccount.SIPUsername + "@" + sipAccount.SIPDomain;

            responseStatus = SIPResponseStatusCodesEnum.Ok;

            try
            {
                userAgent = (userAgent != null && userAgent.Length > MAX_USERAGENT_LENGTH)
                    ? userAgent.Substring(0, MAX_USERAGENT_LENGTH)
                    : userAgent;

                List <SIPRegistrarBinding> bindings =
                    m_bindingsPersistor.Get(b => b.SIPAccountId == sipAccount.Id, null, 0, Int32.MaxValue);

                foreach (SIPContactHeader contactHeader in contactHeaders)
                {
                    SIPURI bindingURI = contactHeader.ContactURI.CopyOf();
                    int    contactHeaderExpiresValue = contactHeader.Expires;
                    int    bindingExpiry             = 0;

                    if (bindingURI.Host == m_sipRegisterRemoveAll)
                    {
                        if (contactHeaders.Count > 1)
                        {
                            // If a register request specifies remove all it cannot contain any other binding requests.
                            FireSIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar,
                                                                              SIPMonitorEventTypesEnum.BindingRemoval,
                                                                              "Remove all bindings requested for " + sipAccountAOR +
                                                                              " but mutliple bindings specified, rejecting as a bad request.",
                                                                              sipAccount.SIPUsername));
                            responseStatus = SIPResponseStatusCodesEnum.BadRequest;
                            break;
                        }

                        #region Process remove all bindings.

                        if (expiresHeaderValue == 0)
                        {
                            // Removing all bindings for user.
                            FireSIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar,
                                                                              SIPMonitorEventTypesEnum.BindingRemoval,
                                                                              "Remove all bindings requested for " + sipAccountAOR + ".", sipAccount.SIPUsername));

                            // Mark all the current bindings as expired.
                            if (bindings != null && bindings.Count > 0)
                            {
                                for (int index = 0; index < bindings.Count; index++)
                                {
                                    bindings[index].RemovalReason = SIPBindingRemovalReason.ClientExpiredAll;
                                    bindings[index].Expiry        = 0;
                                    m_bindingsPersistor.Update(bindings[index]);

                                    // Remove the NAT keep-alive job if present.
                                    if (m_natKeepAliveJobs.ContainsKey(bindings[index].RemoteSIPSocket))
                                    {
                                        m_natKeepAliveJobs[bindings[index].RemoteSIPSocket].CancelJob();
                                    }
                                }
                            }

                            FireSIPMonitorLogEvent(new SIPMonitorMachineEvent(
                                                       SIPMonitorMachineEventTypesEnum.SIPRegistrarBindingRemoval, sipAccount.Owner,
                                                       sipAccount.Id.ToString(), SIPURI.ParseSIPURIRelaxed(sipAccountAOR)));

                            responseStatus = SIPResponseStatusCodesEnum.Ok;
                        }
                        else
                        {
                            // Remove all header cannot be present with other headers and must have an Expiry equal to 0.
                            responseStatus = SIPResponseStatusCodesEnum.BadRequest;
                        }

                        #endregion
                    }
                    else
                    {
                        int requestedExpiry = (contactHeaderExpiresValue != -1)
                            ? contactHeaderExpiresValue
                            : expiresHeaderValue;
                        requestedExpiry =
                            (requestedExpiry == -1)
                                ? maxAllowedExpiry
                                : requestedExpiry; // This will happen if the Expires header and the Expiry on the Contact are both missing.
                        bindingExpiry = (requestedExpiry > maxAllowedExpiry) ? maxAllowedExpiry : requestedExpiry;
                        bindingExpiry = (bindingExpiry < MINIMUM_EXPIRY_SECONDS)
                            ? MINIMUM_EXPIRY_SECONDS
                            : bindingExpiry;

                        bindingURI.Parameters.Remove(m_sipExpiresParameterKey);

                        SIPRegistrarBinding binding = GetBindingForContactURI(bindings, bindingURI.ToString());

                        if (binding != null)
                        {
                            if (requestedExpiry <= 0)
                            {
                                FireSIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar,
                                                                                  SIPMonitorEventTypesEnum.BindingExpired,
                                                                                  "Binding expired by client for " + sipAccountAOR + " from " +
                                                                                  remoteSIPEndPoint.ToString() + ".", sipAccount.SIPUsername));
                                bindings.Remove(binding);
                                m_bindingsPersistor.Delete(binding);
                                bindingExpiry = 0;

                                FireSIPMonitorLogEvent(new SIPMonitorMachineEvent(
                                                           SIPMonitorMachineEventTypesEnum.SIPRegistrarBindingRemoval, sipAccount.Owner,
                                                           sipAccount.Id.ToString(), SIPURI.ParseSIPURIRelaxed(sipAccountAOR)));

                                // Remove the NAT keep-alive job if present.
                                if (m_natKeepAliveJobs.ContainsKey(binding.RemoteSIPSocket))
                                {
                                    m_natKeepAliveJobs[binding.RemoteSIPSocket].CancelJob();
                                }
                            }
                            else
                            {
                                FireSIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar,
                                                                                  SIPMonitorEventTypesEnum.Registrar,
                                                                                  "Binding update request for " + sipAccountAOR + " from " +
                                                                                  remoteSIPEndPoint.ToString() + ", expiry requested " + requestedExpiry +
                                                                                  "s granted " + bindingExpiry + "s.", sipAccount.Owner));
                                binding.RefreshBinding(bindingExpiry, remoteSIPEndPoint, proxySIPEndPoint,
                                                       registrarSIPEndPoint, sipAccount.DontMangleEnabled);

                                DateTime startTime = DateTime.Now;
                                m_bindingsPersistor.Update(binding);
                                TimeSpan duration = DateTime.Now.Subtract(startTime);
                                //FireSIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.RegistrarTiming, "Binding database update time for " + sipAccountAOR + " took " + duration.TotalMilliseconds + "ms.", null));
                                FireSIPMonitorLogEvent(new SIPMonitorMachineEvent(
                                                           SIPMonitorMachineEventTypesEnum.SIPRegistrarBindingUpdate, sipAccount.Owner,
                                                           sipAccount.Id.ToString(), SIPURI.ParseSIPURIRelaxed(sipAccountAOR)));

                                // Add a NAT keep-alive job if required.
                                if (sipAccount.SendNATKeepAlives && proxySIPEndPoint != null)
                                {
                                    AddNATKeepAliveJob(sipAccount, remoteSIPEndPoint, proxySIPEndPoint, binding,
                                                       bindingExpiry);
                                }
                            }
                        }
                        else
                        {
                            if (requestedExpiry > 0)
                            {
                                FireSIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar,
                                                                                  SIPMonitorEventTypesEnum.BindingInProgress,
                                                                                  "New binding request for " + sipAccountAOR + " from " +
                                                                                  remoteSIPEndPoint.ToString() + ", expiry requested " + requestedExpiry +
                                                                                  "s granted " + bindingExpiry + "s.", sipAccount.Owner));

                                if (bindings.Count >= m_maxBindingsPerAccount)
                                {
                                    // Need to remove the oldest binding to stay within limit.
                                    //SIPRegistrarBinding oldestBinding = m_bindingsPersistor.Get(b => b.SIPAccountId == sipAccount.Id, null, 0, Int32.MaxValue).OrderBy(x => x.LastUpdateUTC).Last();
                                    SIPRegistrarBinding oldestBinding = bindings.OrderBy(x => x.LastUpdate).Last();
                                    FireSIPMonitorLogEvent(new SIPMonitorConsoleEvent(
                                                               SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.BindingInProgress,
                                                               "Binding limit exceeded for " + sipAccountAOR + " from " +
                                                               remoteSIPEndPoint.ToString() +
                                                               " removing oldest binding to stay within limit of " + m_maxBindingsPerAccount +
                                                               ".", sipAccount.Owner));
                                    m_bindingsPersistor.Delete(oldestBinding);

                                    if (m_natKeepAliveJobs.ContainsKey(binding.RemoteSIPSocket))
                                    {
                                        m_natKeepAliveJobs[binding.RemoteSIPSocket].CancelJob();
                                    }
                                }

                                SIPRegistrarBinding newBinding = new SIPRegistrarBinding(sipAccount, bindingURI, callId,
                                                                                         cseq, userAgent, remoteSIPEndPoint, proxySIPEndPoint, registrarSIPEndPoint,
                                                                                         bindingExpiry);
                                DateTime startTime = DateTime.Now;
                                bindings.Add(newBinding);
                                m_bindingsPersistor.Add(newBinding);
                                TimeSpan duration = DateTime.Now.Subtract(startTime);
                                //FireSIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.RegistrarTiming, "Binding database add time for " + sipAccountAOR + " took " + duration.TotalMilliseconds + "ms.", null));

                                // Add a NAT keep-alive job if required.
                                if (sipAccount.SendNATKeepAlives && proxySIPEndPoint != null)
                                {
                                    AddNATKeepAliveJob(sipAccount, remoteSIPEndPoint, proxySIPEndPoint, newBinding,
                                                       bindingExpiry);
                                }

                                FireSIPMonitorLogEvent(new SIPMonitorMachineEvent(
                                                           SIPMonitorMachineEventTypesEnum.SIPRegistrarBindingUpdate, sipAccount.Owner,
                                                           sipAccount.Id.ToString(), SIPURI.ParseSIPURIRelaxed(sipAccountAOR)));
                            }
                            else
                            {
                                FireSIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar,
                                                                                  SIPMonitorEventTypesEnum.BindingFailed,
                                                                                  "New binding received for " + sipAccountAOR + " with expired contact," +
                                                                                  bindingURI.ToString() + " no update.", sipAccount.Owner));
                                bindingExpiry = 0;
                            }
                        }

                        responseStatus = SIPResponseStatusCodesEnum.Ok;
                    }
                }

                return(bindings);
            }
            catch (Exception excp)
            {
                Logger.Logger.Error("Exception UpdateBinding. ->" + excp.Message);
                FireSIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar,
                                                                  SIPMonitorEventTypesEnum.Error,
                                                                  "Registrar error updating binding: " + excp.Message + " Binding not updated.",
                                                                  sipAccount.SIPUsername));
                responseStatus = SIPResponseStatusCodesEnum.InternalServerError;
                return(null);
            }
        }
Exemple #34
0
        [Ignore] // Broken after NEtStandard migration.
        public void SingleProviderLegUnitTest()
        {
            Console.WriteLine("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name);

            SIPRequest   inviteRequest = new SIPRequest(SIPMethodsEnum.INVITE, SIPURI.ParseSIPURI("sip:1234@localhost"));
            SIPHeader    inviteHeader  = new SIPHeader(SIPFromHeader.ParseFromHeader("<sip:joe@localhost>"), SIPToHeader.ParseToHeader("<sip:jane@localhost>"), 23, CallProperties.CreateNewCallId());
            SIPViaHeader viaHeader     = new SIPViaHeader("127.0.0.1", 5060, CallProperties.CreateBranchId());

            inviteHeader.Vias.PushViaHeader(viaHeader);
            inviteRequest.Header = inviteHeader;

            List <SIPProvider> providers = new List <SIPProvider>();
            SIPProvider        provider  = new SIPProvider(ProviderTypes.SIP, "test", "blueface", "test", "password", SIPURI.ParseSIPURIRelaxed("sip.blueface.ie"), null, null, null, null, 3600, null, null, null, false, false, null, null, null);

            providers.Add(provider);

            DialStringParser dialStringParser           = new DialStringParser(null, "test", null, providers, delegate { return(null); }, delegate { return(null); }, (host, wildcard) => { return(null); }, null, "test");
            Queue <List <SIPCallDescriptor> > callQueue = dialStringParser.ParseDialString(DialPlanContextsEnum.Script, inviteRequest, "blueface", null, null, null, null, null, null, null, null, CustomerServiceLevels.Free);

            Assert.IsNotNull(callQueue, "The call list should have contained a call.");
            Assert.IsTrue(callQueue.Count == 1, "The call queue list should have contained one leg.");

            List <SIPCallDescriptor> firstLeg = callQueue.Dequeue();

            Assert.IsNotNull(firstLeg, "The first call leg should exist.");
            Assert.IsTrue(firstLeg.Count == 1, "The first call leg should have had one switch call.");
            Assert.IsTrue(firstLeg[0].Username == "test", "The username for the first call leg was not correct.");
            Assert.IsTrue(firstLeg[0].Uri.ToString() == "sip:[email protected]", "The destination URI for the first call leg was not correct.");

            Console.WriteLine("---------------------------------");
        }
Exemple #35
0
        static void Main(string[] args)
        {
            Console.WriteLine("SIPSorcery client user agent example.");
            Console.WriteLine("Press ctrl-c to exit.");

            // Plumbing code to facilitate a graceful exit.
            ManualResetEvent exitMre       = new ManualResetEvent(false);
            bool             isCallHungup  = false;
            bool             hasCallFailed = false;

            AddConsoleLogger();

            SIPURI callUri = SIPURI.ParseSIPURI(DEFAULT_DESTINATION_SIP_URI);

            if (args != null && args.Length > 0)
            {
                if (!SIPURI.TryParse(args[0], out callUri))
                {
                    Log.LogWarning($"Command line argument could not be parsed as a SIP URI {args[0]}");
                }
            }
            Log.LogInformation($"Call destination {callUri}.");

            // Set up a default SIP transport.
            var sipTransport = new SIPTransport();

            EnableTraceLogs(sipTransport);

            // Get the IP address the RTP will be sent from. While we can listen on IPAddress.Any | IPv6Any
            // we can't put 0.0.0.0 or [::0] in the SDP or the callee will treat our RTP stream as inactive.
            var lookupResult = SIPDNSManager.ResolveSIPService(callUri, false);

            Log.LogDebug($"DNS lookup result for {callUri}: {lookupResult?.GetSIPEndPoint()}.");
            var dstAddress        = lookupResult.GetSIPEndPoint().Address;
            var localOfferAddress = NetServices.GetLocalAddressForRemote(dstAddress);

            // Initialise an RTP session to receive the RTP packets from the remote SIP server.
            var audioOptions = new AudioOptions
            {
                AudioSource = AudioSourcesEnum.CaptureDevice,
                AudioCodecs = new List <SDPMediaFormatsEnum> {
                    SDPMediaFormatsEnum.PCMA, SDPMediaFormatsEnum.PCMU
                },
                OutputDeviceIndex = AudioOptions.DEFAULT_OUTPUTDEVICE_INDEX
            };
            var rtpSession = new RtpAVSession(audioOptions, null);
            var offerSDP   = rtpSession.CreateOffer(localOfferAddress);

            // Create a client user agent to place a call to a remote SIP server along with event handlers for the different stages of the call.
            var uac = new SIPClientUserAgent(sipTransport);

            uac.CallTrying  += (uac, resp) => Log.LogInformation($"{uac.CallDescriptor.To} Trying: {resp.StatusCode} {resp.ReasonPhrase}.");
            uac.CallRinging += (uac, resp) =>
            {
                Log.LogInformation($"{uac.CallDescriptor.To} Ringing: {resp.StatusCode} {resp.ReasonPhrase}.");
                if (resp.Status == SIPResponseStatusCodesEnum.SessionProgress)
                {
                    rtpSession.Start();
                }
            };
            uac.CallFailed += (uac, err, resp) =>
            {
                Log.LogWarning($"{uac.CallDescriptor.To} Failed: {err}");
                hasCallFailed = true;
            };
            uac.CallAnswered += (iuac, resp) =>
            {
                if (resp.Status == SIPResponseStatusCodesEnum.Ok)
                {
                    Log.LogInformation($"{uac.CallDescriptor.To} Answered: {resp.StatusCode} {resp.ReasonPhrase}.");

                    var result = rtpSession.SetRemoteDescription(SdpType.answer, SDP.ParseSDPDescription(resp.Body));
                    if (result == SetDescriptionResultEnum.OK)
                    {
                        rtpSession.Start();
                    }
                    else
                    {
                        Log.LogWarning($"Failed to set remote description {result}.");
                        uac.Hangup();
                    }
                }
                else
                {
                    Log.LogWarning($"{uac.CallDescriptor.To} Answered: {resp.StatusCode} {resp.ReasonPhrase}.");
                }
            };

            // The only incoming request that needs to be explicitly handled for this example is if the remote end hangs up the call.
            sipTransport.SIPTransportRequestReceived += async(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) =>
            {
                if (sipRequest.Method == SIPMethodsEnum.BYE)
                {
                    SIPResponse okResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
                    await sipTransport.SendResponseAsync(okResponse);

                    if (uac.IsUACAnswered)
                    {
                        Log.LogInformation("Call was hungup by remote server.");
                        isCallHungup = true;
                        exitMre.Set();
                    }
                }
            };

            // Start the thread that places the call.
            SIPCallDescriptor callDescriptor = new SIPCallDescriptor(
                SIPConstants.SIP_DEFAULT_USERNAME,
                null,
                callUri.ToString(),
                SIPConstants.SIP_DEFAULT_FROMURI,
                callUri.CanonicalAddress,
                null, null, null,
                SIPCallDirection.Out,
                SDP.SDP_MIME_CONTENTTYPE,
                offerSDP.ToString(),
                null);

            uac.Call(callDescriptor);
            uac.ServerTransaction.TransactionTraceMessage += (tx, msg) => Log.LogInformation($"UAC tx trace message. {msg}");

            // Ctrl-c will gracefully exit the call at any point.
            Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
            {
                e.Cancel = true;
                exitMre.Set();
            };

            // Wait for a signal saying the call failed, was cancelled with ctrl-c or completed.
            exitMre.WaitOne();

            Log.LogInformation("Exiting...");

            rtpSession.Close(null);

            if (!isCallHungup && uac != null)
            {
                if (uac.IsUACAnswered)
                {
                    Log.LogInformation($"Hanging up call to {uac.CallDescriptor.To}.");
                    uac.Hangup();
                }
                else if (!hasCallFailed)
                {
                    Log.LogInformation($"Cancelling call to {uac.CallDescriptor.To}.");
                    uac.Cancel();
                }

                // Give the BYE or CANCEL request time to be transmitted.
                Log.LogInformation("Waiting 1s for call to clean up...");
                Task.Delay(1000).Wait();
            }

            SIPSorcery.Net.DNSManager.Stop();

            if (sipTransport != null)
            {
                Log.LogInformation("Shutting down SIP transport...");
                sipTransport.Shutdown();
            }
        }
        public void ProcessExtensionAuthentication(PreprocessSipRequestEventArgs e)
        {
            try
            {
                SIPURI fromURI = new SIPURI(e.Request.HeaderFields["From", "f"].FieldValue);

                // Is this coming from an internal extension
                WOSI.CallButler.Data.CallButlerDataset.ExtensionsRow extension = dataProvider.GetExtensionNumber(Properties.Settings.Default.CustomerID, Convert.ToInt32(fromURI.User));

                if (extension != null)
                {
                    if (ProcessRequestAuthorization(e, fromURI, false))
                        e.Handled = false;
                    else
                        e.Handled = true;
                }
            }
            catch
            {
            }
        }
        public async Task HandleInvalidSdpPortOnPlaceCallUnitTest()
        {
            logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name);
            logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name);

            // This transport will act as the call receiver. It allows the test to provide a
            // tailored response to an incoming call.
            SIPTransport calleeTransport = new SIPTransport();

            // This transport will be used by the SIPUserAgent being tested to place the call.
            SIPTransport callerTransport = new SIPTransport();
            RTPSession   rtpSession      = new RTPSession(false, false, false);

            try
            {
                calleeTransport.AddSIPChannel(new SIPUDPChannel(IPAddress.Loopback, 0));
                calleeTransport.SIPTransportRequestReceived += async(lep, rep, req) =>
                {
                    if (req.Method != SIPMethodsEnum.INVITE)
                    {
                        SIPResponse notAllowedResponse = SIPResponse.GetResponse(req, SIPResponseStatusCodesEnum.MethodNotAllowed, null);
                        await calleeTransport.SendResponseAsync(notAllowedResponse);
                    }
                    else
                    {
                        UASInviteTransaction uasTransaction = new UASInviteTransaction(calleeTransport, req, null);
                        var uas = new SIPServerUserAgent(calleeTransport, null, null, null, SIPCallDirection.In, null, null, uasTransaction);
                        uas.Progress(SIPResponseStatusCodesEnum.Trying, null, null, null, null);
                        uas.Progress(SIPResponseStatusCodesEnum.Ringing, null, null, null, null);

                        var answerSdp = @"
v=0
o=- 1838015445 0 IN IP4 127.0.0.1
s=-
c=IN IP4 127.0.0.1
t=0 0
m=audio 79762 RTP/AVP 0
a=rtpmap:0 PCMU/8000
a=sendrecv";
                        uas.Answer(SDP.SDP_MIME_CONTENTTYPE, answerSdp, null, SIPDialogueTransferModesEnum.NotAllowed);
                    }
                };

                SIPUserAgent userAgent = new SIPUserAgent(callerTransport, null);

                MediaStreamTrack audioTrack = new MediaStreamTrack(SDPMediaTypesEnum.audio, false, new List <SDPAudioVideoMediaFormat> {
                    new SDPAudioVideoMediaFormat(SDPWellKnownMediaFormatsEnum.PCMU)
                });
                rtpSession.addTrack(audioTrack);

                SIPURI dstUri = new SIPURI(SIPSchemesEnum.sip, calleeTransport.GetSIPChannels().First().ListeningSIPEndPoint);
                var    result = await userAgent.Call(dstUri.ToString(), null, null, rtpSession);

                Assert.True(result);
            }
            finally
            {
                rtpSession?.Close("normal");
                callerTransport?.Shutdown();
                calleeTransport?.Shutdown();
            }
        }
        private bool ProcessRequestAuthorization(PreprocessSipRequestEventArgs e, SIPURI fromURI, bool requireRegistration)
        {
            try
            {
                switch (e.Request.SIPMethodType)
                {
                    case SIPMethodType.INVITE:
                    case SIPMethodType.REGISTER:

                        //if (Properties.Settings.Default.SIPRegistrarDomain == null || Properties.Settings.Default.SIPRegistrarDomain.Length == 0 || fromURI.Host == ipClient.LocalIPAddress /*|| fromURI.Host == ipClient.Sip*/ || string.Compare(fromURI.Host, Properties.Settings.Default.SIPRegistrarDomain, true) == 0)
                        //{
                            int extensionNumber = Convert.ToInt32(fromURI.User);

                            // Check to see if this is a valid extension
                            WOSI.CallButler.Data.CallButlerDataset.ExtensionsRow extension = dataProvider.GetExtensionNumber(Properties.Settings.Default.CustomerID, extensionNumber);

                            if (extension == null)
                            {
                                ipClient.SendSipResponse(e.Request.CreateResponse(404, "Not Found"));
                                return false;
                            }

                            // Get our PBX password from our database
                            string pbxPassword = "";

                            if (extension.PBXPassword.Length > 0)
                                pbxPassword = WOSI.Utilities.CryptoUtils.Decrypt(extension.PBXPassword, WOSI.CallButler.Data.Constants.EncryptionPassword);

                            if (requireRegistration && !PresenceInfoExists(extensionNumber, e.Request.SentFrom, e.Request.SentFromPort, true))
                            {
                                // If we require registration and the SIP client isn't registered, return a 404 not found
                                ipClient.SendSipResponse(e.Request.CreateResponse(404, "Not Found"));

                                return false;
                            }
                            else if (IsRequestAuthorized(e.Request, extensionNumber.ToString(), pbxPassword))
                            {
                                return true;
                            }
                            else
                            {
                                string realmDomain = Properties.Settings.Default.SIPRegistrarDomain;

                                if (realmDomain == null || realmDomain.Length == 0)
                                    realmDomain = ipClient.LocalIPAddress;

                                // Tell the client that we need authorization
                                string authString = string.Format("Digest realm=\"{0}\", domain=\"sip:{1}\", nonce=\"{2}\", algorithm=MD5", realmDomain, realmDomain, Guid.NewGuid().ToString());

                                SipResponse response = e.Request.CreateResponse(401, "Unauthorized");
                                response.HeaderFields.InsertAfter("CSeq", "WWW-Authenticate", authString);
                                ipClient.SendSipResponse(response);

                                return false;
                            }
                        /*}
                        else
                        {
                            ipClient.SendSipResponse(e.Request.CreateResponse(404, "Not Found"));
                            return false;
                        }*/

                        break;

                    default:
                        return true;
                }
            }
            catch
            {
            }

            return false;
        }
Exemple #39
0
        /// <summary>
        /// Initiates a SUBSCRIBE request to a notification server.
        /// </summary>
        /// <param name="subscribeToURI">The SIP user that dialog notifications are being subscribed to.</param>
        public void Subscribe(SIPURI subscribeURI, int expiry, SIPEventPackage sipEventPackage, string subscribeCallID, SIPURI contactURI)
        {
            try
            {
                if (m_attempts >= MAX_SUBSCRIBE_ATTEMPTS)
                {
                    Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.NotifierClient, SIPMonitorEventTypesEnum.SubscribeFailed, "Susbcription to " + subscribeURI.ToString() + " reached the maximum number of allowed attempts without a failure condition.", null));
                    m_subscribed = false;
                    SubscriptionFailed(subscribeURI, SIPResponseStatusCodesEnum.InternalServerError, "Subscription reached the maximum number of allowed attempts.");
                    m_waitForSubscribeResponse.Set();
                }
                else
                {
                    m_attempts++;
                    m_localCSeq++;

                    SIPRequest subscribeRequest = m_sipTransport.GetRequest(
                        SIPMethodsEnum.SUBSCRIBE,
                        m_resourceURI,
                        new SIPToHeader(null, subscribeURI, m_subscriptionToTag),
                        null);


                    if (contactURI != null)
                    {
                        subscribeRequest.Header.Contact = new List <SIPContactHeader>()
                        {
                            new SIPContactHeader(null, contactURI)
                        };
                    }

                    subscribeRequest.Header.From    = new SIPFromHeader(null, new SIPURI(m_authUsername, m_authDomain, null, SIPSchemesEnum.sip, SIPProtocolsEnum.udp), m_subscriptionFromTag);
                    subscribeRequest.Header.CSeq    = m_localCSeq;
                    subscribeRequest.Header.Expires = expiry;
                    subscribeRequest.Header.Event   = sipEventPackage.ToString();
                    subscribeRequest.Header.CallId  = subscribeCallID;

                    if (!m_filter.IsNullOrBlank())
                    {
                        subscribeRequest.Body = m_filter;
                        subscribeRequest.Header.ContentLength = m_filter.Length;
                        subscribeRequest.Header.ContentType   = m_filterTextType;
                    }

                    SIPEndPoint dstEndPoint = m_outboundProxy;
                    if (dstEndPoint == null)
                    {
                        SIPDNSLookupResult lookupResult = m_sipTransport.GetURIEndPoint(m_resourceURI, false);
                        if (lookupResult.LookupError != null)
                        {
                            Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.NotifierClient, SIPMonitorEventTypesEnum.SubscribeFailed, "Could not resolve " + m_resourceURI.Host + ", " + lookupResult.LookupError, null));
                        }
                        else
                        {
                            dstEndPoint = lookupResult.GetSIPEndPoint();
                        }
                    }

                    SIPNonInviteTransaction subscribeTransaction = m_sipTransport.CreateNonInviteTransaction(subscribeRequest, dstEndPoint, null, m_outboundProxy);
                    subscribeTransaction.NonInviteTransactionFinalResponseReceived += SubscribeTransactionFinalResponseReceived;
                    subscribeTransaction.NonInviteTransactionTimedOut += SubsribeTransactionTimedOut;

                    m_sipTransport.SendSIPReliable(subscribeTransaction);

                    LastSubscribeAttempt = DateTime.Now;
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception SIPNotifierClient Subscribe. " + excp.Message);
                SubscriptionFailed(m_resourceURI, SIPResponseStatusCodesEnum.InternalServerError, "Exception Subscribing. " + excp.Message);
                m_waitForSubscribeResponse.Set();
            }
        }
        public void UDPProtocolToStringTest()
        {
            Console.WriteLine("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name);

            SIPURI sipURI = new SIPURI(SIPSchemesEnum.sip, SIPEndPoint.ParseSIPEndPoint("127.0.0.1"));
            Console.WriteLine(sipURI.ToString());
            Assert.IsTrue(sipURI.ToString() == "sip:127.0.0.1:5060", "The SIP URI was not ToString'ed correctly.");
            Console.WriteLine("-----------------------------------------");
        }
Exemple #41
0
        static void Main(string[] args)
        {
            Console.WriteLine("SIPSorcery client user agent example.");
            Console.WriteLine("Press ctrl-c to exit.");

            // Plumbing code to facilitate a graceful exit.
            ManualResetEvent exitMre       = new ManualResetEvent(false);
            bool             preferIPv6    = false;
            bool             isCallHungup  = false;
            bool             hasCallFailed = false;

            Log = AddConsoleLogger(LogEventLevel.Verbose);

            SIPURI callUri = SIPURI.ParseSIPURI(DEFAULT_DESTINATION_SIP_URI);

            if (args?.Length > 0)
            {
                if (!SIPURI.TryParse(args[0], out callUri))
                {
                    Log.LogWarning($"Command line argument could not be parsed as a SIP URI {args[0]}");
                }
            }
            if (args?.Length > 1 && args[1] == "ipv6")
            {
                preferIPv6 = true;
            }

            if (preferIPv6)
            {
                Log.LogInformation($"Call destination {callUri}, preferencing IPv6.");
            }
            else
            {
                Log.LogInformation($"Call destination {callUri}.");
            }

            // Set up a default SIP transport.
            var sipTransport = new SIPTransport();

            sipTransport.PreferIPv6NameResolution = preferIPv6;
            sipTransport.EnableTraceLogs();

            var audioSession = new WindowsAudioEndPoint(new AudioEncoder());

            audioSession.RestrictFormats(x => x.Codec == AudioCodecsEnum.PCMA || x.Codec == AudioCodecsEnum.PCMU);
            //audioSession.RestrictFormats(x => x.Codec == AudioCodecsEnum.G722);
            var rtpSession = new VoIPMediaSession(audioSession.ToMediaEndPoints());

            var offerSDP = rtpSession.CreateOffer(preferIPv6 ? IPAddress.IPv6Any : IPAddress.Any);

            // Create a client user agent to place a call to a remote SIP server along with event handlers for the different stages of the call.
            var uac = new SIPClientUserAgent(sipTransport);

            uac.CallTrying  += (uac, resp) => Log.LogInformation($"{uac.CallDescriptor.To} Trying: {resp.StatusCode} {resp.ReasonPhrase}.");
            uac.CallRinging += async(uac, resp) =>
            {
                Log.LogInformation($"{uac.CallDescriptor.To} Ringing: {resp.StatusCode} {resp.ReasonPhrase}.");
                if (resp.Status == SIPResponseStatusCodesEnum.SessionProgress)
                {
                    if (resp.Body != null)
                    {
                        var result = rtpSession.SetRemoteDescription(SdpType.answer, SDP.ParseSDPDescription(resp.Body));
                        if (result == SetDescriptionResultEnum.OK)
                        {
                            await rtpSession.Start();

                            Log.LogInformation($"Remote SDP set from in progress response. RTP session started.");
                        }
                    }
                }
            };
            uac.CallFailed += (uac, err, resp) =>
            {
                Log.LogWarning($"Call attempt to {uac.CallDescriptor.To} Failed: {err}");
                hasCallFailed = true;
            };
            uac.CallAnswered += async(iuac, resp) =>
            {
                if (resp.Status == SIPResponseStatusCodesEnum.Ok)
                {
                    Log.LogInformation($"{uac.CallDescriptor.To} Answered: {resp.StatusCode} {resp.ReasonPhrase}.");

                    if (resp.Body != null)
                    {
                        var result = rtpSession.SetRemoteDescription(SdpType.answer, SDP.ParseSDPDescription(resp.Body));
                        if (result == SetDescriptionResultEnum.OK)
                        {
                            await rtpSession.Start();
                        }
                        else
                        {
                            Log.LogWarning($"Failed to set remote description {result}.");
                            uac.Hangup();
                        }
                    }
                    else if (!rtpSession.IsStarted)
                    {
                        Log.LogWarning($"Failed to set get remote description in session progress or final response.");
                        uac.Hangup();
                    }
                }
                else
                {
                    Log.LogWarning($"{uac.CallDescriptor.To} Answered: {resp.StatusCode} {resp.ReasonPhrase}.");
                }
            };

            // The only incoming request that needs to be explicitly handled for this example is if the remote end hangs up the call.
            sipTransport.SIPTransportRequestReceived += async(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) =>
            {
                if (sipRequest.Method == SIPMethodsEnum.BYE)
                {
                    SIPResponse okResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
                    await sipTransport.SendResponseAsync(okResponse);

                    if (uac.IsUACAnswered)
                    {
                        Log.LogInformation("Call was hungup by remote server.");
                        isCallHungup = true;
                        exitMre.Set();
                    }
                }
            };

            // Start the thread that places the call.
            SIPCallDescriptor callDescriptor = new SIPCallDescriptor(
                SIPConstants.SIP_DEFAULT_USERNAME,
                null,
                callUri.ToString(),
                SIPConstants.SIP_DEFAULT_FROMURI,
                callUri.CanonicalAddress,
                null, null, null,
                SIPCallDirection.Out,
                SDP.SDP_MIME_CONTENTTYPE,
                offerSDP.ToString(),
                null);

            uac.Call(callDescriptor, null);

            // Ctrl-c will gracefully exit the call at any point.
            Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
            {
                e.Cancel = true;
                exitMre.Set();
            };

            // Wait for a signal saying the call failed, was cancelled with ctrl-c or completed.
            exitMre.WaitOne();

            Log.LogInformation("Exiting...");

            rtpSession.Close(null);

            if (!isCallHungup && uac != null)
            {
                if (uac.IsUACAnswered)
                {
                    Log.LogInformation($"Hanging up call to {uac.CallDescriptor.To}.");
                    uac.Hangup();
                }
                else if (!hasCallFailed)
                {
                    Log.LogInformation($"Cancelling call to {uac.CallDescriptor.To}.");
                    uac.Cancel();
                }

                // Give the BYE or CANCEL request time to be transmitted.
                Log.LogInformation("Waiting 1s for call to clean up...");
                Task.Delay(1000).Wait();
            }

            if (sipTransport != null)
            {
                Log.LogInformation("Shutting down SIP transport...");
                sipTransport.Shutdown();
            }
        }
        public void Load(DataRow bindingRow)
        {
            try {
                m_id = (bindingRow.Table.Columns.Contains("id") && bindingRow["id"] != DBNull.Value && bindingRow["id"] != null) ? new Guid(bindingRow["id"] as string) : Guid.NewGuid();
                m_providerId = new Guid(bindingRow["providerid"] as string);
                ProviderName = bindingRow["providername"] as string;
                m_owner = bindingRow["owner"] as string;
                AdminMemberId = bindingRow["adminmemberid"] as string;
                m_isRegistered = (bindingRow.Table.Columns.Contains("isregistered") && bindingRow["isregistered"] != DBNull.Value && bindingRow["isregistered"] != null) ? Convert.ToBoolean(bindingRow["isregistered"]) : false;

                if (bindingRow.Table.Columns.Contains("bindinguri") && bindingRow["bindinguri"] != DBNull.Value && bindingRow["bindinguri"] != null && !bindingRow["bindinguri"].ToString().IsNullOrBlank()) {
                    m_bindingURI = SIPURI.ParseSIPURI(bindingRow["bindinguri"] as string);
                }
                else {
                    logger.Warn("Could not load BindingURI for SIPProviderBinding with id=" + m_id + ".");
                }

                if (bindingRow.Table.Columns.Contains("bindingexpiry") && bindingRow["bindingexpiry"] != DBNull.Value && bindingRow["bindingexpiry"] != null) {
                    m_bindingExpiry = Convert.ToInt32(bindingRow["bindingexpiry"]);
                }

                if (bindingRow.Table.Columns.Contains("cseq") && bindingRow["cseq"] != DBNull.Value && bindingRow["cseq"] != null && bindingRow["cseq"].ToString().Length > 0) {
                    CSeq = Convert.ToInt32(bindingRow["cseq"]);
                }

                if (bindingRow.Table.Columns.Contains("lastregistertime") && bindingRow["lastregistertime"] != DBNull.Value && bindingRow["lastregistertime"] != null && !(bindingRow["lastregistertime"] as string).IsNullOrBlank()) {
                    LastRegisterTime = DateTimeOffset.Parse(bindingRow["lastregistertime"] as string);
                }

                if (bindingRow.Table.Columns.Contains("lastregisterattempt") && bindingRow["lastregisterattempt"] != DBNull.Value && bindingRow["lastregisterattempt"] != null && !(bindingRow["lastregisterattempt"] as string).IsNullOrBlank()) {
                    LastRegisterAttempt = DateTimeOffset.Parse(bindingRow["lastregisterattempt"] as string);
                }

                if (bindingRow.Table.Columns.Contains("nextregistrationtime") && bindingRow["nextregistrationtime"] != DBNull.Value && bindingRow["nextregistrationtime"] != null && !(bindingRow["nextregistrationtime"] as string).IsNullOrBlank()) {
                    NextRegistrationTime = DateTimeOffset.Parse(bindingRow["nextregistrationtime"] as string);
                }

                if (bindingRow.Table.Columns.Contains("registrarsipsocket") && bindingRow["registrarsipsocket"] != DBNull.Value && bindingRow["registrarsipsocket"] != null && bindingRow["registrarsipsocket"].ToString().Length > 0) {
                    RegistrarSIPEndPoint = SIPEndPoint.ParseSIPEndPoint(bindingRow["registrarsipsocket"] as string);
                }

                m_registrationFailureMessage = bindingRow["registrationfailuremessage"] as string;

                //logger.Debug(" loaded SIPProviderBinding for " + Owner + " and " + ProviderName + " and binding " + BindingURI.ToString() + ".");
            }
            catch (Exception excp) {
                logger.Error("Exception SIPProviderBinding Load. " + excp.Message);
                throw excp;
            }
        }
 public void Redirect(SIPResponseStatusCodesEnum redirectCode, SIPURI redirectURI)
 {
     UASStateChanged.Invoke(this, SIPResponseStatusCodesEnum.ExtensionRequired, "ExtensionRequired");
     throw new NotImplementedException();
 }
 public void Redirect(SIPResponseStatusCodesEnum redirectCode, SIPURI redirectURI)
 {
     logger.Debug("SIPB2BUserAgent Redirect.");
     //m_uas.Redirect(redirectCode, redirectURI);
 }
        public static SIPDNSLookupResult DNSARecordLookup(string host, int port, bool async, SIPURI uri)
        {
            SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS A record lookup requested for " + host + ".", null));
            SIPDNSLookupResult result = new SIPDNSLookupResult(uri);

            //DNSResponse aRecordResponse = DNSManager.Lookup(host, DNSQType.A, DNS_A_RECORD_LOOKUP_TIMEOUT, null, true, async);
            //if (aRecordResponse == null && async)
            //{
            //    result.Pending = true;
            //}
            //else if (aRecordResponse.Timedout)
            //{
            //    result.ATimedoutAt = DateTime.Now;
            //}
            //else if (aRecordResponse.Error != null)
            //{
            //    result.LookupError = aRecordResponse.Error;
            //}
            //else if (aRecordResponse.RecordsA == null || aRecordResponse.RecordsA.Length == 0)
            //{
            //    SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS no A records found for " + host + ".", null));
            //    result.LookupError = "No A records found for " + host + ".";
            //}
            //else
            //{
            //    SIPURI sipURI = result.URI;
            //    foreach (RecordA aRecord in aRecordResponse.RecordsA)
            //    {
            //        SIPDNSLookupEndPoint sipLookupEndPoint = new SIPDNSLookupEndPoint(new SIPEndPoint(sipURI.Protocol, new IPEndPoint(aRecord.Address, port)), aRecord.RR.TTL);
            //        result.AddLookupResult(sipLookupEndPoint);
            //        SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS A record found for " + host + ", result " + sipLookupEndPoint.LookupEndPoint.ToString() + ".", null));
            //    }
            //}

            return(result);
        }
 public static SIPDNSLookupResult DNSARecordLookup(SIPDNSServiceResult nextSRVRecord, string host, int port, bool async, SIPURI lookupURI)
 {
     if (nextSRVRecord != null && nextSRVRecord.Data != null)
     {
         return(DNSARecordLookup(nextSRVRecord.Data, port, async, lookupURI));
         //nextSRVRecord.ResolvedAt = DateTime.Now;
     }
     else
     {
         return(DNSARecordLookup(host, port, async, lookupURI));
     }
 }
        public static SIPDNSLookupResult ResolveSIPService(SIPURI sipURI, bool async)
        {
            try
            {
                if (sipURI == null)
                {
                    throw new ArgumentNullException("sipURI", "Cannot resolve SIP service on a null URI.");
                }

                string host         = sipURI.Host;
                int    port         = (sipURI.Scheme == SIPSchemesEnum.sip) ? m_defaultSIPPort : m_defaultSIPSPort;
                bool   explicitPort = false;

                if (sipURI.Host.IndexOf(':') != -1)
                {
                    host         = sipURI.Host.Split(':')[0];
                    _            = int.TryParse(sipURI.Host.Split(':')[1], out port);
                    explicitPort = true;
                }

                if (Regex.Match(host, @"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$").Success)
                {
                    // Target is an IP address, no DNS lookup required.
                    IPAddress hostIP            = IPAddress.Parse(host);
                    var       sipLookupEndPoint = new SIPDNSLookupEndPoint(new SIPEndPoint(sipURI.Protocol, new IPEndPoint(hostIP, port)), 0);
                    var       result            = new SIPDNSLookupResult(sipURI);
                    result.AddLookupResult(sipLookupEndPoint);
                    return(result);
                }
                else if (explicitPort)
                {
                    // Target is a hostname with an explicit port, DNS lookup for A or AAAA record.
                    return(DNSARecordLookup(host, port, async, sipURI));
                }
                else
                {
                    // Target is a hostname with no explicit port, use the whole NAPTR->SRV->A lookup procedure.
                    SIPDNSLookupResult sipLookupResult = new SIPDNSLookupResult(sipURI);

                    // Do without the NAPTR lookup for the time being. Very few organisations appear to use them and it can cost up to 2.5s to get a failed resolution.

                    /*SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS full lookup requested for " + sipURI.ToString() + ".", null));
                     * DNSNAPTRRecordLookup(host, async, ref sipLookupResult);
                     * if (sipLookupResult.Pending)
                     * {
                     *  if (!m_inProgressSIPServiceLookups.Contains(sipURI.ToString()))
                     *  {
                     *      m_inProgressSIPServiceLookups.Add(sipURI.ToString());
                     *      ThreadPool.QueueUserWorkItem(delegate { ResolveSIPService(sipURI, false); });
                     *  }
                     *  return sipLookupResult;
                     * }*/

                    DNSSRVRecordLookup(sipURI.Scheme, sipURI.Protocol, host, async, ref sipLookupResult);
                    if (sipLookupResult.Pending)
                    {
                        //logger.Debug("SIPDNSManager SRV lookup for " + host + " is pending.");
                        return(sipLookupResult);
                    }
                    else
                    {
                        //logger.Debug("SIPDNSManager SRV lookup for " + host + " is final.");
                        SIPDNSServiceResult nextSRVRecord = sipLookupResult.GetNextUnusedSRV();
                        int lookupPort = (nextSRVRecord != null) ? nextSRVRecord.Port : port;
                        return(DNSARecordLookup(nextSRVRecord, host, lookupPort, async, sipLookupResult.URI));
                    }
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception SIPDNSManager ResolveSIPService (" + sipURI.ToString() + "). " + excp.Message);
                m_inProgressSIPServiceLookups.Remove(sipURI.ToString());
                return(new SIPDNSLookupResult(sipURI, excp.Message));
            }
        }
        public static SIPDNSLookupResult DNSARecordLookup(string host, int port, bool async, SIPURI uri)
        {
            SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS A record lookup requested for " + host + ".", null));
            SIPDNSLookupResult result = new SIPDNSLookupResult(uri);

            DNSResponse aRecordResponse = DNSManager.Lookup(host, DNSQType.A, DNS_A_RECORD_LOOKUP_TIMEOUT, null, true, async);
            if (aRecordResponse == null && async)
            {
                result.Pending = true;
            }
            else if (aRecordResponse.Timedout)
            {
                result.ATimedoutAt = DateTime.Now;
            }
            else if (aRecordResponse.Error != null)
            {
                result.LookupError = aRecordResponse.Error;
            }
            else if (aRecordResponse.RecordsA == null || aRecordResponse.RecordsA.Length == 0)
            {
                SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS no A records found for " + host + ".", null));
                result.LookupError = "No A records found for " + host + ".";
            }
            else
            {
                SIPURI sipURI = result.URI;
                foreach (RecordA aRecord in aRecordResponse.RecordsA)
                {
                    SIPDNSLookupEndPoint sipLookupEndPoint = new SIPDNSLookupEndPoint(new SIPEndPoint(sipURI.Protocol, new IPEndPoint(aRecord.Address, port)), aRecord.RR.TTL);
                    result.AddLookupResult(sipLookupEndPoint);
                    SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS A record found for " + host + ", result " + sipLookupEndPoint.LookupEndPoint.ToString() + ".", null));
                }
            }

            return result;
        }
Exemple #49
0
        // TODO: Remove this nasty code duplication with ResolveSIPService!
        public static async Task <SIPDNSLookupResult> ResolveAsync(SIPURI sipURI, bool?preferIPv6 = null)
        {
            try
            {
                if (sipURI == null)
                {
                    throw new ArgumentNullException("sipURI", "Cannot resolve SIP service on a null URI.");
                }

                if (IPSocket.TryParseIPEndPoint(sipURI.MAddrOrHost, out var ipEndPoint))
                {
                    // Target is an IP address, no DNS lookup required.
                    SIPDNSLookupEndPoint sipLookupEndPoint = new SIPDNSLookupEndPoint(new SIPEndPoint(sipURI.Protocol, ipEndPoint), 0);
                    SIPDNSLookupResult   result            = new SIPDNSLookupResult(sipURI);
                    result.AddLookupResult(sipLookupEndPoint);
                    return(result);
                }
                else
                {
                    string host = sipURI.MAddrOrHostAddress;
                    //int port = IPSocket.ParsePortFromSocket(host);
                    int port = sipURI.Protocol != SIPProtocolsEnum.tls ? m_defaultSIPPort : m_defaultSIPSPort;
                    if (preferIPv6 == null)
                    {
                        preferIPv6 = SIPDNSManager.PreferIPv6NameResolution;
                    }
                    bool explicitPort = false;

                    try
                    {
                        //Parse returns true if sipURI.Host can be parsed as an ipaddress
                        bool parseresult = SIPSorcery.Sys.IPSocket.Parse(sipURI.MAddrOrHost, out host, out port);
                        explicitPort = port >= 0;
                        if (!explicitPort)
                        {
                            //port = (sipURI.Scheme == SIPSchemesEnum.sip) ? m_defaultSIPPort : m_defaultSIPSPort;
                            port = sipURI.Protocol != SIPProtocolsEnum.tls ? m_defaultSIPPort : m_defaultSIPSPort;
                        }
                        if (parseresult == true)
                        {
                            IPAddress            hostIP            = IPAddress.Parse(host);
                            SIPDNSLookupEndPoint sipLookupEndPoint = new SIPDNSLookupEndPoint(new SIPEndPoint(sipURI.Protocol, new IPEndPoint(hostIP, port)), 0);
                            SIPDNSLookupResult   result            = new SIPDNSLookupResult(sipURI);
                            result.AddLookupResult(sipLookupEndPoint);
                            return(result);
                        }
                    }
                    catch (Exception ex)
                    {
                        SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "Exception SIPDNSManager ResolveSIPService (" + sipURI.ToString() + "). " + ex, null));

                        //rj2: if there is a parsing exception, then fallback to original sipsorcery parsing mechanism
                        port         = IPSocket.ParsePortFromSocket(sipURI.Host);
                        explicitPort = port > 0;

                        //if(Regex.Match(host, @"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$").Success)
                        if (SIPSorcery.Sys.IPSocket.IsIPAddress(host))
                        {
                            // Target is an IP address, no DNS lookup required.
                            IPAddress            hostIP            = IPAddress.Parse(host);
                            SIPDNSLookupEndPoint sipLookupEndPoint = new SIPDNSLookupEndPoint(new SIPEndPoint(sipURI.Protocol, new IPEndPoint(hostIP, port)), 0);
                            SIPDNSLookupResult   result            = new SIPDNSLookupResult(sipURI);
                            result.AddLookupResult(sipLookupEndPoint);
                            return(result);
                        }
                    }

                    if (!explicitPort)
                    {
                        //port = (sipURI.Scheme == SIPSchemesEnum.sip) ? m_defaultSIPPort : m_defaultSIPSPort;
                        port = sipURI.Protocol != SIPProtocolsEnum.tls ? m_defaultSIPPort : m_defaultSIPSPort;
                    }

                    if (host.Contains(".") == false)
                    {
                        string hostOnly = IPSocket.ParseHostFromSocket(host);

                        // If host is not fully qualified then assume there's no point using NAPTR or SRV record look ups and go straight to A's.
                        if (hostOnly.ToLower() == System.Net.Dns.GetHostName()?.ToLower())
                        {
                            // The lookup is for the current machine.
                            var addressList = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList;

                            if (addressList?.Length == 0)
                            {
                                return(new SIPDNSLookupResult(sipURI, $"Failed to resolve local machine hostname."));
                            }
                            else
                            {
                                // Preference for IPv4 IP address for local host name lookup.
                                IPAddress   firstAddress = addressList.Where(x => x.AddressFamily == (preferIPv6 == true ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork)).FirstOrDefault() ?? addressList.FirstOrDefault();
                                SIPEndPoint resultEp     = new SIPEndPoint(sipURI.Protocol, new IPEndPoint(firstAddress, port));
                                return(new SIPDNSLookupResult(sipURI, resultEp));
                            }
                        }
                        else
                        {
                            return(await Task.Run(() => DNSNameRecordLookup(hostOnly, port, false, sipURI, null, preferIPv6)));
                        }
                    }
                    else if (explicitPort)
                    {
                        // If target is a hostname with an explicit port then SIP lookup rules state to use DNS lookup for A or AAAA record.
                        host = host.Substring(0, host.LastIndexOf(':'));
                        return(await Task.Run(() => DNSNameRecordLookup(host, port, false, sipURI, null, preferIPv6)));
                    }
                    else
                    {
                        // Target is a hostname with no explicit port, use the whole NAPTR->SRV->A lookup procedure.
                        SIPDNSLookupResult sipLookupResult = new SIPDNSLookupResult(sipURI);

                        // Do without the NAPTR lookup for the time being. Very few organisations appear to use them and it can cost up to 2.5s to get a failed resolution.
                        //rj2: uncomment this section for telekom 1TR118 lookup
                        SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS full lookup requested for " + sipURI.ToString() + ".", null));
                        DNSNAPTRRecordLookup(host, false, ref sipLookupResult);
                        if (sipLookupResult.Pending)
                        {
                            if (!m_inProgressSIPServiceLookups.Contains(sipURI.ToString()))
                            {
                                m_inProgressSIPServiceLookups.Add(sipURI.ToString());
                                //ThreadPool.QueueUserWorkItem(delegate { ResolveSIPService(sipURI, false); });
                                System.Threading.ThreadPool.QueueUserWorkItem((obj) => ResolveSIPService(sipURI, false, preferIPv6));
                            }
                            return(sipLookupResult);
                        }

                        return(await Task.Run(() =>
                        {
                            DNSSRVRecordLookup(sipURI.Scheme, sipURI.Protocol, host, false, ref sipLookupResult);
                            if (sipLookupResult.Pending)
                            {
                                //logger.LogDebug("SIPDNSManager SRV lookup for " + host + " is pending.");
                                return sipLookupResult;
                            }
                            else
                            {
                                //logger.LogDebug("SIPDNSManager SRV lookup for " + host + " is final.");

                                // Add some custom logic to cope with sips SRV records using _sips._tcp (e.g. free.call.ciscospark.com).
                                // By default only _sips._tls SRV records are checked for. THis block adds an additional check for _sips._tcp SRV records.
                                //if ((sipLookupResult.SIPSRVResults == null || sipLookupResult.SIPSRVResults.Count == 0) && sipURI.Scheme == SIPSchemesEnum.sips)
                                //{
                                //    DNSSRVRecordLookup(sipURI.Scheme, SIPProtocolsEnum.tcp, host, async, ref sipLookupResult);
                                //    SIPDNSServiceResult nextSRVRecord = sipLookupResult.GetNextUnusedSRV();
                                //    int lookupPort = (nextSRVRecord != null) ? nextSRVRecord.Port : port;
                                //    return DNSARecordLookup(nextSRVRecord, host, lookupPort, async, sipLookupResult.URI);
                                //}
                                //else
                                //{
                                //   SIPDNSServiceResult nextSRVRecord = sipLookupResult.GetNextUnusedSRV();
                                //   int lookupPort = (nextSRVRecord != null) ? nextSRVRecord.Port : port;
                                //   return DNSARecordLookup(nextSRVRecord, host, lookupPort, false, sipLookupResult.URI);
                                //}

                                // The SRV record can indicate the SIP server is using a non-standard port.
                                SIPDNSServiceResult nextSRVRecord = sipLookupResult.GetNextUnusedSRV();
                                int lookupPort = (nextSRVRecord != null) ? nextSRVRecord.Port : port;

                                return DNSNameRecordLookup(host, lookupPort, false, sipLookupResult.URI, ref sipLookupResult, preferIPv6);
                            }
                        }));
                    }
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception SIPDNSManager ResolveSIPService (" + sipURI.ToString() + "). " + excp.Message);
                m_inProgressSIPServiceLookups.Remove(sipURI.ToString());
                return(new SIPDNSLookupResult(sipURI, excp.Message));
            }
        }
        public static SIPDNSLookupResult ResolveSIPService(SIPURI sipURI, bool async)
        {
            try
            {
                if (sipURI == null)
                {
                    throw new ArgumentNullException("sipURI", "Cannot resolve SIP service on a null URI.");
                }

                string host = sipURI.Host;
                int port = (sipURI.Scheme == SIPSchemesEnum.sip) ? m_defaultSIPPort : m_defaultSIPSPort;
                bool explicitPort = false;

                if (sipURI.Host.IndexOf(':') != -1)
                {
                    host = sipURI.Host.Split(':')[0];
                    Int32.TryParse(sipURI.Host.Split(':')[1], out port);
                    explicitPort = true;
                }

                if (Regex.Match(host, @"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$").Success)
                {
                    // Target is an IP address, no DNS lookup required.
                    IPAddress hostIP = IPAddress.Parse(host);
                    SIPDNSLookupEndPoint sipLookupEndPoint = new SIPDNSLookupEndPoint(new SIPEndPoint(sipURI.Protocol, new IPEndPoint(hostIP, port)), 0);
                    SIPDNSLookupResult result = new SIPDNSLookupResult(sipURI);
                    result.AddLookupResult(sipLookupEndPoint);
                    return result;
                }
                else if (explicitPort)
                {
                    // Target is a hostname with an explicit port, DNS lookup for A or AAAA record.
                    return DNSARecordLookup(host, port, async, sipURI);
                }
                else
                {
                    // Target is a hostname with no explicit port, use the whole NAPTR->SRV->A lookup procedure.
                    SIPDNSLookupResult sipLookupResult = new SIPDNSLookupResult(sipURI);

                    // Do without the NAPTR lookup for the time being. Very few organisations appear to use them and it can cost up to 2.5s to get a failed resolution.
                    /*SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS full lookup requested for " + sipURI.ToString() + ".", null));
                    DNSNAPTRRecordLookup(host, async, ref sipLookupResult);
                    if (sipLookupResult.Pending)
                    {
                        if (!m_inProgressSIPServiceLookups.Contains(sipURI.ToString()))
                        {
                            m_inProgressSIPServiceLookups.Add(sipURI.ToString());
                            ThreadPool.QueueUserWorkItem(delegate { ResolveSIPService(sipURI, false); });
                        }
                        return sipLookupResult;
                    }*/

                    DNSSRVRecordLookup(sipURI.Scheme, sipURI.Protocol, host, async, ref sipLookupResult);
                    if (sipLookupResult.Pending)
                    {
                        //logger.Debug("SIPDNSManager SRV lookup for " + host + " is pending.");
                        return sipLookupResult;
                    }
                    else
                    {
                        //logger.Debug("SIPDNSManager SRV lookup for " + host + " is final.");
                        SIPDNSServiceResult nextSRVRecord = sipLookupResult.GetNextUnusedSRV();
                        int lookupPort = (nextSRVRecord != null) ? nextSRVRecord.Port : port;
                        return DNSARecordLookup(nextSRVRecord, host, lookupPort, async, sipLookupResult.URI);
                    }
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception SIPDNSManager ResolveSIPService (" + sipURI.ToString() + "). " + excp.Message);
                m_inProgressSIPServiceLookups.Remove(sipURI.ToString());
                return new SIPDNSLookupResult(sipURI, excp.Message);
            }
        }
Exemple #51
0
        public static SIPDNSLookupResult DNSAAAARecordLookup(string host, int port, bool async, SIPURI uri, SIPDNSLookupResult lookupResult = null)
        {
            SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS A record lookup requested for " + host + ".", null));

            SIPDNSLookupResult result = lookupResult ?? new SIPDNSLookupResult(uri);

            result.LookupError = null;

            DNSResponse aaaaRecordResponse = DNSManager.Lookup(host, QType.AAAA, DNS_A_RECORD_LOOKUP_TIMEOUT, null, true, async);

            if (aaaaRecordResponse == null)
            {
                if (async)
                {
                    result.Pending = true;
                }
            }
            else if (aaaaRecordResponse.Timedout)
            {
                result.ATimedoutAt = DateTime.Now;
            }
            else if (!string.IsNullOrWhiteSpace(aaaaRecordResponse.Error))
            {
                result.LookupError = aaaaRecordResponse.Error;
            }
            else if (aaaaRecordResponse.RecordsAAAA == null || aaaaRecordResponse.RecordsAAAA.Length == 0)
            {
                SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS no AAAA records found for " + host + ".", null));
                result.LookupError = "No AAAA records found for " + host + ".";
            }
            else
            {
                SIPURI sipURI = result.URI;
                foreach (RecordAAAA aRecord in aaaaRecordResponse.RecordsAAAA)
                {
                    SIPDNSLookupEndPoint sipLookupEndPoint = new SIPDNSLookupEndPoint(new SIPEndPoint(sipURI.Protocol, new IPEndPoint(aRecord.Address, port)), aRecord.RR.TTL);
                    result.AddLookupResult(sipLookupEndPoint);
                    SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS AAAA record found for " + host + ", result " + sipLookupEndPoint.LookupEndPoint.ToString() + ".", null));
                }
            }

            return(result);
        }
Exemple #52
0
        public void Load(DataRow providerRow)
        {
            try
            {
                m_id = (providerRow.Table.Columns.Contains("id") && providerRow["id"] != DBNull.Value && providerRow["id"] != null) ? new Guid(providerRow["id"] as string) : Guid.NewGuid();
                m_providerType = (ProviderTypes)Enum.Parse(typeof(ProviderTypes), providerRow["providertype"] as string, true);
                m_owner = providerRow["owner"] as string;
                AdminMemberId = (providerRow.Table.Columns.Contains("adminmemberid") && providerRow["adminmemberid"] != null) ? providerRow["adminmemberid"] as string : null;
                m_providerName = providerRow["providername"] as string;
                m_providerUsername = providerRow["providerusername"] as string;
                m_providerPassword = providerRow["providerpassword"] as string;
                m_providerServer = SIPURI.ParseSIPURIRelaxed(providerRow["providerserver"] as string);
                m_providerAuthUsername = (providerRow.Table.Columns.Contains("providerauthusername") && providerRow["providerauthusername"] != null) ? providerRow["providerauthusername"] as string : null;
                m_providerOutboundProxy = (providerRow.Table.Columns.Contains("provideroutboundproxy") && providerRow["provideroutboundproxy"] != null) ? providerRow["provideroutboundproxy"] as string : null;
                m_providerFrom = (providerRow.Table.Columns.Contains("providerfrom") && providerRow["providerfrom"] != null) ? providerRow["providerfrom"] as string : null;
                m_customHeaders = (providerRow.Table.Columns.Contains("customheaders") && providerRow["customheaders"] != null) ? providerRow["customheaders"] as string : null;
                m_registerContact = (providerRow.Table.Columns.Contains("registercontact") && providerRow["registercontact"] != DBNull.Value && providerRow["registercontact"] != null && providerRow["registercontact"].ToString().Length > 0) ? SIPURI.ParseSIPURIRelaxed(providerRow["registercontact"] as string) : null;
                m_registerExpiry = (providerRow.Table.Columns.Contains("registerexpiry") && providerRow["registerexpiry"] != DBNull.Value && providerRow["registerexpiry"] != null) ? Convert.ToInt32(providerRow["registerexpiry"]) : REGISTER_DEFAULT_EXPIRY;
                m_registerServer = (providerRow.Table.Columns.Contains("registerserver") && providerRow["registerserver"] != null) ? SIPURI.ParseSIPURIRelaxed(providerRow["registerserver"] as string) : null;
                m_registerRealm = (providerRow.Table.Columns.Contains("registerrealm") && providerRow["registerrealm"] != null) ? providerRow["registerrealm"] as string : null;
                m_registerEnabled = (providerRow.Table.Columns.Contains("registerenabled") && providerRow["registerenabled"] != DBNull.Value && providerRow["registerenabled"] != null) ? Convert.ToBoolean(providerRow["registerenabled"]) : false;
                m_registerAdminEnabled = (providerRow.Table.Columns.Contains("registeradminenabled") && providerRow["registeradminenabled"] != DBNull.Value && providerRow["registeradminenabled"] != null) ? Convert.ToBoolean(providerRow["registeradminenabled"]) : true;
                m_registerDisabledReason = (providerRow.Table.Columns.Contains("registerdisabledreason") && providerRow["registerdisabledreason"] != DBNull.Value && providerRow["registerdisabledreason"] != null) ? providerRow["registerdisabledreason"] as string : null;
                m_gvCallbackNumber = (providerRow.Table.Columns.Contains("gvcallbacknumber") && providerRow["gvcallbacknumber"] != null) ? providerRow["gvcallbacknumber"] as string : null;
                m_gvCallbackPattern = (providerRow.Table.Columns.Contains("gvcallbackpattern") && providerRow["gvcallbackpattern"] != null) ? providerRow["gvcallbackpattern"] as string : null;
                m_gvCallbackType = (providerRow.Table.Columns.Contains("gvcallbacktype") && providerRow["gvcallbacktype"] != DBNull.Value && providerRow["gvcallbacktype"] != null && (providerRow["gvcallbacktype"] as string).NotNullOrBlank()) ? (GoogleVoiceCallbackTypes)Enum.Parse(typeof(GoogleVoiceCallbackTypes), providerRow["gvcallbacktype"] as string, true) : (GoogleVoiceCallbackTypes?)null;
                LastUpdate = (providerRow.Table.Columns.Contains("lastupdate") && providerRow["lastupdate"] != DBNull.Value && providerRow["lastupdate"] != null) ? DateTimeOffset.Parse(providerRow["lastupdate"] as string) : DateTimeOffset.UtcNow;
                Inserted = (providerRow.Table.Columns.Contains("inserted") && providerRow["inserted"] != DBNull.Value && providerRow["inserted"] != null) ? DateTimeOffset.Parse(providerRow["inserted"] as string) : DateTimeOffset.UtcNow;
                m_isReadOnly = (providerRow.Table.Columns.Contains("isreadonly") && providerRow["isreadonly"] != DBNull.Value && providerRow["isreadonly"] != null) ? Convert.ToBoolean(providerRow["isreadonly"]) : false;
                m_sendMWISubscribe = (providerRow.Table.Columns.Contains("sendmwisubscribe") && providerRow["sendmwisubscribe"] != DBNull.Value && providerRow["sendmwisubscribe"] != null) ? Convert.ToBoolean(providerRow["sendmwisubscribe"]) : false;

                if (m_registerContact == null && m_registerEnabled)
                {
                    m_registerEnabled = false;
                    m_registerDisabledReason = "No Contact URI was specified for the registration.";
                     logger.Warn("Registrations for provider " + m_providerName + " owned by " + m_owner + " have been disabled due to an empty or invalid Contact URI.");
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception SIPProvider Load. " + excp.Message);
                throw;
            }
        }
Exemple #53
0
        public static SIPDNSLookupResult DNSNameRecordLookup(string host, int port, bool async, SIPURI uri, SIPDNSLookupResult lookupResult = null, bool?preferIPv6 = null, int recursionLevel = 0)
        {
            SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS Name record lookup requested for " + host + ".", null));

            SIPDNSLookupResult result = lookupResult ?? new SIPDNSLookupResult(uri);

            result.LookupError = null;

            if (UseANYLookups)
            {
                DNSResponse aRecordResponse = DNSManager.Lookup(host, QType.ANY, DNS_A_RECORD_LOOKUP_TIMEOUT, null, true, async);
                if (aRecordResponse == null && async)
                {
                    result.Pending = true;
                }
                else if (aRecordResponse == null)
                {
                }
                else if (aRecordResponse.Timedout)
                {
                    result.ATimedoutAt = DateTime.Now;
                }
                else if (!string.IsNullOrWhiteSpace(aRecordResponse.Error))
                {
                    result.LookupError = aRecordResponse.Error;
                }
                else if ((aRecordResponse.RecordsAAAA == null || aRecordResponse.RecordsAAAA.Length == 0) && (aRecordResponse.RecordsA == null || aRecordResponse.RecordsA.Length == 0) && (aRecordResponse.RecordsCNAME == null || aRecordResponse.RecordsCNAME.Length == 0))
                {
                    SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS no CNAME, A or AAAA records found for " + host + ".", null));
                    result.LookupError = "No CNAME, A or AAAA records found for " + host + ".";
                }
                else
                {
                    if (preferIPv6 == null)
                    {
                        preferIPv6 = SIPDNSManager.PreferIPv6NameResolution;
                    }

                    foreach (RecordCNAME aRecord in aRecordResponse.RecordsCNAME)
                    {
                        //CNAME could be another CNAME or A/AAAA Record -> max 3 levels recursive name resolution
                        if (recursionLevel < 3)
                        {
                            SIPDNSLookupResult resultCName = DNSNameRecordLookup(aRecord.CNAME, port, async, uri, lookupResult, preferIPv6, recursionLevel + 1);
                            if (resultCName != null)
                            {
                                foreach (SIPDNSLookupEndPoint ep in resultCName.EndPointResults)
                                {
                                    result.AddLookupResult(ep);
                                }
                            }
                        }
                    }
                    if (preferIPv6 == true)
                    {
                        SIPURI sipURI = result.URI;
                        foreach (RecordAAAA aRecord in aRecordResponse.RecordsAAAA)
                        {
                            SIPDNSLookupEndPoint sipLookupEndPoint = new SIPDNSLookupEndPoint(new SIPEndPoint(sipURI.Protocol, new IPEndPoint(aRecord.Address, port)), aRecord.RR.TTL);
                            result.AddLookupResult(sipLookupEndPoint);
                            SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS AAAA record found for " + host + ", result " + sipLookupEndPoint.LookupEndPoint.ToString() + ".", null));
                        }
                        foreach (RecordA aRecord in aRecordResponse.RecordsA)
                        {
                            SIPDNSLookupEndPoint sipLookupEndPoint = new SIPDNSLookupEndPoint(new SIPEndPoint(sipURI.Protocol, new IPEndPoint(aRecord.Address, port)), aRecord.RR.TTL);
                            result.AddLookupResult(sipLookupEndPoint);
                            SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS A record found for " + host + ", result " + sipLookupEndPoint.LookupEndPoint.ToString() + ".", null));
                        }
                    }
                    else
                    {
                        SIPURI sipURI = result.URI;
                        foreach (RecordA aRecord in aRecordResponse.RecordsA)
                        {
                            SIPDNSLookupEndPoint sipLookupEndPoint = new SIPDNSLookupEndPoint(new SIPEndPoint(sipURI.Protocol, new IPEndPoint(aRecord.Address, port)), aRecord.RR.TTL);
                            result.AddLookupResult(sipLookupEndPoint);
                            SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS A record found for " + host + ", result " + sipLookupEndPoint.LookupEndPoint.ToString() + ".", null));
                        }
                        foreach (RecordAAAA aRecord in aRecordResponse.RecordsAAAA)
                        {
                            SIPDNSLookupEndPoint sipLookupEndPoint = new SIPDNSLookupEndPoint(new SIPEndPoint(sipURI.Protocol, new IPEndPoint(aRecord.Address, port)), aRecord.RR.TTL);
                            result.AddLookupResult(sipLookupEndPoint);
                            SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS AAAA record found for " + host + ", result " + sipLookupEndPoint.LookupEndPoint.ToString() + ".", null));
                        }
                    }
                }
            }

            if (result.LookupError != null || result.EndPointResults == null || result.EndPointResults.Count == 0)
            {
                if (preferIPv6 == true)
                {
                    result = DNSAAAARecordLookup(host, port, async, uri, lookupResult);
                }
                else
                {
                    result = DNSARecordLookup(host, port, async, uri, lookupResult);
                }
            }

            return(result);
        }
        /// <summary></summary>
        /// <param name="uacRecvdEndPoint">If this is non-null it indicates the contact header should be mangled based on the public socket the register request was demmed
        /// to have originated from rather then relying on the contact value recieved from the uac.</param>
        public SIPRegistrarBinding(
            SIPAccount sipAccount,
            SIPURI bindingURI,
            string callId,
            int cseq,
            string userAgent,
            SIPEndPoint remoteSIPEndPoint,
            SIPEndPoint proxySIPEndPoint,
            SIPEndPoint registrarSIPEndPoint,
            int expiry)
        {
            Id = Guid.NewGuid();
            LastUpdate = DateTime.UtcNow;
            SIPAccountId = sipAccount.Id;
            SIPAccountName = sipAccount.SIPUsername + "@" + sipAccount.SIPDomain;
            Owner = sipAccount.Owner;
            AdminMemberId = sipAccount.AdminMemberId;
            m_contactURI = bindingURI.CopyOf();
            m_mangledContactURI = m_contactURI.CopyOf();
            CallId = callId;
            CSeq = cseq;
            UserAgent = userAgent;
            RemoteSIPEndPoint = remoteSIPEndPoint;
            m_proxySIPEndPoint = proxySIPEndPoint;
            m_registrarSIPEndPoint = registrarSIPEndPoint;

            //if (SIPTransport.IsPrivateAddress(sipRequest.Header.Contact[0].ContactURI.Host) && m_mangleUACContact)
            if (!sipAccount.DontMangleEnabled && Regex.Match(m_mangledContactURI.Host, @"(\d+\.){3}\d+").Success)
            {
                // The Contact URI Host is used by registrars as the contact socket for the user so it needs to be changed to reflect the socket
                // the intial request was received on in order to work around NAT. It's no good just relying on private addresses as a lot of User Agents
                // determine their public IP but NOT their public port so they send the wrong port in the Contact header.

                //logger.Debug("Mangling contact header from " + m_mangledContactURI.Host + " to " + IPSocket.GetSocketString(uacRecvdEndPoint) + ".");

                m_mangledContactURI.Host = remoteSIPEndPoint.GetIPEndPoint().ToString();
            }

            m_expiry = expiry;
        }
Exemple #55
0
 public static SIPDNSLookupResult DNSNameRecordLookup(SIPDNSServiceResult nextSRVRecord, string host, int port, bool async, SIPURI lookupURI, bool?preferIPv6 = null)
 {
     if (nextSRVRecord != null && nextSRVRecord.Data != null)
     {
         return(DNSNameRecordLookup(nextSRVRecord.Data, port, async, lookupURI, null, preferIPv6));
     }
     else
     {
         return(DNSNameRecordLookup(host, port, async, lookupURI, null, preferIPv6));
     }
 }
        public SIPMonitorMachineEvent(SIPMonitorMachineEventTypesEnum machineEventType, string owner, string resourceID, SIPURI resourceURI)
        {
            m_serialisationPrefix = SERIALISATION_PREFIX;

            ClientType = SIPMonitorClientTypesEnum.Machine;
            Username = owner;
            MachineEventType = machineEventType;
            ResourceID = resourceID;
            ResourceURI = resourceURI;
        }
        public void ReferOutOfDialog(SIPURI fromUri, SIPURI toUri, SIPURI referToUri, ReplacesCallDescriptor sipReplacesCallDescriptor)
        {
            try
            {
                m_sipCallDescriptor = new SIPCallDescriptor(null,toUri.ToString(),fromUri.ToString(),null,null);
                m_sipCallDescriptor.Gruu = toUri.Parameters.Get(SIPCallDescriptor.GRUU_KEY);
                m_sipCallDescriptor.ReplacesCall = sipReplacesCallDescriptor;

                SIPURI callURI = SIPURI.ParseSIPURI(m_sipCallDescriptor.Uri);

                    // If the outbound proxy is a loopback address, as it will normally be for local deployments, then it cannot be overriden.
                    if (m_outboundProxy != null && IPAddress.IsLoopback(m_outboundProxy.Address))
                    {
                        m_serverEndPoint = m_outboundProxy;
                    }
                    else if (!m_sipCallDescriptor.ProxySendFrom.IsNullOrBlank())
                    {
                        // If the binding has a specific proxy end point sent then the request needs to be forwarded to the proxy's default end point for it to take care of.
                        SIPEndPoint outboundProxyEndPoint = SIPEndPoint.ParseSIPEndPoint(m_sipCallDescriptor.ProxySendFrom);
                        m_outboundProxy = new SIPEndPoint(SIPProtocolsEnum.udp, new IPEndPoint(outboundProxyEndPoint.Address, m_defaultSIPPort));
                        m_serverEndPoint = m_outboundProxy;
                        Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.ReferUserAgentClient, SIPMonitorEventTypesEnum.Refer, "SIPReferClientUserAgent refer request using alternate outbound proxy of " + m_outboundProxy + ".", Owner));
                    }
                    else if (m_outboundProxy != null)
                    {
                        // Using the system outbound proxy only, no additional user routing requirements.
                        m_serverEndPoint = m_outboundProxy;
                    }

                    // A custom route set may have been specified for the call.
                    if (m_sipCallDescriptor.RouteSet != null && m_sipCallDescriptor.RouteSet.IndexOf(OUTBOUNDPROXY_AS_ROUTESET_CHAR) != -1)
                    {
                        try
                        {
                            RouteSet = new SIPRouteSet();
                            RouteSet.PushRoute(new SIPRoute(m_sipCallDescriptor.RouteSet, true));
                        }
                        catch
                        {
                            Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.ReferUserAgentClient, SIPMonitorEventTypesEnum.Refer, "Error an outbound proxy value was not recognised in SIPReferClientUserAgent refer request. " + m_sipCallDescriptor.RouteSet + ".", Owner));
                        }
                    }

                    // No outbound proxy, determine the forward destination based on the SIP request.
                    if (m_serverEndPoint == null)
                    {
                        SIPDNSLookupResult lookupResult = null;

                        if (RouteSet == null || RouteSet.Length == 0)
                        {
                            Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.ReferUserAgentClient, SIPMonitorEventTypesEnum.Refer, "Attempting to resolve " + callURI.Host + ".", Owner));
                            lookupResult = m_sipTransport.GetURIEndPoint(callURI, false);
                        }
                        else
                        {
                            Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.ReferUserAgentClient, SIPMonitorEventTypesEnum.Refer, "Route set for refer request " + RouteSet.ToString() + ".", Owner));
                            lookupResult = m_sipTransport.GetURIEndPoint(RouteSet.TopRoute.URI, false);
                        }

                        if (lookupResult.LookupError != null)
                        {
                            Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.ReferUserAgentClient, SIPMonitorEventTypesEnum.Refer, "DNS error resolving " + callURI.Host + ", " + lookupResult.LookupError + ". Refer request cannot proceed.", Owner));
                        }
                        else
                        {
                            m_serverEndPoint = lookupResult.GetSIPEndPoint();
                        }
                    }

                    if (m_serverEndPoint != null)
                    {
                        Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.ReferUserAgentClient, SIPMonitorEventTypesEnum.Refer, "Switching to " + SIPURI.ParseSIPURI(m_sipCallDescriptor.Uri).CanonicalAddress + " via " + m_serverEndPoint + ".", Owner));

                        m_localSIPEndPoint = m_sipTransport.GetDefaultSIPEndPoint(m_serverEndPoint);
                        if (m_localSIPEndPoint == null)
                        {
                            throw new ApplicationException("The refer request could not locate an appropriate SIP transport channel for protocol " + callURI.Protocol + ".");
                        }

                        SIPRequest referRequest = GetReferRequest(m_localSIPEndPoint,referToUri, sipReplacesCallDescriptor);

                        // Now that we have a destination socket create a new UAC transaction for forwarded leg of the call.
                        m_serverTransaction = m_sipTransport.CreateNonInviteTransaction(referRequest, m_serverEndPoint, m_localSIPEndPoint, m_outboundProxy);

                        m_serverTransaction.NonInviteTransactionFinalResponseReceived += m_serverTransaction_NonInviteTransactionFinalResponseReceived;
                        m_serverTransaction.NonInviteTransactionTimedOut += m_serverTransaction_NonInviteTransactionTimedOut;
                        m_serverTransaction.TransactionTraceMessage += TransactionTraceMessage;

                        m_serverTransaction.SendReliableRequest();

                    }
                    else
                    {
                        if (RouteSet == null || RouteSet.Length == 0)
                        {
                            Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.ReferUserAgentClient, SIPMonitorEventTypesEnum.Refer, "Forward leg failed, could not resolve URI host " + callURI.Host, Owner));
                            FireReferFailed(this, "unresolvable destination " + callURI.Host);
                        }
                        else
                        {
                            Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.ReferUserAgentClient, SIPMonitorEventTypesEnum.Refer, "Forward leg failed, could not resolve top Route host " + RouteSet.TopRoute.Host, Owner));
                            FireReferFailed(this, "unresolvable destination " + RouteSet.TopRoute.Host);
                        }
                    }
            }
            catch (ApplicationException appExcp)
            {
                FireReferFailed(this, appExcp.Message);
            }
            catch (Exception excp)
            {
                Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.ReferUserAgentClient, SIPMonitorEventTypesEnum.Refer, "Exception UserAgentClient Call. " + excp.Message, Owner));
                FireReferFailed(this, excp.Message);
            }
        }