Example #1
0
 /// <summary>
 /// Sets the remote end point for the RTP channel. This will be set from the SDP packet received from the remote
 /// end of the VoIP call.
 /// </summary>
 /// <param name="remoteEndPoint">The remote end point to send RTP to.</param>
 public void SetRemoteRTPEndPoints(IPEndPoint audioRemoteEndPoint, IPEndPoint videoRemoteEndPoint)
 {
     if (audioRemoteEndPoint != null)
     {
         logger.Debug("Remote RTP audio end point set as " + audioRemoteEndPoint + ".");
         _rtpAudioChannel.RemoteEndPoint = audioRemoteEndPoint;
         _rtpAudioChannel.Start();
     }
     else if (videoRemoteEndPoint != null)
     {
         logger.Debug("Remote RTP video end point set as " + videoRemoteEndPoint + ".");
         _remoteVideoEP = videoRemoteEndPoint;
         _rtpVideoChannel.RemoteEndPoint = videoRemoteEndPoint;
         _rtpVideoChannel.Start();
     }
 }
Example #2
0
        /// <summary>
        /// 实时视频请求
        /// </summary>
        public void RealVideoRequest()
        {
            SipInitialize();
            _mediaPort = _messageCore.SetMediaPort();

            SIPRequest request = InviteRequest();
            RealVideo  real    = new RealVideo()
            {
                Address    = _cameraId,
                Variable   = VariableType.RealMedia,
                Privilege  = 90,
                Format     = "4CIF CIF QCIF 720p 1080p",
                Video      = "H.264",
                Audio      = "G.711",
                MaxBitrate = 800,
                Socket     = this.ToString()
            };

            string xmlBody = RealVideo.Instance.Save <RealVideo>(real);

            request.Body = xmlBody;
            _m_sipTransport.SendRequest(_remoteEndPoint, request);

            //启动RTP通道
            _rtpChannel.IsClosed = false;
            _rtpChannel.ReservePorts(_mediaPort[0], _mediaPort[1]);
            _rtpChannel.Start();
        }
        /// <summary>
        /// 确认接收视频请求
        /// </summary>
        /// <param name="response">响应消息</param>
        /// <returns></returns>
        public void AckRequest(SIPResponse response)
        {
            _rtpChannel = new RTPChannel(_remoteEndPoint.GetIPEndPoint(), _mediaPort[0], _mediaPort[1], FrameTypesEnum.H264);
            _rtpChannel.OnFrameReady += _rtpChannel_OnFrameReady;
            _rtpChannel.Start();

            SIPURI           localUri      = new SIPURI(_msgCore.LocalSIPId, _msgCore.LocalEndPoint.ToHost(), "");
            SIPURI           remoteUri     = new SIPURI(_deviceId, _remoteEndPoint.ToHost(), "");
            SIPRequest       ackReq        = _msgCore.Transport.GetRequest(SIPMethodsEnum.ACK, remoteUri);
            SIPFromHeader    from          = new SIPFromHeader(null, response.Header.From.FromURI, response.Header.From.FromTag);
            SIPToHeader      to            = new SIPToHeader(null, remoteUri, response.Header.To.ToTag);
            SIPContactHeader contactHeader = new SIPContactHeader(null, localUri);
            SIPHeader        header        = new SIPHeader(from, to, response.Header.CSeq, response.Header.CallId);

            header.CSeqMethod = SIPMethodsEnum.ACK;
            header.Contact    = response.Header.Contact;
            header.Contact.Clear();
            header.Contact.Add(contactHeader);
            header.Vias          = response.Header.Vias;
            header.MaxForwards   = response.Header.MaxForwards;
            header.ContentLength = response.Header.ContentLength;
            header.UserAgent     = _msgCore.UserAgent;
            header.Allow         = null;
            ackReq.Header        = header;
            _okTag   = response.Header.To.ToTag;
            _contact = header.Contact.FirstOrDefault();
            _via     = header.Vias;
            _msgCore.Transport.SendRequest(_remoteEndPoint, ackReq);
        }
Example #4
0
        public void MultipleRtpChannelLoopbackUnitTest()
        {
            logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name);
            logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name);

            const int PACKET_LENGTH = 100;

            List <Task> tasks = new List <Task>();

            for (int i = 0; i < 3; i++)
            {
                var t = Task.Run(async() =>
                {
                    RTPChannel channel1 = new RTPChannel(false, null);

                    bool testResult = false;
                    ManualResetEventSlim testCompleteEvent = new ManualResetEventSlim(false);

                    RTPChannel channel2         = new RTPChannel(false, null);
                    channel2.OnRTPDataReceived += (lep, rep, pkt) =>
                    {
                        logger.LogDebug($"RTP data receive packet length {pkt.Length}.");
                        testResult = pkt.Length == PACKET_LENGTH;
                        testCompleteEvent.Set();
                    };

                    channel1.Start();
                    channel2.Start();

                    // Give the socket receive tasks time to fire up.
                    await Task.Delay(2000);

                    IPAddress channel2Address = (channel2.RTPLocalEndPoint.AddressFamily == AddressFamily.InterNetworkV6) ? IPAddress.IPv6Loopback : IPAddress.Loopback;
                    IPEndPoint channel2Dst    = new IPEndPoint(channel2Address, channel2.RTPPort);

                    logger.LogDebug($"Attempting to send packet from {channel1.RTPLocalEndPoint} to {channel2Dst}.");

                    var sendResult = channel1.SendAsync(RTPChannelSocketsEnum.RTP, channel2Dst, new byte[PACKET_LENGTH]);

                    logger.LogDebug($"Send result {sendResult}.");

                    testCompleteEvent.Wait(TimeSpan.FromSeconds(TEST_TIMEOUT_SECONDS));

                    Assert.True(testResult);

                    channel1.Close("normal");
                    channel2.Close("normal");
                });

                tasks.Add(t);
            }

            CancellationTokenSource cts = new CancellationTokenSource();

            Assert.True(Task.WaitAll(tasks.ToArray(), 10000, cts.Token));

            logger.LogDebug($"Test complete.");
        }
Example #5
0
        public async void RtpChannelLoopbackUnitTest()
        {
            logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name);
            logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name);

            RTPChannel channel1 = new RTPChannel(false, null);

            bool testResult = false;
            ManualResetEventSlim testCompleteEvent = new ManualResetEventSlim(false);

            RTPChannel channel2 = new RTPChannel(false, null);

            channel2.OnRTPDataReceived += (lep, rep, pkt) =>
            {
                logger.LogDebug($"RTP data receive packet length {pkt.Length}.");
                testResult = true;
                testCompleteEvent.Set();
            };

            channel1.Start();
            channel2.Start();

            // Give the socket receive tasks time to fire up.
            await Task.Delay(1000);

            IPAddress  channel2Address = (channel2.RTPLocalEndPoint.AddressFamily == AddressFamily.InterNetworkV6) ? IPAddress.IPv6Loopback : IPAddress.Loopback;
            IPEndPoint channel2Dst     = new IPEndPoint(channel2Address, channel2.RTPPort);

            logger.LogDebug($"Attempting to send packet from {channel1.RTPLocalEndPoint} to {channel2Dst}.");

            var sendResult = channel1.SendAsync(RTPChannelSocketsEnum.RTP, channel2Dst, new byte[] { 0x00 });

            logger.LogDebug($"Send result {sendResult}.");

            testCompleteEvent.Wait(TimeSpan.FromSeconds(TEST_TIMEOUT_SECONDS));

            Assert.True(testResult);

            channel1.Close("normal");
            channel2.Close("normal");

            logger.LogDebug($"Test complete.");
        }
Example #6
0
        private void Uac_CallAnswered(ISIPClientUserAgent uac, SIPResponse sipResponse)
        {
            logger.Debug($"{ prefix } Call answered; { sipResponse.StatusCode } { sipResponse.Status }");

            switch (sipResponse.StatusCode)
            {
            case 404:
                logger.Error($"{ prefix } Received 404 Not Found from remote endpoint");
                break;

            case 486:
                // Busy
                logger.Error($"{ prefix } Received 486 Remote endpoint is busy; try again later");
                break;

            case 488:
                // Possible audio format issue
                logger.Error($"{ prefix } Received 488 Not Acceptable from remote endpoint; check audio format");
                break;

            case 503:
                // Check Twilio service and geo-permissions
                logger.Error($"{ prefix } Received 503 Service Unavailable from remote endpoint; check service permissions");
                break;

            case 200:
                if (sipResponse.Header.ContentType != SDP.SDP_MIME_CONTENTTYPE)
                {
                    logger.Error($"{ prefix } Received incorrect content type");

                    Stop();
                    return;
                }

                if (sipResponse.Body.IsNullOrBlank())
                {
                    logger.Error($"{ prefix } Received an empty SDP payload");

                    Stop();
                    return;
                }

                var sdp          = SDP.ParseSDPDescription(sipResponse.Body);
                var ip           = IPAddress.Parse(sdp.Connection.ConnectionAddress);
                var announcement = sdp.Media.Where(x => x.Media == SDPMediaTypesEnum.audio).FirstOrDefault();

                if (announcement != null)
                {
                    if (announcement.Port != 0)
                    {
                        rtpChannel.OnControlDataReceived       += (b) => { logger.Debug($"{prefix} Control Data Received; {b.Length} bytes"); };
                        rtpChannel.OnControlSocketDisconnected += () => { logger.Debug($"{prefix} Control Socket Disconnected"); };

                        rtpChannel.RemoteEndPoint = new IPEndPoint(ip, announcement.Port);
                        rtpChannel.Start();

                        // Send some setup parameters to punch a hole in the firewall/router
                        rtpChannel.SendRTPRaw(new byte[] { 80, 95, 198, 88, 55, 96, 225, 141, 215, 205, 185, 242, 00 });
                    }
                    else
                    {
                        logger.Error($"{ prefix } Remote endpoint did not specify a port number");
                        return;
                    }
                }
                else
                {
                    logger.Error($"{ prefix } Remote endpoint has not valid audio announcement");
                    return;
                }
                break;
            }
        }
        private void Transport_SIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
        {
            var endpoint = new SIPEndPoint(SIPProtocolsEnum.udp, publicIPAddress, localSIPEndPoint.Port);

            if (sipRequest.Method == SIPMethodsEnum.INVITE)
            {
                if (transaction != null)
                {
                    return;
                }

                logger.DebugFormat("{0} Incoming call from {1}", prefix, sipRequest.Header.From.FromURI.User);

                transaction = transport.CreateUASTransaction(sipRequest, remoteEndPoint, endpoint, null);
                agent       = new SIPServerUserAgent(
                    transport,
                    null,
                    sipRequest.Header.From.FromURI.User,
                    null,
                    SIPCallDirection.In,
                    null,
                    null,
                    null,
                    transaction);

                agent.CallCancelled       += Agent_CallCancelled;
                agent.TransactionComplete += Agent_TransactionComplete;

                agent.Progress(SIPResponseStatusCodesEnum.Trying, null, null, null, null);
                agent.Progress(SIPResponseStatusCodesEnum.Ringing, null, null, null, null);

                var answer  = SDP.ParseSDPDescription(agent.CallRequest.Body);
                var address = IPAddress.Parse(answer.Connection.ConnectionAddress);
                var port    = answer.Media.FirstOrDefault(m => m.Media == SDPMediaTypesEnum.audio).Port;
                var random  = Crypto.GetRandomInt(5).ToString();
                var sdp     = new SDP
                {
                    Version     = 2,
                    Username    = "******",
                    SessionId   = random,
                    Address     = localIPEndPoint.Address.ToString(),
                    SessionName = "redfox_" + random,
                    Timing      = "0 0",
                    Connection  = new SDPConnectionInformation(publicIPAddress.ToString())
                };

                rtpChannel = new RTPChannel
                {
                    DontTimeout    = true,
                    RemoteEndPoint = new IPEndPoint(address, port)
                };

                rtpChannel.SetFrameType(FrameTypesEnum.Audio);
                // TODO Fix hardcoded ports
                rtpChannel.ReservePorts(15000, 15090);
                rtpChannel.OnFrameReady += Channel_OnFrameReady;
                rtpChannel.Start();

                // Send some setup parameters to punch a hole in the firewall/router
                rtpChannel.SendRTPRaw(new byte[] { 80, 95, 198, 88, 55, 96, 225, 141, 215, 205, 185, 242, 00 });

                rtpChannel.OnControlDataReceived       += (b) => { logger.Debug($"{prefix} Control Data Received; {b.Length} bytes"); };
                rtpChannel.OnControlSocketDisconnected += () => { logger.Debug($"{prefix} Control Socket Disconnected"); };

                var announcement = new SDPMediaAnnouncement
                {
                    Media        = SDPMediaTypesEnum.audio,
                    MediaFormats = new List <SDPMediaFormat>()
                    {
                        new SDPMediaFormat((int)SDPMediaFormatsEnum.PCMU, "PCMU", 8000)
                    },
                    Port = rtpChannel.RTPPort
                };

                sdp.Media.Add(announcement);

                SetState(State.Listening, sipRequest.Header.From.FromURI.User);

                agent.Progress(SIPResponseStatusCodesEnum.Accepted, null, null, null, null);
                agent.Answer(SDP.SDP_MIME_CONTENTTYPE, sdp.ToString(), null, SIPDialogueTransferModesEnum.NotAllowed);

                SetState(State.Busy, "");
                return;
            }
            if (sipRequest.Method == SIPMethodsEnum.BYE)
            {
                if (State != State.Busy)
                {
                    return;
                }

                logger.DebugFormat("{0} Hangup from {1}", prefix, sipRequest.Header.From.FromURI.User);

                var noninvite = transport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, endpoint, null);
                var response  = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);

                noninvite.SendFinalResponse(response);

                SetState(State.Finished, Endpoint);

                rtpChannel.OnFrameReady -= Channel_OnFrameReady;
                rtpChannel.Close();

                agent.TransactionComplete -= Agent_TransactionComplete;
                agent.CallCancelled       -= Agent_CallCancelled;
                agent       = null;
                transaction = null;

                SetState(State.Ready, Endpoint);

                return;
            }
            if (sipRequest.Method == SIPMethodsEnum.ACK)
            {
            }
            if (sipRequest.Method == SIPMethodsEnum.CANCEL)
            {
            }
        }