Пример #1
0
 internal void Failed(SocketError failureReason)
 {
     DeliveryPending = false;
     DeliveryFailed  = true;
     TransactionTraceMessage?.Invoke(this, $"Transaction failed {failureReason} {this.TransactionFinalResponse?.ShortDescription}");
     TransactionFailed?.Invoke(this, failureReason);
     UpdateTransactionState(SIPTransactionStatesEnum.Terminated);
 }
Пример #2
0
 /// <summary>
 /// Marks a transaction as expired and prevents any more delivery attempts of outstanding
 /// requests of responses.
 /// </summary>
 internal void Expire(DateTime now)
 {
     DeliveryPending = false;
     DeliveryFailed  = true;
     TimedOutAt      = now;
     HasTimedOut     = true;
     TransactionTraceMessage?.Invoke(this, $"Transaction failed due to a timeout {this.TransactionFinalResponse?.ShortDescription}");
     TransactionFailed?.Invoke(this, SocketError.TimedOut);
     UpdateTransactionState(SIPTransactionStatesEnum.Terminated);
 }
Пример #3
0
 private void FireTransactionTraceMessage(string message)
 {
     try
     {
         TransactionTraceMessage?.Invoke(this, message);
     }
     catch (Exception excp)
     {
         logger.LogError("Exception FireTransactionTraceMessage. " + excp.Message);
     }
 }
Пример #4
0
        protected void SendReliableRequest()
        {
            TransactionTraceMessage?.Invoke(this, $"Transaction send request reliable {TransactionRequest.StatusLine}");

            if (TransactionType == SIPTransactionTypesEnum.InviteClient && this.TransactionRequest.Method == SIPMethodsEnum.INVITE)
            {
                UpdateTransactionState(SIPTransactionStatesEnum.Calling);
            }

            m_sipTransport.AddTransaction(this);
        }
Пример #5
0
        public Task <SocketError> GotResponse(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPResponse sipResponse)
        {
            if (TransactionState == SIPTransactionStatesEnum.Completed || TransactionState == SIPTransactionStatesEnum.Confirmed)
            {
                TransactionTraceMessage?.Invoke(this, $"Transaction received duplicate response {localSIPEndPoint}<-{remoteEndPoint}: {sipResponse.ShortDescription}");
                TransactionDuplicateResponse?.Invoke(localSIPEndPoint, remoteEndPoint, this, sipResponse);

                if (sipResponse.Header.CSeqMethod == SIPMethodsEnum.INVITE)
                {
                    if (sipResponse.StatusCode > 100 && sipResponse.StatusCode <= 199)
                    {
                        return(ResendPrackRequest());
                    }
                    else
                    {
                        return(ResendAckRequest());
                    }
                }
                else
                {
                    return(Task.FromResult(SocketError.Success));
                }
            }
            else
            {
                TransactionTraceMessage?.Invoke(this, $"Transaction received Response {localSIPEndPoint}<-{remoteEndPoint}: {sipResponse.ShortDescription}");

                if (sipResponse.StatusCode >= 100 && sipResponse.StatusCode <= 199)
                {
                    UpdateTransactionState(SIPTransactionStatesEnum.Proceeding);
                    return(TransactionInformationResponseReceived(localSIPEndPoint, remoteEndPoint, this, sipResponse));
                }
                else
                {
                    m_transactionFinalResponse = sipResponse;

                    if (TransactionType == SIPTransactionTypesEnum.NonInvite)
                    {
                        // No ACK's for non-INVITE's so go straight to confirmed.
                        UpdateTransactionState(SIPTransactionStatesEnum.Confirmed);
                    }
                    else
                    {
                        UpdateTransactionState(SIPTransactionStatesEnum.Completed);
                    }

                    return(TransactionFinalResponseReceived(localSIPEndPoint, remoteEndPoint, this, sipResponse));
                }
            }
        }
Пример #6
0
        protected virtual Task <SocketError> SendProvisionalResponse(SIPResponse sipResponse)
        {
            TransactionTraceMessage?.Invoke(this, $"Transaction send info response (is reliable {PrackSupported}) {sipResponse.ShortDescription}");

            if (sipResponse.StatusCode == 100)
            {
                UpdateTransactionState(SIPTransactionStatesEnum.Trying);
                UnreliableProvisionalResponse = sipResponse;
                return(m_sipTransport.SendResponseAsync(sipResponse));
            }
            else if (sipResponse.StatusCode > 100 && sipResponse.StatusCode <= 199)
            {
                UpdateTransactionState(SIPTransactionStatesEnum.Proceeding);

                if (PrackSupported == true)
                {
                    if (RSeq == 0)
                    {
                        RSeq = Crypto.GetRandomInt(1, Int32.MaxValue / 2 - 1);
                    }
                    else
                    {
                        RSeq++;
                    }

                    sipResponse.Header.RSeq     = RSeq;
                    sipResponse.Header.Require += SIPExtensionHeaders.REPLACES + ", " + SIPExtensionHeaders.NO_REFER_SUB + ", " + SIPExtensionHeaders.PRACK;

                    // If reliable provisional responses are supported then need to send this response reliably.
                    if (ReliableProvisionalResponse != null)
                    {
                        logger.LogWarning("A new reliable provisional response is being sent but the previous one was not yet acknowledged.");
                    }

                    ReliableProvisionalResponse = sipResponse;
                    m_sipTransport.AddTransaction(this);
                    return(Task.FromResult(SocketError.Success));
                }
                else
                {
                    UnreliableProvisionalResponse = sipResponse;
                    return(m_sipTransport.SendResponseAsync(sipResponse));
                }
            }
            else
            {
                throw new ApplicationException("SIPTransaction.SendProvisionalResponse was passed a non-provisional response type.");
            }
        }
Пример #7
0
        protected void UpdateTransactionState(SIPTransactionStatesEnum transactionState)
        {
            m_transactionState = transactionState;

            if (transactionState == SIPTransactionStatesEnum.Confirmed ||
                transactionState == SIPTransactionStatesEnum.Terminated ||
                transactionState == SIPTransactionStatesEnum.Cancelled)
            {
                DeliveryPending = false;
            }
            else if (transactionState == SIPTransactionStatesEnum.Completed)
            {
                CompletedAt = DateTime.Now;
            }

            TransactionStateChanged?.Invoke(this);
            TransactionTraceMessage?.Invoke(this, $"Transaction state changed to {this.TransactionState}.");
        }
Пример #8
0
        protected virtual void SendFinalResponse(SIPResponse finalResponse)
        {
            m_transactionFinalResponse = finalResponse;

            if (TransactionState != SIPTransactionStatesEnum.Cancelled)
            {
                UpdateTransactionState(SIPTransactionStatesEnum.Completed);
            }

            // Reset transaction state variables to reset any provisional reliable responses.
            InitialTransmit = DateTime.MinValue;
            Retransmits     = 0;
            DeliveryPending = true;
            DeliveryFailed  = false;
            HasTimedOut     = false;

            TransactionTraceMessage?.Invoke(this, $"Transaction send final response {finalResponse.ShortDescription}");

            m_sipTransport.AddTransaction(this);
        }
Пример #9
0
 private void FireTransactionTraceMessage(string message)
 {
     TransactionTraceMessage?.Invoke(this, message);
 }
Пример #10
0
 public void OnTimedOutProvisionalResponse()
 {
     TransactionTraceMessage?.Invoke(this, $"Transaction provisional response delivery timed out {this.ReliableProvisionalResponse?.ShortDescription}");
 }
Пример #11
0
 public void OnRetransmitProvisionalResponse()
 {
     TransactionTraceMessage?.Invoke(this, $"Transaction send provisional response retransmit {Retransmits} {this.ReliableProvisionalResponse.ShortDescription}");
 }
Пример #12
0
 public void OnRetransmitFinalResponse()
 {
     TransactionTraceMessage?.Invoke(this, $"Transaction send response retransmit {Retransmits} {this.TransactionFinalResponse?.ShortDescription}");
 }
Пример #13
0
 internal void RequestRetransmit()
 {
     TransactionRequestRetransmit?.Invoke(this, this.TransactionRequest, this.Retransmits);;
     TransactionTraceMessage?.Invoke(this, $"Transaction send request retransmit {Retransmits} {this.TransactionRequest.StatusLine}");
 }
Пример #14
0
 public void GotRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
 {
     TransactionTraceMessage?.Invoke(this, $"Transaction received Request {localSIPEndPoint}<-{remoteEndPoint}: {sipRequest.StatusLine}");
     TransactionRequestReceived?.Invoke(localSIPEndPoint, remoteEndPoint, this, sipRequest);
 }