Ejemplo n.º 1
0
        /// <summary>
        /// Sends the RTSP teardown request for an existing RTSP session.
        /// </summary>
        private void Teardown()
        {
            try
            {
                if (_rtspStream != null && _rtspConnection.Connected)
                {
                    logger.LogDebug("RTSP client sending teardown request for " + _url + ".");

                    RTSPRequest teardownRequest = new RTSPRequest(RTSPMethodsEnum.TEARDOWN, _url);
                    RTSPHeader  teardownHeader  = new RTSPHeader(_cseq++, _rtspSession.SessionID);
                    teardownRequest.Header = teardownHeader;

                    System.Diagnostics.Debug.WriteLine(teardownRequest.ToString());

                    var buffer = Encoding.UTF8.GetBytes(teardownRequest.ToString());
                    _rtspStream.Write(buffer, 0, buffer.Length);
                }
                else
                {
                    logger.LogDebug("RTSP client did not send teardown request for " + _url + ", the socket was closed.");
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception RTSPClient.Teardown. " + excp);
            }
        }
Ejemplo n.º 2
0
        public static RTSPResponse ParseRTSPResponse(RTSPMessage rtspMessage,
                                                     out RTSPResponseParserError responseParserError)
        {
            responseParserError = RTSPResponseParserError.None;

            try
            {
                RTSPResponse rtspResponse = new RTSPResponse();

                string statusLine = rtspMessage.FirstLine;

                int firstSpacePosn = statusLine.IndexOf(" ");

                rtspResponse.RTSPVersion = statusLine.Substring(0, firstSpacePosn).Trim();
                statusLine = statusLine.Substring(firstSpacePosn).Trim();
                rtspResponse.StatusCode   = Convert.ToInt32(statusLine.Substring(0, 3));
                rtspResponse.Status       = RTSPResponseStatusCodes.GetStatusTypeForCode(rtspResponse.StatusCode);
                rtspResponse.ReasonPhrase = statusLine.Substring(3).Trim();

                rtspResponse.Header = RTSPHeader.ParseRTSPHeaders(rtspMessage.RTSPHeaders);
                rtspResponse.Body   = rtspMessage.Body;

                return(rtspResponse);
            }
            catch (Exception excp)
            {
                logger.LogError("Exception parsing RTSP response. " + excp.Message);
                throw new ApplicationException("There was an exception parsing an RTSP response. " + excp.Message);
            }
        }
Ejemplo n.º 3
0
        public static RTSPMessage ParseRTSPMessage(string message, IPEndPoint receivedFrom, IPEndPoint receivedOn)
        {
            try
            {
                RTSPMessage rtspMessage = new RTSPMessage();
                rtspMessage.ReceivedAt   = DateTime.Now;
                rtspMessage.ReceivedFrom = receivedFrom;
                rtspMessage.ReceivedOn   = receivedOn;

                rtspMessage.RawMessage = message;
                int endFistLinePosn = message.IndexOf(m_CRLF);

                if (endFistLinePosn != -1)
                {
                    rtspMessage.FirstLine = message.Substring(0, endFistLinePosn);

                    if (rtspMessage.FirstLine.Substring(0, RTSP_RESPONSE_PREFIX.Length) == RTSP_RESPONSE_PREFIX)
                    {
                        rtspMessage.RTSPMessageType = RTSPMessageTypesEnum.Response;
                    }
                    else
                    {
                        rtspMessage.RTSPMessageType = RTSPMessageTypesEnum.Request;
                    }

                    int endHeaderPosn = message.IndexOf(m_CRLF + m_CRLF);
                    if (endHeaderPosn == -1)
                    {
                        // Assume flakey implementation if message does not contain the required CRLFCRLF sequence and treat the message as having no body.
                        string headerString =
                            message.Substring(endFistLinePosn + 2, message.Length - endFistLinePosn - 2);
                        rtspMessage.RTSPHeaders = RTSPHeader.SplitHeaders(headerString);
                    }
                    else if (endHeaderPosn > endFistLinePosn + 2)
                    {
                        string headerString =
                            message.Substring(endFistLinePosn + 2, endHeaderPosn - endFistLinePosn - 2);
                        rtspMessage.RTSPHeaders = RTSPHeader.SplitHeaders(headerString);

                        if (message.Length > endHeaderPosn + 4)
                        {
                            rtspMessage.Body = message.Substring(endHeaderPosn + 4);
                        }
                    }

                    return(rtspMessage);
                }
                else
                {
                    logger.LogError(
                        "Error ParseRTSPMessage, there were no end of line characters in the string being parsed.");
                    return(null);
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception ParseRTSPMessage. " + excp.Message + "\nRTSP Message=" + message + ".");
                return(null);
            }
        }
Ejemplo n.º 4
0
        public string GetStreamDescription(string url)
        {
            try
            {
                string hostname = Regex.Match(url, @"rtsp://(?<hostname>\S+?)/").Result("${hostname}");
                //IPEndPoint rtspEndPoint = DNSResolver.R(hostname, DNS_RESOLUTION_TIMEOUT);

                logger.LogDebug("RTSP Client Connecting to " + hostname + ".");
                TcpClient     rtspSocket = new TcpClient(hostname, RTSP_PORT);
                NetworkStream rtspStream = rtspSocket.GetStream();

                string      rtspSDP     = null;
                RTSPRequest rtspRequest = new RTSPRequest(RTSPMethodsEnum.DESCRIBE, url);
                RTSPHeader  rtspHeader  = new RTSPHeader(1, null);
                rtspRequest.Header = rtspHeader;
                string rtspReqStr = rtspRequest.ToString();

                RTSPMessage  rtspMessage  = null;
                RTSPResponse rtspResponse = null;

                byte[] rtspRequestBuffer = Encoding.UTF8.GetBytes(rtspReqStr);
                rtspStream.Write(rtspRequestBuffer, 0, rtspRequestBuffer.Length);

                byte[] buffer    = new byte[2048];
                int    bytesRead = rtspStream.Read(buffer, 0, 2048);

                if (bytesRead > 0)
                {
                    logger.LogDebug(Encoding.UTF8.GetString(buffer, 0, bytesRead));
                    byte[] msgBuffer = new byte[bytesRead];
                    Buffer.BlockCopy(buffer, 0, msgBuffer, 0, bytesRead);
                    rtspMessage = RTSPMessage.ParseRTSPMessage(msgBuffer, null, null);

                    if (rtspMessage.RTSPMessageType == RTSPMessageTypesEnum.Response)
                    {
                        rtspResponse = RTSPResponse.ParseRTSPResponse(rtspMessage);
                        logger.LogDebug("RTSP Response received: " + rtspResponse.StatusCode + " " + rtspResponse.Status + " " + rtspResponse.ReasonPhrase + ".");
                    }

                    rtspSDP = rtspResponse.Body;
                }
                else
                {
                    logger.LogWarning("Socket closed prematurely in GetStreamDescription for " + url + ".");
                }

                rtspSocket.Close();

                return(rtspSDP);
            }
            catch (Exception excp)
            {
                logger.LogError("Exception GetStreamDescription. " + excp.Message);
                throw excp;
            }
        }
Ejemplo n.º 5
0
        public string GetStreamDescription(string url)
        {
            try
            {
                string hostname = Regex.Match(url, @"rtsp://(?<hostname>\S+?)/").Result("${hostname}");
                //IPEndPoint rtspEndPoint = DNSResolver.R(hostname, DNS_RESOLUTION_TIMEOUT);

                logger.Debug("RTSP Client Connecting to " + hostname + ".");
                TcpClient rtspSocket = new TcpClient(hostname, RTSP_PORT);
                NetworkStream rtspStream = rtspSocket.GetStream();

                string rtspSDP = null;
                RTSPRequest rtspRequest = new RTSPRequest(RTSPMethodsEnum.DESCRIBE, url);
                RTSPHeader rtspHeader = new RTSPHeader(1, null);
                rtspRequest.Header = rtspHeader;
                string rtspReqStr = rtspRequest.ToString();

                RTSPMessage rtspMessage = null;
                RTSPResponse rtspResponse = null;

                byte[] rtspRequestBuffer = Encoding.UTF8.GetBytes(rtspReqStr);
                rtspStream.Write(rtspRequestBuffer, 0, rtspRequestBuffer.Length);

                byte[] buffer = new byte[2048];
                int bytesRead = rtspStream.Read(buffer, 0, 2048);

                if (bytesRead > 0)
                {
                    logger.Debug(Encoding.UTF8.GetString(buffer, 0, bytesRead));
                    byte[] msgBuffer = new byte[bytesRead];
                    Buffer.BlockCopy(buffer, 0, msgBuffer, 0, bytesRead);
                    rtspMessage = RTSPMessage.ParseRTSPMessage(msgBuffer, null, null);

                    if (rtspMessage.RTSPMessageType == RTSPMessageTypesEnum.Response)
                    {
                        rtspResponse = RTSPResponse.ParseRTSPResponse(rtspMessage);
                        logger.Debug("RTSP Response received: " + rtspResponse.StatusCode + " " + rtspResponse.Status + " " + rtspResponse.ReasonPhrase + ".");
                    }

                    rtspSDP = rtspResponse.Body;
                }
                else
                {
                    logger.Warn("Socket closed prematurely in GetStreamDescription for " + url + ".");
                }

                rtspSocket.Close();

                return rtspSDP;
            }
            catch (Exception excp)
            {
                logger.Error("Exception GetStreamDescription. " + excp.Message);
                throw excp;
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Sends a keep-alive packet to keep the RTSP RTP connection from being shut.
        /// </summary>
        private void SendKeepAlives()
        {
            try
            {
                Thread.CurrentThread.Name = "rtspclient-keepalive";

                // Set the initial pause as half the keep-alive interval.
                Thread.Sleep(RTP_KEEP_ALIVE_INTERVAL * 500);

                while (!_isClosed)
                {
                    _rtspSession.SendRTPRaw(new byte[] { 0x00, 0x00, 0x00, 0x00 });

                    // Also send an OPTIONS request on the RTSP connection to prevent the remote server from timing it out.
                    RTSPRequest optionsRequest = new RTSPRequest(RTSPMethodsEnum.OPTIONS, _url);
                    RTSPHeader  optionsHeader  = new RTSPHeader(_cseq++, _rtspSession.SessionID);
                    optionsRequest.Header = optionsHeader;

                    System.Diagnostics.Debug.WriteLine(optionsRequest.ToString());

                    var rtspRequestBuffer = Encoding.UTF8.GetBytes(optionsRequest.ToString());
                    _rtspStream.Write(rtspRequestBuffer, 0, rtspRequestBuffer.Length);

                    var buffer    = new byte[2048];
                    var bytesRead = _rtspStream.Read(buffer, 0, 2048);

                    if (bytesRead > 0)
                    {
                        System.Diagnostics.Debug.WriteLine(Encoding.UTF8.GetString(buffer, 0, bytesRead));

                        var rtspMessage = RTSPMessage.ParseRTSPMessage(buffer, null, null);

                        if (rtspMessage.RTSPMessageType == RTSPMessageTypesEnum.Response)
                        {
                            var optionsResponse = RTSPResponse.ParseRTSPResponse(rtspMessage);
                            //logger.LogDebug("RTSP Response received for OPTIONS keep-alive request: " + optionsResponse.StatusCode + " " + optionsResponse.Status + " " + optionsResponse.ReasonPhrase + ".");
                        }
                    }
                    else
                    {
                        logger.LogWarning("Zero bytes were read from the RTSP client socket in response to an OPTIONS keep-alive request.");
                    }

                    _sendKeepAlivesMRE.Reset();
                    _sendKeepAlivesMRE.WaitOne(RTP_KEEP_ALIVE_INTERVAL * 1000);
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception RTSPClient.SendKeepAlives. " + excp);
            }
        }
Ejemplo n.º 7
0
        public static RTSPRequest ParseRTSPRequest(RTSPMessage rtspMessage,
                                                   out RTSPRequestParserError requestParserError)
        {
            requestParserError = RTSPRequestParserError.None;
            string urlStr = null;

            try
            {
                RTSPRequest rtspRequest = new RTSPRequest();

                string statusLine = rtspMessage.FirstLine;

                int firstSpacePosn = statusLine.IndexOf(" ");

                string method = statusLine.Substring(0, firstSpacePosn).Trim();
                rtspRequest.Method = RTSPMethods.GetMethod(method);
                if (rtspRequest.Method == RTSPMethodsEnum.UNKNOWN)
                {
                    rtspRequest.UnknownMethod = method;
                    logger.LogWarning("Unknown RTSP method received " + rtspRequest.Method + ".");
                }

                statusLine = statusLine.Substring(firstSpacePosn).Trim();
                int secondSpacePosn = statusLine.IndexOf(" ");

                if (secondSpacePosn != -1)
                {
                    urlStr = statusLine.Substring(0, secondSpacePosn);

                    rtspRequest.URL         = RTSPURL.ParseRTSPURL(urlStr);
                    rtspRequest.RTSPVersion = statusLine.Substring(secondSpacePosn, statusLine.Length - secondSpacePosn)
                                              .Trim();
                    rtspRequest.Header = (rtspMessage.RTSPHeaders != null)
                        ? RTSPHeader.ParseRTSPHeaders(rtspMessage.RTSPHeaders)
                        : new RTSPHeader(0, null);
                    rtspRequest.Body = rtspMessage.Body;

                    return(rtspRequest);
                }
                else
                {
                    throw new ApplicationException("URI was missing on RTSP request.");
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception parsing RTSP request. URI, " + urlStr + ".");
                throw new ApplicationException("There was an exception parsing an RTSP request. " + excp.Message);
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Send a PLAY request to the RTSP server to commence the media stream.
        /// </summary>
        public void Play()
        {
            ThreadPool.QueueUserWorkItem(delegate
                                         { ProcessRTPPackets(); });
            ThreadPool.QueueUserWorkItem(delegate
                                         { SendKeepAlives(); });

            RTSPRequest playRequest = new RTSPRequest(RTSPMethodsEnum.PLAY, _url);
            RTSPHeader  playHeader  = new RTSPHeader(_cseq++, _rtspSession.SessionID);

            playRequest.Header = playHeader;

            System.Diagnostics.Debug.WriteLine(playRequest.ToString());

            var rtspRequestBuffer = Encoding.UTF8.GetBytes(playRequest.ToString());

            _rtspStream.Write(rtspRequestBuffer, 0, rtspRequestBuffer.Length);

            var buffer    = new byte[2048];
            var bytesRead = _rtspStream.Read(buffer, 0, 2048);

            if (bytesRead > 0)
            {
                System.Diagnostics.Debug.WriteLine(Encoding.UTF8.GetString(buffer, 0, bytesRead));

                var rtspMessage = RTSPMessage.ParseRTSPMessage(buffer, null, null);

                if (rtspMessage.RTSPMessageType == RTSPMessageTypesEnum.Response)
                {
                    var playResponse = RTSPResponse.ParseRTSPResponse(rtspMessage);
                    logger.LogDebug("RTSP Response received to PLAY: " + playResponse.StatusCode + " " + playResponse.Status + " " + playResponse.ReasonPhrase + ".");
                }
            }
            else
            {
                throw new ApplicationException("Zero bytes were read from the RTSP client socket in response to a PLAY request.");
            }
        }
Ejemplo n.º 9
0
        public void Start(string url)
        {
            _url = url;

            Match urlMatch = Regex.Match(url, @"rtsp://(?<hostname>\S+?)/", RegexOptions.IgnoreCase);

            if (!urlMatch.Success)
            {
                throw new ApplicationException("The URL provided to the RTSP client was not recognised, " + url + ".");
            }
            else
            {
                string hostname = urlMatch.Result("${hostname}");
                int    port     = RTSP_PORT;

                if (hostname.Contains(':'))
                {
                    port     = SIPSorcery.Sys.IPSocket.ParsePortFromSocket(hostname);
                    hostname = SIPSorcery.Sys.IPSocket.ParseHostFromSocket(hostname);
                }

                logger.LogDebug("RTSP client connecting to " + hostname + ", port " + port + ".");

                _rtspConnection = new TcpClient(hostname, port);
                _rtspStream     = _rtspConnection.GetStream();

                _rtspSession = new RTSPSession();
                _rtspSession.RTPPayloadHeaderLength = _rtpPayloadHeaderLength;
                _rtspSession.ReservePorts();
                _rtspSession.OnRTPQueueFull += RTPQueueFull;

                RTSPRequest rtspRequest = new RTSPRequest(RTSPMethodsEnum.SETUP, url);
                RTSPHeader  rtspHeader  = new RTSPHeader(_cseq++, null);
                rtspHeader.Transport = new RTSPTransportHeader()
                {
                    ClientRTPPortRange = _rtspSession.RTPPort + "-" + _rtspSession.ControlPort
                };
                rtspRequest.Header = rtspHeader;
                string rtspReqStr = rtspRequest.ToString();

                RTSPMessage rtspMessage = null;

                System.Diagnostics.Debug.WriteLine(rtspReqStr);

                byte[] rtspRequestBuffer = Encoding.UTF8.GetBytes(rtspReqStr);
                _rtspStream.Write(rtspRequestBuffer, 0, rtspRequestBuffer.Length);

                byte[] buffer    = new byte[2048];
                int    bytesRead = _rtspStream.Read(buffer, 0, 2048);

                if (bytesRead > 0)
                {
                    System.Diagnostics.Debug.WriteLine(Encoding.UTF8.GetString(buffer, 0, bytesRead));

                    rtspMessage = RTSPMessage.ParseRTSPMessage(buffer, null, null);

                    if (rtspMessage.RTSPMessageType == RTSPMessageTypesEnum.Response)
                    {
                        var setupResponse = RTSPResponse.ParseRTSPResponse(rtspMessage);

                        if (setupResponse.Status == RTSPResponseStatusCodesEnum.OK)
                        {
                            _rtspSession.SessionID      = setupResponse.Header.Session;
                            _rtspSession.RemoteEndPoint = new IPEndPoint((_rtspConnection.Client.RemoteEndPoint as IPEndPoint).Address, setupResponse.Header.Transport.GetServerRTPPort());
                            _rtspSession.Start();

                            logger.LogDebug("RTSP Response received to SETUP: " + setupResponse.Status + ", session ID " + _rtspSession.SessionID + ", server RTP endpoint " + _rtspSession.RemoteEndPoint + ".");

                            if (OnSetupSuccess != null)
                            {
                                OnSetupSuccess(this);
                            }
                        }
                        else
                        {
                            logger.LogWarning("RTSP Response received to SETUP: " + setupResponse.Status + ".");
                            throw new ApplicationException("An error response of " + setupResponse.Status + " was received for an RTSP setup request.");
                        }
                    }
                }
                else
                {
                    throw new ApplicationException("Zero bytes were read from the RTSP client socket in response to a SETUP request.");
                }
            }
        }
Ejemplo n.º 10
0
        public static RTSPHeader ParseRTSPHeaders(string[] headersCollection)
        {
            try
            {
                RTSPHeader rtspHeader = new RTSPHeader();

                string lastHeader = null;

                for (int lineIndex = 0; lineIndex < headersCollection.Length; lineIndex++)
                {
                    string headerLine = headersCollection[lineIndex];

                    if (headerLine == null || headerLine.Trim().Length == 0)
                    {
                        // No point processing blank headers.
                        continue;
                    }

                    string headerName = null;
                    string headerValue = null;

                    // If the first character of a line is whitespace it's a contiuation of the previous line.
                    if (headerLine.StartsWith(" "))
                    {
                        headerName = lastHeader;
                        headerValue = headerLine.Trim();
                    }
                    else
                    {
                        string[] headerParts = headerLine.Trim().Split(delimiterChars, 2);

                        if (headerParts == null || headerParts.Length < 2)
                        {
                            logger.Error("Invalid RTSP header, ignoring. header=" + headerLine + ".");

                            try
                            {
                                string errorHeaders = String.Join(m_CRLF, headersCollection);
                                logger.Error("Full Invalid Headers: " + errorHeaders);
                            }
                            catch { }

                            continue;
                        }

                        headerName = headerParts[0].Trim();
                        headerValue = headerParts[1].Trim();
                    }

                    try
                    {
                        string headerNameLower = headerName.ToLower();

                        #region Accept
                        if (headerNameLower == RTSPHeaders.RTSP_HEADER_ACCEPT.ToLower())
                        {
                            rtspHeader.Accept = headerValue;
                        }
                        #endregion
                        #region ContentType
                        if (headerNameLower == RTSPHeaders.RTSP_HEADER_CONTENTTYPE.ToLower())
                        {
                            rtspHeader.ContentType = headerValue;
                        }
                        #endregion
                        #region ContentLength
                        if (headerNameLower == RTSPHeaders.RTSP_HEADER_CONTENTLENGTH.ToLower())
                        {
                            rtspHeader.RawCSeq = headerValue;

                            if (headerValue == null || headerValue.Trim().Length == 0)
                            {
                                logger.Warn("Invalid RTSP header, the " + RTSPHeaders.RTSP_HEADER_CONTENTLENGTH + " was empty.");
                            }
                            else if (!Int32.TryParse(headerValue.Trim(), out rtspHeader.ContentLength))
                            {
                                logger.Warn("Invalid RTSP header, the " + RTSPHeaders.RTSP_HEADER_CONTENTLENGTH + " was not a valid 32 bit integer, " + headerValue + ".");
                            }
                        }
                        #endregion
                        #region CSeq
                        if (headerNameLower == RTSPHeaders.RTSP_HEADER_CSEQ.ToLower())
                        {
                            rtspHeader.RawCSeq = headerValue;

                            if (headerValue == null || headerValue.Trim().Length == 0)
                            {
                                rtspHeader.CSeqParserError = RTSPHeaderParserError.CSeqEmpty;
                                logger.Warn("Invalid RTSP header, the " + RTSPHeaders.RTSP_HEADER_CSEQ + " was empty.");
                            }
                            else if (!Int32.TryParse(headerValue.Trim(), out rtspHeader.CSeq))
                            {
                                rtspHeader.CSeqParserError = RTSPHeaderParserError.CSeqNotValidInteger;
                                logger.Warn("Invalid SIP header, the " + RTSPHeaders.RTSP_HEADER_CSEQ + " was not a valid 32 bit integer, " + headerValue + ".");
                            }
                        }
                        #endregion
                        #region Session
                        if (headerNameLower == RTSPHeaders.RTSP_HEADER_SESSION.ToLower())
                        {
                            rtspHeader.Session = headerValue;
                        }
                        #endregion
                        #region Transport
                        if (headerNameLower == RTSPHeaders.RTSP_HEADER_TRANSPORT.ToLower())
                        {
                            rtspHeader.Transport = RTSPTransportHeader.Parse(headerValue);
                        }
                        #endregion
                        else
                        {
                            rtspHeader.UnknownHeaders.Add(headerLine);
                        }

                        lastHeader = headerName;
                    }
                    catch (Exception parseExcp)
                    {
                        logger.Error("Error parsing RTSP header " + headerLine + ". " + parseExcp.Message);
                        throw parseExcp;
                    }
                }

                //sipHeader.Valid = sipHeader.Validate(out sipHeader.ValidationError);

                return rtspHeader;
            }
            catch (ApplicationException appHeaderExcp)
            {
                throw appHeaderExcp;
            }
            catch (Exception excp)
            {
                logger.Error("Exception ParseRTSPHeaders. " + excp.Message);
                throw excp;
            }
        }
Ejemplo n.º 11
0
        public static RTSPHeader ParseRTSPHeaders(string[] headersCollection)
        {
            try
            {
                RTSPHeader rtspHeader = new RTSPHeader();

                string lastHeader = null;

                for (int lineIndex = 0; lineIndex < headersCollection.Length; lineIndex++)
                {
                    string headerLine = headersCollection[lineIndex];

                    if (headerLine == null || headerLine.Trim().Length == 0)
                    {
                        // No point processing blank headers.
                        continue;
                    }

                    string headerName  = null;
                    string headerValue = null;

                    // If the first character of a line is whitespace it's a continuation of the previous line.
                    if (headerLine.StartsWith(" "))
                    {
                        headerName  = lastHeader;
                        headerValue = headerLine.Trim();
                    }
                    else
                    {
                        string[] headerParts = headerLine.Trim().Split(delimiterChars, 2);

                        if (headerParts == null || headerParts.Length < 2)
                        {
                            logger.LogError("Invalid RTSP header, ignoring. header=" + headerLine + ".");

                            try
                            {
                                string errorHeaders = String.Join(m_CRLF, headersCollection);
                                logger.LogError("Full Invalid Headers: " + errorHeaders);
                            }
                            catch
                            {
                            }

                            continue;
                        }

                        headerName  = headerParts[0].Trim();
                        headerValue = headerParts[1].Trim();
                    }

                    try
                    {
                        string headerNameLower = headerName.ToLower();

                        #region Accept

                        if (headerNameLower == RTSPHeaders.RTSP_HEADER_ACCEPT.ToLower())
                        {
                            rtspHeader.Accept = headerValue;
                        }

                        #endregion

                        #region ContentType

                        if (headerNameLower == RTSPHeaders.RTSP_HEADER_CONTENTTYPE.ToLower())
                        {
                            rtspHeader.ContentType = headerValue;
                        }

                        #endregion

                        #region ContentLength

                        if (headerNameLower == RTSPHeaders.RTSP_HEADER_CONTENTLENGTH.ToLower())
                        {
                            rtspHeader.RawCSeq = headerValue;

                            if (headerValue == null || headerValue.Trim().Length == 0)
                            {
                                logger.LogWarning("Invalid RTSP header, the " + RTSPHeaders.RTSP_HEADER_CONTENTLENGTH +
                                                  " was empty.");
                            }
                            else if (!Int32.TryParse(headerValue.Trim(), out rtspHeader.ContentLength))
                            {
                                logger.LogWarning("Invalid RTSP header, the " + RTSPHeaders.RTSP_HEADER_CONTENTLENGTH +
                                                  " was not a valid 32 bit integer, " + headerValue + ".");
                            }
                        }

                        #endregion

                        #region CSeq

                        if (headerNameLower == RTSPHeaders.RTSP_HEADER_CSEQ.ToLower())
                        {
                            rtspHeader.RawCSeq = headerValue;

                            if (headerValue == null || headerValue.Trim().Length == 0)
                            {
                                rtspHeader.CSeqParserError = RTSPHeaderParserError.CSeqEmpty;
                                logger.LogWarning("Invalid RTSP header, the " + RTSPHeaders.RTSP_HEADER_CSEQ +
                                                  " was empty.");
                            }
                            else if (!Int32.TryParse(headerValue.Trim(), out rtspHeader.CSeq))
                            {
                                rtspHeader.CSeqParserError = RTSPHeaderParserError.CSeqNotValidInteger;
                                logger.LogWarning("Invalid SIP header, the " + RTSPHeaders.RTSP_HEADER_CSEQ +
                                                  " was not a valid 32 bit integer, " + headerValue + ".");
                            }
                        }

                        #endregion

                        #region Session

                        if (headerNameLower == RTSPHeaders.RTSP_HEADER_SESSION.ToLower())
                        {
                            rtspHeader.Session = headerValue;
                        }

                        #endregion

                        #region Transport

                        if (headerNameLower == RTSPHeaders.RTSP_HEADER_TRANSPORT.ToLower())
                        {
                            rtspHeader.Transport = RTSPTransportHeader.Parse(headerValue);
                        }

                        #endregion

                        else
                        {
                            rtspHeader.UnknownHeaders.Add(headerLine);
                        }

                        lastHeader = headerName;
                    }
                    catch (Exception parseExcp)
                    {
                        logger.LogError("Error parsing RTSP header " + headerLine + ". " + parseExcp.Message);
                        throw;
                    }
                }

                //sipHeader.Valid = sipHeader.Validate(out sipHeader.ValidationError);

                return(rtspHeader);
            }
            catch (ApplicationException)
            {
                throw;
            }
            catch (Exception excp)
            {
                logger.LogError("Exception ParseRTSPHeaders. " + excp.Message);
                throw;
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Sends the RTSP teardown request for an existing RTSP session.
        /// </summary>
        private void Teardown()
        {
            try
            {
                if (_rtspStream != null && _rtspConnection.Connected)
                {
                    logger.Debug("RTSP client sending teardown request for " + _url + ".");

                    RTSPRequest teardownRequest = new RTSPRequest(RTSPMethodsEnum.TEARDOWN, _url);
                    RTSPHeader teardownHeader = new RTSPHeader(_cseq++, _rtspSession.SessionID);
                    teardownRequest.Header = teardownHeader;

                    System.Diagnostics.Debug.WriteLine(teardownRequest.ToString());

                    var buffer = Encoding.UTF8.GetBytes(teardownRequest.ToString());
                    _rtspStream.Write(buffer, 0, buffer.Length);
                }
                else
                {
                    logger.Debug("RTSP client did not send teardown request for " + _url + ", the socket was closed.");
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception RTSPClient.Teardown. " + excp);
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Sends a keep-alive packet to keep the RTSP RTP connection from being shut.
        /// </summary>
        private void SendKeepAlives()
        {
            try
            {
                Thread.CurrentThread.Name = "rtspclient-keepalive";

                // Set the initial pause as half the keep-alive interval.
                Thread.Sleep(RTP_KEEP_ALIVE_INTERVAL * 500);

                while (!_isClosed)
                {
                    _rtspSession.SendRTPRaw(new byte[] { 0x00, 0x00, 0x00, 0x00 });

                    // Also send an OPTIONS request on the RTSP connection to prevent the remote server from timing it out.
                    RTSPRequest optionsRequest = new RTSPRequest(RTSPMethodsEnum.OPTIONS, _url);
                    RTSPHeader optionsHeader = new RTSPHeader(_cseq++, _rtspSession.SessionID);
                    optionsRequest.Header = optionsHeader;

                    System.Diagnostics.Debug.WriteLine(optionsRequest.ToString());

                    var rtspRequestBuffer = Encoding.UTF8.GetBytes(optionsRequest.ToString());
                    _rtspStream.Write(rtspRequestBuffer, 0, rtspRequestBuffer.Length);

                    var buffer = new byte[2048];
                    var bytesRead = _rtspStream.Read(buffer, 0, 2048);

                    if (bytesRead > 0)
                    {
                        System.Diagnostics.Debug.WriteLine(Encoding.UTF8.GetString(buffer, 0, bytesRead));

                        var rtspMessage = RTSPMessage.ParseRTSPMessage(buffer, null, null);

                        if (rtspMessage.RTSPMessageType == RTSPMessageTypesEnum.Response)
                        {
                            var optionsResponse = RTSPResponse.ParseRTSPResponse(rtspMessage);
                            //logger.Debug("RTSP Response received for OPTIONS keep-alive request: " + optionsResponse.StatusCode + " " + optionsResponse.Status + " " + optionsResponse.ReasonPhrase + ".");
                        }
                    }
                    else
                    {
                        logger.Warn("Zero bytes were read from the RTSP client socket in response to an OPTIONS keep-alive request.");
                    }

                    _sendKeepAlivesMRE.Reset();
                    _sendKeepAlivesMRE.WaitOne(RTP_KEEP_ALIVE_INTERVAL * 1000);
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception RTSPClient.SendKeepAlives. " + excp);
            }
        }
Ejemplo n.º 14
0
        public void Start(string url)
        {
            _url = url;

            Match urlMatch = Regex.Match(url, @"rtsp://(?<hostname>\S+?)/", RegexOptions.IgnoreCase);

            if (!urlMatch.Success)
            {
                throw new ApplicationException("The URL provided to the RTSP client was not recognised, " + url + ".");
            }
            else
            {
                string hostname = urlMatch.Result("${hostname}");
                int port = RTSP_PORT;

                if (hostname.Contains(':'))
                {
                    port = SIPSorcery.Sys.IPSocket.ParsePortFromSocket(hostname);
                    hostname = SIPSorcery.Sys.IPSocket.ParseHostFromSocket(hostname);
                }

                logger.Debug("RTSP client connecting to " + hostname + ", port " + port + ".");

                _rtspConnection = new TcpClient(hostname, port);
                _rtspStream = _rtspConnection.GetStream();

                _rtspSession = new RTSPSession();
                _rtspSession.RTPPayloadHeaderLength = _rtpPayloadHeaderLength;
                _rtspSession.ReservePorts();
                _rtspSession.OnRTPQueueFull += RTPQueueFull;

                RTSPRequest rtspRequest = new RTSPRequest(RTSPMethodsEnum.SETUP, url);
                RTSPHeader rtspHeader = new RTSPHeader(_cseq++, null);
                rtspHeader.Transport = new RTSPTransportHeader() { ClientRTPPortRange = _rtspSession.RTPPort + "-" + _rtspSession.ControlPort };
                rtspRequest.Header = rtspHeader;
                string rtspReqStr = rtspRequest.ToString();

                RTSPMessage rtspMessage = null;

                System.Diagnostics.Debug.WriteLine(rtspReqStr);

                byte[] rtspRequestBuffer = Encoding.UTF8.GetBytes(rtspReqStr);
                _rtspStream.Write(rtspRequestBuffer, 0, rtspRequestBuffer.Length);

                byte[] buffer = new byte[2048];
                int bytesRead = _rtspStream.Read(buffer, 0, 2048);

                if (bytesRead > 0)
                {
                    System.Diagnostics.Debug.WriteLine(Encoding.UTF8.GetString(buffer, 0, bytesRead));

                    rtspMessage = RTSPMessage.ParseRTSPMessage(buffer, null, null);

                    if (rtspMessage.RTSPMessageType == RTSPMessageTypesEnum.Response)
                    {
                        var setupResponse = RTSPResponse.ParseRTSPResponse(rtspMessage);

                        if (setupResponse.Status == RTSPResponseStatusCodesEnum.OK)
                        {
                            _rtspSession.SessionID = setupResponse.Header.Session;
                            _rtspSession.RemoteEndPoint = new IPEndPoint((_rtspConnection.Client.RemoteEndPoint as IPEndPoint).Address, setupResponse.Header.Transport.GetServerRTPPort());
                            _rtspSession.Start();

                            logger.Debug("RTSP Response received to SETUP: " + setupResponse.Status + ", session ID " + _rtspSession.SessionID + ", server RTP endpoint " + _rtspSession.RemoteEndPoint + ".");

                            if (OnSetupSuccess != null)
                            {
                                OnSetupSuccess(this);
                            }
                        }
                        else
                        {
                            logger.Warn("RTSP Response received to SETUP: " + setupResponse.Status + ".");
                            throw new ApplicationException("An error response of " + setupResponse.Status + " was received for an RTSP setup request.");
                        }
                    }
                }
                else
                {
                    throw new ApplicationException("Zero bytes were read from the RTSP client socket in response to a SETUP request.");
                }
            }
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Send a PLAY request to the RTSP server to commence the media stream.
        /// </summary>
        public void Play()
        {
            ThreadPool.QueueUserWorkItem(delegate { ProcessRTPPackets(); });
            ThreadPool.QueueUserWorkItem(delegate { SendKeepAlives(); });

            RTSPRequest playRequest = new RTSPRequest(RTSPMethodsEnum.PLAY, _url);
            RTSPHeader playHeader = new RTSPHeader(_cseq++, _rtspSession.SessionID);
            playRequest.Header = playHeader;

            System.Diagnostics.Debug.WriteLine(playRequest.ToString());

            var rtspRequestBuffer = Encoding.UTF8.GetBytes(playRequest.ToString());
            _rtspStream.Write(rtspRequestBuffer, 0, rtspRequestBuffer.Length);

            var buffer = new byte[2048];
            var bytesRead = _rtspStream.Read(buffer, 0, 2048);

            if (bytesRead > 0)
            {
                System.Diagnostics.Debug.WriteLine(Encoding.UTF8.GetString(buffer, 0, bytesRead));

                var rtspMessage = RTSPMessage.ParseRTSPMessage(buffer, null, null);

                if (rtspMessage.RTSPMessageType == RTSPMessageTypesEnum.Response)
                {
                    var playResponse = RTSPResponse.ParseRTSPResponse(rtspMessage);
                    logger.Debug("RTSP Response received to PLAY: " + playResponse.StatusCode + " " + playResponse.Status + " " + playResponse.ReasonPhrase + ".");
                }
            }
            else
            {
                throw new ApplicationException("Zero bytes were read from the RTSP client socket in response to a PLAY request.");
            }
        }
Ejemplo n.º 16
0
        public void Start(string url, IPAddress remoteAddress, int rtpPort)
        {
            string hostname = Regex.Match(url, @"rtsp://(?<hostname>\S+?)/").Result("${hostname}");

            logger.Debug("RTSP Client Connecting to " + hostname + ".");
            TcpClient rtspSocket = new TcpClient(hostname, RTSP_PORT);
            NetworkStream rtspStream = rtspSocket.GetStream();

            RTSPRequest rtspRequest = new RTSPRequest(RTSPMethodsEnum.SETUP, url);
            RTSPHeader rtspHeader = new RTSPHeader(2, null);
            int controlPort = rtpPort + 1;
            rtspHeader.Transport = "RTP/AVP;unicast;dest_addr=" + remoteAddress + ";client_port=" + rtpPort + "-" + controlPort;
            rtspRequest.Header = rtspHeader;
            string rtspReqStr = rtspRequest.ToString();

            RTSPMessage rtspMessage = null;
            RTSPResponse rtspResponse = null;

            Console.WriteLine(rtspReqStr);
            byte[] rtspRequestBuffer = Encoding.UTF8.GetBytes(rtspReqStr);
            rtspStream.Write(rtspRequestBuffer, 0, rtspRequestBuffer.Length);

            byte[] buffer = new byte[2048];
            int bytesRead = rtspStream.Read(buffer, 0, 2048);

            if (bytesRead > 0)
            {
                Console.Write(Encoding.UTF8.GetString(buffer, 0, bytesRead));
                rtspMessage = RTSPMessage.ParseRTSPMessage(buffer, null, null);

                if (rtspMessage.RTSPMessageType == RTSPMessageTypesEnum.Response)
                {
                    rtspResponse = RTSPResponse.ParseRTSPResponse(rtspMessage);
                    Console.WriteLine("RTSP Response received to SETUP: " + rtspResponse.StatusCode + " " + rtspResponse.Status + " " + rtspResponse.ReasonPhrase + ".");
                }
            }
            else
            {
                Console.WriteLine("socket closed.");
            }

            if (rtspResponse != null && rtspResponse.StatusCode >= 200 && rtspResponse.StatusCode <= 299)
            {
                RTSPRequest playRequest = new RTSPRequest(RTSPMethodsEnum.PLAY, url);
                RTSPHeader playHeader = new RTSPHeader(3, rtspResponse.Header.Session);
                playRequest.Header = playHeader;

                Console.WriteLine(playRequest.ToString());
                rtspRequestBuffer = Encoding.UTF8.GetBytes(playRequest.ToString());
                rtspStream.Write(rtspRequestBuffer, 0, rtspRequestBuffer.Length);
            }

            buffer = new byte[2048];
            bytesRead = rtspStream.Read(buffer, 0, 2048);

            if (bytesRead > 0)
            {
                Console.Write(Encoding.UTF8.GetString(buffer, 0, bytesRead));
                rtspMessage = RTSPMessage.ParseRTSPMessage(buffer, null, null);

                if (rtspMessage.RTSPMessageType == RTSPMessageTypesEnum.Response)
                {
                    rtspResponse = RTSPResponse.ParseRTSPResponse(rtspMessage);
                    Console.WriteLine("RTSP Response received to PLAY: " + rtspResponse.StatusCode + " " + rtspResponse.Status + " " + rtspResponse.ReasonPhrase + ".");
                }
            }
            else
            {
                Console.WriteLine("socket closed.");
            }
        }