Reject() public method

public Reject ( SIPResponseStatusCodesEnum failureStatus, string reasonPhrase, string customHeaders ) : void
failureStatus SIPResponseStatusCodesEnum
reasonPhrase string
customHeaders string
return void
Esempio n. 1
0
        /// <summary>
        /// This method can be used to start the processing of a new incoming call request.
        /// The user agent will is acting as a server for this operation and it can be considered
        /// the opposite of the Call method.
        /// </summary>
        /// <param name="uasInviteTx">The invite transaction representing the incoming call.</param>
        /// <returns>True if the call is accepted, false otherwise.</returns>
        public bool AcceptCall(UASInviteTransaction uasInviteTx)
        {
            SIPServerUserAgent uas = new SIPServerUserAgent(m_transport, m_outboundProxy, null, null, SIPCallDirection.In, null, null, null, uasInviteTx);

            uas.Progress(SIPResponseStatusCodesEnum.Trying, null, null, null, null);

            // TODO: Decide how to deal with multiple simultaneous calls.
            if (m_uas != null)
            {
                uas.Reject(SIPResponseStatusCodesEnum.BusyHere, null, null);
                return(false);
            }
            else
            {
                uas.Progress(SIPResponseStatusCodesEnum.Ringing, null, null, null, null);
                m_uas = uas;
                return(true);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Answers the call request contained in the user agent server parameter. Note the
        /// <see cref="AcceptCall(SIPRequest)"/> method should be used to create the user agent server.
        /// Any existing call will be hungup.
        /// </summary>
        /// <param name="uas">The user agent server holding the pending call to answer.</param>
        /// <param name="mediaSession">The media session used for this call</param>
        /// <param name="customHeaders">Custom SIP-Headers to use in Answer.</param>
        public async Task Answer(SIPServerUserAgent uas, IMediaSession mediaSession, string[] customHeaders)
        {
            // This call is now taking over any existing call.
            if (IsCallActive)
            {
                Hangup();
            }
            else if (uas.IsCancelled)
            {
                logger.LogDebug("The incoming call has been cancelled.");
                mediaSession?.Close("call cancelled");
            }
            else
            {
                m_cts = new CancellationTokenSource();
                var sipRequest = uas.ClientTransaction.TransactionRequest;

                MediaSession             = mediaSession;
                MediaSession.OnRtpEvent += OnRemoteRtpEvent;
                //MediaSession.OnRtpClosed += (reason) => Hangup();
                MediaSession.OnRtpClosed += (reason) =>
                {
                    if (!MediaSession.IsClosed)
                    {
                        logger.LogWarning($"RTP channel was closed with reason {reason}.");
                    }
                };

                string sdp = null;

                if (!String.IsNullOrEmpty(sipRequest.Body))
                {
                    // The SDP offer was included in the INVITE request.
                    SDP remoteSdp = SDP.ParseSDPDescription(sipRequest.Body);
                    MediaSession.setRemoteDescription(new RTCSessionDescription {
                        sdp = remoteSdp, type = RTCSdpType.offer
                    });

                    var sdpAnswer = await MediaSession.createAnswer(null).ConfigureAwait(false);

                    if (sdpAnswer == null)
                    {
                        logger.LogWarning($"Could not generate an SDP answer.");
                        m_uas.Reject(SIPResponseStatusCodesEnum.NotAcceptable, null);
                        return;
                    }
                    else
                    {
                        MediaSession.setLocalDescription(new RTCSessionDescription {
                            sdp = sdpAnswer, type = RTCSdpType.answer
                        });
                        sdp = sdpAnswer.ToString();
                    }
                }
                else
                {
                    // No SDP offer was included in the INVITE request need to wait for the ACK.
                    RTCOfferOptions offerOptions = new RTCOfferOptions {
                        RemoteSignallingAddress = sipRequest.RemoteSIPEndPoint.GetIPEndPoint().Address
                    };
                    var sdpOffer = await MediaSession.createOffer(offerOptions).ConfigureAwait(false);

                    if (sdpOffer == null)
                    {
                        // This shouldn't occur unless we're unable to create an audio/video track.
                        logger.LogWarning($"Could not generate an SDP answer.");
                        m_uas.Reject(SIPResponseStatusCodesEnum.NotAcceptable, null);
                        return;
                    }
                    else
                    {
                        MediaSession.setLocalDescription(new RTCSessionDescription {
                            sdp = sdpOffer, type = RTCSdpType.offer
                        });
                        sdp = sdpOffer.ToString();
                    }
                }

                m_uas = uas;

                // In cases where the initial INVITE did not contain an SDP offer the action sequence is:
                // - INVITE with no SDP offer received,
                // - Reply with OK and an SDP offer,
                // - Wait for ACK with SDP answer.
                TaskCompletionSource <SIPDialogue> dialogueCreatedTcs = new TaskCompletionSource <SIPDialogue>(TaskCreationOptions.RunContinuationsAsynchronously);
                m_uas.OnDialogueCreated += (dialogue) => dialogueCreatedTcs.TrySetResult(dialogue);

                m_uas.Answer(m_sdpContentType, sdp, null, SIPDialogueTransferModesEnum.Default, customHeaders);

                await Task.WhenAny(dialogueCreatedTcs.Task, Task.Delay(WAIT_DIALOG_TIMEOUT)).ConfigureAwait(false);

                if (Dialogue != null)
                {
                    if (MediaSession.remoteDescription == null || MediaSession.remoteDescription.sdp == null)
                    {
                        // If the initial INVITE did not contain an offer then the remote description will not yet be set.
                        var remoteSDP = SDP.ParseSDPDescription(Dialogue.RemoteSDP);
                        MediaSession.setRemoteDescription(new RTCSessionDescription {
                            sdp = remoteSDP, type = RTCSdpType.answer
                        });
                    }

                    Dialogue.DialogueState = SIPDialogueStateEnum.Confirmed;

                    await MediaSession.Start().ConfigureAwait(false);
                }
                else
                {
                    logger.LogWarning("The attempt to answer a call failed as the dialog was not created. The likely cause is the ACK not being received in time.");

                    MediaSession.Close("dialog creation failed");
                    Hangup();
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Answers the call request contained in the user agent server parameter. Note the
        /// <see cref="AcceptCall(SIPRequest)"/> method should be used to create the user agent server.
        /// Any existing call will be hungup.
        /// </summary>
        /// <param name="uas">The user agent server holding the pending call to answer.</param>
        /// <param name="mediaSession">The media session used for this call</param>
        /// <param name="customHeaders">Custom SIP-Headers to use in Answer.</param>
        /// <returns>True if the call was successfully answered or false if there was a problem
        /// such as incompatible codecs.</returns>
        public async Task <bool> Answer(SIPServerUserAgent uas, IMediaSession mediaSession, string[] customHeaders)
        {
            // This call is now taking over any existing call.
            if (IsCallActive)
            {
                Hangup();
            }

            if (uas.IsCancelled)
            {
                logger.LogDebug("The incoming call has been cancelled.");
                mediaSession?.Close("call cancelled");
                return(false);
            }
            else
            {
                m_cts = new CancellationTokenSource();
                var sipRequest = uas.ClientTransaction.TransactionRequest;

                MediaSession              = mediaSession;
                MediaSession.OnRtpEvent  += OnRemoteRtpEvent;
                MediaSession.OnRtpClosed += (reason) =>
                {
                    if (!MediaSession.IsClosed)
                    {
                        logger.LogWarning($"RTP channel was closed with reason {reason}.");
                    }
                };

                string sdp = null;

                if (!String.IsNullOrEmpty(sipRequest.Body))
                {
                    // The SDP offer was included in the INVITE request.
                    SDP remoteSdp       = SDP.ParseSDPDescription(sipRequest.Body);
                    var setRemoteResult = MediaSession.SetRemoteDescription(remoteSdp);

                    if (setRemoteResult != SetDescriptionResultEnum.OK)
                    {
                        logger.LogWarning($"Error setting remote description from INVITE {setRemoteResult}.");
                        uas.Reject(SIPResponseStatusCodesEnum.NotAcceptable, setRemoteResult.ToString());
                        MediaSession.Close("sdp offer not acceptable");
                        Hangup();

                        return(false);
                    }
                    else
                    {
                        var sdpAnswer = MediaSession.CreateAnswer(null);
                        sdp = sdpAnswer.ToString();
                    }
                }
                else
                {
                    // No SDP offer was included in the INVITE request need to wait for the ACK.
                    var sdpAnnounceAddress = NetServices.GetLocalAddressForRemote(sipRequest.RemoteSIPEndPoint.GetIPEndPoint().Address);
                    var sdpOffer           = MediaSession.CreateOffer(sdpAnnounceAddress);
                    sdp = sdpOffer.ToString();
                }

                m_uas = uas;

                // In cases where the initial INVITE did not contain an SDP offer the action sequence is:
                // - INVITE with no SDP offer received,
                // - Reply with OK and an SDP offer,
                // - Wait for ACK with SDP answer.
                TaskCompletionSource <SIPDialogue> dialogueCreatedTcs = new TaskCompletionSource <SIPDialogue>(TaskCreationOptions.RunContinuationsAsynchronously);
                m_uas.OnDialogueCreated += (dialogue) => dialogueCreatedTcs.TrySetResult(dialogue);

                m_uas.Answer(m_sdpContentType, sdp, null, SIPDialogueTransferModesEnum.Default, customHeaders);

                await Task.WhenAny(dialogueCreatedTcs.Task, Task.Delay(WAIT_DIALOG_TIMEOUT)).ConfigureAwait(false);

                if (Dialogue != null)
                {
                    if (MediaSession.RemoteDescription == null)
                    {
                        // If the initial INVITE did not contain an offer then the remote description will not yet be set.
                        var remoteSDP       = SDP.ParseSDPDescription(Dialogue.RemoteSDP);
                        var setRemoteResult = MediaSession.SetRemoteDescription(remoteSDP);

                        if (setRemoteResult != SetDescriptionResultEnum.OK)
                        {
                            // Failed to set the remote SDP from the ACK request. Only option is to hangup.
                            logger.LogWarning($"Error setting remote description from ACK {setRemoteResult}.");
                            MediaSession.Close(setRemoteResult.ToString());
                            Hangup();

                            return(false);
                        }
                        else
                        {
                            // SDP from the ACK request was accepted. Start the RTP session.
                            Dialogue.DialogueState = SIPDialogueStateEnum.Confirmed;
                            await MediaSession.Start().ConfigureAwait(false);

                            return(true);
                        }
                    }
                    else
                    {
                        Dialogue.DialogueState = SIPDialogueStateEnum.Confirmed;
                        await MediaSession.Start().ConfigureAwait(false);

                        return(true);
                    }
                }
                else
                {
                    logger.LogWarning("The attempt to answer a call failed as the dialog was not created. The likely cause is the ACK not being received in time.");

                    MediaSession.Close("dialog creation failed");
                    Hangup();

                    return(false);
                }
            }
        }