/// <summary> /// An asynchronous task that attempts to send a single OPTIONS request. /// </summary> /// <param name="sipTransport">The transport object to use for the send.</param> /// <param name="dst">The destination end point to send the request to.</param> /// <returns>The received IP address in the response Via header. This indicates the local IP address that was used to /// reach the destination.</returns> private static async Task <IPAddress> SendOptionsTaskAsync(SIPTransport sipTransport, SIPURI dst) { TaskCompletionSource <IPAddress> tcs = new TaskCompletionSource <IPAddress>(); try { sipTransport.SIPTransportResponseReceived += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPResponse sipResponse) => { Log.LogDebug($"Response received {localSIPEndPoint.ToString()}<-{remoteEndPoint.ToString()}: {sipResponse.ShortDescription}"); //Log.LogDebug(sipResponse.ToString()); tcs.SetResult(IPAddress.Parse(sipResponse.Header.Vias.TopViaHeader.ReceivedFromIPAddress)); }; var optionsRequest = sipTransport.GetRequest(SIPMethodsEnum.OPTIONS, dst); //Log.LogDebug(optionsRequest.ToString()); SocketError sendResult = await sipTransport.SendRequestAsync(optionsRequest); if (sendResult != SocketError.Success) { Log.LogWarning($"Attempt to send request failed with {sendResult}."); tcs.SetResult(null); } } catch (Exception excp) { Log.LogError($"Exception SendOptionsTask. {excp.Message}"); tcs.SetResult(null); } return(await tcs.Task); }
private SIPRequest GetRegistrationRequest(SIPEndPoint localSIPEndPoint) { try { string realm = (m_realm != null) ? m_realm : IPSocket.ParseHostFromSocket(m_registrarHost); SIPURI registerURI = m_sipAccountAOR.CopyOf(); registerURI.User = null; SIPRequest registerRequest = m_sipTransport.GetRequest( SIPMethodsEnum.REGISTER, registerURI, new SIPToHeader(null, m_sipAccountAOR, null), localSIPEndPoint); registerRequest.Header.From = new SIPFromHeader(null, m_sipAccountAOR, CallProperties.CreateNewTag()); registerRequest.Header.Contact[0] = new SIPContactHeader(null, m_contactURI); registerRequest.Header.CSeq = ++m_cseq; registerRequest.Header.CallId = m_callID; registerRequest.Header.UserAgent = (!UserAgent.IsNullOrBlank()) ? UserAgent : m_userAgent; registerRequest.Header.Expires = m_expiry; return(registerRequest); } catch (Exception excp) { logger.LogError("Exception GetRegistrationRequest. " + excp.Message); throw excp; } }
/// <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; } SIPNonInviteTransaction subscribeTransaction = m_sipTransport.CreateNonInviteTransaction(subscribeRequest, 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(); } }
private SIPRequest ByeRequest() { SIPURI uri = new SIPURI(_cameraId, _remoteEndPoint.ToHost(), ""); SIPRequest byeRequest = _m_sipTransport.GetRequest(SIPMethodsEnum.BYE, uri); SIPFromHeader from = new SIPFromHeader(null, _sipRequest.URI, _realReqSession.Header.From.FromTag); SIPHeader header = new SIPHeader(from, byeRequest.Header.To, _realReqSession.Header.CSeq, _realReqSession.Header.CallId); header.ContentType = "application/DDCP"; header.Expires = byeRequest.Header.Expires; header.CSeqMethod = byeRequest.Header.CSeqMethod; header.Vias = byeRequest.Header.Vias; header.MaxForwards = byeRequest.Header.MaxForwards; header.UserAgent = _userAgent; byeRequest.Header.From = from; byeRequest.Header = header; return(byeRequest); }
/// <summary> /// Initialises a SIP tranpsort to act as the client in a single request/response exchange. /// </summary> /// <param name="testClientChannel">The client SIP channel to test.</param> /// <param name="serverUri">The URI of the server end point to test the client against.</param> /// <param name="tcs">The task completion source that this method will set if it receives the expected response.</param> private async Task RunClient(SIPChannel testClientChannel, SIPURI serverUri, TaskCompletionSource <bool> tcs) { logger.LogDebug($"Starting client task for {testClientChannel.ListeningSIPEndPoint}."); var clientSIPTransport = new SIPTransport(); try { clientSIPTransport.AddSIPChannel(testClientChannel); logger.LogDebug($"RunClient test channel created on {testClientChannel.ListeningSIPEndPoint}."); clientSIPTransport.SIPTransportResponseReceived += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPResponse sipResponse) => { logger.LogDebug($"Expected response received {localSIPEndPoint}<-{remoteEndPoint}: {sipResponse.ShortDescription}"); if (sipResponse.Status == SIPResponseStatusCodesEnum.Ok) { // Got the expected response, set the signal. tcs.SetResult(true); } }; clientSIPTransport.SIPRequestOutTraceEvent += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) => { logger.LogDebug($"CLIENT REQUEST OUT {localSIPEndPoint}->{remoteEndPoint}"); logger.LogDebug(sipRequest.ToString()); }; clientSIPTransport.SIPResponseInTraceEvent += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPResponse sipResponse) => { logger.LogDebug($"CLIENT RESPONSE IN {localSIPEndPoint}<-{remoteEndPoint}"); logger.LogDebug(sipResponse.ToString()); }; var optionsRequest = clientSIPTransport.GetRequest(SIPMethodsEnum.OPTIONS, serverUri); clientSIPTransport.SendRequest(optionsRequest); await tcs.Task; } catch (Exception excp) { logger.LogError($"Exception RunClient. {excp.Message}"); } finally { logger.LogDebug($"Client task completed for {testClientChannel.ListeningSIPEndPoint}."); clientSIPTransport.Shutdown(); logger.LogDebug($"Client task SIP transport shutdown."); } }
private void SendNotifyRequestForSubscription(SIPEventSubscription subscription) { try { subscription.SubscriptionDialogue.CSeq++; //logger.Debug(DateTime.Now.ToString("HH:mm:ss:fff") + " Sending NOTIFY request for " + subscription.SubscriptionDialogue.Owner + " event " + subscription.SubscriptionEventPackage.ToString() // + " and " + subscription.ResourceURI.ToString() + " to " + subscription.SubscriptionDialogue.RemoteTarget.ToString() + ", cseq=" + (subscription.SubscriptionDialogue.CSeq) + "."); int secondsRemaining = Convert.ToInt32(subscription.LastSubscribe.AddSeconds(subscription.Expiry).Subtract(DateTime.Now).TotalSeconds % Int32.MaxValue); SIPRequest notifyRequest = m_sipTransport.GetRequest(SIPMethodsEnum.NOTIFY, subscription.SubscriptionDialogue.RemoteTarget); notifyRequest.Header.From = SIPFromHeader.ParseFromHeader(subscription.SubscriptionDialogue.LocalUserField.ToString()); notifyRequest.Header.To = SIPToHeader.ParseToHeader(subscription.SubscriptionDialogue.RemoteUserField.ToString()); notifyRequest.Header.Event = subscription.SubscriptionEventPackage.ToString(); notifyRequest.Header.CSeq = subscription.SubscriptionDialogue.CSeq; notifyRequest.Header.CallId = subscription.SubscriptionDialogue.CallId; notifyRequest.Body = subscription.GetNotifyBody(); notifyRequest.Header.ContentLength = notifyRequest.Body.Length; notifyRequest.Header.SubscriptionState = "active;expires=" + secondsRemaining.ToString(); notifyRequest.Header.ContentType = subscription.NotifyContentType; notifyRequest.Header.ProxySendFrom = subscription.SubscriptionDialogue.ProxySendFrom; // If the outbound proxy is a loopback address, as it will normally be for local deployments, then it cannot be overriden. SIPEndPoint dstEndPoint = m_outboundProxy; if (m_outboundProxy != null && IPAddress.IsLoopback(m_outboundProxy.Address)) { dstEndPoint = m_outboundProxy; } else if (subscription.SubscriptionDialogue.ProxySendFrom != null) { // The proxy will always be listening on UDP port 5060 for requests from internal servers. dstEndPoint = new SIPEndPoint(SIPProtocolsEnum.udp, new IPEndPoint(SIPEndPoint.ParseSIPEndPoint(subscription.SubscriptionDialogue.ProxySendFrom).Address, m_defaultSIPPort)); } SIPNonInviteTransaction notifyTransaction = m_sipTransport.CreateNonInviteTransaction(notifyRequest, dstEndPoint, m_sipTransport.GetDefaultSIPEndPoint(dstEndPoint), m_outboundProxy); notifyTransaction.NonInviteTransactionFinalResponseReceived += (local, remote, transaction, response) => { NotifyTransactionFinalResponseReceived(local, remote, transaction, response, subscription); }; m_sipTransport.SendSIPReliable(notifyTransaction); //logger.Debug(notifyRequest.ToString()); MonitorLogEvent_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.NotifySent, "Notification sent for " + subscription.SubscriptionEventPackage.ToString() + " and " + subscription.ResourceURI.ToString() + " to " + subscription.SubscriptionDialogue.RemoteTarget.ToString() + " (cseq=" + notifyRequest.Header.CSeq + ").", subscription.SubscriptionDialogue.Owner)); subscription.NotificationSent(); } catch (Exception excp) { logger.Error("Exception SendNotifyRequestForSubscription. " + excp.Message); throw; } }
/// <summary> /// 查询设备目录请求 /// </summary> /// <returns></returns> private SIPRequest QueryItems(SIPEndPoint remoteEndPoint, string remoteSIPId) { string fromTag = CallProperties.CreateNewTag(); string toTag = CallProperties.CreateNewTag(); int cSeq = CallProperties.CreateNewCSeq(); string callId = CallProperties.CreateNewCallId(); SIPURI remoteUri = new SIPURI(remoteSIPId, remoteEndPoint.ToHost(), ""); SIPURI localUri = new SIPURI(LocalSIPId, LocalEP.ToHost(), ""); SIPFromHeader from = new SIPFromHeader(null, localUri, fromTag); SIPToHeader to = new SIPToHeader(null, remoteUri, null); SIPRequest catalogReq = Transport.GetRequest(SIPMethodsEnum.MESSAGE, remoteUri); catalogReq.Header.From = from; catalogReq.Header.Contact = null; catalogReq.Header.Allow = null; catalogReq.Header.To = to; catalogReq.Header.UserAgent = SIPConstants.SIP_USERAGENT_STRING; catalogReq.Header.CSeq = cSeq; catalogReq.Header.CallId = callId; catalogReq.Header.ContentType = "application/MANSCDP+xml"; return(catalogReq); }
/// <summary> /// An asynchronous task that attempts to send a single OPTIONS request. /// </summary> /// <param name="sipTransport">The transport object to use for the send.</param> /// <param name="dst">The destination end point to send the request to.</param> /// <returns>True if the expected response was recevived, false otherwise.</returns> private static async Task <bool> SendOptionsTaskAsync(SIPTransport sipTransport, SIPURI dst) { TaskCompletionSource <bool> tcs = new TaskCompletionSource <bool>(); try { sipTransport.SIPRequestOutTraceEvent += (localEP, remoteEP, req) => { logger.LogDebug($"Request sent: {localEP}->{remoteEP}"); logger.LogDebug(req.ToString()); }; sipTransport.SIPResponseInTraceEvent += (localEP, remoteEP, resp) => { logger.LogDebug($"Response received: {localEP}<-{remoteEP}"); logger.LogDebug(resp.ToString()); }; var optionsRequest = sipTransport.GetRequest(SIPMethodsEnum.OPTIONS, dst); sipTransport.SIPTransportResponseReceived += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPResponse sipResponse) => { if (sipResponse.Header.CSeqMethod == SIPMethodsEnum.OPTIONS && sipResponse.Header.CallId == optionsRequest.Header.CallId) { logger.LogDebug($"Expected response received {localSIPEndPoint.ToString()}<-{remoteEndPoint.ToString()}: {sipResponse.ShortDescription}"); tcs.SetResult(true); } }; SocketError sendResult = await sipTransport.SendRequestAsync(optionsRequest); if (sendResult != SocketError.Success) { logger.LogWarning($"Attempt to send request failed with {sendResult}."); tcs.SetResult(false); } } catch (Exception excp) { logger.LogError($"Exception SendOptionsTask. {excp.Message}"); tcs.SetResult(false); } return(await tcs.Task); }
/// <summary> /// 查询设备目录请求 /// </summary> /// <returns></returns> private SIPRequest QueryItems(string fromTag, string toTag, int cSeq, string callId) { SIPURI remoteUri = new SIPURI(RemoteSIPId, RemoteEndPoint.ToHost(), ""); SIPURI localUri = new SIPURI(LocalSIPId, LocalEndPoint.ToHost(), ""); SIPFromHeader from = new SIPFromHeader(null, localUri, fromTag); SIPToHeader to = new SIPToHeader(null, remoteUri, toTag); SIPRequest catalogReq = Transport.GetRequest(SIPMethodsEnum.MESSAGE, remoteUri); catalogReq.Header.From = from; catalogReq.Header.Contact = null; catalogReq.Header.Allow = null; catalogReq.Header.To = to; catalogReq.Header.UserAgent = UserAgent; catalogReq.Header.CSeq = cSeq; catalogReq.Header.CallId = callId; catalogReq.Header.ContentType = "application/MANSCDP+xml"; return(catalogReq); }
/// <summary> /// Initialises a SIP tranpsort to act as the client in a single request/response exchange. /// </summary> /// <param name="testClientChannel">The client SIP channel to test.</param> /// <param name="serverUri">The URI of the server end point to test the client against.</param> /// <param name="tcs">The task completion source that this method will set if it receives the expected response.</param> private async Task RunClient(SIPChannel testClientChannel, SIPURI serverUri, TaskCompletionSource <bool> tcs) { logger.LogDebug($"Starting client task for {testClientChannel.SIPChannelEndPoint.ToString()}."); var clientSIPTransport = new SIPTransport(); try { clientSIPTransport.AddSIPChannel(testClientChannel); logger.LogDebug(clientSIPTransport.GetDefaultSIPEndPoint().ToString()); clientSIPTransport.SIPTransportResponseReceived += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPResponse sipResponse) => { logger.LogDebug($"Response received {localSIPEndPoint.ToString()}<-{remoteEndPoint.ToString()}: {sipResponse.ShortDescription}"); logger.LogDebug(sipResponse.ToString()); if (sipResponse.Status == SIPResponseStatusCodesEnum.Ok) { // Got the expected response, set the signal. tcs.SetResult(true); } }; var optionsRequest = clientSIPTransport.GetRequest(SIPMethodsEnum.OPTIONS, serverUri); logger.LogDebug(optionsRequest.ToString()); clientSIPTransport.SendRequest(optionsRequest); await tcs.Task; } finally { logger.LogDebug($"Client task completed for {testClientChannel.SIPChannelEndPoint.ToString()}."); clientSIPTransport.Shutdown(); } }
static void Main(string[] args) { try { var sipTransport = new SIPTransport(SIPDNSManager.ResolveSIPService, new SIPTransactionEngine()); sipTransport.SIPTransportRequestReceived += SIPRequestReceived; sipTransport.SIPTransportResponseReceived += SIPResponseReceived; X509Certificate2 cert = new X509Certificate2("test-cert.cer"); SIPTLSChannel tlsChannel = new SIPTLSChannel(cert, new IPEndPoint(IPAddress.Any, 5061)); sipTransport.AddSIPChannel(tlsChannel); var optionsReq = sipTransport.GetRequest(SIPMethodsEnum.OPTIONS, SIPURI.ParseSIPURI("sips:67.222.131.147:5061")); sipTransport.SendRequest(optionsReq); } catch (Exception excp) { Console.WriteLine("Exception Main. " + excp); } finally { Console.WriteLine("Press any key to exit..."); Console.Read(); } }
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 TcpTrickleReceiveTest() { TaskCompletionSource <bool> testComplete = new TaskCompletionSource <bool>(); IPEndPoint listenEP = new IPEndPoint(IPAddress.Loopback, 9067); var transport = new SIPTransport(); var tcpChannel = new SIPTCPChannel(new IPEndPoint(IPAddress.Loopback, 9066)); tcpChannel.DisableLocalTCPSocketsCheck = true; transport.AddSIPChannel(tcpChannel); int requestCount = 10; int recvdReqCount = 0; Task.Run(() => { try { TcpListener listener = new TcpListener(listenEP); listener.Start(); var tcpClient = listener.AcceptTcpClient(); logger.LogDebug($"Dummy 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, tcpChannel.GetContactURI(SIPSchemesEnum.sip, listenEP.Address)); byte[] reqBytes = Encoding.UTF8.GetBytes(req.ToString()); tcpClient.GetStream().Write(reqBytes, 0, reqBytes.Length); tcpClient.GetStream().Flush(); Task.Delay(30).Wait(); } tcpClient.GetStream().Close(); } catch (Exception excp) { logger.LogError($"Exception on dummy TCP listener task. {excp.Message}"); testComplete.SetResult(false); } }); 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(TRANSPORT_TEST_TIMEOUT) }).Wait(); transport.Shutdown(); // Give the SIP transport time to shutdown. Keeps exception messages out of the logs. Task.Delay(500).Wait(); Assert.True(testComplete.Task.IsCompleted); Assert.True(testComplete.Task.Result); Assert.True(requestCount == recvdReqCount, $"The count of {recvdReqCount} for the requests received did not match what was expected."); }