/// <summary> /// Builds the REFER request to initiate an attended transfer on an established call. /// </summary> /// <param name="target">A target dialogue representing the Transferee.</param> /// <returns>A SIP REFER request.</returns> private SIPRequest GetReferRequest(SIPDialogue target) { SIPRequest referRequest = Dialogue.GetInDialogRequest(SIPMethodsEnum.REFER); SIPURI targetUri = target.RemoteTarget.CopyOf(); referRequest.Header.Contact = new List <SIPContactHeader> { SIPContactHeader.GetDefaultSIPContactHeader() }; SIPParameters replacesHeaders = new SIPParameters(); if (target.Direction == SIPCallDirection.Out) { replacesHeaders.Set("Replaces", SIPEscape.SIPURIParameterEscape($"{target.CallId};to-tag={target.RemoteTag};from-tag={target.LocalTag}")); var from = new SIPUserField(target.LocalUserField.Name, target.LocalUserField.URI.CopyOf(), null); referRequest.Header.ReferredBy = from.ToString(); } else { replacesHeaders.Set("Replaces", SIPEscape.SIPURIParameterEscape($"{target.CallId};to-tag={target.RemoteTag};from-tag={target.LocalTag}")); var from = new SIPUserField(target.RemoteUserField.Name, target.RemoteUserField.URI.CopyOf(), null); referRequest.Header.ReferredBy = from.ToString(); } targetUri.Headers = replacesHeaders; var referTo = new SIPUserField(null, targetUri, null); referRequest.Header.ReferTo = referTo.ToString(); return(referRequest); }
public SIPResponse GetOkResponse(string contentType, string messageBody) { SIPResponse okResponse = new SIPResponse(SIPResponseStatusCodesEnum.Ok, null); okResponse.SetSendFromHints(TransactionRequest.LocalSIPEndPoint); SIPHeader requestHeader = TransactionRequest.Header; okResponse.Header = new SIPHeader( SIPContactHeader.GetDefaultSIPContactHeader(TransactionRequest.URI.Scheme), requestHeader.From, requestHeader.To, requestHeader.CSeq, requestHeader.CallId); okResponse.Header.To.ToTag = m_localTag; okResponse.Header.CSeqMethod = requestHeader.CSeqMethod; okResponse.Header.Vias = requestHeader.Vias; okResponse.Header.Server = SIPConstants.SipUserAgentVersionString; okResponse.Header.MaxForwards = Int32.MinValue; okResponse.Header.RecordRoutes = requestHeader.RecordRoutes; okResponse.Header.Supported = SIPExtensionHeaders.REPLACES + ", " + SIPExtensionHeaders.NO_REFER_SUB + ((PrackSupported == true) ? ", " + SIPExtensionHeaders.PRACK : ""); okResponse.Body = messageBody; okResponse.Header.ContentType = contentType; okResponse.Header.ContentLength = (messageBody != null) ? messageBody.Length : 0; return(okResponse); }
public SIPResponse GetOkResponse(string contentType, string messageBody) { try { SIPResponse okResponse = new SIPResponse(SIPResponseStatusCodesEnum.Ok, null); okResponse.SetSendFromHints(TransactionRequest.LocalSIPEndPoint); SIPHeader requestHeader = TransactionRequest.Header; okResponse.Header = new SIPHeader(SIPContactHeader.GetDefaultSIPContactHeader(), requestHeader.From, requestHeader.To, requestHeader.CSeq, requestHeader.CallId); okResponse.Header.To.ToTag = m_localTag; okResponse.Header.CSeqMethod = requestHeader.CSeqMethod; okResponse.Header.Vias = requestHeader.Vias; okResponse.Header.Server = m_sipServerAgent; okResponse.Header.MaxForwards = Int32.MinValue; okResponse.Header.RecordRoutes = requestHeader.RecordRoutes; okResponse.Header.Supported = (PrackSupported == true) ? SIPExtensionHeaders.PRACK : null; okResponse.Body = messageBody; okResponse.Header.ContentType = contentType; okResponse.Header.ContentLength = (messageBody != null) ? messageBody.Length : 0; return(okResponse); } catch (Exception excp) { logger.LogError("Exception GetOkResponse. " + excp.Message); throw excp; } }
/// <summary> /// Builds the REFER request to transfer an established call. /// </summary> /// <param name="sipDialogue">A SIP dialogue object representing the established call.</param> /// <param name="referToUri">The SIP URI to transfer the call to.</param> /// <returns>A SIP REFER request.</returns> private static SIPRequest GetReferRequest(SIPClientUserAgent uac, SIPURI referToUri) { SIPDialogue sipDialogue = uac.SIPDialogue; SIPRequest referRequest = new SIPRequest(SIPMethodsEnum.REFER, sipDialogue.RemoteTarget); referRequest.SetSendFromHints(uac.ServerTransaction.TransactionRequest.LocalSIPEndPoint); SIPFromHeader referFromHeader = SIPFromHeader.ParseFromHeader(sipDialogue.LocalUserField.ToString()); SIPToHeader referToHeader = SIPToHeader.ParseToHeader(sipDialogue.RemoteUserField.ToString()); int cseq = sipDialogue.CSeq + 1; sipDialogue.CSeq++; SIPHeader referHeader = new SIPHeader(referFromHeader, referToHeader, cseq, sipDialogue.CallId); referHeader.CSeqMethod = SIPMethodsEnum.REFER; referRequest.Header = referHeader; referRequest.Header.Routes = sipDialogue.RouteSet; referRequest.Header.ProxySendFrom = sipDialogue.ProxySendFrom; referRequest.Header.Vias.PushViaHeader(SIPViaHeader.GetDefaultSIPViaHeader()); referRequest.Header.ReferTo = referToUri.ToString(); referRequest.Header.Contact = new List <SIPContactHeader>() { SIPContactHeader.GetDefaultSIPContactHeader() }; return(referRequest); }
private SIPRequest GetDummyINVITERequest(SIPURI dummyURI) { string dummyFrom = "<sip:[email protected]>"; SIPRequest inviteRequest = new SIPRequest(SIPMethodsEnum.INVITE, dummyURI); SIPHeader inviteHeader = new SIPHeader(SIPFromHeader.ParseFromHeader(dummyFrom), new SIPToHeader(null, dummyURI, null), 1, CallProperties.CreateNewCallId()); inviteHeader.From.FromTag = CallProperties.CreateNewTag(); inviteHeader.Contact = new List <SIPContactHeader> { SIPContactHeader.GetDefaultSIPContactHeader() }; inviteHeader.CSeqMethod = SIPMethodsEnum.INVITE; inviteHeader.UserAgent = "unittest"; inviteRequest.Header = inviteHeader; SIPViaHeader viaHeader = SIPViaHeader.GetDefaultSIPViaHeader(); inviteRequest.Header.Vias.PushViaHeader(viaHeader); inviteRequest.Body = "dummy"; inviteRequest.Header.ContentLength = inviteRequest.Body.Length; inviteRequest.Header.ContentType = "application/sdp"; return(inviteRequest); }
/// <summary> /// Builds the REFER request to initiate a blind transfer on an established call. /// </summary> /// <param name="referToUri">The SIP URI to transfer the call to.</param> /// <returns>A SIP REFER request.</returns> private SIPRequest GetReferRequest(SIPURI referToUri) { SIPRequest referRequest = Dialogue.GetInDialogRequest(SIPMethodsEnum.REFER); referRequest.Header.ReferTo = referToUri.ToString(); referRequest.Header.Supported = SIPExtensionHeaders.NO_REFER_SUB; referRequest.Header.Contact = new List <SIPContactHeader> { SIPContactHeader.GetDefaultSIPContactHeader() }; return(referRequest); }
/// <summary> /// Sends a re-INVITE request to the remote call party with the supplied SDP. /// </summary> private void SendReInviteRequest(SDP sdp) { if (Dialogue == null) { logger.LogWarning("No dialog available, re-INVITE request cannot be sent."); } else { Dialogue.SDP = sdp.ToString(); var reinviteRequest = Dialogue.GetInDialogRequest(SIPMethodsEnum.INVITE); reinviteRequest.Header.UserAgent = m_userAgent; reinviteRequest.Header.ContentType = m_sdpContentType; reinviteRequest.Body = sdp.ToString(); reinviteRequest.Header.Supported = SIPExtensionHeaders.PRACK; if (m_uac != null) { reinviteRequest.Header.Contact = m_uac.ServerTransaction.TransactionRequest.Header.Contact; reinviteRequest.SetSendFromHints(m_uac.ServerTransaction.TransactionRequest.LocalSIPEndPoint); } else if (m_uas != null) { reinviteRequest.Header.Contact = m_uas.ClientTransaction.TransactionFinalResponse.Header.Contact; reinviteRequest.SetSendFromHints(m_uas.ClientTransaction.TransactionFinalResponse.LocalSIPEndPoint); } else { reinviteRequest.Header.Contact = new List <SIPContactHeader>() { SIPContactHeader.GetDefaultSIPContactHeader() }; } UACInviteTransaction reinviteTransaction = new UACInviteTransaction(m_transport, reinviteRequest, m_outboundProxy); reinviteTransaction.SendInviteRequest(); reinviteTransaction.UACInviteTransactionFinalResponseReceived += ReinviteRequestFinalResponseReceived; } }
/// <summary> /// Initiates a SUBSCRIBE request to a notification server. /// </summary> /// <param name="subscribeURI">The SIP user that dialog notifications are being subscribed to.</param> public void Subscribe(SIPURI subscribeURI, int expiry, SIPEventPackagesEnum sipEventPackage, string subscribeCallID, SIPURI contactURI) { try { if (m_attempts >= MAX_SUBSCRIBE_ATTEMPTS) { logger.LogWarning($"Subscription to {subscribeURI} reached the maximum number of allowed attempts without a failure condition."); m_subscribed = false; SubscriptionFailed?.Invoke(subscribeURI, SIPResponseStatusCodesEnum.InternalServerError, "Subscription reached the maximum number of allowed attempts."); m_waitForSubscribeResponse.Set(); } else { m_attempts++; m_localCSeq++; SIPRequest subscribeRequest = SIPRequest.GetRequest( SIPMethodsEnum.SUBSCRIBE, m_resourceURI, new SIPToHeader(null, subscribeURI, m_subscriptionToTag), new SIPFromHeader(null, new SIPURI(m_authUsername, m_authDomain, null, m_resourceURI.Scheme, SIPProtocolsEnum.udp), m_subscriptionFromTag)); if (contactURI != null) { subscribeRequest.Header.Contact = new List <SIPContactHeader>() { new SIPContactHeader(null, contactURI) }; } else { subscribeRequest.Header.Contact = new List <SIPContactHeader>() { SIPContactHeader.GetDefaultSIPContactHeader(subscribeRequest.URI.Scheme) }; } subscribeRequest.Header.CSeq = m_localCSeq; subscribeRequest.Header.Expires = expiry; subscribeRequest.Header.Event = SIPEventPackageType.GetEventHeader(sipEventPackage); 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 = new SIPNonInviteTransaction(m_sipTransport, subscribeRequest, m_outboundProxy); subscribeTransaction.NonInviteTransactionFinalResponseReceived += SubscribeTransactionFinalResponseReceived; subscribeTransaction.NonInviteTransactionFailed += SubscribeTransactionFailed; LastSubscribeAttempt = DateTime.Now; subscribeTransaction.SendRequest(); } } catch (Exception excp) { logger.LogError("Exception SIPNotifierClient Subscribe. " + excp.Message); SubscriptionFailed?.Invoke(m_resourceURI, SIPResponseStatusCodesEnum.InternalServerError, "Exception Subscribing. " + excp.Message); m_waitForSubscribeResponse.Set(); } }
private SIPRequest GetInviteRequest(SIPCallDescriptor sipCallDescriptor, string branchId, string callId, SIPRouteSet routeSet, string content, string contentType) { SIPRequest inviteRequest = new SIPRequest(SIPMethodsEnum.INVITE, sipCallDescriptor.Uri); SIPHeader inviteHeader = new SIPHeader(sipCallDescriptor.GetFromHeader(), SIPToHeader.ParseToHeader(sipCallDescriptor.To), 1, callId); inviteHeader.From.FromTag = CallProperties.CreateNewTag(); inviteHeader.Contact = new List <SIPContactHeader>() { SIPContactHeader.GetDefaultSIPContactHeader(inviteRequest.URI.Scheme) }; inviteHeader.Contact[0].ContactURI.User = sipCallDescriptor.Username; inviteHeader.CSeqMethod = SIPMethodsEnum.INVITE; inviteHeader.UserAgent = SIPConstants.SipUserAgentVersionString; inviteHeader.Routes = routeSet; inviteHeader.Supported = SIPExtensionHeaders.REPLACES + ", " + SIPExtensionHeaders.NO_REFER_SUB + ((PrackSupported == true) ? ", " + SIPExtensionHeaders.PRACK : ""); inviteRequest.Header = inviteHeader; if (!sipCallDescriptor.ProxySendFrom.IsNullOrBlank()) { inviteHeader.ProxySendFrom = sipCallDescriptor.ProxySendFrom; } SIPViaHeader viaHeader = new SIPViaHeader(new IPEndPoint(IPAddress.Any, 0), branchId); inviteRequest.Header.Vias.PushViaHeader(viaHeader); inviteRequest.Body = content; inviteRequest.Header.ContentLength = (inviteRequest.Body != null) ? inviteRequest.Body.Length : 0; inviteRequest.Header.ContentType = contentType; try { if (sipCallDescriptor.CustomHeaders != null && sipCallDescriptor.CustomHeaders.Count > 0) { foreach (string customHeader in sipCallDescriptor.CustomHeaders) { if (customHeader.IsNullOrBlank()) { continue; } else if (customHeader.Trim().StartsWith(SIPHeaders.SIP_HEADER_USERAGENT)) { inviteRequest.Header.UserAgent = customHeader.Substring(customHeader.IndexOf(":") + 1).Trim(); } else if (customHeader.Trim().StartsWith(SIPHeaders.SIP_HEADER_TO + ":")) { var customToHeader = SIPUserField.ParseSIPUserField(customHeader.Substring(customHeader.IndexOf(":") + 1).Trim()); if (customToHeader != null) { inviteRequest.Header.To.ToUserField = customToHeader; } } else { inviteRequest.Header.UnknownHeaders.Add(customHeader); } } } } catch (Exception excp) { logger.LogError("Exception Parsing CustomHeader for GetInviteRequest. " + excp.Message + sipCallDescriptor.CustomHeaders); } if (AdjustInvite != null) { inviteRequest = AdjustInvite(inviteRequest); } return(inviteRequest); }
/// <summary> /// Because this is a server user agent the SIP transport must start listening for client user agents. /// </summary> private async Task OnRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { try { var banResult = _sipFail2Ban.IsBanned(remoteEndPoint); if (banResult == BanReasonsEnum.None) { if (sipRequest.Header.From != null && sipRequest.Header.From.FromTag != null && sipRequest.Header.To != null && sipRequest.Header.To.ToTag != null) { _sipCallManager.ProcessInDialogueRequest(localSIPEndPoint, remoteEndPoint, sipRequest); } else { switch (sipRequest.Method) { case SIPMethodsEnum.BYE: case SIPMethodsEnum.CANCEL: // BYE's and CANCEL's should always have dialog fields set. SIPResponse badResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.BadRequest, null); await _sipTransport.SendResponseAsync(badResponse); break; case SIPMethodsEnum.INVITE: if (!await WasRejected(sipRequest)) { _logger.LogInformation($"Incoming call request: {localSIPEndPoint}<-{remoteEndPoint} {sipRequest.URI}."); _b2bUserAgentCore.AddInviteRequest(sipRequest); } break; case SIPMethodsEnum.OPTIONS: SIPResponse optionsResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); optionsResponse.Header.Contact = new List <SIPContactHeader> { SIPContactHeader.GetDefaultSIPContactHeader(sipRequest.URI.Scheme) }; optionsResponse.Header.Server = SIPConstants.SIP_USERAGENT_STRING; await _sipTransport.SendResponseAsync(optionsResponse); break; case SIPMethodsEnum.REGISTER: if (!await WasRejected(sipRequest)) { _registrarCore.AddRegisterRequest(localSIPEndPoint, remoteEndPoint, sipRequest); } break; case SIPMethodsEnum.SUBSCRIBE: if (!await WasRejected(sipRequest)) { _subscriberCore.AddSubscribeRequest(localSIPEndPoint, remoteEndPoint, sipRequest); } break; default: var notAllowedResp = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null); await _sipTransport.SendResponseAsync(notAllowedResp); break; } } } else { _logger.LogWarning($"Ban list hit for {remoteEndPoint} and {banResult} dropped request {sipRequest.StatusLine}, user agent {sipRequest.Header.UserAgent}."); } } catch (Exception reqExcp) { _logger.LogWarning($"Exception handling {sipRequest.Method}. {reqExcp.Message}"); } }