Exemple #1
0
        /// <summary>
        /// Default constructor.
        /// </summary>
        public SIP_UA()
        {
            m_pStack = new SIP_Stack();
            m_pStack.RequestReceived += m_pStack_RequestReceived;

            m_pCalls = new List<SIP_UA_Call>();
        }
Exemple #2
0
        /// <summary>
        /// Initializes dialog.
        /// </summary>
        /// <param name="stack">Owner stack.</param>
        /// <param name="transaction">Owner transaction.</param>
        /// <param name="response">SIP response what caused dialog creation.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>stack</b>,<b>transaction</b> or <b>response</b>.</exception>
        protected internal override void Init(SIP_Stack stack,
                                              SIP_Transaction transaction,
                                              SIP_Response response)
        {
            if (stack == null)
            {
                throw new ArgumentNullException("stack");
            }
            if (transaction == null)
            {
                throw new ArgumentNullException("transaction");
            }
            if (response == null)
            {
                throw new ArgumentNullException("response");
            }

            base.Init(stack, transaction, response);

            if (transaction is SIP_ServerTransaction)
            {
                if (response.StatusCodeType == SIP_StatusCodeType.Success)
                {
                    SetState(SIP_DialogState.Early, false);

                    // We need to retransmit 2xx response while we get ACK or timeout. (RFC 3261 13.3.1.4.)
                    m_pUasInvite2xxRetransmits.Add(new UasInvite2xxRetransmit(this, response));
                }
                else if (response.StatusCodeType == SIP_StatusCodeType.Provisional)
                {
                    SetState(SIP_DialogState.Early, false);

                    m_pActiveInvite = transaction;
                    m_pActiveInvite.StateChanged += delegate
                    {
                        if (m_pActiveInvite != null &&
                            m_pActiveInvite.State ==
                            SIP_TransactionState.Terminated)
                        {
                            m_pActiveInvite = null;
                        }
                    };
                    // Once we send 2xx response, we need to retransmit it while get ACK or timeout. (RFC 3261 13.3.1.4.)
                    ((SIP_ServerTransaction)m_pActiveInvite).ResponseSent +=
                        delegate(object s, SIP_ResponseSentEventArgs a)
                    {
                        if (a.Response.StatusCodeType == SIP_StatusCodeType.Success)
                        {
                            m_pUasInvite2xxRetransmits.Add(new UasInvite2xxRetransmit(this, a.Response));
                        }
                    };
                }
                else
                {
                    throw new ArgumentException(
                              "Argument 'response' has invalid status code, 1xx - 2xx is only allowed.");
                }
            }
            else
            {
                if (response.StatusCodeType == SIP_StatusCodeType.Success)
                {
                    SetState(SIP_DialogState.Confirmed, false);

                    //  Wait for retransmited 2xx responses. (RFC 3261 13.2.2.4.)
                    m_pUacInvite2xxRetransmitWaits.Add(new UacInvite2xxRetransmissionWaiter(this,
                                                                                            transaction.
                                                                                            Request));
                }
                else if (response.StatusCodeType == SIP_StatusCodeType.Provisional)
                {
                    SetState(SIP_DialogState.Early, false);

                    m_pActiveInvite = transaction;
                    m_pActiveInvite.StateChanged += delegate
                    {
                        if (m_pActiveInvite != null &&
                            m_pActiveInvite.State ==
                            SIP_TransactionState.Terminated)
                        {
                            m_pActiveInvite = null;
                        }
                    };
                    // Once we receive 2xx response, we need to wait for retransmitted 2xx responses. (RFC 3261 13.2.2.4)
                    ((SIP_ClientTransaction)m_pActiveInvite).ResponseReceived +=
                        delegate(object s, SIP_ResponseReceivedEventArgs a)
                    {
                        if (a.Response.StatusCodeType == SIP_StatusCodeType.Success)
                        {
                            UacInvite2xxRetransmissionWaiter waiter =
                                new UacInvite2xxRetransmissionWaiter(this, m_pActiveInvite.Request);
                            m_pUacInvite2xxRetransmitWaits.Add(waiter);
                            // Force to send initial ACK to 2xx response.
                            waiter.Process(a.Response);

                            SetState(SIP_DialogState.Confirmed, true);
                        }
                    };
                }
                else
                {
                    throw new ArgumentException(
                              "Argument 'response' has invalid status code, 1xx - 2xx is only allowed.");
                }
            }
        }
        /// <summary>
        /// Initializes dialog.
        /// </summary>
        /// <param name="stack">Owner stack.</param>
        /// <param name="transaction">Owner transaction.</param>
        /// <param name="response">SIP response what caused dialog creation.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>stack</b>,<b>transaction</b> or <b>response</b>.</exception>
        internal protected virtual void Init(SIP_Stack stack, SIP_Transaction transaction, SIP_Response response)
        {
            if (stack == null)
            {
                throw new ArgumentNullException("stack");
            }
            if (transaction == null)
            {
                throw new ArgumentNullException("transaction");
            }
            if (response == null)
            {
                throw new ArgumentNullException("response");
            }

            m_pStack = stack;


            /* RFC 3261 12.1.1.
             *  The UAS then constructs the state of the dialog.  This state MUST be
             *  maintained for the duration of the dialog.
             *
             *  If the request arrived over TLS, and the Request-URI contained a SIPS
             *  URI, the "secure" flag is set to TRUE.
             *
             *  The route set MUST be set to the list of URIs in the Record-Route
             *  header field from the request, taken in order and preserving all URI
             *  parameters.  If no Record-Route header field is present in the
             *  request, the route set MUST be set to the empty set.  This route set,
             *  even if empty, overrides any pre-existing route set for future
             *  requests in this dialog.  The remote target MUST be set to the URI
             *  from the Contact header field of the request.
             *
             *  The remote sequence number MUST be set to the value of the sequence
             *  number in the CSeq header field of the request.  The local sequence
             *  number MUST be empty.  The call identifier component of the dialog ID
             *  MUST be set to the value of the Call-ID in the request.  The local
             *  tag component of the dialog ID MUST be set to the tag in the To field
             *  in the response to the request (which always includes a tag), and the
             *  remote tag component of the dialog ID MUST be set to the tag from the
             *  From field in the request.  A UAS MUST be prepared to receive a
             *  request without a tag in the From field, in which case the tag is
             *  considered to have a value of null.
             *
             *      This is to maintain backwards compatibility with RFC 2543, which
             *      did not mandate From tags.
             *
             *  The remote URI MUST be set to the URI in the From field, and the
             *  local URI MUST be set to the URI in the To field.
             */

            if (transaction is SIP_ServerTransaction)
            {
                m_IsSecure      = ((SIP_Uri)transaction.Request.RequestLine.Uri).IsSecure;
                m_pRouteSet     = (SIP_t_AddressParam[])Net_Utils.ReverseArray(transaction.Request.RecordRoute.GetAllValues());
                m_pRemoteTarget = (SIP_Uri)transaction.Request.Contact.GetTopMostValue().Address.Uri;
                m_RemoteSeqNo   = transaction.Request.CSeq.SequenceNumber;
                m_LocalSeqNo    = 0;
                m_CallID        = transaction.Request.CallID;
                m_LocalTag      = response.To.Tag;
                m_RemoteTag     = transaction.Request.From.Tag;
                m_pRemoteUri    = transaction.Request.From.Address.Uri;
                m_pLocalUri     = transaction.Request.To.Address.Uri;
                m_pLocalContact = (SIP_Uri)response.Contact.GetTopMostValue().Address.Uri;

                List <string> allow = new List <string>();
                foreach (SIP_t_Method m in response.Allow.GetAllValues())
                {
                    allow.Add(m.Method);
                }
                m_pRemoteAllow = allow.ToArray();

                List <string> supported = new List <string>();
                foreach (SIP_t_OptionTag s in response.Supported.GetAllValues())
                {
                    supported.Add(s.OptionTag);
                }
                m_pRemoteSupported = supported.ToArray();
            }



            /* RFC 3261 12.1.2.
             *  When a UAC receives a response that establishes a dialog, it
             *  constructs the state of the dialog.  This state MUST be maintained
             *  for the duration of the dialog.
             *
             *  If the request was sent over TLS, and the Request-URI contained a
             *  SIPS URI, the "secure" flag is set to TRUE.
             *
             *  The route set MUST be set to the list of URIs in the Record-Route
             *  header field from the response, taken in reverse order and preserving
             *  all URI parameters.  If no Record-Route header field is present in
             *  the response, the route set MUST be set to the empty set.  This route
             *  set, even if empty, overrides any pre-existing route set for future
             *  requests in this dialog.  The remote target MUST be set to the URI
             *  from the Contact header field of the response.
             *
             *  The local sequence number MUST be set to the value of the sequence
             *  number in the CSeq header field of the request.  The remote sequence
             *  number MUST be empty (it is established when the remote UA sends a
             *  request within the dialog).  The call identifier component of the
             *  dialog ID MUST be set to the value of the Call-ID in the request.
             *  The local tag component of the dialog ID MUST be set to the tag in
             *  the From field in the request, and the remote tag component of the
             *  dialog ID MUST be set to the tag in the To field of the response.  A
             *  UAC MUST be prepared to receive a response without a tag in the To
             *  field, in which case the tag is considered to have a value of null.
             *
             *      This is to maintain backwards compatibility with RFC 2543, which
             *      did not mandate To tags.
             *
             *  The remote URI MUST be set to the URI in the To field, and the local
             *  URI MUST be set to the URI in the From field.
             */

            else
            {
                // TODO: Validate request or client transaction must do it ?

                m_IsSecure      = ((SIP_Uri)transaction.Request.RequestLine.Uri).IsSecure;
                m_pRouteSet     = (SIP_t_AddressParam[])Net_Utils.ReverseArray(response.RecordRoute.GetAllValues());
                m_pRemoteTarget = (SIP_Uri)response.Contact.GetTopMostValue().Address.Uri;
                m_LocalSeqNo    = transaction.Request.CSeq.SequenceNumber;
                m_RemoteSeqNo   = 0;
                m_CallID        = transaction.Request.CallID;
                m_LocalTag      = transaction.Request.From.Tag;
                m_RemoteTag     = response.To.Tag;
                m_pRemoteUri    = transaction.Request.To.Address.Uri;
                m_pLocalUri     = transaction.Request.From.Address.Uri;
                m_pLocalContact = (SIP_Uri)transaction.Request.Contact.GetTopMostValue().Address.Uri;

                List <string> allow = new List <string>();
                foreach (SIP_t_Method m in response.Allow.GetAllValues())
                {
                    allow.Add(m.Method);
                }
                m_pRemoteAllow = allow.ToArray();

                List <string> supported = new List <string>();
                foreach (SIP_t_OptionTag s in response.Supported.GetAllValues())
                {
                    supported.Add(s.OptionTag);
                }
                m_pRemoteSupported = supported.ToArray();
            }



            m_pFlow = transaction.Flow;
            AddTransaction(transaction);
        }
Exemple #4
0
        /// <summary>
        /// Initializes dialog.
        /// </summary>
        /// <param name="stack">Owner stack.</param>
        /// <param name="transaction">Owner transaction.</param>
        /// <param name="response">SIP response what caused dialog creation.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>stack</b>,<b>transaction</b> or <b>response</b>.</exception>
        internal protected override void Init(SIP_Stack stack, SIP_Transaction transaction, SIP_Response response)
        {
            if (stack == null)
            {
                throw new ArgumentNullException("stack");
            }
            if (transaction == null)
            {
                throw new ArgumentNullException("transaction");
            }
            if (response == null)
            {
                throw new ArgumentNullException("response");
            }

            base.Init(stack, transaction, response);

            if (transaction is SIP_ServerTransaction)
            {
                if (response.StatusCodeType == SIP_StatusCodeType.Success)
                {
                    SetState(SIP_DialogState.Early, false);
                }
                else if (response.StatusCodeType == SIP_StatusCodeType.Provisional)
                {
                    SetState(SIP_DialogState.Early, false);

                    m_pActiveInvite = transaction;
                    m_pActiveInvite.StateChanged += delegate(object s, EventArgs a){
                        if (m_pActiveInvite != null && m_pActiveInvite.State == SIP_TransactionState.Terminated)
                        {
                            m_pActiveInvite = null;

                            /* RFC 3261 13.3.1.4.
                             *  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.
                             */
                            if (this.State == SIP_DialogState.Early)
                            {
                                this.SetState(SIP_DialogState.Confirmed, true);
                                Terminate("ACK was not received for initial INVITE 2xx response.", true);
                            }
                            else if (this.State == SIP_DialogState.Terminating)
                            {
                                this.SetState(SIP_DialogState.Confirmed, false);
                                Terminate(m_TerminateReason, true);
                            }
                        }
                    };
                }
                else
                {
                    throw new ArgumentException("Argument 'response' has invalid status code, 1xx - 2xx is only allowed.");
                }
            }
            else
            {
                if (response.StatusCodeType == SIP_StatusCodeType.Success)
                {
                    SetState(SIP_DialogState.Confirmed, false);
                }
                else if (response.StatusCodeType == SIP_StatusCodeType.Provisional)
                {
                    SetState(SIP_DialogState.Early, false);

                    m_pActiveInvite = transaction;
                    m_pActiveInvite.StateChanged += delegate(object s, EventArgs a){
                        if (m_pActiveInvite != null && m_pActiveInvite.State == SIP_TransactionState.Terminated)
                        {
                            m_pActiveInvite = null;
                        }
                    };

                    // Once we receive 2xx response, dialog will switch to confirmed state.
                    ((SIP_ClientTransaction)transaction).ResponseReceived += delegate(object s, SIP_ResponseReceivedEventArgs a){
                        if (a.Response.StatusCodeType == SIP_StatusCodeType.Success)
                        {
                            SetState(SIP_DialogState.Confirmed, true);
                        }
                    };
                }
                else
                {
                    throw new ArgumentException("Argument 'response' has invalid status code, 1xx - 2xx is only allowed.");
                }
            }
        }
        /// <summary>
        /// Cleans up any resources being used.
        /// </summary>
        public void Dispose()
        {
            if (m_IsDisposed)
            {
                return;
            }
            m_IsDisposed = true;

            if (m_pStack != null)
            {
                m_pStack.Dispose();
                m_pStack = null;
            }
            m_pRegistrar = null;
            m_pB2BUA = null;
            m_pProxyContexts = null;
        }
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="stack">Reference to SIP stack.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>sipStack</b> is null.</exception>
        public SIP_ProxyCore(SIP_Stack stack)
        {
            if (stack == null)
            {
                throw new ArgumentNullException("stack");
            }

            m_pStack = stack;
            m_pStack.RequestReceived += m_pStack_RequestReceived;
            m_pStack.ResponseReceived += m_pStack_ResponseReceived;

            m_pRegistrar = new SIP_Registrar(this);
            m_pB2BUA = new SIP_B2BUA(this);
            m_Opaque = Auth_HttpDigest.CreateOpaque();
            m_pProxyContexts = new List<SIP_ProxyContext>();
        }
 /// <summary>
 /// Default constructor.
 /// </summary>
 /// <param name="stack">Reference to SIP stack.</param>
 /// <param name="flow">SIP data flow.</param>
 /// <param name="request">Recieved request.</param>
 internal SIP_RequestReceivedEventArgs(SIP_Stack stack, SIP_Flow flow, SIP_Request request) : this(stack, flow, request, null)
 {
 }
        /// <summary>
        /// Cleans up any resources being used.
        /// </summary>
        internal void Dispose()
        {
            if (m_IsDisposed)
            {
                return;
            }
            m_IsDisposed = true;

            CanRegister = null;
            AorRegistered = null;
            AorUnregistered = null;
            AorUpdated = null;

            m_pProxy = null;
            m_pStack = null;
            m_pRegistrations = null;
            if (m_pTimer != null)
            {
                m_pTimer.Dispose();
                m_pTimer = null;
            }
        }
        /// <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_ProxyCore proxy)
        {
            if (proxy == null)
            {
                throw new ArgumentNullException("proxy");
            }

            m_pProxy = proxy;
            m_pStack = m_pProxy.Stack;

            m_pRegistrations = new SIP_RegistrationCollection();

            m_pTimer = new Timer(15000);
            m_pTimer.Elapsed += m_pTimer_Elapsed;
            m_pTimer.Enabled = true;
        }
Exemple #10
0
        static void Main(string[] args)
        {
            throw new NotImplementedException("");

            System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();
            DirectoryInfo tmpPath          = new DirectoryInfo(Path.Combine(Path.GetDirectoryName(asm.Location), "audio"));

            if (!tmpPath.Exists)
            {
                tmpPath.Create();

                //Descompacta os zips em uma estrutura temporária
                //DecompressData(Resource1.audios, tmpPath);
            }

            //Carrega arquivo de config
            if (args.Length == 0)
            {
                return;
            }

            if (!File.Exists(args[0]))
            {
                return;
            }

            XmlDocument doc = new XmlDocument();

            doc.LoadXml(File.ReadAllText(args[0], Encoding.UTF8));

            XmlNode configNode   = doc.SelectSingleNode("/call/config");
            XmlNode commandsNode = doc.SelectSingleNode("/call/commands");

            if ((configNode == null) || (commandsNode == null))
            {
                return;
            }

            String target   = "";
            String server   = "";
            String username = "";
            String password = "";

            foreach (XmlNode n in doc.SelectNodes("/call/config/item"))
            {
                XmlNode key   = n.SelectSingleNode("key");
                XmlNode value = n.SelectSingleNode("value");

                switch (key.InnerText.ToLower())
                {
                case "target":
                    target = value.InnerText;
                    break;

                case "host":
                    server = value.InnerText;
                    break;

                case "username":
                    username = value.InnerText;
                    break;

                case "password":
                    password = value.InnerText;
                    break;
                }
            }

            SIP_Debug.DebugLevel = 5;

            List <String> cmds = new List <string>();

            foreach (XmlNode n in commandsNode.ChildNodes)
            {
                cmds.Add(n.InnerText);
            }

            SIP_Stack stack = new SIP_Stack(server, 5060, username, password);

            try
            {
                using (SIP_Dial dial = new SIP_Dial(ref stack, target))
                {
                    dial.Dial(true, cmds);
                    dial.WaitEnd();
                    //dial.DialOK
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
 /// <summary>
 /// Default constructor.
 /// </summary>
 /// <param name="stack">Reference to SIP stack.</param>
 /// <param name="transaction">Client transaction what response it is. This value can be null if no matching client response.</param>
 /// <param name="response">Received response.</param>
 internal SIP_ResponseReceivedEventArgs(SIP_Stack stack, SIP_ClientTransaction transaction, SIP_Response response)
 {
     m_pStack       = stack;
     m_pResponse    = response;
     m_pTransaction = transaction;
 }
Exemple #12
0
        /// <summary>
        /// Cleans up any resources being used.
        /// </summary>
        public void Dispose()
        {
            lock (m_pLock)
            {
                if (m_IsDisposed)
                {
                    return;
                }

                // Hang up all calls.
                foreach (SIP_UA_Call call in m_pCalls.ToArray())
                {
                    call.Terminate();
                }

                // Wait till all registrations and calls disposed or wait timeout reached.
                DateTime start = DateTime.Now;
                while (m_pCalls.Count > 0)
                {
                    Thread.Sleep(500);

                    // Timeout, just kill all UA.
                    if (((DateTime.Now - start)).Seconds > 15)
                    {
                        break;
                    }
                }

                m_IsDisposed = true;

                RequestReceived = null;
                IncomingCall = null;

                m_pStack.Dispose();
                m_pStack = null;
            }
        }