Example #1
0
        /// <summary>
        /// Stops SMTP relay server.
        /// </summary>
        /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception>
        public virtual void Stop()
        {
            if(m_IsDisposed){
                throw new ObjectDisposedException(this.GetType().Name);
            }
            if(!m_IsRunning){
                return;
            }
            m_IsRunning = false;

            // TODO: We need to send notify to all not processed messages, then they can be Disposed as needed.
                        
            // Clean up.            
            m_pLocalEndPointIPv4 = null;
            m_pLocalEndPointIPv6 = null;
            //m_pSessions.Dispose();
            m_pSessions = null;
            m_pConnectionsPerIP = null;
            m_pTimerTimeout.Dispose();
            m_pTimerTimeout = null;
        }
Example #2
0
        private void Handle2xx(SIP_Dialog dialog, SIP_ServerTransaction transaction)
        {
            if (dialog == null)
            {
                throw new ArgumentNullException("dialog");
            }
            if (transaction == null)
            {
                throw new ArgumentException("transaction");
            }

            /* RFC 6026 8.1.
                Once the response has been constructed, it is passed to the INVITE
                server transaction.  In order to ensure reliable end-to-end
                transport of the response, 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.
             
                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.
              
                 T1 - 500
                 T2 - 4000
            */

            TimerEx timer = null;

            EventHandler<SIP_RequestReceivedEventArgs> callback = delegate(object s1, SIP_RequestReceivedEventArgs e)
            {
                try
                {
                    if (e.Request.RequestLine.Method == SIP_Methods.ACK)
                    {
                        // ACK for INVITE 2xx response received, stop retransmitting INVITE 2xx response.
                        if (transaction.Request.CSeq.SequenceNumber == e.Request.CSeq.SequenceNumber)
                        {
                            if (timer != null)
                            {
                                timer.Dispose();
                            }
                        }
                    }
                }
                catch
                {
                    // We don't care about errors here.
                }
            };
            dialog.RequestReceived += callback;

            // Create timer and sart retransmitting INVITE 2xx response.
            timer = new TimerEx(500);
            timer.AutoReset = false;
            timer.Elapsed += delegate(object s, System.Timers.ElapsedEventArgs e)
            {
                try
                {
                    lock (transaction.SyncRoot)
                    {
                        if (transaction.State == SIP_TransactionState.Accpeted)
                        {
                            transaction.SendResponse(transaction.FinalResponse);
                        }
                        else
                        {
                            timer.Dispose();

                            return;
                        }
                    }

                    timer.Interval = Math.Min(timer.Interval * 2, 4000);
                    timer.Enabled = true;
                }
                catch
                {
                    // We don't care about errors here.
                }
            };
            timer.Disposed += delegate(object s1, EventArgs e1)
            {
                try
                {
                    dialog.RequestReceived -= callback;
                }
                catch
                {
                    // We don't care about errors here.
                }
            };
            timer.Enabled = true;
        }
Example #3
0
        /// <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();
        }
Example #4
0
        /// <summary>
        /// Initializes call from Calling state to active..
        /// </summary>
        /// <param name="dialog">SIP dialog.</param>
        /// <param name="localSDP">Local SDP.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>dialog</b> or <b>localSDP</b> is null reference.</exception>
        internal void InitCalling(SIP_Dialog dialog, SDP_Message localSDP)
        {
            if (dialog == null)
            {
                throw new ArgumentNullException("dialog");
            }
            if (localSDP == null)
            {
                throw new ArgumentNullException("localSDP");
            }

            m_pDialog = (SIP_Dialog_Invite)dialog;
            m_pFlow = dialog.Flow;
            m_pLocalSDP = localSDP;

            m_StartTime = DateTime.Now;
            dialog.StateChanged += new EventHandler(m_pDialog_StateChanged);

            SetState(SIP_CallState.Active);

            // Start ping timer.
            m_pKeepAliveTimer = new TimerEx(40000);
            m_pKeepAliveTimer.Elapsed += new System.Timers.ElapsedEventHandler(m_pKeepAliveTimer_Elapsed);
            m_pKeepAliveTimer.Enabled = true;
        }
Example #5
0
        /// <summary>
        /// Cleans up any resource being used.
        /// </summary>
        public void Dispose()
        {
            lock (m_pLock)
            {
                if (this.State == SIP_CallState.Disposed)
                {
                    return;
                }
                SetState(SIP_CallState.Disposed);

                // TODO: Clean up
                m_pStack = null;
                m_pLocalSDP = null;
                if (m_pDialog != null)
                {
                    m_pDialog.Dispose();
                    m_pDialog = null;
                }
                m_pFlow = null;
                if (m_pKeepAliveTimer != null)
                {
                    m_pKeepAliveTimer.Dispose();
                    m_pKeepAliveTimer = null;
                }

                this.StateChanged = null;
            }
        }
Example #6
0
        /// <summary>
        /// Incoming call constructor.
        /// </summary>
        /// <param name="stack">Reference to SIP stack.</param>
        /// <param name="dialog">Reference SIP dialog.</param>
        /// <param name="session">Call RTP multimedia session.</param>
        /// <param name="localSDP">Local SDP.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>stack</b>,<b>dialog</b>,<b>session</b> or <b>localSDP</b> is null reference.</exception>
        internal SIP_Call(SIP_Stack stack, SIP_Dialog dialog, RTP_MultimediaSession session, SDP_Message localSDP)
        {
            if (stack == null)
            {
                throw new ArgumentNullException("stack");
            }
            if (dialog == null)
            {
                throw new ArgumentNullException("dialog");
            }
            if (session == null)
            {
                throw new ArgumentNullException("session");
            }
            if (localSDP == null)
            {
                throw new ArgumentNullException("localSDP");
            }

            m_pStack = stack;
            m_pDialog = (SIP_Dialog_Invite)dialog;
            m_pRtpMultimediaSession = session;
            m_pLocalSDP = localSDP;

            m_StartTime = DateTime.Now;
            m_pFlow = dialog.Flow;
            dialog.StateChanged += new EventHandler(m_pDialog_StateChanged);

            SetState(SIP_CallState.Active);

            // Start ping timer.
            m_pKeepAliveTimer = new TimerEx(40000);
            m_pKeepAliveTimer.Elapsed += new System.Timers.ElapsedEventHandler(m_pKeepAliveTimer_Elapsed);
            m_pKeepAliveTimer.Enabled = true;
        }
Example #7
0
            /// <summary>
            /// Starts IDLE command processing.
            /// </summary>
            private void Start()
            {
                /* RFC 2177 IDLE command example.
                    C: A004 IDLE
                    S: * 2 EXPUNGE
                    S: * 3 EXISTS
                    S: + idling
                    ...time passes; another client expunges message 3...
                    S: * 3 EXPUNGE
                    S: * 2 EXISTS
                    ...time passes; new mail arrives...
                    S: * 3 EXISTS
                    C: DONE
                    S: A004 OK IDLE terminated
                */

                // Send status reponse to connected client if any.
                m_pSession.ProcessMailboxChanges();

                // Send "+ idling" to connected client.
                m_pSession.Socket.WriteLine("+ idling");

                // Start timer to poll mailbox changes.
                m_pTimer = new TimerEx(60000,true);
                m_pTimer.Elapsed += new System.Timers.ElapsedEventHandler(m_pTimer_Elapsed);
                m_pTimer.Enabled = true;

                // Start waiting DONE command from connected client.
                MemoryStream ms = new MemoryStream();
                m_pSession.Socket.BeginReadLine(ms,1024,ms,new SocketCallBack(this.ReadLineCompleted));
            }
Example #8
0
            /// <summary>
            /// Cleans up any resources being used.
            /// </summary>
            public void Dispose()
            {
                if(m_IsDisposed){
                    return;
                }
                m_IsDisposed = true;

                m_pSession.m_pIDLE = null;
                m_pSession = null;
                m_pTimer.Dispose();
                m_pTimer = null;
            }