/// <summary> /// This method is called when INVITE 2xx retransmit timer triggered. /// </summary> /// <param name="sender">Sender.</param> /// <param name="e">Event data.</param> private void m_pTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { /* RFC 3261 13.3.1.4. * Once the response has been constructed, it is passed to the INVITE * server transaction. Note, however, that the INVITE server * transaction will be destroyed as soon as it receives this final * response and passes it to the transport. Therefore, it is necessary * to periodically pass the response directly to the transport until the * ACK arrives. The 2xx response is passed to the transport with an * interval that starts at T1 seconds and doubles for each * retransmission until it reaches T2 seconds (T1 and T2 are defined in * Section 17). Response retransmissions cease when an ACK request for * the response is received. This is independent of whatever transport * protocols are used to send the response. * * Since 2xx is retransmitted end-to-end, there may be hops between * UAS and UAC that are UDP. To ensure reliable delivery across * these hops, the response is retransmitted periodically even if the * transport at the UAS is reliable. * * If the server retransmits the 2xx response for 64*T1 seconds without * receiving an ACK, the dialog is confirmed, but the session SHOULD be * terminated. This is accomplished with a BYE, as described in Section * 15. */ lock (m_pLock){ if (m_StartTime.AddMilliseconds(64 * SIP_TimerConstants.T1) < DateTime.Now) { // Log if (m_pDialog.Stack.Logger != null) { m_pDialog.Stack.Logger.AddText("Dialog [id='" + m_pDialog.ID + "'] ACK was not received for (re-)INVITE, terminating INVITE session."); } m_pDialog.Terminate("Dialog Error: ACK was not received for (re-)INVITE.", true); Dispose(); } else { // Retransmit response. try{ m_pDialog.Flow.Send(m_pResponse); // Log if (m_pDialog.Stack.Logger != null) { m_pDialog.Stack.Logger.AddText("Dialog [id='" + m_pDialog.ID + "';statusCode=" + m_pResponse.StatusCode + "] UAS 2xx response retransmited"); } } catch (Exception x) { // Log if (m_pDialog.Stack.Logger != null) { m_pDialog.Stack.Logger.AddText("Dialog [id='" + m_pDialog.ID + "'] UAS 2xx response retransmission failed: " + x.Message); } } m_pTimer.Interval = Math.Min(m_pTimer.Interval * 2, SIP_TimerConstants.T2); m_pTimer.Enabled = true; } } }