예제 #1
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="requestUri">The request URI.</param>
 /// <param name="to">Populates the request's <b>To</b> header.</param>
 /// <param name="from">Populates the request's <b>From</b> header.</param>
 /// <param name="desiredTTL">The requested lifetime of the registration.</param>
 /// <remarks>
 /// <para>
 /// The RFC 3261 requires that UACs use the same Call-ID for all REGISTER requests
 /// made to a registrar and also that that UA must increment the CSeq value by
 /// one for each request.  The UAC will need to track these values and pass them
 /// to this constructor.
 /// </para>
 /// </remarks>
 public SipRegisterRequest(string requestUri, string to, string from, TimeSpan desiredTTL)
     : base(SipMethod.Register, requestUri, SipHelper.SIP20)
 {
     base.AddHeader(SipHeader.To, to);
     base.AddHeader(SipHeader.From, from);
     base.AddHeader(SipHeader.CallID, SipHelper.GenerateCallID());
     base.AddHeader(SipHeader.Expires, ((int)desiredTTL.TotalSeconds).ToString());
 }
예제 #2
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="requestUri">The request URI.</param>
        /// <param name="to">Populates the request's <b>To</b> header.</param>
        /// <param name="from">Populates the request's <b>From</b> header.</param>
        /// <param name="sdp">The SDP information describing this side's session media.</param>
        public SipInviteRequest(string requestUri, string to, string from, SdpPayload sdp)
            : base(SipMethod.Invite, requestUri, SipHelper.SIP20)
        {
            base.AddHeader(SipHeader.To, to);
            base.AddHeader(SipHeader.From, from);
            base.AddHeader(SipHeader.CallID, SipHelper.GenerateCallID());
            base.AddHeader("Allow", "ACK, CANCEL, BYE");
            base.AddHeader("Accept", SipHelper.SdpMimeType);
            base.AddHeader("Content-Disposition", "session");

            base.Contents = Helper.ToUTF8(sdp.ToString());
        }
예제 #3
0
        /// <summary>
        /// Initiates an asynchronous SIP request transaction.
        /// </summary>
        /// <param name="request">The <see cref="SipRequest" /> to be submitted.</param>
        /// <param name="dialog">The <see cref="SipDialog" /> for requests that initiate a dialog (or <c>null</c>).</param>
        /// <param name="callback">The delegate to be called when the operation completes (or <c>null</c>).</param>
        /// <param name="state">Application defined state (or <c>null</c>).</param>
        /// <returns>The <see cref="IAsyncResult" /> to be used to track the operation's progress.</returns>
        /// <remarks>
        /// <para>
        /// All requests to <see cref="BeginRequest(SipRequest,SipDialog,AsyncCallback,object)" /> must be matched with a
        /// call to <see cref="EndRequest" />.
        /// </para>
        /// <note>
        /// This method adds reasonable <b>Call-ID</b> and <b>CSeq</b> headers to the request if these
        /// headers are not already present.
        /// </note>
        /// </remarks>
        public IAsyncResult BeginRequest(SipRequest request, SipDialog dialog, AsyncCallback callback, object state)
        {
            ClientAsyncResult    arClient = new ClientAsyncResult(request, dialog, callback, state);
            SipValue             viaValue;
            SipCSeqValue         vCSeq;
            string               transactionID;
            SipClientTransaction transaction;
            ISipTransport        transport;
            NetworkBinding       remoteEP;

            if (dialog != null && request.Method != SipMethod.Invite)
            {
                throw new InvalidOperationException("Dialogs may be created only for INVITE requests.");
            }

            arClient.Dialog = dialog;

            transport = router.SelectTransport(this, request, out remoteEP);
            if (transport == null)
            {
                throw new SipException("No approriate transport is available.");
            }

            // Initialize the request's Via header and transaction ID as necessary.

            transactionID      = SipHelper.GenerateBranchID();
            viaValue           = new SipValue(string.Format("SIP/2.0/{0} {1}", transport.Name, transport.Settings.ExternalBinding.Address));
            viaValue["branch"] = transactionID;
            viaValue["rport"]  = string.Empty;

            request.PrependHeader(SipHeader.Via, viaValue);

            // Initialize common headers as necessary

            if (!request.ContainsHeader(SipHeader.CallID))
            {
                request.AddHeader(SipHeader.CallID, SipHelper.GenerateCallID());
            }

            vCSeq = request.GetHeader <SipCSeqValue>(SipHeader.CSeq);
            if (vCSeq == null)
            {
                vCSeq = new SipCSeqValue(SipHelper.GenCSeq(), request.MethodText);
                request.AddHeader(SipHeader.CSeq, vCSeq);
            }

            // Initialize the transaction

            transaction            = new SipClientTransaction(this, request, transactionID, transport, remoteEP);
            transaction.AgentState = arClient;

            // Handle initial dialog INVITE specific initialization

            if (dialog != null && request.Method == SipMethod.Invite && dialog.State == SipDialogState.Waiting)
            {
                // Client-side dialogs need to know the transaction so
                // they'll be able to send the confirming ACK.

                dialog.InitiatingTransaction = transaction;

                // Dialogs need to know about the sequence number used in INVITE requests so
                // that the ACK can be generated with the same sequence number.

                dialog.AckCSeq = vCSeq.Number;

                // The dialog has been intialized enough to be added to the core's
                // early dialog table.

                core.AddEarlyDialog(dialog);
            }

            // Start the transaction

            using (TimedLock.Lock(this))
            {
                transactions.Add(transactionID, transaction);
            }

            transaction.Start();
            arClient.Started();

            return(arClient);
        }