public bool Options(RTSPRequestParser parser)
        {
            // TODO : Take care of the Uri format
            string media = parser.Media;


            ServerMediaSession session = Server.lookupServerMediaSession(media);

            if (session == null)
            {
                HandleNotFound(parser);
                return(false);
            }



            StringBuilder sb = new StringBuilder();

            sb.Append("RTSP/1.0 200 OK\r\n");
            sb.AppendFormat("Server: {0}\r\n", RTSPServer.ServerVersion);
            sb.AppendFormat("Cseq: {0}\r\n", parser.Headers["CSEQ"]);
            sb.AppendFormat("Public: {0}\r\n", _supportedCommands);
            sb.Append("\r\n");
            SendResponse(sb.ToString());
            return(true);
        }
        void HandleCommandNotSupported(RTSPRequestParser parser)
        {
            string reply = String.Format("RTSP/1.0 405 Method Not Allowed\r\nCSeq: {0}\r\n{1}\r\nAllow: {2}\r\n\r\n",
                                         parser.Headers["CSEQ"], "Tue, 30 Aug 2016 01:33:17 GMT", _supportedCommands);

            SendResponse(reply);
        }
        public void HandleUnsupportedTransport(RTSPRequestParser parser)
        {
            string reply = String.Format("RTSP/1.0 461 Unsupported Transport\r\nCSeq: {0}\r\n{1}\r\n\r\n",
                                         parser.Headers["CSEQ"], "Tue, 30 Aug 2016 01:33:17 GMT");

            SendResponse(reply);
        }
        public void HandleInvalidState(RTSPRequestParser parser)
        {
            string reply = String.Format("RTSP/1.0 455 Method Not Valid in This State\r\nCSeq: {0}\r\n{1}\r\n\r\n",
                                         parser.Headers["CSEQ"], "Tue, 30 Aug 2016 01:33:17 GMT");

            SendResponse(reply);
        }
        void HandleSessionNotFound(RTSPRequestParser parser)
        {
            string reply = String.Format("RTSP/1.0 454 Session Not Found\r\nCSeq: {0}\r\n{1}\r\n\r\n",
                                         parser.Headers["CSEQ"], "Tue, 30 Aug 2016 01:33:17 GMT");

            SendResponse(reply);
        }
Beispiel #6
0
 private void ParseGetParameter(RTSPRequestParser parser)
 {
     if (String.IsNullOrEmpty(parser.Body))
     {
         _connection.HandleInvalidParameter(parser);
     }
 }
Beispiel #7
0
        public bool GetParameter(RTSPRequestParser parser)
        {
            string media = parser.Media;


            ServerMediaSession session = _connection.Server.lookupServerMediaSession(media);

            if (session == null)
            {
                _connection.HandleNotFound(parser);
                return(false);
            }
            // Look up information for the specified subsession (track):


            ServerMediaSubsession subsession = session.LookupSubSession(media);

            // Not yet implemented
            //ParseGetParameter(parser);

            StringBuilder sb = new StringBuilder();

            sb.Append("RTSP/1.0 200 OK\r\n");
            sb.AppendFormat("Server: {0}\r\n", RTSPServer.ServerVersion);
            sb.AppendFormat("Cseq: {0}\r\n", parser.Headers["CSEQ"]);
            sb.AppendFormat("Session: {0}\r\n", SessionId);
            sb.Append("Last-Modified: Tue, 30 Aug 2016 01:33:17 GMT\r\n");
            sb.Append("Date: Sat, 22 Dec 2018 16:18:03 GMT\r\n");
            sb.Append("Expires: Sun, 23 Dec 2018 12:01:28 GMT\r\n\r\n");

            string reply = sb.ToString();

            _connection.SendResponse(reply);
            return(true);
        }
Beispiel #8
0
 public void Teardown(RTSPRequestParser parser)
 {
     try
     {
         Close();
     }
     catch (Exception ex)
     {
         _logger.Error(ex);
     }
 }
Beispiel #9
0
        public async Task <bool> Play(RTSPRequestParser parser)
        {
            string stream = parser.Media;


            ServerMediaSession session = _connection.Server.lookupServerMediaSession(stream);

            if (session == null)
            {
                _connection.HandleNotFound(parser);
                return(false);
            }
            // Look up information for the specified subsession (track):
            ServerMediaSubsession subsession;

            subsession = session.LookupSubSession(stream);
            ushort rtpSeqNum    = 0;
            uint   rtpTimestamp = 0;

            _rtpStream = subsession.GetStreamInstance();

            rtpSeqNum    = _rtpStream.CurrentSeqNo();
            rtpTimestamp = _rtpStream.CurrentTimeStamp();            // presetNextTimestamp();
            Playing      = true;

            await _rtpStream.AddDestination(this, _destinations);

            if (_destinations.isTCP)
            {
                _connection.RegisterFilter(_rtpStream);
            }

            StringBuilder sb = new StringBuilder();

            sb.Append("RTSP/1.0 200 OK\r\n");
            sb.AppendFormat("Server: {0}\r\n", RTSPServer.ServerVersion);
            sb.AppendFormat("Cseq: {0}\r\n", parser.Headers["CSEQ"]);
            sb.AppendFormat("Session: {0}\r\n", parser.Headers["SESSION"]);
            sb.Append("Last-Modified: Tue, 30 Aug 2016 01:33:17 GMT\r\n");
            sb.Append("Cache-Control: must-revalidate\r\n");
            sb.Append("Date: Sat, 22 Dec 2018 16:18:03 GMT\r\n");
            sb.Append("Expires: Sun, 23 Dec 2018 12:01:28 GMT\r\n");
            sb.Append("Range: npt=0.000-\r\n").
            AppendFormat("RTP-Info: url=rtsp://{0}:{1}/{2}/track1;seq={3};rtptime={4}\r\n\r\n",
                         SocketExtensions.GetLocalIPV4Address(),
                         _connection.Server.Port,
                         subsession.Name,
                         rtpSeqNum, rtpTimestamp);

            string reply = sb.ToString();

            _connection.SendResponse(reply);
            return(true);
        }
        private bool SetParameter(RTSPRequestParser parser)
        {
            // Begin by looking up the "ServerMediaSession" object for the specified "urlTotalSuffix":
            string media = parser.Media;


            ServerMediaSession session = Server.lookupServerMediaSession(media);

            if (session == null)
            {
                HandleNotFound(parser);
                return(false);
            }

            // Look up information for the specified subsession (track):
            ServerMediaSubsession subsession;

            media      = media.TrimEnd('/');       // parser.Uri.Segments[2].TrimStart('/');
            subsession = session.LookupSubSession(media);

            string body = parser.Body;

            if (String.IsNullOrEmpty(body))
            {
                HandleInvalidParameter(parser);
            }

            Dictionary <string, string> parameters = new Dictionary <string, string>();

            try
            {
                StringParser bodyParser = new StringParser(body.ToUpper());
                ParseParameters(parser, bodyParser, parameters);
                Server.NewParameters(parameters);
            }
            catch
            {
                return(true);
            }
            StringBuilder sb = new StringBuilder();

            sb.Append("RTSP/1.0 200 OK\r\n");
            sb.AppendFormat("Server: {0}\r\n", RTSPServer.ServerVersion);
            sb.AppendFormat("Cseq: {0}\r\n", parser.Headers["CSEQ"]);
            sb.Append("\r\n");
            SendResponse(sb.ToString());
            return(true);
        }
        private bool Describes(RTSPRequestParser parser)
        {
            // Begin by looking up the "ServerMediaSession" object for the specified "urlTotalSuffix":
            string media = parser.Media;


            ServerMediaSession session = Server.lookupServerMediaSession(media);

            if (session == null)
            {
                HandleNotFound(parser);
                return(false);
            }

            // Look up information for the specified subsession (track):
            ServerMediaSubsession subsession;

            media      = media.TrimEnd('/');       // parser.Uri.Segments[2].TrimStart('/');
            subsession = session.LookupSubSession(media);

            var sdp = subsession.GenerateSDPDescription();


            StringBuilder sb = new StringBuilder();

            sb.Append("RTSP/1.0 200 OK\r\n");
            sb.AppendFormat("Server: {0}\r\n", RTSPServer.ServerVersion);
            sb.AppendFormat("Cseq: {0}\r\n", parser.Headers["CSEQ"]);
            sb.Append("Last-Modified: Tue, 30 Aug 2016 01:33:17 GMT\r\n");
            sb.Append("Cache-Control: must-revalidate\r\n");

            sb.AppendFormat("Content-length: {0}\r\n", sdp.Length);

            sb.Append("Date: Sat, 22 Dec 2018 16:18:03 GMT\r\n");
            sb.Append("Expires: Sat, 22 Dec 2018 16:18:03 GMT\r\n");
            sb.Append("Content-Type: application/sdp\r\n").
            Append("x-Accept-Retransmit: our-retransmit\r\n").
            Append("x-Accept-Dynamic-Rate: 1\r\n").
            AppendFormat("Content-Base: rtsp://{0}:{1}/{2}\r\n\r\n", SocketExtensions.GetLocalIPV4Address(), Server.Port, subsession.Name).
            Append(sdp);

            var str = sb.ToString();

            SendResponse(str);
            return(true);
        }
        public void HandleInvalidParameter(RTSPRequestParser parser, params string[] parameters)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("RTSP/1.0 451 Invalid Parameter\r\n");
            sb.AppendFormat("CSeq: {0}\r\n", parser.Headers["CSEQ"]);

            StringBuilder body = new StringBuilder();

            foreach (var str in parameters)
            {
                body.AppendFormat("{0}\r\n", str);
            }
            string tmp = body.ToString();

            sb.AppendFormat("Content-length: {0}\r\n", tmp.Length);
            sb.Append("Content-type: text/parameters\r\n\r\n");
            sb.AppendFormat("{0}", tmp);

            SendResponse(sb.ToString());
        }
Beispiel #13
0
        public bool Pause(RTSPRequestParser parser)
        {
            if (!Playing)
            {
                _connection.HandleInvalidState(parser);
                return(true);
            }

            if (_rtpStream != null)
            {
                _rtpStream.RemoveSession(SessionId);
                Playing = false;
            }
            StringBuilder sb = new StringBuilder();

            sb.Append("RTSP/1.0 200 OK\r\n");
            sb.AppendFormat("Cseq: {0}\r\n", parser.Headers["CSEQ"]);
            sb.AppendFormat("Session: {0}\r\n", parser.Headers["SESSION"]);
            sb.Append("Date: Sat, 22 Dec 2018 16:18:03 GMT\r\n\r\n");
            _connection.SendResponse(sb.ToString());
            return(true);
        }
        public async Task <bool> ProcessIncomingRequest(string message)
        {
            bool retVal = false;

            if (_logger.IsDebugEnabled)
            {
                _logger.Debug("C->S:\n{0}", message);
            }

            if (_session != null)
            {
                _session.LastKeepAlive = DateTime.Now;
            }

            RTSPRequestParser parser = new RTSPRequestParser();

            try
            {
                parser.Parse(message.ToUpper());                 // TODO : Error handling
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                HandleBadRequest();
                return(false);
            }

            if (!_commands.Contains(parser.Method))
            {
                HandleCommandNotSupported(parser);
                return(false);
            }

            if (!String.IsNullOrEmpty(parser.TransportType))
            {
                if (parser.TransportType != "RTP/AVP" && parser.TransportType != "RTP/AVP/TCP")
                {
                    HandleUnsupportedTransport(parser);
                    return(false);
                }
            }

            // Handle session less verbs first
            if (parser.Method == "OPTIONS")
            {
                retVal = Options(parser);
                return(retVal);
            }

            if (parser.Method == "DESCRIBE")
            {
                retVal = Describes(parser);
                return(retVal);
            }


            if (parser.Method == "SET_PARAMETER")
            {
                retVal = SetParameter(parser);
                return(retVal);
            }


            if (parser.Headers.ContainsKey("SESSION"))
            {
                _session = Server.GetSession(Convert.ToInt32(parser.Headers["SESSION"]));
                if (_session == null)
                {
                    HandleSessionNotFound(parser);
                    return(false);
                }
            }
            else
            {
                _session = Server.GenerateSession(this);
                if (_logger.IsDebugEnabled)
                {
                    _logger.Debug("Generating new session {0}", _session.SessionId);
                }
            }

            _session.LastKeepAlive = DateTime.Now;

            if (parser.Method == "SETUP")
            {
                retVal = _session.Setup(_tcpClient, parser);
            }

            else if (parser.Method == "PAUSE")
            {
                retVal = _session.Pause(parser);
            }

            else if (parser.Method == "GET_PARAMETER")
            {
                retVal = _session.GetParameter(parser);
            }

            else if (parser.Method == "PLAY")
            {
                retVal = await _session.Play(parser);
            }

            else if (parser.Method == "TEARDOWN")
            {
                _session.Teardown(parser);
                return(false);
            }
            else
            {
                HandleBadRequest();
            }

            return(retVal);
        }
        public void HandleNotFound(RTSPRequestParser parser)
        {
            string reply = String.Format("RTSP/1.0 404 Stream Not Found\r\nCSeq: {0}\r\n\r\n", parser.Headers["CSEQ"]);

            SendResponse(reply);
        }
Beispiel #16
0
        public bool Setup(TcpClient tcpSocket, RTSPRequestParser parser)
        {
            string media = parser.Media;


            ServerMediaSession session = _connection.Server.lookupServerMediaSession(media);

            if (session == null)
            {
                _connection.HandleNotFound(parser);
                return(false);
            }
            // Look up information for the specified subsession (track):


            ServerMediaSubsession subsession = session.LookupSubSession(media);


            Socket socket = null;

            if (String.Compare(parser.TransportType, "RTP/AVP/TCP") == 0)
            {
                socket       = tcpSocket.Client;
                IsRTPOverTCP = true;
            }

            if ((subsession.IsMulticast && parser.TransportMode == "UNICAST") || (!subsession.IsMulticast && parser.TransportMode == "MULTICAST"))
            {
                _connection.HandleUnsupportedTransport(parser);
                return(false);
            }

            int clientRTPPort  = parser.ClientPort1;
            int clientRTCPPort = parser.ClientPort2;

            int    serverRTPPort;
            int    serverRTCPPort;
            string multiCastAddress;
            var    clientAddress = tcpSocket.Client.RemoteEndPoint as IPEndPoint;

            subsession.GetStreamParameters(out serverRTPPort, out serverRTCPPort, out multiCastAddress);

            SetupDestinations(socket, clientAddress, null, clientRTPPort, clientRTCPPort, (byte)parser.Channel1, (byte)parser.Channel2);

            StringBuilder sb = new StringBuilder();

            sb.Append("RTSP/1.0 200 OK\r\n");
            sb.AppendFormat("Server: {0}\r\n", RTSPServer.ServerVersion);
            sb.AppendFormat("Cseq: {0}\r\n", parser.Headers["CSEQ"]);

            var localIP = SocketExtensions.GetLocalIPV4Address();

            if (parser.TransportMode == "UNICAST")
            {
                sb.AppendFormat("Session: {0}\r\n", SessionId);
                sb.Append("Last-Modified: Tue, 30 Aug 2016 01:33:17 GMT\r\n");
                sb.Append("Cache-Control: must-revalidate\r\n");
                sb.Append("Date: Sat, 22 Dec 2018 16:18:03 GMT\r\n");
                sb.Append("Expires: Sun, 23 Dec 2018 12:01:28 GMT\r\n");

                if (socket == null)
                {
                    // UDP
                    sb.AppendFormat("Transport: RTP/AVP;unicast;destination={0};source={1};client_port={2}-{3};server_port={4}-{5};\r\n\r\n",
                                    clientAddress.Address,
                                    localIP,
                                    parser.ClientPort1,
                                    parser.ClientPort2,
                                    serverRTPPort,
                                    serverRTCPPort);
                }
                else
                {
                    // TCP
                    sb.AppendFormat("Transport: RTP/AVP/TCP;unicast;destination={0};source={1};interleaved={2}-{3}\r\n\r\n",
                                    clientAddress.Address,
                                    localIP,
                                    parser.Channel1,
                                    parser.Channel2);
                }
            }
            // Multicast
            else
            {
                sb.Append("Date: Sat, 22 Dec 2018 16:18:03 GMT\r\n");
                sb.AppendFormat("Transport: RTP/AVP;multicast;destination={0};source={1};port={2}-{3};ttl=255\r\n",
                                multiCastAddress,
                                localIP,
                                serverRTPPort,
                                serverRTCPPort).
                AppendFormat("Session: {0};timeout=65\r\n\r\n", SessionId);
            }

            var reply = sb.ToString();

            _connection.SendResponse(reply);
            return(true);
        }
        private void ParseParameters(RTSPRequestParser requestParser, StringParser parser, Dictionary <string, string> parameters)
        {
            while ((parser.Peek() != '\r') && (parser.Peek() != '\n'))
            {
                //First get the parameter identifier
                bool   isOk;
                string keyword = parser.GetThru(':', out isOk);
                if (!isOk)
                {
                    if (!parser.ParserEndOfString())
                    {
                        throw new Exception(String.Format("Missing semicolumn in body {0}", parser.ToString()));
                    }
                    else
                    {
                        return;
                    }
                }

                keyword = keyword.Trim();


                //Look up the proper header enumeration based on the header string.
                //Use the enumeration to look up the dictionary ID of this header,
                //and set that dictionary attribute to be whatever is in the body of the header

                var headerVal = parser.ConsumeUntil(StringParser.sEOLMask);
                headerVal = headerVal.Trim();
                if (!RTSPServer._validParameters.Contains(keyword))
                {
                    HandleInvalidParameter(requestParser, keyword);
                }
                else
                {
                    parameters.Add(keyword, headerVal);
                }


                if ((parser.Peek() == '\r') || (parser.Peek() == '\n'))
                {
                    isOk = true;
                    parser.ConsumeEOL();
                }
                else
                {
                    isOk = false;
                }

                while ((parser.Peek() == ' ') || (parser.Peek() == '\t'))
                {
                    parser.ConsumeUntil(StringParser.sEOLMask);
                    if ((parser.Peek() == '\r') || (parser.Peek() == '\n'))
                    {
                        isOk = true;
                        parser.ConsumeEOL();
                    }
                    else
                    {
                        isOk = false;
                    }
                }

                try
                {
                    switch (keyword)
                    {
                    case "WIDTH":
                        Convert.ToInt32(headerVal);
                        break;

                    case "HEIGHT":
                        Convert.ToInt32(headerVal);
                        break;
                    }
                }
                catch
                {
                    HandleInvalidParameter(requestParser, keyword, headerVal);
                    throw;
                }
                if (!isOk)
                {
                    throw new Exception(String.Format("Error in header {0}", parser.ToString()));
                }
                ;
            }
            if (!parser.ExpectEOL())
            {
                throw new Exception(String.Format("Invalid request {0}", parser.ToString()));
            }
        }