public void ReceiveMessageInterrupt()
        {
            string message = string.Empty;

            message += "PLAY rtsp://audio.example.com/audio RTSP/1.";
            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);

            // No exception should be generate.
            stream.Close();

            // Check the transport was closed.
            _mockTransport.Received().Close();
            //Check the message recevied
            Assert.AreEqual(0, _receivedMessage.Count);
            Assert.AreEqual(0, _receivedData.Count);
        }
Esempio n. 2
0
        public void Dispose()
        {
            if (_listener != null)
            {
                LOG.Info($"Disposing RTSP client connected to '{_connection.Endpoint}'");

                _listener?.Stop();
                _rtpQueue?.Dispose();

                foreach (var cb in _callbacks)
                {
                    cb.Value.Dispose();
                }
                _callbacks.Clear();

                _listener = null;

                foreach (var src in _sources)
                {
                    src.Value.Stop();
                }
                _sources.Clear();

                GC.SuppressFinalize(this);
            }
        }
Esempio n. 3
0
        internal void HandleClientSocketException(SocketException se, RtspListener listener)
        {
            if (se == null)
            {
                return;
            }

            switch (se.SocketErrorCode)
            {
            case SocketError.TimedOut:
            case SocketError.ConnectionAborted:
            case SocketError.ConnectionReset:
            case SocketError.Disconnecting:
            case SocketError.Shutdown:
            case SocketError.NotConnected:
            {
                CloseConnection("socket exception");
                return;
            }

            default:
            {
                _logger.Error(se);
                return;
            }
            }
        }
Esempio n. 4
0
        private void RTSP_SocketException_Raised(object sender, RtspSocketExceptionEventArgs e)
        {
            RtspListener    listener = sender as RtspListener;
            SocketException ex       = e.Ex;

            HandleClientSocketException(ex, listener);
        }
Esempio n. 5
0
        public void SendDataTooLargeSync()
        {
            const int dataLenght = 0x10001;

            MemoryStream stream = new MemoryStream();

            _mockTransport.GetStream().Returns(stream);

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

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



            RtspData data = new RtspData();

            data.Channel = 12;
            data.Data    = new byte[dataLenght];


            TestDelegate test = () => testedListener.SendData(data.Channel, data.Data);

            Assert.That(test, Throws.InstanceOf <ArgumentException>());
        }
        /// <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);
                    }
                }
            }
        }
Esempio n. 7
0
        public void SendMessage()
        {
            MemoryStream stream = new MemoryStream();

            _mockTransport.GetStream().Returns(stream);

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

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

            RtspMessage message = new RtspRequestOptions();

            // Run
            var isSuccess = testedListener.SendMessage(message);

            Assert.That(isSuccess, Is.True);
            string result = Encoding.UTF8.GetString(stream.GetBuffer());

            result = result.TrimEnd('\0');
            Assert.That(result, Does.StartWith("OPTIONS * RTSP/1.0\r\n"));
            // packet without payload must end with double return
            Assert.That(result, Does.EndWith("\r\n\r\n"));
        }
Esempio n. 8
0
    /// <summary>
    /// Accepts the connection.
    /// </summary>
    private void AcceptConnection()
    {
        try
        {
            while (!_Stopping.WaitOne(0))
            {
                // Wait for an incoming TCP Connection
                TcpClient oneClient = _RTSPServerListener.AcceptTcpClient();
                Console.WriteLine("Connection from " + oneClient.Client.RemoteEndPoint.ToString());

                // Hand the incoming TCP connection over to the RTSP classes
                var          rtsp_socket = new RtspTcpTransport(oneClient);
                RtspListener newListener = new RtspListener(rtsp_socket);
                newListener.MessageReceived += new EventHandler <RtspChunkEventArgs>(async(s, e) => await RTSP_Message_ReceivedAsync(s, e));
                //RTSPDispatcher.Instance.AddListener(newListener);

                // Add the RtspListener to the RTSPConnections List


                newListener.Start();
            }
        }
        catch (SocketException error)
        {
            // _logger.Warn("Got an error listening, I have to handle the stopping which also throw an error", error);
        }
        catch (Exception error)
        {
            // _logger.Error("Got an error listening...", error);
            throw;
        }
    }
Esempio n. 9
0
        private void RTSP_ProcessPlayRequest(RtspRequestPlay message, RtspListener listener)
        {
            OnPlay?.Invoke(Id);

            Play = true;  // ACTUALLY YOU COULD PAUSE JUST THE VIDEO (or JUST THE AUDIO)
            _logger.Info($"Connection {Id} play started");

            string range    = "npt=0-";                                                  // Playing the 'video' from 0 seconds until the end
            string rtp_info = "url=" + message.RtspUri + ";seq=" + _videoSequenceNumber; // TODO Add rtptime  +";rtptime="+session.rtp_initial_timestamp;

            // Send the reply
            Rtsp.Messages.RtspResponse play_response = message.CreateResponse(_logger);
            play_response.AddHeader("Range: " + range);
            play_response.AddHeader("RTP-Info: " + rtp_info);
            listener.SendMessage(play_response);



            //TODO: find a p[lace for this check]
            // Session ID was not found in the list of Sessions. Send a 454 error

            /*   Rtsp.Messages.RtspResponse play_failed_response = (e.Message as Rtsp.Messages.RtspRequestPlay).CreateResponse();
             * play_failed_response.ReturnCode = 454; // Session Not Found
             * listener.SendMessage(play_failed_response);*/
        }
Esempio n. 10
0
        /// <summary>
        /// Handles the request play.
        /// Do not forward message if already playing
        /// </summary>
        /// <param name="destination">The destination.</param>
        /// <param name="requestPlay">The request play.</param>
        /// <returns>The message to transmit</returns>
        private RtspMessage HandleRequestPlay(ref RtspListener destination, RtspRequestPlay requestPlay)
        {
            Contract.Requires(requestPlay != null);
            Contract.Requires(destination != null);
            Contract.Ensures(Contract.Result <RtspMessage>() != null);
            Contract.Ensures(Contract.ValueAtReturn(out destination) != null);


            string sessionKey = RtspSession.GetSessionName(requestPlay.RtspUri, requestPlay.Session);

            if (_activesSession.ContainsKey(sessionKey))
            {
                RtspSession session = _activesSession[sessionKey];

                // si on est dèjà en play on n'envoie pas la commande a la source.
                if (session.State == RtspSession.SessionState.Playing)
                {
                    session.Start(requestPlay.SourcePort.RemoteAdress);
                    RtspResponse returnValue = requestPlay.CreateResponse();
                    destination = requestPlay.SourcePort;
                    return(returnValue);
                }

                // ajoute un client
                session.Start(requestPlay.SourcePort.RemoteAdress);
            }
            return(requestPlay);
        }
Esempio n. 11
0
        /// <summary>
        /// Gets the RTSP listener for destination.
        /// </summary>
        /// <param name="destinationUri">The destination URI.</param>
        /// <returns>An RTSP listener</returns>
        /// <remarks>
        /// This method try to get one of openned TCP listener and
        /// if it does not find it, it create it.
        /// </remarks>
        private RtspListener GetRtspListenerForDestination(Uri destinationUri)
        {
            Contract.Requires(destinationUri != null);

            RtspListener destination;
            string       destinationName = destinationUri.Authority;

            if (_serverListener.ContainsKey(destinationName))
            {
                destination = _serverListener[destinationName];
            }
            else
            {
                destination = new RtspListener(
                    new RtspTcpTransport(destinationUri.Host, destinationUri.Port)
                    );

                // un peu pourri mais pas d'autre idée...
                // pour avoir vraiment des clef avec IP....
                if (_serverListener.ContainsKey(destination.RemoteAdress))
                {
                    destination = _serverListener[destination.RemoteAdress];
                }
                else
                {
                    AddListener(destination);
                    destination.Start();
                }
            }
            return(destination);
        }
Esempio n. 12
0
        private void RTSP_ProcessAuthorization(RtspRequest message, RtspListener listener)
        {
            bool authorized = false;

            if (message.Headers.ContainsKey("Authorization") == true)
            {
                // The Header contained Authorization
                // Check the message has the correct Authorization
                // If it does not have the correct Authorization then close the RTSP connection
                authorized = _auth.IsValid(message);

                if (authorized == false)
                {
                    // Send a 401 Authentication Failed reply, then close the RTSP Socket
                    Rtsp.Messages.RtspResponse authorization_response = message.CreateResponse(_logger);
                    authorization_response.AddHeader("WWW-Authenticate: " + _auth.GetHeader());
                    authorization_response.ReturnCode = 401;
                    listener.SendMessage(authorization_response);

                    CloseConnection("unauthorized");
                    listener.Dispose();
                    return;
                }
            }
            if ((message.Headers.ContainsKey("Authorization") == false))
            {
                // Send a 401 Authentication Failed with extra info in WWW-Authenticate
                // to tell the Client if we are using Basic or Digest Authentication
                Rtsp.Messages.RtspResponse authorization_response = message.CreateResponse(_logger);
                authorization_response.AddHeader("WWW-Authenticate: " + _auth.GetHeader()); // 'Basic' or 'Digest'
                authorization_response.ReturnCode = 401;
                listener.SendMessage(authorization_response);
                return;
            }
        }
Esempio n. 13
0
    /// <summary>
    /// Accepts the connection.
    /// </summary>
    private void AcceptConnection()
    {
        try
        {
            while (!_Stopping.WaitOne(0))
            {
                TcpClient oneClient = _RTSPServerListener.AcceptTcpClient();
                Console.WriteLine("Connection from " + oneClient.Client.RemoteEndPoint.ToString());

                var          rtsp_socket = new RtspTcpTransport(oneClient);
                RtspListener newListener = new RtspListener(rtsp_socket);
                newListener.MessageReceived += RTSP_Message_Received;
                //RTSPDispatcher.Instance.AddListener(newListener);
                newListener.Start();
            }
        }
        catch (SocketException error)
        {
            // _logger.Warn("Got an error listening, I have to handle the stopping which also throw an error", error);
        }
        catch (Exception error)
        {
            // _logger.Error("Got an error listening...", error);
            throw;
        }
    }
Esempio n. 14
0
        /// <summary>
        /// Add a listener.
        /// </summary>
        /// <param name="listener">A listener.</param>
        public void AddListener(RtspListener listener)
        {
            if (listener == null)
            {
                throw new ArgumentNullException("listener");
            }
            Contract.EndContractBlock();

            listener.MessageReceived += new EventHandler <RtspChunkEventArgs>(Listener_MessageReceived);
            _serverListener.Add(listener.RemoteAdress, listener);
        }
Esempio n. 15
0
        private void RTSP_ProcessTeardownRequest(RtspRequestTeardown message, RtspListener listener)
        {
            if (message.Session == _videoSessionId) // SHOULD HAVE AN AUDIO TEARDOWN AS WELL
            {
                // If this is UDP, close the transport
                // For TCP there is no transport to close (as RTP packets were interleaved into the RTSP connection)

                Rtsp.Messages.RtspResponse teardown_response = message.CreateResponse(_logger);
                listener.SendMessage(teardown_response);

                CloseConnection("teardown");
            }
        }
Esempio n. 16
0
        public RTSPClient(string ipAddress, uint port, string username, string password)
        {
            _url = $"rtsp://{username}:{password}@{ipAddress}:{port}/Streaming/channels/1/";

            RtspUtils.RegisterUri();

            RtspTcpTransport socket = new RtspTcpTransport(ipAddress, (int)port);

            _client = new RtspListener(socket);

            _client.MessageReceived += MessageReceived;
            _client.DataReceived    += DataReceived;
        }
Esempio n. 17
0
        private void RTSP_ProcessOptionsRequest(RtspRequestOptions message, RtspListener listener)
        {
            String requested_url = message.RtspUri.ToString();

            _logger.Info($"Connection {listener.ConnectionId} requested for url: {requested_url}");

            _videoSource = _requestUrlVideoSourceResolverStrategy.ResolveVideoSource(requested_url);
            OnConnectionAdded?.Invoke(Id, _videoSource); //treat connection useful when VideoSource determined

            // Create the reponse to OPTIONS
            Rtsp.Messages.RtspResponse options_response = message.CreateResponse(_logger);
            // Rtsp.Messages.RtspResponse options_response = OnRtspMessageReceived?.Invoke(message as Rtsp.Messages.RtspRequest,targetConnection);
            listener.SendMessage(options_response);
        }
Esempio n. 18
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}");
            }
        }
Esempio n. 19
0
        private void RTSP_ProcessPauseRequest(RtspRequestPause message, RtspListener listener)
        {
            if (message.Session == _videoSessionId /* OR AUDIO SESSION ID */)
            {
                OnStop?.Invoke(Id);

                // found the session
                Play = false; // COULD HAVE PLAY/PAUSE FOR VIDEO AND AUDIO
            }


            // ToDo - only send back the OK response if the Session in the RTSP message was found
            Rtsp.Messages.RtspResponse pause_response = message.CreateResponse(_logger);
            listener.SendMessage(pause_response);
        }
Esempio n. 20
0
    // /// <summary>
    // /// Starts the listen.
    // /// </summary>
    // public async Task StartListen()
    // {
    //     _RTSPServerListener.Start();
    //
    //     _Stopping = new ManualResetEvent(false);
    //     _ListenTread = new Thread(new ThreadStart(AcceptConnection));
    //     _ListenTread.Start();
    //
    //     /*
    //     // Initialise the H264 encoder
    //     h264_encoder = new SimpleH264Encoder(h264_width, h264_height, h264_fps);
    //     //h264_encoder = new TinyH264Encoder(); // hard coded to 192x128
    //
    //     // Start the VideoSource
    //     video_source = new TestCard(h264_width, h264_height, h264_fps);
    //     video_source.ReceivedYUVFrame += video_source_ReceivedYUVFrame;
    //     */
    // }

    public async Task ListenAsync()
    {
        rtspServerListener.Start();
        try
        {
            while (!stopping)
            {
                // Wait for an incoming TCP Connection
                TcpClient oneClient = await rtspServerListener.AcceptTcpClientAsync();

                Console.WriteLine("Connection from " + oneClient.Client.RemoteEndPoint.ToString());

                // Hand the incoming TCP connection over to the RTSP classes
                var          rtsp_socket = new RtspTcpTransport(oneClient);
                RtspListener newListener = new RtspListener(rtsp_socket);
                newListener.MessageReceived += RTSP_Message_Received;
                //RTSPDispatcher.Instance.AddListener(newListener);

                // Add the RtspListener to the RTSPConnections List
                lock (rtsp_list)
                {
                    RTSPConnection new_connection = new RTSPConnection();
                    new_connection.listener        = newListener;
                    new_connection.client_hostname = newListener.RemoteAdress.Split(':')[0];
                    new_connection.ssrc            = global_ssrc;

                    new_connection.time_since_last_rtsp_keepalive       = DateTime.UtcNow;
                    new_connection.video_time_since_last_rtcp_keepalive = DateTime.UtcNow;

                    rtsp_list.Add(new_connection);
                }

                newListener.Start();
                await UpdateClients();
            }
        }
        catch (SocketException error)
        {
            // _logger.Warn("Got an error listening, I have to handle the stopping which also throw an error", error);
        }
        catch (Exception error)
        {
            // _logger.Error("Got an error listening...", error);
            throw;
        }
    }
        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);
        }
Esempio n. 22
0
        public RtspClient(Uri uri, Credentials creds = null)
        {
            _uri            = uri ?? throw new ArgumentNullException("Cannot create RTSP client from null uri");
            _cseq           = 0;
            _credentials    = creds;
            _defaultTimeout = TimeSpan.FromSeconds(20);
            _callbacks      = new ConcurrentDictionary <int, AsyncResponse>();
            _sources        = new ConcurrentDictionary <int, RtpInterleaveMediaSource>();
            _connection     = new RtspConnection(IPAddress.Parse(uri.Host), uri.Port == -1 ? DEFAULT_RTSP_PORT : uri.Port);
            _listener       = new RtspListener(_connection, OnRtspChunk);
            _rtpQueue       = new BlockingCollection <ByteBuffer>();

            LOG.Info($"Created RTSP client for '{_connection.Endpoint}'");

            Task.Run(() => ProcessInterleavedData());

            _listener.Start();
        }
Esempio n. 23
0
        public void SendDataAsync()
        {
            const int dataLenght = 45;

            MemoryStream stream = new MemoryStream();

            _mockTransport.GetStream().Returns(stream);

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

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



            RtspData data = new RtspData();

            data.Channel = 12;
            data.Data    = new byte[dataLenght];
            for (int i = 0; i < dataLenght; i++)
            {
                data.Data[i] = (byte)i;
            }


            // Run
            var asyncResult = testedListener.BeginSendData(data, null, null);

            testedListener.EndSendData(asyncResult);

            var result = stream.GetBuffer();

            int index = 0;

            Assert.That(result[index++], Is.EqualTo((byte)'$'));
            Assert.That(result[index++], Is.EqualTo(data.Channel));
            Assert.That(result[index++], Is.EqualTo((dataLenght & 0xFF00) >> 8));
            Assert.That(result[index++], Is.EqualTo(dataLenght & 0x00FF));
            for (int i = 0; i < dataLenght; i++)
            {
                Assert.That(result[index++], Is.EqualTo(data.Data[i]));
            }
        }
Esempio n. 24
0
        /// <summary>
        /// Accepts the connection.
        /// </summary>
        private void AcceptConnection()
        {
            Console.WriteLine($"Now streaming via RTSP on port {portNumber}");
            Console.WriteLine($"Connect with your player to rtsp://127.0.0.1:{portNumber}/");
            try
            {
                while (!_Stopping.WaitOne(0))
                {
                    // Wait for an incoming TCP Connection
                    TcpClient oneClient = _RTSPServerListener.AcceptTcpClient();
                    Console.WriteLine("Connection from " + oneClient.Client.RemoteEndPoint.ToString());

                    // Hand the incoming TCP connection over to the RTSP classes
                    var          rtsp_socket = new RtspTcpTransport(oneClient);
                    RtspListener newListener = new RtspListener(rtsp_socket);
                    newListener.MessageReceived += RTSP_Message_Received;
                    //RTSPDispatcher.Instance.AddListener(newListener);

                    // Add the RtspListener to the RTSPConnections List
                    lock (rtsp_list)
                    {
                        RTSPConnection new_connection = new RTSPConnection();
                        new_connection.listener        = newListener;
                        new_connection.client_hostname = newListener.RemoteAdress.Split(':')[0];
                        new_connection.ssrc            = global_ssrc;

                        new_connection.time_since_last_rtsp_keepalive = DateTime.UtcNow;
                        //new_connection.video_time_since_last_rtcp_keepalive = DateTime.UtcNow;

                        rtsp_list.Add(new_connection);
                    }

                    newListener.Start();
                }
            }
            catch (Exception error)
            {
                if (!_Stopping.WaitOne(0))
                {
                    Console.WriteLine("[AcceptConnection] Error: " + error.ToString());
                }
            }
        }
        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);
        }
        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);
        }
        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);
        }
Esempio n. 28
0
        private void RTSP_ProcessDescribeRequest(RtspRequestDescribe message, RtspListener listener)
        {
            String requested_url = message.RtspUri.ToString();

            Task <byte[]> sdpDataTask = _videoSource != null?
                                        OnProvideSdpData?.Invoke(Id, _videoSource)
                                            : Task.FromResult <byte[]>(null);

            byte[] sdpData = sdpDataTask.Result;

            if (sdpData != null)
            {
                Rtsp.Messages.RtspResponse describe_response = message.CreateResponse(_logger);

                describe_response.AddHeader("Content-Base: " + requested_url);
                describe_response.AddHeader("Content-Type: application/sdp");
                describe_response.Data = sdpData;
                describe_response.AdjustContentLength();

                // Create the reponse to DESCRIBE
                // This must include the Session Description Protocol (SDP)

                describe_response.Headers.TryGetValue(RtspHeaderNames.ContentBase, out contentBase);

                using (StreamReader sdp_stream = new StreamReader(new MemoryStream(describe_response.Data)))
                {
                    _sdpFile = Rtsp.Sdp.SdpFile.Read(sdp_stream);
                }

                listener.SendMessage(describe_response);
            }
            else
            {
                Rtsp.Messages.RtspResponse describe_response = (message as Rtsp.Messages.RtspRequestDescribe).CreateResponse(_logger);
                //Method Not Valid In This State"
                describe_response.ReturnCode = 455;
                listener.SendMessage(describe_response);
            }
        }
Esempio n. 29
0
        private void Accept(object state)
        {
            while (!_stop.WaitOne(0))
            {
                try
                {
                    var client   = _listener.AcceptTcpClient();
                    var conn     = new RtspConnection(client);
                    var listener = new RtspListener(conn, OnRtspRequest);

                    LOG.Debug($"Accepted client connection from '{conn.RemoteAddress}'");

                    listener.Start();

                    _listeners.Add(conn.RemoteAddress, listener);
                }
                catch (Exception e)
                {
                    LOG.Error(e, $"Caught exception while accepting client connection, message={e.Message}");
                }
            }
        }
Esempio n. 30
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);
        }
Esempio n. 31
0
 /// <summary>
 /// Accepts the connection.
 /// </summary>
 private void AcceptConnection()
 {
     try
     {
         while (!_Stopping.WaitOne(0))
         {
             TcpClient    oneClient   = _RTSPServerListener.AcceptTcpClient();
             RtspListener newListener = new RtspListener(
                 new RtspTcpTransport(oneClient));
             RTSPDispatcher.Instance.AddListener(newListener);
             newListener.Start();
         }
     }
     catch (SocketException error)
     {
         _logger.Warn("Got an error listening, I have to handle the stopping which also throw an error", error);
     }
     catch (Exception error)
     {
         _logger.Error("Got an error listening...", error);
         throw;
     }
 }
Esempio n. 32
0
        public void SendDataTooLarge()
        {
            const int dataLenght = 0x10001;

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

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

            RtspData data = new RtspData();
            data.Channel = 12;
            data.Data = new byte[dataLenght];

            ActualValueDelegate<object> test = () => testedListener.BeginSendData(data,null,null);
            Assert.That(test, Throws.InstanceOf<ArgumentException>());
        }
Esempio n. 33
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);
        }
Esempio n. 34
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);
        }
Esempio n. 35
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);
        }
Esempio n. 36
0
        public void ReceiveMessageInterrupt()
        {
            string message = string.Empty;
            message += "PLAY rtsp://audio.example.com/audio RTSP/1.";
            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);

            // No exception should be generate.
            stream.Close();

            // Check the transport was closed.
            _mockTransport.Received().Close();
            //Check the message recevied
            Assert.AreEqual(0, _receivedMessage.Count);
            Assert.AreEqual(0, _receivedData.Count);
        }
Esempio n. 37
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);
        }
Esempio n. 38
0
        public void SendData()
        {
            const int dataLenght = 45;

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

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

            RtspData data = new RtspData();
            data.Channel = 12;
            data.Data = new byte[dataLenght];
            for (int i = 0; i < dataLenght; i++)
            {
                data.Data[i] = (byte)i;
            }

            // Run
            var asyncResult = testedListener.BeginSendData(data, null, null);
            testedListener.EndSendData(asyncResult);

            var result = stream.GetBuffer();

            int index = 0;
            Assert.That(result[index++], Is.EqualTo((byte)'$'));
            Assert.That(result[index++], Is.EqualTo(data.Channel));
            Assert.That(result[index++], Is.EqualTo((dataLenght & 0xFF00) >> 8));
            Assert.That(result[index++], Is.EqualTo(dataLenght & 0x00FF));
            for (int i = 0; i < dataLenght; i++)
            {
                Assert.That(result[index++], Is.EqualTo(data.Data[i]));
            }
        }
Esempio n. 39
0
        public void SendMessage()
        {
            MemoryStream stream = new MemoryStream();
            _mockTransport.GetStream().Returns(stream);

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

            RtspMessage message = new RtspRequestOptions();

            // Run
            var isSuccess = testedListener.SendMessage(message);

            Assert.That(isSuccess, Is.True);
            string result = Encoding.UTF8.GetString(stream.GetBuffer());
            result = result.TrimEnd('\0');
            Assert.That(result, Does.StartWith("OPTIONS * RTSP/1.0\r\n"));
            // packet without payload must end with double return
            Assert.That(result, Does.EndWith("\r\n\r\n"));
        }