/// <summary> /// Cleans up any resources being used. /// </summary> public void Dispose() { if(m_State == SIP_StackState.Disposed){ return; } Stop(); m_State = SIP_StackState.Disposed; // TODO: "clean" clean up with disposing state, wait some time transaction/dialogs to die, block new ones. // TODO: Currently stack switched Disposed state before all transactions has disposed, so some active // transaction which accesses stack will get disposed exception. // Release events. this.RequestReceived = null; this.ResponseReceived = null; this.Error = null; if(m_pTransactionLayer != null){ m_pTransactionLayer.Dispose(); } if(m_pTransportLayer != null){ m_pTransportLayer.Dispose(); } if(m_pNonceManager != null){ m_pNonceManager.Dispose(); } if(m_pLogger != null){ m_pLogger.Dispose(); } }
/// <summary> /// Stops SIP stack. /// </summary> public void Stop() { if(m_State != SIP_StackState.Started){ return; } m_State = SIP_StackState.Stopping; /* Cleanup order: *) Unregister registrations. *) Terminate dialogs. *) Wait while all active transactions has terminated or timeout reaches. */ // Unregister registrations. foreach(SIP_UA_Registration reg in m_pRegistrations.ToArray()){ reg.BeginUnregister(true); } // Terminate dialogs. foreach(SIP_Dialog dialog in m_pTransactionLayer.Dialogs){ dialog.Terminate(); } // Wait while all active transactions has completed. DateTime start = DateTime.Now; while(true){ bool activeTransactions = false; foreach(SIP_Transaction tr in m_pTransactionLayer.Transactions){ // We have active transactions. if(tr.State == SIP_TransactionState.WaitingToStart || tr.State == SIP_TransactionState.Calling || tr.State == SIP_TransactionState.Proceeding || tr.State == SIP_TransactionState.Trying){ activeTransactions = true; break; } } if(activeTransactions){ System.Threading.Thread.Sleep(500); // Timeout. if(((TimeSpan)(DateTime.Now - start)).Seconds > 10){ break; } } else{ break; } } // REMOVE ME: Dispose Transaction layer instead. foreach(SIP_Transaction tr in m_pTransactionLayer.Transactions){ try{ tr.Dispose(); } catch{ } } m_pTransportLayer.Stop(); m_State = SIP_StackState.Stopped; }
/// <summary> /// Starts SIP stack. /// </summary> public void Start() { if(m_State == SIP_StackState.Started){ return; } m_State = SIP_StackState.Started; m_pTransportLayer.Start(); }