Exemple #1
0
 public TSIP_HeaderContact(String displayName, TSIP_Uri uri, Int64 expires)
     : base(tsip_header_type_t.Contact)
 {
     mDisplayName = displayName;
     mUri         = uri;
     mExpires     = expires;
 }
 public TSIP_HeaderFrom(String displayName, TSIP_Uri uri, String tag)
     : base(tsip_header_type_t.From)
 {
     this.DisplayName = displayName;
     this.Uri         = uri;
     this.Tag         = tag;
 }
        internal TSIP_Header CreateHeaderAuthorization(TSIP_Request request)
        {
            if (request == null)
            {
                TSK_Debug.Error("Invalid parameter");
                return(null);
            }

            String response, nc = null, uristring;

            if (String.IsNullOrEmpty(uristring = TSIP_Uri.ToString(request.Uri, true, false)))
            {
                TSK_Debug.Error("Failed to parse URI: {0}", request.Uri);
                return(null);
            }

            /* We compute the nc here because @ref tsip_challenge_get_response function will increment it's value. */
            if (mNc > 0)
            {
                nc = THTTP_Auth.GetNonceString(mNc).ToString();
            }
            /* entity_body ==> request-content */
            response = GetResponse(request.Method, uristring, request.Content);

            if (mProxy)
            {
                // FIXME
                TSK_Debug.Error("Proxy-Authorization header not supported yet");
            }
            else
            {
                TSIP_HeaderAuthorization header = new TSIP_HeaderAuthorization();
                header.UserName  = ChallengeUserName;
                header.Scheme    = mScheme;
                header.Realm     = mRealm;
                header.Nonce     = mNonce;
                header.Qop       = mQop;
                header.Algorithm = String.IsNullOrEmpty(mAlgorithm) ? "MD5" : mAlgorithm;
                header.Cnonce    = mNc > 0 ? mCnonce : null;
                header.Uri       = uristring;
                header.Nc        = mNc > 0 ? nc : null;
                header.Response  = response;

                return(header);
            }

            return(null);
        }
Exemple #4
0
        internal TSIP_Uri GetUri(Boolean lr)
        {
            Boolean ipv6 = TNET_Socket.IsIPv6Type(this.Type);

            String uristring = String.Format("{0}:{1}{2}{3}:{4};{5};transport={6}",
                                             this.Scheme,
                                             ipv6 ? "[" : String.Empty,
                                             mStack.AoRIP,
                                             ipv6 ? "]" : String.Empty,
                                             mStack.AoRPort,
                                             lr ? "lr" : String.Empty,
                                             this.Protocol);

            TSIP_Uri uri = TSIP_ParserUri.Parse(uristring);

            uri.HostType = ipv6 ? tsip_host_type_t.IPv6 : tsip_host_type_t.IPv4;
            return(uri);
        }
        internal const Int64 SHUTDOWN_TIMEOUT = 2000; /* miliseconds. */

        internal TSIP_Dialog(tsip_dialog_type_t type, String callId, TSip_Session session)
        {
            mId           = sUniqueId++;
            mRecordRoutes = new List <TSIP_HeaderRecordRoute>();
            mChallenges   = new List <TSIP_Challenge>();

            mPaths          = new List <TSIP_Uri>();
            mServiceRoutes  = new List <TSIP_Uri>();
            mAssociatedUris = new List <TSIP_Uri>();

            mState = tsip_dialog_state_t.Initial;
            mType  = type;

            mCallId     = String.IsNullOrEmpty(callId) ? TSIP_HeaderCallId.RandomCallId() : callId;
            mSipSession = session;

            /* Sets some default values */
            mExpires   = TSip_Session.DEFAULT_EXPIRES;
            mTagLocal  = TSK_String.Random();
            mCSeqValue = (UInt32) new Random().Next();

            /*=== SIP Session ===*/
            if (mSipSession != null)
            {
                mExpires  = mSipSession.Expires;
                mUriLocal = !String.IsNullOrEmpty(callId) /* Server Side */ ? mSipSession.UriTo : mSipSession.UriFrom;
                if (mSipSession.UriTo != null)
                {
                    mUriRemote       = mSipSession.UriTo;
                    mUriRemoteTarget = mSipSession.UriTo;
                }
                else
                {
                    mUriRemote       = mSipSession.UriFrom;
                    mUriRemoteTarget = mSipSession.Stack.Realm;
                }
            }
            else
            {
                TSK_Debug.Error("Invalid Sip Session");
            }
        }
Exemple #6
0
        internal static void TestUriParser()
        {
            int i;

            for (i = 0; i < __Uris.Length; i++)
            {
                TSIP_Uri uri = TSIP_ParserUri.Parse(__Uris[i]);

                TSK_Debug.Info("\n== Parsing {{ {0} }} ==\n", __Uris[i]);

                if (uri != null)
                {
                    TSK_Debug.Info("scheme: {0}", uri.Scheme);
                    TSK_Debug.Info("user-name: {0}", uri.UserName);
                    TSK_Debug.Info("password: {0}", uri.Password);
                    TSK_Debug.Info("host: {0}", uri.Host);
                    TSK_Debug.Info("port: {0}", uri.Port);
                    TSK_Debug.Info("host-type: {0}", uri.HostType == tsip_host_type_t.IPv4 ? "IPv4" : (uri.HostType == tsip_host_type_t.IPv6 ? "IPv6" : (uri.HostType == tsip_host_type_t.Hostname ? "HOSTNAME" : "UNKNOWN")));

                    TSK_Debug.Info("---PARAMS---");

                    /* dump all parameters */
                    foreach (TSK_Param param in uri.Params)
                    {
                        TSK_Debug.Info("-->{0}={1}", param.Name, param.Value);
                    }

                    TSK_Debug.Info("Is-secure: {0}", uri.IsSecure ? "YES" : "NO");

                    TestToString(uri);

                    uri.Dispose();
                }
                else
                {
                    TSK_Debug.Error("INVALID SIP URI");
                }

                TSK_Debug.Info("\n\n");
            }
        }
        protected Boolean UpdateWithINVITE(TSIP_Request invite)
        {
            if (invite == null)
            {
                return(false);
            }

            /* Remote target */
            if (invite.Contact != null && invite.Contact.Uri != null)
            {
                mUriRemoteTarget = invite.Contact.Uri.Clone(true, false);
            }

            /* cseq + tags + remote-uri */
            mTagRemote = invite.From != null ? invite.From.Tag : "doubango";

            /* self->cseq_value = invite->CSeq ? invite->CSeq->seq : self->cseq_value; */
            if (invite.From != null && invite.From.Uri != null)
            {
                mUriRemote = invite.From.Uri;
            }

            /* Route sets */
            {
                int index;
                TSIP_HeaderRecordRoute recordRoute;

                mRecordRoutes.Clear();

                for (index = 0; (recordRoute = (invite.GetHeaderAtIndex(TSIP_Header.tsip_header_type_t.Record_Route, index)) as TSIP_HeaderRecordRoute) != null; index++)
                {
                    mRecordRoutes.Insert(0, recordRoute);            /* Copy non-reversed. */
                }
            }

            this.State = tsip_dialog_state_t.Established;

            return(true);
        }
Exemple #8
0
/* #line 124 "./ragel/tsip_parser_uri.rl" */

    public static TSIP_Uri Parse(String data)
    {
        if (String.IsNullOrEmpty(data))
        {
            return(null);
        }

        int cs  = 0;
        int p   = 0;
        int pe  = data.Length;
        int eof = pe;

        int ts = 0, te = 0;
        int act = 0;

        TSIP_Uri uri = TSIP_Uri.Create(tsip_uri_type_t.Unknown);

        int tag_start = 0;


/* #line 395 "../Parsers/TSIP_ParserUri.cs" */
        {
            cs  = tsip_machine_parser_uri_start;
            ts  = -1;
            te  = -1;
            act = 0;
        }

/* #line 145 "./ragel/tsip_parser_uri.rl" */

/* #line 405 "../Parsers/TSIP_ParserUri.cs" */
        {
            sbyte _klen;
            short _trans;
            sbyte _acts;
            sbyte _nacts;
            short _keys;

            if (p == pe)
            {
                goto _test_eof;
            }
            if (cs == 0)
            {
                goto _out;
            }
_resume:
            _acts  = _tsip_machine_parser_uri_from_state_actions[cs];
            _nacts = _tsip_machine_parser_uri_actions[_acts++];
            while (_nacts-- > 0)
            {
                switch (_tsip_machine_parser_uri_actions[_acts++])
                {
                case 12:
/* #line 1 "./ragel/tsip_parser_uri.rl" */
                { ts = p; }
                break;

/* #line 426 "../Parsers/TSIP_ParserUri.cs" */
                default: break;
                }
            }

            _keys  = _tsip_machine_parser_uri_key_offsets[cs];
            _trans = (short)_tsip_machine_parser_uri_index_offsets[cs];

            _klen = _tsip_machine_parser_uri_single_lengths[cs];
            if (_klen > 0)
            {
                short _lower = _keys;
                short _mid;
                short _upper = (short)(_keys + _klen - 1);
                while (true)
                {
                    if (_upper < _lower)
                    {
                        break;
                    }

                    _mid = (short)(_lower + ((_upper - _lower) >> 1));
                    if (data[p] < _tsip_machine_parser_uri_trans_keys[_mid])
                    {
                        _upper = (short)(_mid - 1);
                    }
                    else if (data[p] > _tsip_machine_parser_uri_trans_keys[_mid])
                    {
                        _lower = (short)(_mid + 1);
                    }
                    else
                    {
                        _trans += (short)(_mid - _keys);
                        goto _match;
                    }
                }
                _keys  += (short)_klen;
                _trans += (short)_klen;
            }

            _klen = _tsip_machine_parser_uri_range_lengths[cs];
            if (_klen > 0)
            {
                short _lower = _keys;
                short _mid;
                short _upper = (short)(_keys + (_klen << 1) - 2);
                while (true)
                {
                    if (_upper < _lower)
                    {
                        break;
                    }

                    _mid = (short)(_lower + (((_upper - _lower) >> 1) & ~1));
                    if (data[p] < _tsip_machine_parser_uri_trans_keys[_mid])
                    {
                        _upper = (short)(_mid - 2);
                    }
                    else if (data[p] > _tsip_machine_parser_uri_trans_keys[_mid + 1])
                    {
                        _lower = (short)(_mid + 2);
                    }
                    else
                    {
                        _trans += (short)((_mid - _keys) >> 1);
                        goto _match;
                    }
                }
                _trans += (short)_klen;
            }

_match:
            _trans = (short)_tsip_machine_parser_uri_indicies[_trans];
_eof_trans:
            cs = _tsip_machine_parser_uri_trans_targs[_trans];

            if (_tsip_machine_parser_uri_trans_actions[_trans] == 0)
            {
                goto _again;
            }

            _acts  = _tsip_machine_parser_uri_trans_actions[_trans];
            _nacts = _tsip_machine_parser_uri_actions[_acts++];
            while (_nacts-- > 0)
            {
                switch (_tsip_machine_parser_uri_actions[_acts++])
                {
                case 0:
/* #line 36 "./ragel/tsip_parser_uri.rl" */
                {
                    tag_start = p;
                }
                break;

                case 1:
/* #line 41 "./ragel/tsip_parser_uri.rl" */
                { uri.Scheme = "sip"; uri.Type = tsip_uri_type_t.Sip; }
                break;

                case 2:
/* #line 42 "./ragel/tsip_parser_uri.rl" */
                { uri.Scheme = "sips"; uri.Type = tsip_uri_type_t.Sips; }
                break;

                case 3:
/* #line 43 "./ragel/tsip_parser_uri.rl" */
                { uri.Scheme = "tel"; uri.Type = tsip_uri_type_t.Tel; }
                break;

                case 4:
/* #line 46 "./ragel/tsip_parser_uri.rl" */
                { uri.HostType = tsip_host_type_t.IPv4; }
                break;

                case 5:
/* #line 47 "./ragel/tsip_parser_uri.rl" */
                { uri.HostType = tsip_host_type_t.IPv6; }
                break;

                case 6:
/* #line 48 "./ragel/tsip_parser_uri.rl" */
                { uri.HostType = tsip_host_type_t.Hostname; }
                break;

                case 7:
/* #line 54 "./ragel/tsip_parser_uri.rl" */
                {
                    uri.UserName = TSK_RagelState.Parser.GetString(data, p, tag_start);
                }
                break;

                case 8:
/* #line 58 "./ragel/tsip_parser_uri.rl" */
                {
                    uri.Password = TSK_RagelState.Parser.GetString(data, p, tag_start);
                }
                break;

                case 9:
/* #line 70 "./ragel/tsip_parser_uri.rl" */
                {
                    TSK_Param param = TSK_RagelState.Parser.GetParam(data, p, tag_start);
                    if (param != null)
                    {
                        uri.Params.Add(param);
                    }
                }
                break;

                case 10:
/* #line 84 "./ragel/tsip_parser_uri.rl" */
                { { cs = 26; if (true)
                    {
                        goto _again;
                    }
                  } }
                  break;

                case 13:
/* #line 1 "./ragel/tsip_parser_uri.rl" */
                { te = p + 1; }
                break;

                case 14:
/* #line 97 "./ragel/tsip_parser_uri.rl" */
                { te = p + 1; {
                      uri.Host = TSK_RagelState.Scanner.GetString(data, ts, te);
                      if (uri.HostType == tsip_host_type_t.IPv6)
                      {
                          uri.Host = TSK_String.UnQuote(uri.Host, '[', ']');
                      }
                  } }
                  break;

                case 15:
/* #line 88 "./ragel/tsip_parser_uri.rl" */
                { te = p; p--; {
                      if (TSK_String.Contains(data.Substring(te), (pe - te), "@"))
                      {
                          { cs = 18; if (true)
                    {
                        goto _again;
                    }
                          }
                      }
                  } }
                  break;

                case 16:
/* #line 94 "./ragel/tsip_parser_uri.rl" */
                { te = p; p--; { } }
                break;

                case 17:
/* #line 97 "./ragel/tsip_parser_uri.rl" */
                { te = p; p--; {
                      uri.Host = TSK_RagelState.Scanner.GetString(data, ts, te);
                      if (uri.HostType == tsip_host_type_t.IPv6)
                      {
                          uri.Host = TSK_String.UnQuote(uri.Host, '[', ']');
                      }
                  } }
                  break;

                case 18:
/* #line 105 "./ragel/tsip_parser_uri.rl" */
                { te = p; p--; {
                      ts++;
                      uri.Port = (ushort)TSK_RagelState.Scanner.GetInt32(data, ts, te);
                  } }
                  break;

                case 19:
/* #line 110 "./ragel/tsip_parser_uri.rl" */
                { te = p; p--; {  } }
                break;

                case 20:
/* #line 111 "./ragel/tsip_parser_uri.rl" */
                { te = p; p--; {  } }
                break;

                case 21:
/* #line 94 "./ragel/tsip_parser_uri.rl" */
                { { p = ((te)) - 1; } { } }
                break;

                case 22:
/* #line 97 "./ragel/tsip_parser_uri.rl" */
                { { p = ((te)) - 1; } {
                      uri.Host = TSK_RagelState.Scanner.GetString(data, ts, te);
                      if (uri.HostType == tsip_host_type_t.IPv6)
                      {
                          uri.Host = TSK_String.UnQuote(uri.Host, '[', ']');
                      }
                  } }
                  break;

                case 23:
/* #line 110 "./ragel/tsip_parser_uri.rl" */
                { { p = ((te)) - 1; } {  } }
                break;

/* #line 615 "../Parsers/TSIP_ParserUri.cs" */
                default: break;
                }
            }

_again:
            _acts  = _tsip_machine_parser_uri_to_state_actions[cs];
            _nacts = _tsip_machine_parser_uri_actions[_acts++];
            while (_nacts-- > 0)
            {
                switch (_tsip_machine_parser_uri_actions[_acts++])
                {
                case 11:
/* #line 1 "./ragel/tsip_parser_uri.rl" */
                { ts = -1; }
                break;

/* #line 629 "../Parsers/TSIP_ParserUri.cs" */
                default: break;
                }
            }

            if (cs == 0)
            {
                goto _out;
            }
            if (++p != pe)
            {
                goto _resume;
            }
            _test_eof : {}
            if (p == eof)
            {
                if (_tsip_machine_parser_uri_eof_trans[cs] > 0)
                {
                    _trans = (short)(_tsip_machine_parser_uri_eof_trans[cs] - 1);
                    goto _eof_trans;
                }
            }

            _out : {}
        }

/* #line 146 "./ragel/tsip_parser_uri.rl" */

        if (cs <
/* #line 653 "../Parsers/TSIP_ParserUri.cs" */
            26
/* #line 147 "./ragel/tsip_parser_uri.rl" */
            )
        {
            TSK_Debug.Error("Failed to parse SIP/SIPS/TEL URI");
            uri.Dispose();
            return(null);
        }

        return(uri);
    }
Exemple #9
0
        static void Main(string[] args)
        {
            //Test_FSM.DefaultTest();

            //TSIP_TransportUDP transportUdp = new TSIP_TransportUDP("192.168.0.13", TNET_Socket.TNET_SOCKET_PORT_ANY, false, "Sip Tansport using UDP");
            //IPEndPoint remoteEP = TNET_Socket.CreateEndPoint("192.168.0.10", 5060);
            // Int32 count = transportUdp.SendTo(remoteEP, Encoding.UTF8.GetBytes("test"));

            //Test_UriParser.TestUriParser();
            //Test_UriParser.TestMessageParser();

            /*List<TSIP_HeaderVia> headers = TSIP_HeaderVia.Parse("Via: SIP/2.0/tcp 127.0.0.1:5082;branch=z9hG4bKc16be5aee32df400d01015675ab911ba,SIP/2.0/udp 127.0.0.1:5082;branch=z9hG4bKeec53b25db240bec92ea250964b8c1fa;received_port_ext=5081;received=192.168.0.13,SIP/2.0/UDP 192.168.0.12:57121;rport=57121;branch=z9hG4bK1274980921982;received_port_ext=5081;received=192.168.0.12\r\n");
             * foreach (TSIP_HeaderVia h in headers)
             * {
             *  Console.WriteLine(h.ToString(true, true, true));
             * }*/

            //TSIP_HeaderTo header = TSIP_HeaderTo.Parse("t:    <sip:[email protected]>;tag= 12345\r\n");
            //if (header != null)
            //{
            //    Console.WriteLine(header.ToString(true, true, true));
            //}

            TSIP_Stack sipStack = new TSIP_Stack(
                TSIP_Uri.Create("sip:doubango.org"),
                "004",
                TSIP_Uri.Create("sip:[email protected]"),
                "192.168.0.10", 5060
                );

            sipStack.LocalIP = "192.168.0.13";//FIXME

            sipStack.Callback = delegate(TSIP_Event @event)
            {
                switch (@event.Type)
                {
                case TSIP_Event.tsip_event_type_t.DIALOG:
                {
                    TSIP_EventDialog eventDialog = (@event as TSIP_EventDialog);
                    break;
                }

                case TSIP_Event.tsip_event_type_t.REGISTER:
                {
                    TSIP_EventRegister eventDialog = (@event as TSIP_EventRegister);
                    break;
                }

                default:
                {
                    return(false);
                }
                }
                return(true);
            };


            if (sipStack.Start())
            {
                TSIP_SessionRegister register = new TSIP_SessionRegister(sipStack);
                register.Register();
            }

            Console.ReadLine();
        }
Exemple #10
0
 internal static void TestToString(TSIP_Uri uri)
 {
     TSK_Debug.Info("uri_to_string={0}", uri);
 }
        protected TSIP_Request CreateRequest(String method)
        {
            TSIP_Request request = null;
            TSIP_Uri     to_uri, from_uri, request_uri;
            String       call_id;
            int          copy_routes_start = -1; /* NONE */

            /*
             *  RFC 3261 - 12.2.1.1 Generating the Request
             *
             *  The Call-ID of the request MUST be set to the Call-ID of the dialog.
             */
            call_id = mCallId;

            /*
             *  RFC 3261 - 12.2.1.1 Generating the Request
             *
             *  Requests within a dialog MUST contain strictly monotonically
             *  increasing and contiguous CSeq sequence numbers (increasing-by-one)
             *  in each direction (excepting ACK and CANCEL of course, whose numbers
             *  equal the requests being acknowledged or cancelled).  Therefore, if
             *  the local sequence number is not empty, the value of the local
             *  sequence number MUST be incremented by one, and this value MUST be
             *  placed into the CSeq header field.
             */
            /*if(!tsk_striequals(method, "ACK") && !tsk_striequals(method, "CANCEL"))
             * {
             *  TSIP_DIALOG(self)->cseq_value +=1;
             * }
             * ===> See send method (cseq will be incremented before sending the request)
             */


            /*
             * RFC 3261 - 12.2.1.1 Generating the Request
             *
             * The URI in the To field of the request MUST be set to the remote URI
             * from the dialog state.  The tag in the To header field of the request
             * MUST be set to the remote tag of the dialog ID.  The From URI of the
             * request MUST be set to the local URI from the dialog state.  The tag
             * in the From header field of the request MUST be set to the local tag
             * of the dialog ID.  If the value of the remote or local tags is null,
             * the tag parameter MUST be omitted from the To or From header fields,
             * respectively.
             */
            to_uri   = mUriRemote;
            from_uri = mUriLocal;

            /*
             *  RFC 3261 - 12.2.1.1 Generating the Request
             *
             *  If the route set is empty, the UAC MUST place the remote target URI
             *  into the Request-URI.  The UAC MUST NOT add a Route header field to
             *  the request.
             */
            if (mRecordRoutes == null || mRecordRoutes.Count == 0)
            {
                request_uri = mUriRemoteTarget;
            }

            /*
             *  RFC 3261 - 12.2.1.1 Generating the Request
             *
             *  If the route set is not empty, and the first URI in the route set
             *  contains the lr parameter (see Section 19.1.1), the UAC MUST place
             *  the remote target URI into the Request-URI and MUST include a Route
             *  header field containing the route set values in order, including all
             *  parameters.
             *
             *  If the route set is not empty, and its first URI does not contain the
             *  lr parameter, the UAC MUST place the first URI from the route set
             *  into the Request-URI, stripping any parameters that are not allowed
             *  in a Request-URI.  The UAC MUST add a Route header field containing
             *  the remainder of the route set values in order, including all
             *  parameters.  The UAC MUST then place the remote target URI into the
             *  Route header field as the last value.
             *
             *  For example, if the remote target is sip:user@remoteua and the route
             *  set contains:
             *
             *  <sip:proxy1>,<sip:proxy2>,<sip:proxy3;lr>,<sip:proxy4>
             */
            else
            {
                TSIP_Uri first_route = mRecordRoutes[0].Uri;
                if (TSK_Param.HasParam(first_route.Params, "lr"))
                {
                    request_uri       = mUriRemoteTarget;
                    copy_routes_start = 0;             /* Copy all */
                }
                else
                {
                    request_uri       = first_route;
                    copy_routes_start = 1;             /* Copy starting at index 1. */
                }
            }

            /*=====================================================================
             */
            request              = new TSIP_Request(method, request_uri, from_uri, to_uri, call_id, (Int32)mCSeqValue);
            request.To.Tag       = mTagRemote;
            request.From.Tag     = mTagLocal;
            request.ShouldUpdate = true; /* Now signal that the message should be updated by the transport layer (Contact, SigComp, IPSec, ...) */

            /*
             *  RFC 3261 - 12.2.1.1 Generating the Request
             *
             *  A UAC SHOULD include a Contact header field in any target refresh
             *  requests within a dialog, and unless there is a need to change it,
             *  the URI SHOULD be the same as used in previous requests within the
             *  dialog.  If the "secure" flag is true, that URI MUST be a SIPS URI.
             *  As discussed in Section 12.2.2, a Contact header field in a target
             *  refresh request updates the remote target URI.  This allows a UA to
             *  provide a new contact address, should its address change during the
             *  duration of the dialog.
             */
            switch (request.RequestType)
            {
            case TSIP_Message.tsip_request_type_t.MESSAGE:
            case TSIP_Message.tsip_request_type_t.PUBLISH:
            case TSIP_Message.tsip_request_type_t.BYE:
            {
                if (request.RequestType == TSIP_Message.tsip_request_type_t.PUBLISH)
                {
                    request.AddHeader(new TSIP_HeaderExpires(mExpires));
                }
                /* add caps in Accept-Contact headers */
                foreach (TSK_Param param in mSipSession.Caps)
                {
                    request.AddHeader(new TSIP_HeaderDummy("Accept-Contact",
                                                           String.Format("*;{0}{1}{2}",
                                                                         param.Name,
                                                                         !String.IsNullOrEmpty(param.Value) ? "=" : String.Empty,
                                                                         !String.IsNullOrEmpty(param.Value) ? param.Value : String.Empty)
                                                           ));
                }
                break;
            }

            default:
            {
                String contact = null;
                List <TSIP_HeaderContact> hdr_contacts = null;
                if (request.RequestType == TSIP_Message.tsip_request_type_t.OPTIONS ||
                    request.RequestType == TSIP_Message.tsip_request_type_t.PUBLISH ||
                    request.RequestType == TSIP_Message.tsip_request_type_t.REGISTER)
                {
                    /**** with expires */
                    contact = String.Format("m: <{0}:{1}@{2}:{3}>;expires={4}\r\n",
                                            "sip",
                                            from_uri.UserName,
                                            "127.0.0.1",
                                            5060,
                                            TSK_Time.Milliseconds2Seconds(mExpires));
                }
                else
                {
                    /**** without expires */
                    if (request.RequestType == TSIP_Message.tsip_request_type_t.SUBSCRIBE)
                    {
                        /* RFC 3265 - 3.1.1. Subscription Duration
                         *                              An "expires" parameter on the "Contact" header has no semantics for SUBSCRIBE and is explicitly
                         *                              not equivalent to an "Expires" header in a SUBSCRIBE request or response.
                         */
                        request.AddHeader(new TSIP_HeaderExpires(TSK_Time.Milliseconds2Seconds(mExpires)));
                    }
                    contact = String.Format("m: <{0}:{1}@{2}:{3}>\r\n",
                                            "sip",
                                            from_uri.UserName,
                                            "127.0.0.1",
                                            5060);
                }

                hdr_contacts = TSIP_HeaderContact.Parse(contact);
                if (hdr_contacts != null && hdr_contacts.Count > 0)
                {
                    request.Contact = hdr_contacts[0];
                }

                /* Add capabilities as per RFC 3840 */
                if (request.Contact != null)
                {
                    foreach (TSK_Param param in mSipSession.Caps)
                    {
                        request.Contact.Params = TSK_Param.AddParam(request.Contact.Params, param.Name, param.Value);
                    }
                }

                break;
            }
            }

            /* Update authorizations */
            if (mState == tsip_dialog_state_t.Initial && mChallenges == null || mChallenges.Count == 0)
            {
                /* 3GPP TS 33.978 6.2.3.1 Procedures at the UE
                 *              On sending a REGISTER request in order to indicate support for early IMS security procedures, the UE shall not
                 *              include an Authorization header field and not include header fields or header field values as required by RFC3329.
                 */
                if (request.IsREGISTER && !this.Stack.EarlyIMS)
                {
                    /*	3GPP TS 24.229 - 5.1.1.2.2 Initial registration using IMS AKA
                     *                  On sending a REGISTER request, the UE shall populate the header fields as follows:
                     *                          a) an Authorization header field, with:
                     *                          - the "username" header field parameter, set to the value of the private user identity;
                     *                          - the "realm" header field parameter, set to the domain name of the home network;
                     *                          - the "uri" header field parameter, set to the SIP URI of the domain name of the home network;
                     *                          - the "nonce" header field parameter, set to an empty value; and
                     *                          - the "response" header field parameter, set to an empty value;
                     */
                    String      realm        = this.Stack.Realm != null ? this.Stack.Realm.Host : "(null)";
                    String      request_uri_ = TSIP_Uri.ToString(request.Uri, false, false);
                    TSIP_Header auth_hdr     = TSIP_Challenge.CreateEmptyAuthorization(this.Stack.PrivateIdentity, realm, request_uri_);
                    if (auth_hdr != null)
                    {
                        request.AddHeader(auth_hdr);
                    }
                }
            }
            else if (mChallenges != null && mChallenges.Count > 0)
            {
                TSIP_Header auth_hdr;
                foreach (TSIP_Challenge challenge in mChallenges)
                {
                    auth_hdr = challenge.CreateHeaderAuthorization(request);
                    if (auth_hdr != null)
                    {
                        request.AddHeader(auth_hdr);
                    }
                }
            }

            /* Update CSeq */

            /*	RFC 3261 - 13.2.2.4 2xx Responses
             * Generating ACK: The sequence number of the CSeq header field MUST be
             * the same as the INVITE being acknowledged, but the CSeq method MUST
             * be ACK.  The ACK MUST contain the same credentials as the INVITE.  If
             * the 2xx contains an offer (based on the rules above), the ACK MUST
             * carry an answer in its body.
             * ==> CSeq number will be added/updated by the caller of this function,
             * credentials were added above.
             */
            if (!request.IsACK && !request.IsCANCEL)
            {
                request.CSeq.CSeq = ++mCSeqValue;
            }

            /* Route generation
             *	==> http://betelco.blogspot.com/2008/11/proxy-and-service-route-discovery-in.html
             * The dialog Routes have been copied above.
             *
             *          3GPP TS 24.229 - 5.1.2A.1 UE-originating case
             *
             *          The UE shall build a proper preloaded Route header field value for all new dialogs and standalone transactions. The UE
             *          shall build a list of Route header field values made out of the following, in this order:
             *          a) the P-CSCF URI containing the IP address or the FQDN learnt through the P-CSCF discovery procedures; and
             *          b) the P-CSCF port based on the security mechanism in use:
             *
             *          - if IMS AKA or SIP digest with TLS is in use as a security mechanism, the protected server port learnt during
             *          the registration procedure;
             *          - if SIP digest without TLS, NASS-IMS bundled authentciation or GPRS-IMS-Bundled authentication is in
             *          use as a security mechanism, the unprotected server port used during the registration procedure;
             *          c) and the values received in the Service-Route header field saved from the 200 (OK) response to the last
             *          registration or re-registration of the public user identity with associated contact address.
             */
            if (!request.IsREGISTER)
            {     // According to the above link ==> Initial/Re/De registration do not have routes.
                if (copy_routes_start != -1)
                { /* The dialog already have routes ==> copy them. */
                    if (mState == tsip_dialog_state_t.Early || mState == tsip_dialog_state_t.Established)
                    {
                        Int32 index = -1;
                        foreach (TSIP_HeaderRecordRoute record_route in mRecordRoutes)
                        {
                            TSIP_Uri uri = record_route.Uri;
                            if (++index < copy_routes_start || uri == null)
                            {
                                continue;
                            }
                            TSIP_HeaderRoute route = new TSIP_HeaderRoute(uri);
                            // copy parameters: see http://code.google.com/p/imsdroid/issues/detail?id=52
                            route.Params.AddRange(record_route.Params);
                            request.AddHeader(route);
                        }
                    }
                }
            }
            else
            {/* No routes associated to this dialog. */
                if (mState == tsip_dialog_state_t.Initial || mState == tsip_dialog_state_t.Early)
                {
                    /*	GPP TS 24.229 section 5.1.2A [Generic procedures applicable to all methods excluding the REGISTER method]:
                     *                      The UE shall build a proper preloaded Route header field value for all new dialogs and standalone transactions. The UE
                     *                      shall build a list of Route header field values made out of the following, in this order:
                     *                      a) the P-CSCF URI containing the IP address or the FQDN learnt through the P-CSCF discovery procedures; and
                     *                      b) the P-CSCF port based on the security mechanism in use:
                     *                              - if IMS AKA or SIP digest with TLS is in use as a security mechanism, the protected server port learnt during
                     *                              the registration procedure;
                     *                              - if SIP digest without TLS, NASS-IMS bundled authentciation or GPRS-IMS-Bundled authentication is in
                     *                              use as a security mechanism, the unprotected server port used during the registration procedure;
                     *                      c) and the values received in the Service-Route header field saved from the 200 (OK) response to the last
                     *                      registration or re-registration of the public user identity with associated contact address.
                     */
#if _DEBUG && SDS_HACK
                    /* Ericsson SDS hack (INVITE with Proxy-CSCF as First route fail) */
#else
                    TSIP_Uri uri = this.Stack.GetProxyCSCFUri(true);
                    // Proxy-CSCF as first route
                    if (uri != null)
                    {
                        request.AddHeader(new TSIP_HeaderRoute(uri));
                    }
#endif
                    // Service routes
                    foreach (TSIP_Uri uriServiceRoute in mServiceRoutes)
                    {
                        request.AddHeader(new TSIP_HeaderRoute(uriServiceRoute));
                    }
                }
            }

            /* Add headers associated to the dialog's session */
            foreach (TSK_Param param in mSipSession.Headers)
            {
                request.AddHeader(new TSIP_HeaderDummy(param.Name, param.Value));
            }

            /* Add headers associated to the dialog's stack */
            foreach (TSK_Param param in this.Stack.Headers)
            {
                request.AddHeader(new TSIP_HeaderDummy(param.Name, param.Value));
            }

            /* Add common headers */
            this.AddCommonHeaders(request);

            /* SigComp */


            return(request);
        }
 public TSIP_HeaderContact(String displayName, TSIP_Uri uri, Int64 expires)
     : base(tsip_header_type_t.Contact)
 {
     mDisplayName = displayName;
     mUri = uri;
     mExpires = expires;
 }
 public TSIP_HeaderFrom(String displayName, TSIP_Uri uri, String tag)
     : base(tsip_header_type_t.From)
 {
     this.DisplayName = displayName;
     this.Uri = uri;
     this.Tag = tag;
 }
        protected Int64 GetNewDelay(TSIP_Response response)
        {
            Int64       expires  = mExpires;
            Int64       newdelay = expires; /* default value */
            TSIP_Header hdr;
            int         i;

            /*== NOTIFY with subscription-state header with expires parameter */
            if (response.CSeq.RequestType == TSIP_Message.tsip_request_type_t.NOTIFY)
            {
                TSIP_HeaderSubscriptionState hdr_state = response.GetHeader(TSIP_Header.tsip_header_type_t.Subscription_State) as TSIP_HeaderSubscriptionState;
                if (hdr_state != null && hdr_state.Expires > 0)
                {
                    expires = TSK_Time.Seconds2Milliseconds(hdr_state.Expires);
                    goto compute;
                }
            }

            /*== Expires header */
            if ((hdr = response.GetHeader(TSIP_Header.tsip_header_type_t.Expires)) != null)
            {
                expires = TSK_Time.Seconds2Milliseconds((hdr as TSIP_HeaderExpires).DeltaSeconds);
                goto compute;
            }

            /*== Contact header */
            for (i = 0; (hdr = response.GetHeaderAtIndex(TSIP_Header.tsip_header_type_t.Contact, i)) != null; i++)
            {
                TSIP_HeaderContact contact = hdr as TSIP_HeaderContact;

                if (contact != null && contact.Uri != null)
                {
                    String   transport  = TSK_Param.GetValueByName(contact.Uri.Params, "transport");
                    TSIP_Uri contactUri = this.Stack.GetContactUri(String.IsNullOrEmpty(transport) ? "udp" : transport);
                    if (contactUri != null)
                    {
                        if (String.Equals(contact.Uri.UserName, contactUri.UserName) &&
                            String.Equals(contact.Uri.Host, contactUri.Host) &&
                            contact.Uri.Port == contactUri.Port)
                        {
                            if (contact.Expires >= 0) /* No expires parameter ==> -1*/
                            {
                                expires = TSK_Time.Seconds2Milliseconds(contact.Expires);
                                goto compute;
                            }
                        }
                    }
                }
            }

            /*
             *	3GPP TS 24.229 -
             *
             *	The UE shall reregister the public user identity either 600 seconds before the expiration time if the initial
             *	registration was for greater than 1200 seconds, or when half of the time has expired if the initial registration
             *	was for 1200 seconds or less.
             */
compute:
            expires  = TSK_Time.Milliseconds2Seconds(expires);
            newdelay = (expires > 1200) ? (expires - 600) : (expires / 2);

            return(TSK_Time.Seconds2Milliseconds(newdelay));
        }
        /// <summary>
        /// Updates the dialog state:
        /// - Authorizations (using challenges from the @a response message)
        /// - State (early, established, disconnected, ...)
        /// - Routes (and Service-Route)
        /// - Target (remote)
        /// - ...
        /// </summary>
        /// <param name="response"></param>
        /// <returns></returns>
        protected Boolean UpdateWithResponse(TSIP_Response response)
        {
            if (response == null || response.To == null || response.CSeq == null)
            {
                return(false);
            }
            String tag = response.To.Tag;

            /*
             *	1xx (!100) or 2xx
             */
            /*
             *	401 or 407 or 421 or 494
             */
            if (response.StatusCode == 401 || response.StatusCode == 407 || response.StatusCode == 421 || response.StatusCode == 494)
            {
                Boolean acceptNewVector;

                /* 3GPP IMS - Each authentication vector is used only once.
                 *	==> Re-registration/De-registration ==> Allow 401/407 challenge.
                 */
                acceptNewVector = (response.CSeq.RequestType == TSIP_Message.tsip_request_type_t.REGISTER && this.State == tsip_dialog_state_t.Established);
                return(this.UpdateChallenges(response, acceptNewVector));
            }
            else if (100 < response.StatusCode && response.StatusCode < 300)
            {
                tsip_dialog_state_t state = this.State;

                /* 1xx */
                if (response.StatusCode <= 199)
                {
                    if (String.IsNullOrEmpty(response.To.Tag))
                    {
                        TSK_Debug.Error("Invalid tag  parameter");
                        return(false);
                    }
                    state = tsip_dialog_state_t.Early;
                }
                /* 2xx */
                else
                {
                    state = tsip_dialog_state_t.Established;
                }

                /* Remote target */
                {
                    /*	RFC 3261 12.2.1.2 Processing the Responses
                     *  When a UAC receives a 2xx response to a target refresh request, it
                     *  MUST replace the dialog's remote target URI with the URI from the
                     *  Contact header field in that response, if present.
                     *
                     *  FIXME: Because PRACK/UPDATE sent before the session is established MUST have
                     *  the rigth target URI to be delivered to the UAS ==> Do not not check that we are connected
                     */
                    if (response.CSeq.RequestType != TSIP_Message.tsip_request_type_t.REGISTER && response.Contact != null && response.Contact.Uri != null)
                    {
                        mUriRemoteTarget = response.Contact.Uri.Clone(true, false);
                    }
                }

                /* Route sets */
                {
                    int index;
                    TSIP_HeaderRecordRoute recordRoute;

                    mRecordRoutes.Clear();

                    for (index = 0; (recordRoute = response.GetHeaderAtIndex(TSIP_Header.tsip_header_type_t.Record_Route, index) as TSIP_HeaderRecordRoute) != null; index++)
                    {
                        mRecordRoutes.Insert(0, recordRoute); /* Copy reversed. */
                    }
                }

                /* cseq + tags + ... */
                if (this.State == tsip_dialog_state_t.Established && String.Equals(mTagRemote, tag, StringComparison.InvariantCultureIgnoreCase))
                {
                    return(true);
                }
                else
                {
                    if (response.CSeq.RequestType != TSIP_Message.tsip_request_type_t.REGISTER && response.CSeq.RequestType != TSIP_Message.tsip_request_type_t.PUBLISH)
                    { /* REGISTER and PUBLISH don't establish dialog */
                        mTagRemote = tag;
                    }
#if NEVER_EXECUTE_00    // PRACK and BYE will have same CSeq value ==> Let CSeq value to be incremented by "tsip_dialog_request_new()"
                    self->cseq_value = response->CSeq ? response->CSeq->seq : self->cseq_value;
#endif
                }

                this.State = state;
                return(true);
            }

            return(true);
        }
        // Constructor
        public MainPage()
        {
            InitializeComponent();


            String mm = "SIP/2.0 200 OK\r\n" +
                        "Via: SIP/2.0/UDP 192.168.0.13:5060;branch=z9hG4bK_56ef1cda-aef6-4d76-ab7e-d148af3b18ac;rport=51049\r\n" +
                        "Record-Route: <sip:192.168.0.10:5060;lr;transport=udp>\r\n" +
                        "To: <sip:[email protected]>\r\n" +
                        "From: <sip:[email protected]>;tag=9bff9c34-35e3-4fa8-8de4-290ce275c981\r\n" +
                        "Call-ID: 272b67b9-08b2-4fce-8f6e-6ccaf5e5ec9a\r\n" +
                        "CSeq: 1990525622 REGISTER\r\n" +
                        "Server: mjsip stack 1.6\r\n" +
                        "Contact: <sip:[email protected]:5060>;expires=10\r\n" +
                        "Content-Length: 0\r\n" +
                        "\r\n";

            /*TSIP_Message message = TSIP_ParserMessage.Parse(UTF8Encoding.UTF8.GetBytes(mm), true);
             * if (message != null)
             * {
             * }*/



            TSIP_Stack sipStack = new TSIP_Stack(
                TSIP_Uri.Create("sip:doubango.org"),
                "004",
                TSIP_Uri.Create("sip:[email protected]"),
                "192.168.0.10", 5060
                );

            // sipStack.Headers.Add(new TSK_Param("User-Agent", "wp-ngn-stack"));
            sipStack.AoRIP   = "192.168.0.13";
            sipStack.AoRPort = 5060;

            sipStack.Callback = delegate(TSIP_Event @event)
            {
                switch (@event.Type)
                {
                case TSIP_Event.tsip_event_type_t.DIALOG:
                {
                    TSIP_EventDialog eventDialog = (@event as TSIP_EventDialog);
                    break;
                }

                case TSIP_Event.tsip_event_type_t.REGISTER:
                {
                    TSIP_EventRegister eventDialog = (@event as TSIP_EventRegister);
                    break;
                }

                default:
                {
                    return(false);
                }
                }
                return(true);
            };


            if (sipStack.Start())
            {
                TSIP_SessionRegister register = new TSIP_SessionRegister(sipStack);
                register.Register();
            }
        }
 public TSIP_HeaderRecordRoute(TSIP_Uri uri)
     : base(tsip_header_type_t.Record_Route)
 {
     mUri = uri;
 }
Exemple #18
0
 public TSIP_HeaderRoute(TSIP_Uri uri)
     : base(tsip_header_type_t.Record_Route)
 {
     mUri = uri;
 }