Exemplo n.º 1
0
        /// <summary>
        /// Handles one message.
        /// </summary>
        /// <param name="message">The message.</param>
        private void HandleOneMessage(RtspMessage message)
        {
            Contract.Requires(message != null);

            RtspListener destination = null;

            if (message is RtspRequest)
            {
                destination = HandleRequest(ref message);
                _logger.Debug("Dispatch message from {0} to {1}",
                              message.SourcePort != null ? message.SourcePort.RemoteAdress : "UNKNOWN", destination != null ? destination.RemoteAdress : "UNKNOWN");

                // HandleRequest can change message type.
                if (message is RtspRequest)
                {
                    var context = new OriginContext();
                    context.OriginCSeq                   = message.CSeq;
                    context.OriginSourcePort             = message.SourcePort;
                    (message as RtspRequest).ContextData = context;
                }
            }
            else if (message is RtspResponse)
            {
                RtspResponse response = message as RtspResponse;

                if (response.OriginalRequest != null)
                {
                    var context = response.OriginalRequest.ContextData as OriginContext;
                    if (context != null)
                    {
                        destination   = context.OriginSourcePort;
                        response.CSeq = context.OriginCSeq;
                        _logger.Debug("Dispatch response back to {0}", destination.RemoteAdress);
                    }
                }

                HandleResponse(response);
            }

            if (destination != null)
            {
                bool isGood = destination.SendMessage(message);

                if (!isGood)
                {
                    destination.Stop();
                    _serverListener.Remove(destination.RemoteAdress);

                    // send back a message because we can't forward.
                    if (message is RtspRequest && message.SourcePort != null)
                    {
                        RtspRequest  request           = message as RtspRequest;
                        RtspResponse theDirectResponse = request.CreateResponse();
                        _logger.Warn("Error during forward : {0}. So sending back a direct error response", message.Command);
                        theDirectResponse.ReturnCode = 500;
                        request.SourcePort.SendMessage(theDirectResponse);
                    }
                }
            }
        }
Exemplo n.º 2
0
 public void Disconnect()
 {
     _client.Stop();
     _keepaliveTimer   = null;
     _videoDataChannel = 0;
     _decoder          = null;
     _h264Payload      = new H264Payload();
 }
Exemplo n.º 3
0
        private async void HandleRequest(RtspRequest request)
        {
            RtspListener listener = null;

            if (_listeners.TryGetValue(request.RemoteEndpoint.ToString(), out listener))
            {
                await Task.Run(() =>
                {
                    try
                    {
                        int receivedCseq = request.CSeq;
                        request.Context  = new RequestContext(listener);
                        var response     = _dispatcher.Dispatch(request);

                        if (response != null)
                        {
                            if (response.HasBody)
                            {
                                response.Headers[RtspHeaders.Names.CONTENT_LENGTH] = response.Body.Length.ToString();
                            }

                            response.Headers[RtspHeaders.Names.CSEQ] = receivedCseq.ToString();
                            listener.SendResponse(response);

                            // Remove listener on teardown.
                            // VLC will terminate the connection and the listener will stop itself properly.
                            // Some clients will send Teardown but keep the connection open, in this type scenario we'll close it.
                            if (request.Method == RtspRequest.RtspMethod.TEARDOWN)
                            {
                                listener.Stop();
                                _listeners.Remove(listener.Endpoint.ToString());
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        LOG.Error(e, $"Caught exception while procesing RTSP request from {request.URI}");

                        listener.SendResponse(RtspResponse.CreateBuilder()
                                              .Status(RtspResponse.Status.InternalServerError)
                                              .Build());
                    }
                });
            }
            else
            {
                LOG.Error($"Unable to process request because no active connection was found for {request.URI}");
            }
        }
Exemplo n.º 4
0
        public void ReceiveOptionsMessage()
        {
            string message = string.Empty;

            message += "OPTIONS * RTSP/1.0\n";
            message += "CSeq: 1\n";
            message += "Require: implicit-play\n";
            message += "Proxy-Require: gzipped-messages\n";
            message += "\n";
            MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message));

            _mockTransport.GetStream().Returns(stream);

            // Setup test object.
            RtspListener testedListener = new RtspListener(_mockTransport);

            testedListener.MessageReceived += new EventHandler <RtspChunkEventArgs>(MessageReceived);
            testedListener.DataReceived    += new EventHandler <RtspChunkEventArgs>(DataReceived);

            // Run
            testedListener.Start();
            System.Threading.Thread.Sleep(100);
            testedListener.Stop();

            // Check the transport was closed.
            _mockTransport.Received().Close();
            //Check the message recevied
            Assert.AreEqual(1, _receivedMessage.Count);
            RtspChunk theMessage = _receivedMessage[0];

            Assert.IsInstanceOf <RtspRequest>(theMessage);
            Assert.AreEqual(0, theMessage.Data.Length);
            Assert.AreSame(testedListener, theMessage.SourcePort);

            RtspRequest theRequest = theMessage as RtspRequest;

            Assert.AreEqual(RtspRequest.RequestType.OPTIONS, theRequest.RequestTyped);
            Assert.AreEqual(3, theRequest.Headers.Count);
            Assert.AreEqual(1, theRequest.CSeq);
            Assert.Contains("Require", theRequest.Headers.Keys);
            Assert.Contains("Proxy-Require", theRequest.Headers.Keys);
            Assert.AreEqual(null, theRequest.RtspUri);

            Assert.AreEqual(0, _receivedData.Count);
        }
Exemplo n.º 5
0
        public void ReceiveResponseMessage()
        {
            string message = string.Empty;

            message += "RTSP/1.0 551 Option not supported\n";
            message += "CSeq: 302\n";
            message += "Unsupported: funky-feature\n";
            message += "\r\n";
            MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message));

            _mockTransport.GetStream().Returns(stream);

            // Setup test object.
            RtspListener testedListener = new RtspListener(_mockTransport);

            testedListener.MessageReceived += new EventHandler <RtspChunkEventArgs>(MessageReceived);
            testedListener.DataReceived    += new EventHandler <RtspChunkEventArgs>(DataReceived);

            // Run
            testedListener.Start();
            System.Threading.Thread.Sleep(100);
            testedListener.Stop();

            // Check the transport was closed.
            _mockTransport.Received().Close();
            //Check the message recevied
            Assert.AreEqual(1, _receivedMessage.Count);
            RtspChunk theMessage = _receivedMessage[0];

            Assert.IsInstanceOf <RtspResponse>(theMessage);
            Assert.AreEqual(0, theMessage.Data.Length);
            Assert.AreSame(testedListener, theMessage.SourcePort);

            RtspResponse theResponse = theMessage as RtspResponse;

            Assert.AreEqual(551, theResponse.ReturnCode);
            Assert.AreEqual("Option not supported", theResponse.ReturnMessage);
            Assert.AreEqual(2, theResponse.Headers.Count);
            Assert.AreEqual(302, theResponse.CSeq);

            Assert.AreEqual(0, _receivedData.Count);
        }
Exemplo n.º 6
0
        public void ReceivePlayMessage()
        {
            string message = string.Empty;

            message += "PLAY rtsp://audio.example.com/audio RTSP/1.0\r\n";
            message += "CSeq: 835\r\n";
            message += "\r\n";
            MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message));

            _mockTransport.GetStream().Returns(stream);

            // Setup test object.
            RtspListener testedListener = new RtspListener(_mockTransport);

            testedListener.MessageReceived += new EventHandler <RtspChunkEventArgs>(MessageReceived);
            testedListener.DataReceived    += new EventHandler <RtspChunkEventArgs>(DataReceived);

            // Run
            testedListener.Start();
            System.Threading.Thread.Sleep(100);
            testedListener.Stop();

            // Check the transport was closed.
            _mockTransport.Received().Close();
            //Check the message recevied
            Assert.AreEqual(1, _receivedMessage.Count);
            RtspChunk theMessage = _receivedMessage[0];

            Assert.IsInstanceOf <RtspRequest>(theMessage);
            Assert.AreEqual(0, theMessage.Data.Length);
            Assert.AreSame(testedListener, theMessage.SourcePort);

            RtspRequest theRequest = theMessage as RtspRequest;

            Assert.AreEqual(RtspRequest.RequestType.PLAY, theRequest.RequestTyped);
            Assert.AreEqual(1, theRequest.Headers.Count);
            Assert.AreEqual(835, theRequest.CSeq);
            Assert.AreEqual("rtsp://audio.example.com/audio", theRequest.RtspUri.ToString());

            Assert.AreEqual(0, _receivedData.Count);
        }
Exemplo n.º 7
0
        public void ReceiveData()
        {
            Random rnd = new Random();

            byte[] data = new byte[0x0234];
            rnd.NextBytes(data);

            byte[] buffer = new byte[data.Length + 4];
            buffer[0] = 0x24; // $
            buffer[1] = 11;
            buffer[2] = 0x02;
            buffer[3] = 0x34;
            Buffer.BlockCopy(data, 0, buffer, 4, data.Length);

            MemoryStream stream = new MemoryStream(buffer);

            _mockTransport.GetStream().Returns(stream);

            // Setup test object.
            RtspListener testedListener = new RtspListener(_mockTransport);

            testedListener.MessageReceived += new EventHandler <RtspChunkEventArgs>(MessageReceived);
            testedListener.DataReceived    += new EventHandler <RtspChunkEventArgs>(DataReceived);

            // Run
            testedListener.Start();
            System.Threading.Thread.Sleep(500);
            testedListener.Stop();

            // Check the transport was closed.
            _mockTransport.Received().Close();
            //Check the message recevied
            Assert.AreEqual(0, _receivedMessage.Count);
            Assert.AreEqual(1, _receivedData.Count);
            Assert.IsInstanceOf <RtspData>(_receivedData[0]);
            RtspData dataMessage = _receivedData[0] as RtspData;

            Assert.AreEqual(11, dataMessage.Channel);
            Assert.AreSame(testedListener, dataMessage.SourcePort);
            Assert.AreEqual(data, dataMessage.Data);
        }
Exemplo n.º 8
0
        public void ReceiveData()
        {
            Random rnd = new Random();
            byte[] data = new byte[0x0234];
            rnd.NextBytes(data);

            byte[] buffer = new byte[data.Length + 4];
            buffer[0] = 0x24; // $
            buffer[1] = 11;
            buffer[2] = 0x02;
            buffer[3] = 0x34;
            Buffer.BlockCopy(data, 0, buffer, 4, data.Length);

            MemoryStream stream = new MemoryStream(buffer);
            _mockTransport.GetStream().Returns(stream);

            // Setup test object.
            RtspListener testedListener = new RtspListener(_mockTransport);
            testedListener.MessageReceived += new EventHandler<RtspChunkEventArgs>(MessageReceived);
            testedListener.DataReceived += new EventHandler<RtspChunkEventArgs>(DataReceived);

            // Run
            testedListener.Start();
            System.Threading.Thread.Sleep(500);
            testedListener.Stop();

            // Check the transport was closed.
            _mockTransport.Received().Close();
            //Check the message recevied
            Assert.AreEqual(0, _receivedMessage.Count);
            Assert.AreEqual(1, _receivedData.Count);
            Assert.IsInstanceOf<RtspData>(_receivedData[0]);
            RtspData dataMessage = _receivedData[0] as RtspData;

            Assert.AreEqual(11, dataMessage.Channel);
            Assert.AreSame(testedListener, dataMessage.SourcePort);
            Assert.AreEqual(data, dataMessage.Data);
        }
Exemplo n.º 9
0
        public void ReceiveNoMessage()
        {
            string       message = string.Empty;
            MemoryStream stream  = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message));

            _mockTransport.GetStream().Returns(stream);

            // Setup test object.
            RtspListener testedListener = new RtspListener(_mockTransport);

            testedListener.MessageReceived += new EventHandler <RtspChunkEventArgs>(MessageReceived);
            testedListener.DataReceived    += new EventHandler <RtspChunkEventArgs>(DataReceived);

            // Run
            testedListener.Start();
            System.Threading.Thread.Sleep(100);
            testedListener.Stop();

            // Check the transport was closed.
            _mockTransport.Received().Close();
            Assert.AreEqual(0, _receivedMessage.Count);
            Assert.AreEqual(0, _receivedData.Count);
        }
Exemplo n.º 10
0
        public void ReceiveResponseMessage()
        {
            string message = string.Empty;
            message += "RTSP/1.0 551 Option not supported\n";
            message += "CSeq: 302\n";
            message += "Unsupported: funky-feature\n";
            message += "\r\n";
            MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message));
            _mockTransport.GetStream().Returns(stream);

            // Setup test object.
            RtspListener testedListener = new RtspListener(_mockTransport);
            testedListener.MessageReceived += new EventHandler<RtspChunkEventArgs>(MessageReceived);
            testedListener.DataReceived += new EventHandler<RtspChunkEventArgs>(DataReceived);

            // Run
            testedListener.Start();
            System.Threading.Thread.Sleep(100);
            testedListener.Stop();

            // Check the transport was closed.
            _mockTransport.Received().Close();
            //Check the message recevied
            Assert.AreEqual(1, _receivedMessage.Count);
            RtspChunk theMessage = _receivedMessage[0];
            Assert.IsInstanceOf<RtspResponse>(theMessage);
            Assert.AreEqual(0, theMessage.Data.Length);
            Assert.AreSame(testedListener, theMessage.SourcePort);

            RtspResponse theResponse = theMessage as RtspResponse;
            Assert.AreEqual(551, theResponse.ReturnCode);
            Assert.AreEqual("Option not supported", theResponse.ReturnMessage);
            Assert.AreEqual(2, theResponse.Headers.Count);
            Assert.AreEqual(302, theResponse.CSeq);

            Assert.AreEqual(0, _receivedData.Count);
        }
Exemplo n.º 11
0
        public void ReceivePlayMessage()
        {
            string message = string.Empty;
            message += "PLAY rtsp://audio.example.com/audio RTSP/1.0\r\n";
            message += "CSeq: 835\r\n";
            message += "\r\n";
            MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message));
            _mockTransport.GetStream().Returns(stream);

            // Setup test object.
            RtspListener testedListener = new RtspListener(_mockTransport);
            testedListener.MessageReceived += new EventHandler<RtspChunkEventArgs>(MessageReceived);
            testedListener.DataReceived += new EventHandler<RtspChunkEventArgs>(DataReceived);

            // Run
            testedListener.Start();
            System.Threading.Thread.Sleep(100);
            testedListener.Stop();

            // Check the transport was closed.
            _mockTransport.Received().Close();
            //Check the message recevied
            Assert.AreEqual(1, _receivedMessage.Count);
            RtspChunk theMessage = _receivedMessage[0];
            Assert.IsInstanceOf<RtspRequest>(theMessage);
            Assert.AreEqual(0, theMessage.Data.Length);
            Assert.AreSame(testedListener, theMessage.SourcePort);

            RtspRequest theRequest = theMessage as RtspRequest;
            Assert.AreEqual(RtspRequest.RequestType.PLAY, theRequest.RequestTyped);
            Assert.AreEqual(1, theRequest.Headers.Count);
            Assert.AreEqual(835, theRequest.CSeq);
            Assert.AreEqual("rtsp://audio.example.com/audio", theRequest.RtspUri.ToString());

            Assert.AreEqual(0, _receivedData.Count);
        }
Exemplo n.º 12
0
        public void ReceiveOptionsMessage()
        {
            string message = string.Empty;
            message += "OPTIONS * RTSP/1.0\n";
            message += "CSeq: 1\n";
            message += "Require: implicit-play\n";
            message += "Proxy-Require: gzipped-messages\n";
            message += "\n";
            MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message));
            _mockTransport.GetStream().Returns(stream);

            // Setup test object.
            RtspListener testedListener = new RtspListener(_mockTransport);
            testedListener.MessageReceived += new EventHandler<RtspChunkEventArgs>(MessageReceived);
            testedListener.DataReceived += new EventHandler<RtspChunkEventArgs>(DataReceived);

            // Run
            testedListener.Start();
            System.Threading.Thread.Sleep(100);
            testedListener.Stop();

            // Check the transport was closed.
            _mockTransport.Received().Close();
            //Check the message recevied
            Assert.AreEqual(1, _receivedMessage.Count);
            RtspChunk theMessage = _receivedMessage[0];
            Assert.IsInstanceOf<RtspRequest>(theMessage);
            Assert.AreEqual(0, theMessage.Data.Length);
            Assert.AreSame(testedListener, theMessage.SourcePort);

            RtspRequest theRequest = theMessage as RtspRequest;
            Assert.AreEqual(RtspRequest.RequestType.OPTIONS, theRequest.RequestTyped);
            Assert.AreEqual(3, theRequest.Headers.Count);
            Assert.AreEqual(1, theRequest.CSeq);
            Assert.Contains("Require", theRequest.Headers.Keys);
            Assert.Contains("Proxy-Require", theRequest.Headers.Keys);
            Assert.AreEqual(null, theRequest.RtspUri);

            Assert.AreEqual(0, _receivedData.Count);
        }
Exemplo n.º 13
0
        public void ReceiveNoMessage()
        {
            string message = string.Empty;
            MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message));
            _mockTransport.GetStream().Returns(stream);

            // Setup test object.
            RtspListener testedListener = new RtspListener(_mockTransport);
            testedListener.MessageReceived += new EventHandler<RtspChunkEventArgs>(MessageReceived);
            testedListener.DataReceived += new EventHandler<RtspChunkEventArgs>(DataReceived);

            // Run
            testedListener.Start();
            System.Threading.Thread.Sleep(100);
            testedListener.Stop();

            // Check the transport was closed.
            _mockTransport.Received().Close();
            Assert.AreEqual(0, _receivedMessage.Count);
            Assert.AreEqual(0, _receivedData.Count);
        }