public void Process(IRequest request) { // Once in the "Trying" state, any further request // retransmissions are discarded. if (State == TransactionState.Trying) { return; } if (State == TransactionState.Proceeding) { _transport.Send(_response); } }
/// <summary> /// Initializes a new instance of the <see cref="ClientInviteTransaction"/> class. /// </summary> /// <param name="transport">Transport layer used to send stuff.</param> /// <param name="request">Request that will be sent immidiately by the transaction.</param> public ClientInviteTransaction(ITransportLayer transport, IRequest request) { _transport = transport; if (request.Method != "INVITE") { throw new SipSharpException("Can only be used with invite transactions."); } State = TransactionState.Calling; _transport.Send(request); _request = request; // If an unreliable transport is being used, the client transaction MUST // start timer A with a value of T1. If a reliable transport is being used, // the client transaction SHOULD NOT start timer A if (!request.IsReliableProtocol) { _timerAValue = TransactionManager.T1; _timerA = new Timer(OnRetransmission, null, _timerAValue, Timeout.Infinite); } else { _timerDValue = 0; } // For any transport, the client transaction MUST start timer B with a value of 64*T1 seconds _timerB = new Timer(OnTimeout, null, TransactionManager.T1 * 64, Timeout.Infinite); _timerD = new Timer(OnTerminate, null, _timerDValue, Timeout.Infinite); }
private void OnRetransmission(object state) { /* If Timer E fires while in the "Proceeding" state, the request MUST be * passed to the transport layer for retransmission, and Timer E MUST be * reset with a value of T2 seconds. */ _timerEValue = Math.Min(_timerEValue * 2, TransactionManager.T2); _timerE.Change(_timerEValue, Timeout.Infinite); _transport.Send(Request); }
private void OnRetransmission(object state) { /* RFC 3261 17.1.1.2. * When timer A fires, the client transaction MUST retransmit the request by passing * it to the transport layer, and MUST reset the timer with a value of 2*T1. * * These retransmissions SHOULD only be done while the client * transaction is in the "calling" state. * * The formal definition of retransmit within the context of the transaction layer is to take the message * previously sent to the transport layer and pass it to the transport * layer once more. */ if (State != TransactionState.Calling) { return; } _timerAValue *= 2; _timerA.Change(_timerAValue, Timeout.Infinite); _transport.Send(_request); }
/// <summary> /// Initializes a new instance of the <see cref="ClientNonInviteTransaction"/> class. /// </summary> /// <param name="transport">Used to transport messages.</param> /// <param name="message">Request to process.</param> public ClientNonInviteTransaction(ITransportLayer transport, IMessage message) { _transport = transport; if (!(message is IRequest)) { throw new SipSharpException("Client transaction can only be created with requests"); } IRequest request = (Request) message; if (request.Method == "INVITE") throw new SipSharpException("Use ClientInviteTransaction for invite requests."); State = TransactionState.Trying; _timerF = new Timer(OnTimeout, null, TransactionManager.T1*64, Timeout.Infinite); if (!request.IsReliableProtocol) { _timerEValue = TransactionManager.T1; _timerE = new Timer(OnRetransmission, null, _timerEValue, Timeout.Infinite); } _transport.Send(request); }
/// <summary> /// Initializes a new instance of the <see cref="ClientInviteTransaction"/> class. /// </summary> /// <param name="transport">Transport layer used to send stuff.</param> /// <param name="request">Request that will be sent immidiately by the transaction.</param> public ClientInviteTransaction(ITransportLayer transport, IRequest request) { _transport = transport; if (request.Method != "INVITE") throw new SipSharpException("Can only be used with invite transactions."); State = TransactionState.Calling; _transport.Send(request); _request = request; // If an unreliable transport is being used, the client transaction MUST // start timer A with a value of T1. If a reliable transport is being used, // the client transaction SHOULD NOT start timer A if (!request.IsReliableProtocol) { _timerAValue = TransactionManager.T1; _timerA = new Timer(OnRetransmission, null, _timerAValue, Timeout.Infinite); } else _timerDValue = 0; // For any transport, the client transaction MUST start timer B with a value of 64*T1 seconds _timerB = new Timer(OnTimeout, null, TransactionManager.T1*64, Timeout.Infinite); _timerD = new Timer(OnTerminate, null, _timerDValue, Timeout.Infinite); }
/// <summary> /// Initializes a new instance of the <see cref="ClientNonInviteTransaction"/> class. /// </summary> /// <param name="transport">Used to transport messages.</param> /// <param name="message">Request to process.</param> public ClientNonInviteTransaction(ITransportLayer transport, IMessage message) { _transport = transport; if (!(message is IRequest)) { throw new SipSharpException("Client transaction can only be created with requests"); } IRequest request = (Request)message; if (request.Method == "INVITE") { throw new SipSharpException("Use ClientInviteTransaction for invite requests."); } State = TransactionState.Trying; _timerF = new Timer(OnTimeout, null, TransactionManager.T1 * 64, Timeout.Infinite); if (!request.IsReliableProtocol) { _timerEValue = TransactionManager.T1; _timerE = new Timer(OnRetransmission, null, _timerEValue, Timeout.Infinite); } _transport.Send(request); }
private void OnRetransmit(object state) { _timerGValue = Math.Min(_timerGValue * 2, TransactionManager.T2); _timerG.Change(_timerGValue, Timeout.Infinite); _transport.Send(_response); }