/// <summary> /// Default constructor. /// </summary> public Auth_HttpDigest_NonceManager() { m_pNonces = new List <NonceEntry>(); m_pTimer = new TimerEx(m_pTimer_Elapsed, 15000); m_pTimer.Start(); }
/// <summary> /// Starts DNS transaction processing. /// </summary> public void Start() { // Send parallel query to DNS server(s). foreach (string server in Dns_Client.DnsServers) { try{ if (Net_Utils.IsIPAddress(server)) { IPAddress ip = IPAddress.Parse(server); if (ip.AddressFamily == AddressFamily.InterNetwork) { m_pOwner.m_pIPv4Socket.SendTo(m_pQuery, new IPEndPoint(ip, 53)); } else if (ip.AddressFamily == AddressFamily.InterNetworkV6) { m_pOwner.m_pIPv6Socket.SendTo(m_pQuery, new IPEndPoint(ip, 53)); } } } catch { } } m_pTimeoutTimer.Start(); }
/// <summary> /// Starts SMTP relay server. /// </summary> /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception> public virtual void Start() { if (m_IsDisposed) { throw new ObjectDisposedException(this.GetType().Name); } if (m_IsRunning) { return; } m_IsRunning = true; m_pLocalEndPointIPv4 = new CircleCollection <IPBindInfo>(); m_pLocalEndPointIPv6 = new CircleCollection <IPBindInfo>(); m_pSessions = new TCP_SessionCollection <Relay_Session>(); m_pConnectionsPerIP = new Dictionary <IPAddress, long>(); Thread tr1 = new Thread(new ThreadStart(this.Run)); tr1.Start(); m_pTimerTimeout = new TimerEx(30000); m_pTimerTimeout.Elapsed += new System.Timers.ElapsedEventHandler(m_pTimerTimeout_Elapsed); m_pTimerTimeout.Start(); }
/// <summary> /// Default constructor. /// </summary> /// <param name="session">RTP multimedia session.</param> public wfrm_RTP_Debug(RTP_MultimediaSession session) { if (session == null) { throw new ArgumentNullException("session"); } m_pSession = session; InitUI(); // Windows must be visible, otherwise we may get "window handle not created" if RTP session rises events before window gets visible. this.Visible = true; m_pSession.Error += new EventHandler <LumiSoft.Net.ExceptionEventArgs>(m_pSession_Error); m_pSession.SessionCreated += new EventHandler <LumiSoft.Net.EventArgs <RTP_Session> >(m_pSession_SessionCreated); m_pSession.NewParticipant += new EventHandler <RTP_ParticipantEventArgs>(m_pSession_NewParticipant); m_pSession.LocalParticipant.SourceAdded += new EventHandler <RTP_SourceEventArgs>(Participant_SourceAdded); m_pSession.LocalParticipant.SourceRemoved += new EventHandler <RTP_SourceEventArgs>(Participant_SourceRemoved); //m_pSession.Disposed m_pTimer = new TimerEx(m_pTimer_Tick, 1000); m_pTimer.Start(); foreach (RTP_Session s in m_pSession.Sessions) { ComboBoxItem item = new ComboBoxItem("Session: " + s.GetHashCode(), new RTP_SessionStatistics(s)); m_pSessions.Items.Add(item); } if (m_pSessions.Items.Count > 0) { m_pSessions.SelectedIndex = 0; } }
/// <summary> /// Default constructor. /// </summary> internal DNS_ClientCache() { m_pCache = new Dictionary <string, CacheEntry>(); m_pTimerTimeout = new TimerEx(m_pTimerTimeout_Elapsed, 60000); m_pTimerTimeout.Start(); }
/// <summary> /// Starts transaction processing. /// </summary> private void Start() { #region INVITE if (this.Method == SIP_Methods.INVITE) { /* RFC 3261 17.2.1. * When a server transaction is constructed for a request, it enters the "Proceeding" state. The server * transaction MUST generate a 100 (Trying) response unless it knows that the TU will generate a provisional * or final response within 200 ms, in which case it MAY generate a 100 (Trying) response. */ SetState(SIP_TransactionState.Proceeding); m_pTimer100 = new TimerEx(m_pTimer100_Elapsed, 200, false); m_pTimer100.Start(); } #endregion #region Non-INVITE else { // RFC 3261 17.2.2. The state machine is initialized in the "Trying" state. SetState(SIP_TransactionState.Trying); } #endregion }
/// <summary> /// Default constructor. /// </summary> internal DNS_ClientCache() { m_pCache = new Dictionary<string,CacheEntry>(); m_pTimerTimeout = new TimerEx(60000); m_pTimerTimeout.Elapsed += new System.Timers.ElapsedEventHandler(m_pTimerTimeout_Elapsed); m_pTimerTimeout.Start(); }
/// <summary> /// Default constructor. /// </summary> internal DNS_ClientCache() { m_pCache = new Dictionary <string, CacheEntry>(); m_pTimerTimeout = new TimerEx(60000); m_pTimerTimeout.Elapsed += new System.Timers.ElapsedEventHandler(m_pTimerTimeout_Elapsed); m_pTimerTimeout.Start(); }
static void Main(string[] args) { TimerEx timer = new TimerEx(1000, 1, 2, 3, 4, 5); timer.ElapsedEx += new ElapsedExEventHandler(timer_ElapsedEx); timer.Start(); Console.ReadKey(); }
/// <summary> /// Starts DNS transaction processing. /// </summary> /// <exception cref="InvalidOperationException">Is raised when this method is called in invalid transaction state.</exception> public void Start() { if (this.State != DNS_ClientTransactionState.WaitingForStart) { throw new InvalidOperationException("DNS_ClientTransaction.Start may be called only in 'WaitingForStart' transaction state."); } SetState(DNS_ClientTransactionState.Active); // Move processing to thread pool. ThreadPool.QueueUserWorkItem(delegate(object state){ try{ // Use DNS cache if allowed. if (Dns_Client.UseDnsCache) { DnsServerResponse response = m_pOwner.Cache.GetFromCache(m_QName, (int)m_QType); if (response != null) { m_pResponse = response; SetState(DNS_ClientTransactionState.Completed); Dispose(); return; } } byte[] buffer = new byte[1400]; int count = CreateQuery(buffer, m_ID, m_QName, m_QType, 1); // Send parallel query to DNS server(s). foreach (string server in Dns_Client.DnsServers) { if (Net_Utils.IsIPAddress(server)) { IPAddress ip = IPAddress.Parse(server); m_pOwner.Send(ip, buffer, count); } } m_pTimeoutTimer.Start(); } catch { // Check if we have bad unicode qname. try{ System.Globalization.IdnMapping ldn = new System.Globalization.IdnMapping(); ldn.GetAscii(m_QName); } catch { m_pResponse = new DnsServerResponse(true, m_ID, DNS_RCode.NAME_ERROR, new List <DNS_rr>(), new List <DNS_rr>(), new List <DNS_rr>()); } SetState(DNS_ClientTransactionState.Completed); } }); }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); #region 写真をリスト化する CreatePhotoList(); #endregion #region 背景用のビットマップを作成、背景は黒で初期化 _baseBitmap = new Bitmap(Width, Height, PixelFormat.Format24bppRgb); _baseBitmap.Clear(Color.Black); #endregion #region 背景のスクロール用のタイマーを作成 _baseTimer = new TimerEx { Interval = ScrollInterval }; _baseTimer.Tick += BaseTimerOnTick; #endregion #region 写真を追加するタイマーを作成 _photoTimer = new TimerEx { Interval = PhotoInterval }; _photoTimer.Tick += PhotoTimerOnTick; #endregion #region 最初の写真を登録 // 写真を追加するタイマーの間隔が長いため、 // 先にイベントを呼び出し写真を登録しておく PhotoTimerOnTick(this, EventArgs.Empty); #endregion #region 背景のスクロール用のタイマーと、写真読み込み用のタイマーを起動する _baseTimer.Start(); _photoTimer.Start(); #endregion }
/// <summary> /// Default constructor. /// </summary> /// <param name="proxy">Owner proxy.</param> /// <exception cref="ArgumentNullException">Is raised when <b>proxy</b> is null reference.</exception> internal SIP_Registrar(SIP_Proxy proxy) { if (proxy == null) { throw new ArgumentNullException("proxy"); } m_pProxy = proxy; m_pStack = m_pProxy.Stack; m_pRegistrations = new SIP_RegistrationCollection(); m_pTimer = new TimerEx(m_pTimer_Elapsed, 15000); m_pTimer.Start(); }
public MemoryCache(int capacity = 100000) { if (capacity < 1000) { throw new ArgumentException($"Argument '{nameof(capacity)}' value must be >= 1000."); } MaxCapacity = capacity; ItemsByKey = new Dictionary <string, MemoryCacheItem>(capacity); First = Last = new MemoryCacheItem(); ClearTimer = new TimerEx(60 * 1000); ClearTimer.Elapsed += Clear_Elapsed; ClearTimer.Start(); }
/// <summary> /// 构造函数 /// </summary> /// <param name="currentNodeName">当前节点名称</param> public ProcessNamedPipe(string currentNodeName) { _mutex = new Mutex(true, currentNodeName, out var isSuccess); if (!isSuccess) { throw new ArgumentOutOfRangeException("currentNodeName", "指定名称的管道已被注册,无法重复注册"); } _pipName = currentNodeName; beginwaitForConnection(); _checkConnect = new TimerEx(checkServer, 5000, 0); _checkConnect.Start(); }
/// <summary> /// Is raised when INVITE timer G triggered. /// </summary> /// <param name="sender">Sender.</param> /// <param name="e">Event data.</param> private void m_pTimerG_Elapsed(object sender #if !NETSTANDARD , System.Timers.ElapsedEventArgs e #endif ) { /* RFC 3261 17.2.1. * If timer G fires, the response is passed to the transport layer once more for retransmission, and * timer G is set to fire in MIN(2*T1, T2) seconds. From then on, when timer G fires, the response is * passed to the transport again for transmission, and timer G is reset with a value that doubles, unless * that value exceeds T2, in which case it is reset with the value of T2. */ lock (this.SyncRoot){ if (this.State == SIP_TransactionState.Completed) { // Log if (this.Stack.Logger != null) { this.Stack.Logger.AddText(this.ID, "Transaction [branch='" + this.ID + "';method='" + this.Method + "';IsServer=true] timer G(INVITE response(3xx - 6xx) retransmission) triggered."); } try{ this.Stack.TransportLayer.SendResponse(this, this.FinalResponse); // Update(double current) next transmit time. m_pTimerG.Interval *= Math.Min(m_pTimerG.Interval * 2, SIP_TimerConstants.T2); m_pTimerG.Start(); // Log if (this.Stack.Logger != null) { this.Stack.Logger.AddText(this.ID, "Transaction [branch='" + this.ID + "';method='" + this.Method + "';IsServer=false] timer G(INVITE response(3xx - 6xx) retransmission) updated, will trigger after " + m_pTimerG.Interval + "."); } } catch (Exception x) { OnTransportError(x); SetState(SIP_TransactionState.Terminated); } } } }
/// <summary> /// Sends specified response to remote party. /// </summary> /// <param name="response">SIP response to send.</param> /// <exception cref="ObjectDisposedException">Is raised when this class is Disposed and this method is accessed.</exception> /// <exception cref="ArgumentNullException">Is raised when <b>response</b> is null reference.</exception> public void SendResponse(SIP_Response response) { lock (this.SyncRoot){ if (this.State == SIP_TransactionState.Disposed) { throw new ObjectDisposedException(this.GetType().Name); } if (response == null) { throw new ArgumentNullException("response"); } try{ #region INVITE /* RFC 6026 7.1. INVITE server transaction. (Udpates RFC 3261) * |INVITE |pass INV to TU * INVITE V send 100 if TU won't in 200 ms * send response+------------+ +--------| |--------+ 101-199 from TU | | | | send response +------->| |<-------+ | Proceeding | | |--------+ Transport Err. | | | Inform TU | |<-------+ +------------+ | 300-699 from TU | |2xx from TU | send response | |send response +--------------+ +------------+ | | | INVITE V Timer G fires | | send response +-----------+ send response | +--------| |--------+ | | | | | | +------->| Completed |<-------+ INVITE | Transport Err. | | - | Inform TU +--------| |----+ +-----+ | +---+ | +-----------+ | ACK | | v | v | ^ | | - | +------------+ | | | | | | |---+ ACK +----------+ | | +->| Accepted | | to TU | Transport Err. | | | |<--+ | Inform TU | V +------------+ | +-----------+ | ^ | | | | | | | | | Confirmed | | +-----+ | | | | 2xx from TU | Timer H fires | +-----------+ | send response | - | | | | | Timer I fires | | | - | Timer L fires | V | - | +------------+ | | | |<----+ +------->| Terminated | | | +------------+ | */ if (this.Method == SIP_Methods.INVITE) { #region Proceeding if (this.State == SIP_TransactionState.Proceeding) { AddResponse(response); // 1xx if (response.StatusCodeType == SIP_StatusCodeType.Provisional) { this.Stack.TransportLayer.SendResponse(this, response); OnResponseSent(response); } // 2xx else if (response.StatusCodeType == SIP_StatusCodeType.Success) { this.Stack.TransportLayer.SendResponse(this, response); OnResponseSent(response); SetState(SIP_TransactionState.Accpeted); /* RFC 6025 7.1. * When the "Accepted" state is entered, timer L MUST be set to fire in 64*T1. */ m_pTimerL = new TimerEx(m_pTimerL_Elapsed, 64 * SIP_TimerConstants.T1); m_pTimerL.Start(); // Log if (this.Stack.Logger != null) { this.Stack.Logger.AddText(this.ID, "Transaction [branch='" + this.ID + "';method='" + this.Method + "';IsServer=true] timer L(ACK wait) started, will trigger after " + m_pTimerL.Interval + "."); } } // 3xx - 6xx else { this.Stack.TransportLayer.SendResponse(this, response); OnResponseSent(response); SetState(SIP_TransactionState.Completed); /* RFC 3261 17.2.1. * For unreliable transports, timer G is set to fire in T1 seconds, and is not set to fire for reliable transports. */ if (!this.Flow.IsReliable) { m_pTimerG = new TimerEx(m_pTimerG_Elapsed, SIP_TimerConstants.T1, false); m_pTimerG.Start(); // Log if (this.Stack.Logger != null) { this.Stack.Logger.AddText(this.ID, "Transaction [branch='" + this.ID + "';method='" + this.Method + "';IsServer=true] timer G(INVITE response(3xx - 6xx) retransmission) started, will trigger after " + m_pTimerG.Interval + "."); } } /* RFC 3261 17.2.1. * When the "Completed" state is entered, timer H MUST be set to fire in 64*T1 seconds for all transports. */ m_pTimerH = new TimerEx(m_pTimerH_Elapsed, 64 * SIP_TimerConstants.T1); m_pTimerH.Start(); // Log if (this.Stack.Logger != null) { this.Stack.Logger.AddText(this.ID, "Transaction [branch='" + this.ID + "';method='" + this.Method + "';IsServer=true] timer H(INVITE ACK wait) started, will trigger after " + m_pTimerH.Interval + "."); } } } #endregion #region Accepted else if (this.State == SIP_TransactionState.Accpeted) { this.Stack.TransportLayer.SendResponse(this, response); OnResponseSent(response); } #endregion #region Completed else if (this.State == SIP_TransactionState.Completed) { // We do nothing here, we just wait ACK to arrive. } #endregion #region Confirmed else if (this.State == SIP_TransactionState.Confirmed) { // We do nothing, just wait ACK retransmissions. } #endregion #region Terminated else if (this.State == SIP_TransactionState.Terminated) { // We should never rreach here, but if so, skip it. } #endregion } #endregion #region Non-INVITE /* RFC 3261 17.2.2. |Request received |pass to TU * V +-----------+ | | | Trying |-------------+ | | | +-----------+ |200-699 from TU | |send response |1xx from TU | |send response | | | | Request V 1xx from TU | | send response+-----------+send response| +--------| |--------+ | | | Proceeding| | | +------->| |<-------+ | +<--------------| | | |Trnsprt Err +-----------+ | |Inform TU | | | | | | |200-699 from TU | | |send response | | Request V | | send response+-----------+ | | +--------| | | | | | Completed |<------------+ | +------->| | +<--------------| | |Trnsprt Err +-----------+ |Inform TU | | |Timer J fires | |- | | | V | +-----------+ | | | +-------------->| Terminated| | | +-----------+ */ else { #region Trying if (this.State == SIP_TransactionState.Trying) { AddResponse(response); // 1xx if (response.StatusCodeType == SIP_StatusCodeType.Provisional) { this.Stack.TransportLayer.SendResponse(this, response); OnResponseSent(response); SetState(SIP_TransactionState.Proceeding); } // 2xx - 6xx else { this.Stack.TransportLayer.SendResponse(this, response); OnResponseSent(response); SetState(SIP_TransactionState.Completed); /* RFC 3261 17.2.2. * When the server transaction enters the "Completed" state, it MUST set * Timer J to fire in 64*T1 seconds for unreliable transports, and zero * seconds for reliable transports. */ m_pTimerJ = new TimerEx(m_pTimerJ_Elapsed, 64 * SIP_TimerConstants.T1, false); m_pTimerJ.Start(); // Log if (this.Stack.Logger != null) { this.Stack.Logger.AddText(this.ID, "Transaction [branch='" + this.ID + "';method='" + this.Method + "';IsServer=true] timer J(Non-INVITE request retransmission wait) started, will trigger after " + m_pTimerJ.Interval + "."); } } } #endregion #region Proceeding else if (this.State == SIP_TransactionState.Proceeding) { AddResponse(response); // 1xx if (response.StatusCodeType == SIP_StatusCodeType.Provisional) { this.Stack.TransportLayer.SendResponse(this, response); OnResponseSent(response); } // 2xx - 6xx else { this.Stack.TransportLayer.SendResponse(this, response); OnResponseSent(response); SetState(SIP_TransactionState.Completed); /* RFC 3261 17.2.2. * When the server transaction enters the "Completed" state, it MUST set * Timer J to fire in 64*T1 seconds for unreliable transports, and zero * seconds for reliable transports. */ m_pTimerJ = new TimerEx(m_pTimerJ_Elapsed, 64 * SIP_TimerConstants.T1, false); m_pTimerJ.Start(); // Log if (this.Stack.Logger != null) { this.Stack.Logger.AddText(this.ID, "Transaction [branch='" + this.ID + "';method='" + this.Method + "';IsServer=true] timer J(Non-INVITE request retransmission wait) started, will trigger after " + m_pTimerJ.Interval + "."); } } } #endregion #region Completed else if (this.State == SIP_TransactionState.Completed) { // Do nothing. } #endregion #region Terminated else if (this.State == SIP_TransactionState.Terminated) { // Do nothing. } #endregion } #endregion } catch (SIP_TransportException x) { // Log if (this.Stack.Logger != null) { this.Stack.Logger.AddText(this.ID, "Transaction [branch='" + this.ID + "';method='" + this.Method + "';IsServer=true] transport exception: " + x.Message); } OnTransportError(x); } } }
/// <summary> /// This method is called when REGISTER has finished. /// </summary> /// <param name="sender">Sender.</param> /// <param name="e">Event data.</param> private void m_pRegisterSender_ResponseReceived(object sender, SIP_ResponseReceivedEventArgs e) { m_pFlow = e.ClientTransaction.Flow; if (e.Response.StatusCodeType == SIP_StatusCodeType.Provisional) { return; } else if (e.Response.StatusCodeType == SIP_StatusCodeType.Success) { m_pContacts.Clear(); foreach (SIP_t_ContactParam c in e.Response.Contact.GetAllValues()) { m_pContacts.Add(c.Address.Uri); } SetState(SIP_UA_RegistrationState.Registered); OnRegistered(); m_pFlow.SendKeepAlives = true; } else { SetState(SIP_UA_RegistrationState.Error); OnError(e); } // REMOVE ME: if (this.AutoFixContact && (m_pContact is SIP_Uri)) { // If Via: received or rport paramter won't match to our sent-by, use received and rport to construct new contact value. SIP_Uri cContact = ((SIP_Uri)m_pContact); IPAddress cContactIP = Net_Utils.IsIPAddress(cContact.Host) ? IPAddress.Parse(cContact.Host) : null; SIP_t_ViaParm via = e.Response.Via.GetTopMostValue(); if (via != null && cContactIP != null) { IPEndPoint ep = new IPEndPoint(via.Received != null ? via.Received : cContactIP, via.RPort > 0 ? via.RPort : cContact.Port); if (!cContactIP.Equals(ep.Address) || cContact.Port != via.RPort) { // Unregister old contact. BeginUnregister(false); // Fix contact. cContact.Host = ep.Address.ToString(); cContact.Port = ep.Port; m_pRegisterSender.Dispose(); m_pRegisterSender = null; BeginRegister(m_AutoRefresh); return; } } } if (m_AutoRefresh) { // Set registration refresh timer. m_pTimer.Start(); } m_pRegisterSender.Dispose(); m_pRegisterSender = null; }
public void Start() { _timer.Start(); }
/// <summary> /// Processes specified request through this transaction. /// </summary> /// <param name="flow">SIP data flow.</param> /// <param name="request">SIP request.</param> /// <exception cref="ArgumentNullException">Is raised when <b>flow</b> or <b>request</b> is null reference.</exception> internal void ProcessRequest(SIP_Flow flow, SIP_Request request) { if (flow == null) { throw new ArgumentNullException("flow"); } if (request == null) { throw new ArgumentNullException("request"); } lock (this.SyncRoot){ if (this.State == SIP_TransactionState.Disposed) { return; } try{ // Log if (this.Stack.Logger != null) { byte[] requestData = request.ToByteData(); this.Stack.Logger.AddRead( Guid.NewGuid().ToString(), null, 0, "Request [transactionID='" + this.ID + "'; method='" + request.RequestLine.Method + "'; cseq='" + request.CSeq.SequenceNumber + "'; " + "transport='" + flow.Transport + "'; size='" + requestData.Length + "'; received '" + flow.LocalEP + "' <- '" + flow.RemoteEP + "'.", flow.LocalEP, flow.RemoteEP, requestData ); } #region INVITE if (this.Method == SIP_Methods.INVITE) { #region INVITE if (request.RequestLine.Method == SIP_Methods.INVITE) { if (this.State == SIP_TransactionState.Proceeding) { /* RFC 3261 17.2.1. * If a request retransmission is received while in the "Proceeding" state, the most recent provisional * response that was received from the TU MUST be passed to the transport layer for retransmission. */ SIP_Response response = this.LastProvisionalResponse; if (response != null) { this.Stack.TransportLayer.SendResponse(this, response); } } else if (this.State == SIP_TransactionState.Completed) { /* RFC 3261 17.2.1. * While in the "Completed" state, if a request retransmission is received, the server SHOULD * pass the response to the transport for retransmission. */ this.Stack.TransportLayer.SendResponse(this, this.FinalResponse); } } #endregion #region ACK else if (request.RequestLine.Method == SIP_Methods.ACK) { #region Accepeted if (this.State == SIP_TransactionState.Accpeted) { } #endregion #region Completed else if (this.State == SIP_TransactionState.Completed) { /* RFC 3261 17.2.1 * If an ACK is received while the server transaction is in the "Completed" state, the server transaction * MUST transition to the "Confirmed" state. As Timer G is ignored in this state, any retransmissions of the * response will cease. * * When this state is entered, timer I is set to fire in T4 seconds for unreliable transports, * and zero seconds for reliable transports. */ SetState(SIP_TransactionState.Confirmed); // Stop timers G,H if (m_pTimerG != null) { m_pTimerG.Dispose(); m_pTimerG = null; // Log if (this.Stack.Logger != null) { this.Stack.Logger.AddText(this.ID, "Transaction [branch='" + this.ID + "';method='" + this.Method + "';IsServer=true] timer G(INVITE response(3xx - 6xx) retransmission) stopped."); } } if (m_pTimerH != null) { m_pTimerH.Dispose(); m_pTimerH = null; // Log if (this.Stack.Logger != null) { this.Stack.Logger.AddText(this.ID, "Transaction [branch='" + this.ID + "';method='" + this.Method + "';IsServer=true] timer H(INVITE ACK wait) stopped."); } } // Start timer I. m_pTimerI = new TimerEx(m_pTimerI_Elapsed, (flow.IsReliable ? 0 : SIP_TimerConstants.T4), false); // Log if (this.Stack.Logger != null) { this.Stack.Logger.AddText(this.ID, "Transaction [branch='" + this.ID + "';method='" + this.Method + "';IsServer=true] timer I(INVITE ACK retransission wait) started, will trigger after " + m_pTimerI.Interval + "."); } m_pTimerI.Start(); } #endregion } #endregion } #endregion #region Non-INVITE else { // Non-INVITE transaction may have only request retransmission requests. if (this.Method == request.RequestLine.Method) { if (this.State == SIP_TransactionState.Proceeding) { /* RFC 3261 17.2.2. * If a retransmission of the request is received while in the "Proceeding" state, the most * recently sent provisional response MUST be passed to the transport layer for retransmission. */ this.Stack.TransportLayer.SendResponse(this, this.LastProvisionalResponse); } else if (this.State == SIP_TransactionState.Completed) { /* RFC 3261 17.2.2. * While in the "Completed" state, the server transaction MUST pass the final response to the transport * layer for retransmission whenever a retransmission of the request is received. */ this.Stack.TransportLayer.SendResponse(this, this.FinalResponse); } } } #endregion } catch (SIP_TransportException x) { // Log if (this.Stack.Logger != null) { this.Stack.Logger.AddText(this.ID, "Transaction [branch='" + this.ID + "';method='" + this.Method + "';IsServer=true] transport exception: " + x.Message); } OnTransportError(x); } } }
public DefaultMPMessageCache() { _timer = new TimerEx(check, 60 * 1000); _timer.Start(); }