Click here to Skip to main content
15,886,860 members
Articles / Web Development / HTML

My own Mailinator in 5 minutes

Rate me:
Please Sign up or sign in to vote.
5.00/5 (6 votes)
19 Nov 2012CPOL6 min read 31.6K   405   13  
A simple Mailinator clone developed in five minutes with the NetFluid framework
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;

using LumiSoft.Net.SIP.Message;
using LumiSoft.Net.SIP.Stack;

namespace LumiSoft.Net.SIP.Proxy
{
    /// <summary>
    /// This class represents SIP registrar registration binding entry. Defined in RFC 3261 10.3.
    /// </summary>
    public class SIP_RegistrationBinding : IComparable
    {
        private SIP_Registration m_pRegistration = null;
        private DateTime         m_LastUpdate;
        private SIP_Flow         m_pFlow         = null;
        private AbsoluteUri      m_ContactURI    = null;
        private int              m_Expires       = 3600;
        private double           m_QValue        = 1.0;
        private string           m_CallID        = "";
        private int              m_CSeqNo        = 1;

        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="owner">Owner registration.</param>
        /// <param name="contactUri">Contact URI what can be used to contact the registration.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>owner</b> or <b>contactUri</b> is null reference.</exception>
        internal SIP_RegistrationBinding(SIP_Registration owner,AbsoluteUri contactUri)
        {
            if(owner == null){
                throw new ArgumentNullException("owner");
            }
            if(contactUri == null){
                throw new ArgumentNullException("contactUri");
            }

            m_pRegistration = owner;
            m_ContactURI    = contactUri;
        }


        #region method Update

        /// <summary>
        /// Updates specified binding.
        /// </summary>
        /// <param name="flow">SIP data flow what updates this binding. This value is null if binding was not added through network or
        /// flow has disposed.</param>
        /// <param name="expires">Time in seconds when binding will expire.</param>
        /// <param name="qvalue">Binding priority. Higher value means greater priority.</param>
        /// <param name="callID">Call-ID header field value which added/updated this binding.</param>
        /// <param name="cseqNo">CSeq header field sequence number value which added/updated this binding.</param>
        public void Update(SIP_Flow flow,int expires,double qvalue,string callID,int cseqNo)
        {
            if(expires < 0){
                throw new ArgumentException("Argument 'expires' value must be >= 0.");
            }
            if(qvalue < 0 || qvalue > 1){
                throw new ArgumentException("Argument 'qvalue' value must be >= 0.000 and <= 1.000");
            }
            if(callID == null){
                throw new ArgumentNullException("callID");
            }
            if(cseqNo < 0){
                throw new ArgumentException("Argument 'cseqNo' value must be >= 0.");
            }

            m_pFlow    = flow;
            m_Expires  = expires;
            m_QValue   = qvalue;
            m_CallID   = callID;
            m_CSeqNo   = cseqNo;

            m_LastUpdate = DateTime.Now;
        }

        #endregion

        #region method Remove

        /// <summary>
        /// Removes this binding from the registration.
        /// </summary>
        public void Remove()
        {
            m_pRegistration.RemoveBinding(this);
        }

        #endregion

        #region method ToContactValue

        /// <summary>
        /// Converts <b>ContactUri</b> to valid Contact header value.
        /// </summary>
        /// <returns>Returns contact header value.</returns>
        public string ToContactValue()
        {
            SIP_t_ContactParam retVal = new SIP_t_ContactParam();
            retVal.Parse(new StringReader(m_ContactURI.ToString()));
            retVal.Expires = m_Expires;

            return retVal.ToStringValue();
        }

        #endregion


        #region IComparable interface Implementation

        /// <summary>
        /// Compares the current instance with another object of the same type. 
        /// </summary>
        /// <param name="obj">An object to compare with this instance.</param>
        /// <returns>Returns 0 if two objects equal, -1 if this instance is less or 1 this instance is greater.</returns>
        public int CompareTo(object obj)
        {
            if(obj == null){
                return -1;
            }
            if(!(obj is SIP_RegistrationBinding)){
                return -1;
            }

            // We must reverse values, because greater value mean higer priority.

            SIP_RegistrationBinding compareValue = (SIP_RegistrationBinding)obj;
            if(compareValue.QValue == this.QValue){
                return 0;
            }
            else if(compareValue.QValue > this.QValue){
                return 1;
            }            
            else if(compareValue.QValue < this.QValue){
                return -1;
            }

            return -1;
        }

        #endregion

        #region Properties implementation

        /// <summary>
        /// Gets the last time when the binding was updated.
        /// </summary>
        public DateTime LastUpdate
        {
            get{ return m_LastUpdate; }
        }

        /// <summary>
        /// Gets if binding has expired.
        /// </summary>
        public bool IsExpired
        {
            get{ return this.TTL <= 0; }
        }

        /// <summary>
        /// Gets how many seconds binding has time to live. This is live calulated value, so it decreases every second.
        /// </summary>
        public int TTL
        {
            get{
                if(DateTime.Now > m_LastUpdate.AddSeconds(m_Expires)){
                    return 0;
                }
                else{
                    return (int)((TimeSpan)(m_LastUpdate.AddSeconds(m_Expires) - DateTime.Now)).TotalSeconds;
                }
            }
        }

        /// <summary>
        /// Gets data flow what added this binding. This value is null if binding was not added through network or
        /// flow has disposed.
        /// </summary>
        public SIP_Flow Flow
        {
            get{ return m_pFlow; }
        }

        /// <summary>
        /// Gets contact URI what can be used to contact the registration.
        /// </summary>
        public AbsoluteUri ContactURI
        {
            get{ return m_ContactURI; }
        }

        /// <summary>
        /// Gets binding priority. Higher value means greater priority.
        /// </summary>
        public double QValue
        {
            get{ return m_QValue; }
        }

        /// <summary>
        /// Gets Call-ID header field value which added this binding.
        /// </summary>
        public string CallID
        {
            get{ return m_CallID; }
        }

        /// <summary>
        /// Gets CSeq header field sequence number value which added this binding.
        /// </summary>
        public int CSeqNo
        {
            get{ return m_CSeqNo; }
        }

        #endregion

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Chief Technology Officer Genny Mobility
Italy Italy
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions