private SIPResponse GetOkResponse(SIPRequest sipRequest) { try { SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); SIPHeader requestHeader = sipRequest.Header; okResponse.Header = new SIPHeader(requestHeader.Contact, requestHeader.From, requestHeader.To, requestHeader.CSeq, requestHeader.CallId); // RFC3261 has a To Tag on the example in section "24.1 Registration". if (okResponse.Header.To.ToTag == null || okResponse.Header.To.ToTag.Trim().Length == 0) { okResponse.Header.To.ToTag = CallProperties.CreateNewTag(); } okResponse.Header.CSeqMethod = requestHeader.CSeqMethod; okResponse.Header.Vias = requestHeader.Vias; //okResponse.Header.Server = m_serverAgent; okResponse.Header.UserAgent = m_serverAgent; okResponse.Header.MaxForwards = Int32.MinValue; okResponse.Header.SetDateHeader(); return(okResponse); } catch (Exception excp) { Logger.Logger.Error("Exception GetOkResponse. ->" + excp.Message); throw excp; } }
public SIPDialogue Answer(string contentType, string body, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode) { try { logger.Debug("SIPB2BUserAgent Answer."); m_sipDialogue = answeredDialogue; UASStateChanged?.Invoke(this, SIPResponseStatusCodesEnum.Ok, null); SIPResponse uasOkResponse = SIPTransport.GetResponse(m_uasTransaction.TransactionRequest, SIPResponseStatusCodesEnum.Ok, null); m_uasTransaction.SendFinalResponse(uasOkResponse); m_uasTransaction.ACKReceived(m_blackhole, m_blackhole, null); SIPResponse uacOkResponse = SIPTransport.GetResponse(m_uacTransaction.TransactionRequest, SIPResponseStatusCodesEnum.Ok, null); uacOkResponse.Header.Contact = new List <SIPContactHeader>() { new SIPContactHeader(null, new SIPURI(SIPSchemesEnum.sip, m_blackhole)) }; m_uacTransaction.GotResponse(m_blackhole, m_blackhole, uacOkResponse); uacOkResponse.Header.ContentType = contentType; if (!body.IsNullOrBlank()) { uacOkResponse.Body = body; uacOkResponse.Header.ContentLength = body.Length; } CallAnswered.Invoke(this, uacOkResponse); return(null); } catch (Exception excp) { logger.Error("Exception SIPB2BUSerAgent Answer. " + excp.Message); throw; } }
public void Reject(SIPResponseStatusCodesEnum failureStatus, string reasonPhrase, string[] customHeaders) { SIPResponse failureResponse = SIPTransport.GetResponse(m_transaction.TransactionRequest, failureStatus, reasonPhrase); m_transaction.SendFinalResponse(failureResponse); }
static void Main() { Console.WriteLine("SIPSorcery Getting Started Demo"); var sipTransport = new SIPTransport(); var sipChannel = new SIPUDPChannel(IPAddress.Loopback, 5060); sipTransport.AddSIPChannel(sipChannel); sipTransport.SIPTransportRequestReceived += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) => { Console.WriteLine($"Request received {localSIPEndPoint.ToString()}<-{remoteEndPoint.ToString()}: {sipRequest.StatusLine}"); if (sipRequest.Method == SIPMethodsEnum.OPTIONS) { SIPResponse optionsResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); sipTransport.SendResponse(optionsResponse); } }; Console.Write("press any key to exit..."); Console.Read(); sipTransport.Shutdown(); }
private SIPResponse GetAuthReqdResponse(SIPRequest sipRequest, string nonce, string realm) { try { SIPResponse authReqdResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Unauthorised, null); SIPAuthenticationHeader authHeader = new SIPAuthenticationHeader(SIPAuthorisationHeadersEnum.WWWAuthenticate, realm, nonce); SIPHeader requestHeader = sipRequest.Header; SIPHeader unauthHeader = new SIPHeader(requestHeader.Contact, requestHeader.From, requestHeader.To, requestHeader.CSeq, requestHeader.CallId); if (unauthHeader.To.ToTag == null || unauthHeader.To.ToTag.Trim().Length == 0) { unauthHeader.To.ToTag = CallProperties.CreateNewTag(); } unauthHeader.CSeqMethod = requestHeader.CSeqMethod; unauthHeader.Vias = requestHeader.Vias; unauthHeader.AuthenticationHeader = authHeader; //unauthHeader.Server = m_serverAgent; unauthHeader.UserAgent = m_serverAgent; unauthHeader.MaxForwards = Int32.MinValue; authReqdResponse.Header = unauthHeader; return(authReqdResponse); } catch (Exception excp) { Logger.Logger.Error("Exception GetAuthReqdResponse. ->" + excp.Message); throw excp; } }
public void Reject(SIPResponseStatusCodesEnum failureStatus, string reasonPhrase, string[] customHeaders) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, m_transaction.TransactionRequest.Method + " request failed with a response status of " + (int)failureStatus + " " + reasonPhrase + ".", m_owner)); SIPResponse failureResponse = SIPTransport.GetResponse(m_transaction.TransactionRequest, failureStatus, reasonPhrase); m_transaction.SendFinalResponse(failureResponse); }
private SIPResponse GetErrorResponse(SIPRequest sipRequest, SIPResponseStatusCodesEnum errorResponseCode, string errorMessage) { try { SIPResponse errorResponse = SIPTransport.GetResponse(sipRequest, errorResponseCode, null); if (errorMessage != null) { errorResponse.ReasonPhrase = errorMessage; } SIPHeader requestHeader = sipRequest.Header; SIPHeader errorHeader = new SIPHeader(requestHeader.Contact, requestHeader.From, requestHeader.To, requestHeader.CSeq, requestHeader.CallId); if (errorHeader.To.ToTag == null || errorHeader.To.ToTag.Trim().Length == 0) { errorHeader.To.ToTag = CallProperties.CreateNewTag(); } errorHeader.CSeqMethod = requestHeader.CSeqMethod; errorHeader.Vias = requestHeader.Vias; errorHeader.Server = m_serverAgent; errorHeader.MaxForwards = Int32.MinValue; errorResponse.Header = errorHeader; return(errorResponse); } catch (Exception excp) { logger.Error("Exception GetErrorResponse. " + excp.Message); throw excp; } }
public void Reject(SIPResponseStatusCodesEnum rejectCode, string rejectReason, string[] customHeaders) { logger.LogDebug("SIPB2BUserAgent Reject."); if (UASStateChanged != null) { UASStateChanged(this, rejectCode, rejectReason); } SIPResponse uasfailureResponse = SIPTransport.GetResponse(m_uasTransaction.TransactionRequest, rejectCode, rejectReason); m_uasTransaction.SendFinalResponse(uasfailureResponse); SIPResponse uacfailureResponse = SIPTransport.GetResponse(m_uacTransaction.TransactionRequest, rejectCode, rejectReason); if (customHeaders != null && customHeaders.Length > 0) { foreach (string header in customHeaders) { uacfailureResponse.Header.UnknownHeaders.Add(header); } } m_uacTransaction.GotResponse(m_blackhole, m_blackhole, uacfailureResponse); CallAnswered((ISIPClientUserAgent)this, uacfailureResponse); }
private void Transport_SIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { var sipEndPoint = new SIPEndPoint(SIPProtocolsEnum.udp, publicIPAddress, localSIPEndPoint.Port); switch (sipRequest.Method) { case SIPMethodsEnum.BYE: logger.Debug($"{ prefix } Hangup from { sipRequest.Header.From.FromURI.User }"); var noninvite = transport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, sipEndPoint, null); var response = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); noninvite.SendFinalResponse(response); StateChanged?.Invoke(this, new ConsumerStateEventArgs(State.Finished, endpoint, SessionId)); rtpChannel.OnFrameReady -= RtpChannel_OnFrameReady; rtpChannel.Close(); StateChanged?.Invoke(this, new ConsumerStateEventArgs(State.Ready, endpoint, SessionId)); return; case SIPMethodsEnum.CANCEL: break; } }
public void CancelCall() { try { if (TransactionState == SIPTransactionStatesEnum.Calling || TransactionState == SIPTransactionStatesEnum.Trying || TransactionState == SIPTransactionStatesEnum.Proceeding) { base.Cancel(); SIPResponse cancelResponse = SIPTransport.GetResponse(TransactionRequest, SIPResponseStatusCodesEnum.RequestTerminated, null); SendFinalResponse(cancelResponse); if (UASInviteTransactionCancelled != null) { UASInviteTransactionCancelled(this); } } else { logger.LogWarning("A request was made to cancel transaction " + TransactionId + " that was not in the calling, trying or proceeding states, state=" + TransactionState + "."); } //if (CDR != null) { // CDR.Cancelled(); //} } catch (Exception excp) { logger.LogError("Exception UASInviteTransaction CancelCall. " + excp.Message); throw; } }
/// <summary> /// Initialises a SIP transport to act as a server in single request/response exchange. /// </summary> /// <param name="testServerChannel">The server SIP channel to test.</param> /// <param name="cts">Cancellation token to tell the server when to shutdown.</param> private void RunServer(SIPChannel testServerChannel, CancellationTokenSource cts) { logger.LogDebug($"Starting server task for {testServerChannel.SIPChannelEndPoint.ToString()}."); var serverSIPTransport = new SIPTransport(); try { serverSIPTransport.AddSIPChannel(testServerChannel); logger.LogDebug(serverSIPTransport.GetDefaultSIPEndPoint().ToString()); serverSIPTransport.SIPTransportRequestReceived += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) => { logger.LogDebug($"Request received {localSIPEndPoint.ToString()}<-{remoteEndPoint.ToString()}: {sipRequest.StatusLine}"); if (sipRequest.Method == SIPMethodsEnum.OPTIONS) { SIPResponse optionsResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); serverSIPTransport.SendResponse(optionsResponse); } }; cts.Token.WaitHandle.WaitOne(); //WaitHandle.WaitAny(new[] { cts.Token.WaitHandle }); } finally { logger.LogDebug($"Server task for completed for {testServerChannel.SIPChannelEndPoint.ToString()}."); serverSIPTransport.Shutdown(); } }
public void Progress(SIPResponseStatusCodesEnum progressStatus, string reasonPhrase, string[] customHeaders, string progressContentType, string progressBody) { try { if (!IsUASAnswered) { if ((int)progressStatus >= 200) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "UAS call was passed an invalid response status of " + (int)progressStatus + ", ignoring.", m_owner)); } else { UASStateChanged?.Invoke(this, progressStatus, reasonPhrase); // Allow all Trying responses through as some may contain additional useful information on the call state for the caller. // Also if the response is a 183 Session Progress with audio forward it. if (m_uasTransaction.TransactionState == SIPTransactionStatesEnum.Proceeding && progressStatus != SIPResponseStatusCodesEnum.Trying && !(progressStatus == SIPResponseStatusCodesEnum.SessionProgress && progressBody != null)) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "UAS call ignoring progress response with status of " + (int)progressStatus + " as already in " + m_uasTransaction.TransactionState + ".", m_owner)); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "UAS call progressing with " + progressStatus + ".", m_owner)); SIPResponse progressResponse = SIPTransport.GetResponse(m_uasTransaction.TransactionRequest, progressStatus, reasonPhrase); if (progressResponse.Status != SIPResponseStatusCodesEnum.Trying) { progressResponse.Header.To.ToTag = m_uasTransaction.LocalTag; } if (!progressBody.IsNullOrBlank()) { progressResponse.Body = progressBody; progressResponse.Header.ContentType = progressContentType; progressResponse.Header.ContentLength = progressBody.Length; } if (customHeaders != null && customHeaders.Length > 0) { foreach (string header in customHeaders) { progressResponse.Header.UnknownHeaders.Add(header); } } m_uasTransaction.SendProvisionalResponse(progressResponse); } } } else { logger.LogWarning("SIPServerUserAgent Progress fired on already answered call."); } } catch (Exception excp) { logger.LogError("Exception SIPServerUserAgent Progress. " + excp.Message); } }
private static void SIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { if (sipRequest.Method == SIPMethodsEnum.INVITE) { Console.WriteLine("INVITE received from " + localSIPEndPoint.ToString()); IPEndPoint sipPhoneEndPoint = SDP.GetSDPRTPEndPoint(sipRequest.Body); UASInviteTransaction uasTransaction = m_sipTransport.CreateUASTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null); SIPServerUserAgent uas = new SIPServerUserAgent(m_sipTransport, null, null, null, SIPCallDirection.In, null, null, null, uasTransaction); SIPResponse tryingResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Trying, null); uasTransaction.SendInformationalResponse(tryingResponse); if (m_xmppClient == null) { m_xmppClient = new XMPPClient(XMPP_SERVER, XMPP_SERVER_PORT, XMPP_REALM, m_xmppUsername, m_xmppPassword); m_xmppClient.Disconnected += XMPPDisconnected; m_xmppClient.IsBound += () => { XMPPPlaceCall(uas); }; ThreadPool.QueueUserWorkItem(delegate { m_xmppClient.Connect(); }); } else { XMPPPlaceCall(uas); } } else if (sipRequest.Method == SIPMethodsEnum.CANCEL) { UASInviteTransaction inviteTransaction = (UASInviteTransaction)m_sipTransport.GetTransaction(SIPTransaction.GetRequestTransactionId(sipRequest.Header.Vias.TopViaHeader.Branch, SIPMethodsEnum.INVITE)); if (inviteTransaction != null) { Console.WriteLine("Matching CANCEL request received " + sipRequest.URI.ToString() + "."); SIPCancelTransaction cancelTransaction = m_sipTransport.CreateCancelTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, inviteTransaction); cancelTransaction.GotRequest(localSIPEndPoint, remoteEndPoint, sipRequest); } else { Console.WriteLine("No matching transaction was found for CANCEL to " + sipRequest.URI.ToString() + "."); SIPResponse noCallLegResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist, null); m_sipTransport.SendResponse(noCallLegResponse); } } else if (sipRequest.Method == SIPMethodsEnum.BYE) { Console.WriteLine("BYE request received."); if (m_activeCalls.ContainsKey(sipRequest.Header.CallId)) { SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); m_sipTransport.SendResponse(okResponse); m_activeCalls[sipRequest.Header.CallId].TerminateXMPPCall(); m_activeCalls.Remove(sipRequest.Header.CallId); } else { SIPResponse doesntExistResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist, null); m_sipTransport.SendResponse(doesntExistResponse); } } }
public void Progress(SIPResponseStatusCodesEnum progressStatus, string reasonPhrase, string[] customHeaders, string progressContentType, string progressBody) { try { if (!IsUASAnswered) { if ((int)progressStatus >= 200) { } else { UASStateChanged?.Invoke(this, progressStatus, reasonPhrase); if (m_uasTransaction.TransactionState == SIPTransactionStatesEnum.Proceeding) { } else { SIPResponse uasProgressResponse = SIPTransport.GetResponse(m_uasTransaction.TransactionRequest, progressStatus, reasonPhrase); m_uasTransaction.SendInformationalResponse(uasProgressResponse); SIPResponse uacProgressResponse = SIPTransport.GetResponse(m_uacTransaction.TransactionRequest, progressStatus, reasonPhrase); if (!progressBody.IsNullOrBlank()) { uacProgressResponse.Body = progressBody; uacProgressResponse.Header.ContentType = progressContentType; } if (customHeaders != null && customHeaders.Length > 0) { foreach (string header in customHeaders) { uacProgressResponse.Header.UnknownHeaders.Add(header); } } m_uacTransaction.GotResponse(m_blackhole, m_blackhole, uacProgressResponse); CallRinging(this, uacProgressResponse); } } } else { logger.Warn("B2BUserAgent Progress fired on already answered call."); } } catch (Exception excp) { logger.Error("Exception B2BUserAgent Progress. " + excp.Message); } }
public void Progress(SIPResponseStatusCodesEnum progressStatus, string reasonPhrase, string[] customHeaders, string progressContentType, string progressBody) { try { if (!IsUASAnswered) { if ((int)progressStatus >= 200) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "B2BUA call was passed an invalid response status of " + (int)progressStatus + ", ignoring.", m_uacOwner)); } else { if (UASStateChanged != null) { UASStateChanged(this, progressStatus, reasonPhrase); } if (m_uasTransaction.TransactionState == SIPTransactionStatesEnum.Proceeding) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "B2BUA call ignoring progress response with status of " + (int)progressStatus + " as already in " + m_uasTransaction.TransactionState + ".", m_uacOwner)); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "B2BUA call progressing with " + progressStatus + ".", m_uacOwner)); SIPResponse uasProgressResponse = SIPTransport.GetResponse(m_uasTransaction.TransactionRequest, progressStatus, reasonPhrase); m_uasTransaction.SendProvisionalResponse(uasProgressResponse); SIPResponse uacProgressResponse = SIPTransport.GetResponse(m_uacTransaction.TransactionRequest, progressStatus, reasonPhrase); if (!progressBody.IsNullOrBlank()) { uacProgressResponse.Body = progressBody; uacProgressResponse.Header.ContentType = progressContentType; } if (customHeaders != null && customHeaders.Length > 0) { foreach (string header in customHeaders) { uacProgressResponse.Header.UnknownHeaders.Add(header); } } m_uacTransaction.GotResponse(m_blackhole, m_blackhole, uacProgressResponse); CallRinging((ISIPClientUserAgent)this, uacProgressResponse); } } } else { logger.LogWarning("B2BUserAgent Progress fired on already answered call."); } } catch (Exception excp) { logger.LogError("Exception B2BUserAgent Progress. " + excp.Message); } }
/// <summary> /// 处理注册请求消息 /// </summary> /// <param name="localSIPEndPoint">本地终结点</param> /// <param name="remoteEndPoint">远程终结点</param> /// <param name="registerRequest">注册请求</param> private void ProcessRegisterReqMessage(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest registerRequest) { SIPSorceryPerformanceMonitor.IncrementCounter(SIPSorceryPerformanceMonitor.REGISTRAR_REGISTRATION_REQUESTS_PER_SECOND); int requestedExpiry = GetRequestedExpiry(registerRequest); if (registerRequest.Header.To == null) { logger.Debug("Bad register request, no To header from " + remoteEndPoint + "."); SIPResponse badReqResponse = SIPTransport.GetResponse(registerRequest, SIPResponseStatusCodesEnum.BadRequest, "Missing To header"); m_sipTransport.SendResponse(badReqResponse); } else if (registerRequest.Header.To.ToURI.User.IsNullOrBlank()) { logger.Debug("Bad register request, no To user from " + remoteEndPoint + "."); SIPResponse badReqResponse = SIPTransport.GetResponse(registerRequest, SIPResponseStatusCodesEnum.BadRequest, "Missing username on To header"); m_sipTransport.SendResponse(badReqResponse); } else if (registerRequest.Header.Contact == null || registerRequest.Header.Contact.Count == 0) { logger.Debug("Bad register request, no Contact header from " + remoteEndPoint + "."); SIPResponse badReqResponse = SIPTransport.GetResponse(registerRequest, SIPResponseStatusCodesEnum.BadRequest, "Missing Contact header"); m_sipTransport.SendResponse(badReqResponse); } else if (requestedExpiry > 0 && requestedExpiry < MINIMUM_EXPIRY_SECONDS) { logger.Debug("Bad register request, no expiry of " + requestedExpiry + " to small from " + remoteEndPoint + "."); SIPResponse tooFrequentResponse = GetErrorResponse(registerRequest, SIPResponseStatusCodesEnum.IntervalTooBrief, null); tooFrequentResponse.Header.MinExpires = MINIMUM_EXPIRY_SECONDS; m_sipTransport.SendResponse(tooFrequentResponse); } else { if (m_registerQueue.Count < MAX_REGISTER_QUEUE_SIZE) { SIPNonInviteTransaction registrarTransaction = m_sipTransport.CreateNonInviteTransaction(registerRequest, remoteEndPoint, localSIPEndPoint, null); lock (m_registerQueue) { m_registerQueue.Enqueue(registrarTransaction); } FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.BindingInProgress, "Register queued for " + registerRequest.Header.To.ToURI.ToString() + ".", null)); } else { logger.Error("Register queue exceeded max queue size " + MAX_REGISTER_QUEUE_SIZE + ", overloaded response sent."); SIPResponse overloadedResponse = SIPTransport.GetResponse(registerRequest, SIPResponseStatusCodesEnum.TemporarilyUnavailable, "Registrar overloaded, please try again shortly"); m_sipTransport.SendResponse(overloadedResponse); } m_registerARE.Set(); } }
/// <summary> /// PRACK request received to acknowledge the last provisional response that was sent. /// </summary> /// <param name="localSIPEndPoint">The SIP socket the request was received on.</param> /// <param name="remoteEndPoint">The remote SIP socket the request originated from.</param> /// <param name="sipRequest">The PRACK request.</param> public void PRACKReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { if (m_transactionState == SIPTransactionStatesEnum.Proceeding && RSeq == sipRequest.Header.RAckRSeq) { logger.LogDebug("PRACK request matched the current outstanding provisional response, setting as delivered."); DeliveryPending = false; } // We don't keep track of previous provisional response ACK's so always return OK if the request matched the // transaction and got this far. var prackResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); m_sipTransport.SendResponse(prackResponse); }
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); } }
/// <summary> /// Initialises a SIP transport to act as a server in single request/response exchange. /// </summary> /// <param name="testServerChannel">The server SIP channel to test.</param> /// <param name="cts">Cancellation token to tell the server when to shutdown.</param> private void RunServer(SIPChannel testServerChannel, CancellationTokenSource cts) { logger.LogDebug($"RunServer test channel created on {testServerChannel.ListeningSIPEndPoint}."); var serverSIPTransport = new SIPTransport(); try { serverSIPTransport.AddSIPChannel(testServerChannel); serverSIPTransport.SIPTransportRequestReceived += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) => { logger.LogDebug($"Request received {localSIPEndPoint.ToString()}<-{remoteEndPoint.ToString()}: {sipRequest.StatusLine}"); if (sipRequest.Method == SIPMethodsEnum.OPTIONS) { SIPResponse optionsResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); logger.LogDebug(optionsResponse.ToString()); serverSIPTransport.SendResponse(optionsResponse); } }; serverSIPTransport.SIPRequestInTraceEvent += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) => { logger.LogDebug($"SERVER REQUEST IN {localSIPEndPoint}<-{remoteEndPoint}"); logger.LogDebug(sipRequest.ToString()); }; serverSIPTransport.SIPResponseOutTraceEvent += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPResponse sipResponse) => { logger.LogDebug($"SERVER RESPONSE OUT {localSIPEndPoint}->{remoteEndPoint}"); logger.LogDebug(sipResponse.ToString()); }; cts.Token.WaitHandle.WaitOne(); } catch (Exception excp) { logger.LogError($"Exception RunServer. {excp.Message}"); } finally { logger.LogDebug($"Server task for completed for {testServerChannel.ListeningSIPEndPoint}."); serverSIPTransport.Shutdown(); logger.LogDebug($"Server task SIP transport shutdown."); } }
/// <summary> /// Event handler for receiving a re-INVITE request on an established call. /// In call requests can be used for multitude of different purposes. In this /// example program we're only concerned with re-INVITE requests being used /// to place a call on/off hold. /// </summary> /// <param name="uasTransaction">The user agent server invite transaction that /// was created for the request. It needs to be used for sending responses /// to ensure reliable delivery.</param> private static void ReinviteRequestReceived(UASInviteTransaction uasTransaction) { SIPRequest reinviteRequest = uasTransaction.TransactionRequest; // Re-INVITEs can also be changing the RTP end point. We can update this each time. IPEndPoint dstRtpEndPoint = SDP.GetSDPRTPEndPoint(reinviteRequest.Body); _remoteRtpEndPoint = dstRtpEndPoint; // If the RTP callfow attribute has changed it's most likely due to being placed on/off hold. SDP newSDP = SDP.ParseSDPDescription(reinviteRequest.Body); if (GetRTPStatusAttribute(newSDP) == RTP_ATTRIBUTE_SENDONLY) { Log.LogInformation("Remote call party has placed us on hold."); _holdStatus = HoldStatus.RemotePutOnHold; _ourSDP = GetSDP(_ourRtpSocket.LocalEndPoint as IPEndPoint, RTP_ATTRIBUTE_RECVONLY); var okResponse = SIPTransport.GetResponse(reinviteRequest, SIPResponseStatusCodesEnum.Ok, null); okResponse.Header.ContentType = SDP.SDP_MIME_CONTENTTYPE; okResponse.Body = _ourSDP.ToString(); uasTransaction.SendFinalResponse(okResponse); } else if (GetRTPStatusAttribute(newSDP) == RTP_ATTRIBUTE_SENDRECV && _holdStatus != HoldStatus.None) { Log.LogInformation("Remote call party has taken us off hold."); _holdStatus = HoldStatus.None; _ourSDP = GetSDP(_ourRtpSocket.LocalEndPoint as IPEndPoint, RTP_ATTRIBUTE_SENDRECV); var okResponse = SIPTransport.GetResponse(reinviteRequest, SIPResponseStatusCodesEnum.Ok, null); okResponse.Header.ContentType = SDP.SDP_MIME_CONTENTTYPE; okResponse.Body = _ourSDP.ToString(); uasTransaction.SendFinalResponse(okResponse); } else { Log.LogWarning("Not sure what the remote call party wants us to do..."); // We'll just reply Ok and hope eveything is good. var okResponse = SIPTransport.GetResponse(reinviteRequest, SIPResponseStatusCodesEnum.Ok, null); okResponse.Header.ContentType = SDP.SDP_MIME_CONTENTTYPE; okResponse.Body = _ourSDP.ToString(); uasTransaction.SendFinalResponse(okResponse); } }
public void GotNotificationRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { try { Logger.Logger.Debug("SIPNotifierClient GotNotificationRequest for " + sipRequest.Method + " " + sipRequest.URI.ToString() + " " + sipRequest.Header.CSeq + "."); SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); m_sipTransport.SendResponse(okResponse); //logger.Debug(sipRequest.ToString()); if (sipRequest.Method == SIPMethodsEnum.NOTIFY && sipRequest.Header.CallId == m_subscribeCallID && sipRequest.Header.Event == m_sipEventPackage.ToString() && sipRequest.Body != null) { if (sipRequest.Header.CSeq <= m_remoteCSeq) { Logger.Logger.Warn( "A duplicate NOTIFY request received by SIPNotifierClient for subscription Call-ID " + m_subscribeCallID + "."); } else { //logger.Debug("New dialog info notification request received."); m_remoteCSeq = sipRequest.Header.CSeq; T sipEvent = new T(); sipEvent.Load(sipRequest.Body); NotificationReceived(sipEvent); } } else { Logger.Logger.Warn( "A request received by SIPNotifierClient did not match the subscription details, request Call-ID=" + sipRequest.Header.CallId + ", subscribed Call-ID=" + m_subscribeCallID + "."); Logger.Logger.Debug(sipRequest.ToString()); } } catch (Exception excp) { Logger.Logger.Error("Exception GotNotificationRequest. ->" + excp.Message); } }
public void Reject(SIPResponseStatusCodesEnum failureStatus, string reasonPhrase, string[] customHeaders) { try { if (m_uasTransaction.TransactionFinalResponse == null) { if ((int)failureStatus < 400) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "UAS Reject was passed an invalid response status of " + (int)failureStatus + ", ignoring.", m_owner)); } else { if (UASStateChanged != null) { UASStateChanged(this, failureStatus, reasonPhrase); } string failureReason = (!reasonPhrase.IsNullOrBlank()) ? " and " + reasonPhrase : null; Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "UAS call failed with a response status of " + (int)failureStatus + failureReason + ".", m_owner)); SIPResponse failureResponse = SIPTransport.GetResponse(m_uasTransaction.TransactionRequest, failureStatus, reasonPhrase); if (customHeaders != null && customHeaders.Length > 0) { foreach (string header in customHeaders) { failureResponse.Header.UnknownHeaders.Add(header); } } m_uasTransaction.SendFinalResponse(failureResponse); } } else { logger.Warn("SIPServerUserAgent Reject fired on already answered call."); } } catch (Exception excp) { logger.Error("Exception SIPServerUserAgent Reject. " + excp.Message); } }
public void Reject(SIPResponseStatusCodesEnum failureStatus, string reasonPhrase, string[] customHeaders) { try { if (m_uasTransaction.TransactionFinalResponse == null) { if ((int)failureStatus < 400) { } else { if (UASStateChanged != null) { UASStateChanged(this, failureStatus, reasonPhrase); } string failureReason = (!reasonPhrase.IsNullOrBlank()) ? " and " + reasonPhrase : null; SIPResponse failureResponse = SIPTransport.GetResponse(m_uasTransaction.TransactionRequest, failureStatus, reasonPhrase); if (customHeaders != null && customHeaders.Length > 0) { foreach (string header in customHeaders) { failureResponse.Header.UnknownHeaders.Add(header); } } m_uasTransaction.SendFinalResponse(failureResponse); } } else { Logger.Logger.Warn("SIPServerUserAgent Reject fired on already answered call."); } } catch (Exception excp) { Logger.Logger.Error("Exception SIPServerUserAgent Reject. ->" + excp.Message); } }
private void UASInviteTransaction_TransactionRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPRequest sipRequest) { try { if (TransactionState == SIPTransactionStatesEnum.Terminated) { Logger.Logger.Debug( "Request received by UASInviteTransaction for a terminated transaction, ignoring."); } else if (sipRequest.Method != SIPMethodsEnum.INVITE) { Logger.Logger.Warn("Unexpected " + sipRequest.Method + " passed to UASInviteTransaction."); } else { if (TransactionState != SIPTransactionStatesEnum.Trying) { SIPResponse tryingResponse = GetInfoResponse(m_transactionRequest, SIPResponseStatusCodesEnum.Trying); SendInformationalResponse(tryingResponse); } // Notify new call subscribers. if (NewCallReceived != null) { NewCallReceived(localSIPEndPoint, remoteEndPoint, this, sipRequest); } else { // Nobody wants the call so return an error response. SIPResponse declinedResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Decline, "Nothing listening"); SendFinalResponse(declinedResponse); } } } catch (Exception excp) { Logger.Logger.Error("Exception UASInviteTransaction GotRequest. " + excp.Message); } }
private SIPResponse GetOkResponse(SIPRequest sipRequest, string messageBody) { try { SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); okResponse.Header.UserAgent = m_sipProxyUserAgent; okResponse.Header.Contact = SIPContactHeader.ParseContactHeader(sipRequest.LocalSIPEndPoint.ToString()); okResponse.Body = messageBody; okResponse.Header.ContentType = "application/sdp"; okResponse.Header.ContentLength = messageBody.Length; return(okResponse); } catch (Exception excp) { logger.Error("Exception GetOkResponse. " + excp.Message); throw excp; } }
public void AnswerNonInvite(SIPResponseStatusCodesEnum answerStatus, string reasonPhrase, string[] customHeaders, string contentType, string body) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, m_transaction.TransactionRequest.Method + " request succeeded with a response status of " + (int)answerStatus + " " + reasonPhrase + ".", m_owner)); SIPResponse answerResponse = SIPTransport.GetResponse(m_transaction.TransactionRequest, answerStatus, reasonPhrase); if (customHeaders != null && customHeaders.Length > 0) { foreach (string header in customHeaders) { answerResponse.Header.UnknownHeaders.Add(header); } } if (!body.IsNullOrBlank()) { answerResponse.Header.ContentType = contentType; answerResponse.Body = body; } m_transaction.SendFinalResponse(answerResponse); }
public void AnswerNonInvite(SIPResponseStatusCodesEnum answerStatus, string reasonPhrase, string[] customHeaders, string contentType, string body) { SIPResponse answerResponse = SIPTransport.GetResponse(m_transaction.TransactionRequest, answerStatus, reasonPhrase); if (customHeaders != null && customHeaders.Length > 0) { foreach (string header in customHeaders) { answerResponse.Header.UnknownHeaders.Add(header); } } if (!body.IsNullOrBlank()) { answerResponse.Header.ContentType = contentType; answerResponse.Body = body; } m_transaction.SendFinalResponse(answerResponse); }
public void GotRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { try { if (sipRequest.Method == SIPMethodsEnum.NOTIFY) { if (sipRequest.Header.UnknownHeaders.Exists(s => s.Contains("Event: keep-alive"))) { // If this is a NOTIFY request that's being sent for NAT keep-alive purposes repond with Ok. SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); m_sipTransport.SendResponse(okResponse); } if (GetCanonicalDomain_External(sipRequest.URI.Host, true) != null && !sipRequest.URI.User.IsNullOrBlank()) { m_notifyManager.QueueNotification(sipRequest); } else { // Send Not Serviced response to server. SIPResponse notServicedResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotFound, "Domain not serviced"); m_sipTransport.SendResponse(notServicedResponse); } } else if (sipRequest.Method == SIPMethodsEnum.SUBSCRIBE) { m_notifierCore.AddSubscribeRequest(localSIPEndPoint, remoteEndPoint, sipRequest); } else { SIPResponse methodNotSupportedResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null); m_sipTransport.SendResponse(methodNotSupportedResponse); } } catch (Exception excp) { logger.Error("Exception SIPNotifierDaemon GotRequest. " + excp.Message); } }
static void Main() { Console.WriteLine("SIPSorcery Getting Started Demo"); var sipTransport = new SIPTransport(); EnableTraceLogs(sipTransport); var sipChannel = new SIPWebSocketChannel(IPAddress.Loopback, 80); var wssCertificate = new System.Security.Cryptography.X509Certificates.X509Certificate2("localhost.pfx"); var sipChannelSecure = new SIPWebSocketChannel(IPAddress.Loopback, 443, wssCertificate); sipTransport.AddSIPChannel(sipChannel); sipTransport.AddSIPChannel(sipChannelSecure); sipTransport.SIPTransportRequestReceived += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) => { Console.WriteLine($"Request received {localSIPEndPoint.ToString()}<-{remoteEndPoint.ToString()}: {sipRequest.StatusLine}"); if (sipRequest.Method == SIPMethodsEnum.OPTIONS | sipRequest.Method == SIPMethodsEnum.MESSAGE) { SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); sipTransport.SendResponse(okResponse); } else if (sipRequest.Method == SIPMethodsEnum.REGISTER) { SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); okResponse.Header.Contact = sipRequest.Header.Contact; sipTransport.SendResponse(okResponse); } }; Console.Write("press any key to exit..."); Console.Read(); sipTransport.Shutdown(); }
private void SIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { try { switch (sipRequest.Method) { case SIPMethodsEnum.OPTIONS: SIPNonInviteTransaction optionsTransaction = _sipTransport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null); SIPResponse optionsResponse = SipHelper.WG67ResponseNormalize( SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null)); optionsTransaction.SendFinalResponse(optionsResponse); OptionsReceived?.Invoke(remoteEndPoint.ToString()); break; case SIPMethodsEnum.SUBSCRIBE: m_sip_notifier.AddSubscribeRequest(localSIPEndPoint, remoteEndPoint, sipRequest); break; case SIPMethodsEnum.PUBLISH: default: throw new NotImplementedException(); } } catch (NotImplementedException) { _logger.From().Debug(sipRequest.Method + " request processing not implemented for " + sipRequest.URI.ToParameterlessString() + " from " + remoteEndPoint + "."); SIPNonInviteTransaction notImplTransaction = _sipTransport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null); SIPResponse notImplResponse = SipHelper.WG67ResponseNormalize(SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotImplemented, null)); notImplTransaction.SendFinalResponse(notImplResponse); } catch (Exception x) { _logger.From().Debug($"SIPTransportRequestReceived Exception {x.Message}", x); } }