예제 #1
0
        private bool HandleRTSPMessage()
        {
            //1. Get the content
            if (_contentLength > 0)
            {
                if (_contentLength > 1024 * 1024)
                {
                    FATAL("Bogus content length: {0}", _contentLength);
                    return(false);
                }
                var chunkLength = _contentLength - _inboundContent.Length;
                chunkLength      = InputBuffer.AvaliableByteCounts < chunkLength ? InputBuffer.AvaliableByteCounts : chunkLength;
                _inboundContent += InputBuffer.Reader.ReadBytes((int)chunkLength).BytesToString();
                if (_inboundContent.Length < _contentLength)
                {
                    FINEST("Not enough data. Wanted: {0}; got: {1}", _contentLength, _inboundContent.Length);
                    return(true);
                }
            }

            //2. Call the protocol handler
            var result = _inboundHeaders["isRequest"] ? _protocolHandler.HandleRTSPRequest(this, _inboundHeaders, _inboundContent) : _protocolHandler.HandleRTSPResponse(this, _inboundHeaders, ref _inboundContent);

            _state = RtspState.Header;
            return(result);
        }
예제 #2
0
        public RtspProtocol()
        {
            _state = RtspState.Header;
            _rtpData = false;

        }
예제 #3
0
        private bool HandleRTSPMessage()
        {
            //1. Get the content
            if (_contentLength > 0)
            {
                if (_contentLength > 1024 * 1024)
                {
                    FATAL("Bogus content length: {0}", _contentLength);
                    return false;
                }
                var chunkLength = _contentLength - _inboundContent.Length;
                chunkLength = InputBuffer.AvaliableByteCounts < chunkLength ? InputBuffer.AvaliableByteCounts : chunkLength;
                _inboundContent += InputBuffer.Reader.ReadBytes((int) chunkLength).BytesToString();
                if (_inboundContent.Length < _contentLength)
                {
                    FINEST("Not enough data. Wanted: {0}; got: {1}", _contentLength, _inboundContent.Length);
                    return true;
                }
            }

            //2. Call the protocol handler
            var result = _inboundHeaders["isRequest"] ? _protocolHandler.HandleRTSPRequest(this, _inboundHeaders, _inboundContent) : _protocolHandler.HandleRTSPResponse(this, _inboundHeaders,ref _inboundContent);

            _state = RtspState.Header;
            return result;
        }
예제 #4
0
        private bool ParseNormalHeaders()
        {
            _inboundHeaders.SetValue();
            _inboundContent = "";
            if (InputBuffer.AvaliableByteCounts < 4) return true;
            //2. Detect the headers boundaries
            var headersSize = 0;
            var markerFound = false;
            var pos = InputBuffer.Position;
            while (InputBuffer.AvaliableByteCounts >= 4)
            {
                if (InputBuffer.Position - pos >= RTSP_MAX_HEADERS_SIZE)
                {
                    FATAL("Headers section too long");
                    return false;
                }
                if (InputBuffer.ReadByte() != 0x0d || InputBuffer.ReadByte() != 0x0a|| InputBuffer.ReadByte() != 0x0d || InputBuffer.ReadByte() != 0x0a) continue;
              
                    markerFound = true;
                    headersSize = (int) (InputBuffer.Position-pos - 4);
                    break;
            }
           
            //3. Are the boundaries correct?
            //Do we have enough data to parse the headers?
            if (headersSize == 0)
            {
                return !markerFound;
            }
            InputBuffer.Position = pos;
            var rawHeaders = Encoding.ASCII.GetString(InputBuffer.Reader.ReadBytes(headersSize)); 
            System.Diagnostics.Debug.WriteLine(rawHeaders);
            var lines = rawHeaders.Split(new []{ "\r\n" },StringSplitOptions.None);
            if(lines.Length==0)
            {
                FATAL("Incorrect RTSP request");
                return false;
            }

            //4. Get the fisrt line and parse it. This is either a status code
            //for a previous request made by us, or the request that we just received
            if (!ParseFirstLine(lines[0]))
            {
                FATAL("Unable to parse the first line");
                return false;
            }
            _inboundHeaders[RTSP_HEADERS] = Variant.Get();
            foreach (var line in lines.Skip(1))
            {
                string splitter = ": ";
                if (line.StartsWith(splitter) || line.EndsWith(splitter))
                {
                    splitter = ":";
                    if (line.StartsWith(splitter) || line.EndsWith(splitter))
                    {
                        WARN("Invalid header line: {0}", (line));
                        continue;
                    }
                }

                _inboundHeaders[RTSP_HEADERS][line.Substring(0, line.IndexOf(splitter, StringComparison.Ordinal))] =
                    line.Substring(line.IndexOf(splitter, StringComparison.Ordinal) + splitter.Length);
            }
            //6. default a transfer type to Content-Length: 0 if necessary
            if (_inboundHeaders[RTSP_HEADERS, RTSP_HEADERS_CONTENT_LENGTH] == null)
            {
                _inboundHeaders[RTSP_HEADERS,RTSP_HEADERS_CONTENT_LENGTH] = "0";
            }

            //7. read the transfer type and set this request or response flags
            string contentLengthString = _inboundHeaders[RTSP_HEADERS, RTSP_HEADERS_CONTENT_LENGTH];
            contentLengthString= contentLengthString.Replace(" ", "");
            try
            {
                _contentLength = Convert.ToUInt32(contentLengthString);
            }
            catch
            {
                FATAL("Invalid RTSP headers:\n{0}", (_inboundHeaders.ToString()));
                return false;
            }
           
            //7. Advance the state and ignore the headers part from the buffer
            _state = RtspState.Playload;
            _rtpData = false;
            InputBuffer.Ignore(4);
            return true;
        }
예제 #5
0
        public override bool SignalInputData(int recAmount)
        {
            while (InputBuffer.AvaliableByteCounts > 0)
            {
                switch (_state)
                {
                    case RtspState.InterleavedHeader:
                        //6. Do we have enough data?
                        if (InputBuffer.AvaliableByteCounts < _rtpDataLength)
                        {
                            return true;
                        }
                        _state = RtspState.Playload;
                        goto case RtspState.Playload;
                    case RtspState.NormalHeader:
                        ParseNormalHeaders();
                        if (_state != RtspState.Playload)
                            return true;
                        goto case RtspState.Playload;
                    case RtspState.Header:
                        
                        if (InputBuffer.Reader.PeekChar() == '$')
                        {
                            //1. Marl this as a interleaved content
                            _rtpData = true;
                            //2. Do we have at least 4 bytes ($ sign, channel byte an 2-bytes length)?
                            var bufferLength = InputBuffer.AvaliableByteCounts;
                            if (bufferLength < 4) return true;
                            //3. Get the buffer
                            InputBuffer.Reader.ReadByte();
                            //4. Get the channel id
                            _rtpDataChanel = InputBuffer.Reader.ReadByte();
                            //5. Get the packet length
                            _rtpDataLength = InputBuffer.Reader.ReadUInt16();

                            if (_rtpDataLength > 8192)
                            {
                                FATAL("RTP data length too big");
                                return false;
                            }
                            //6. Do we have enough data?
                            if (_rtpDataLength + 4 > bufferLength)
                            {
                                _state = RtspState.InterleavedHeader;
                                return true;
                            }
                            _state = RtspState.Playload;
                            goto case RtspState.Playload;
                        }
                        _state = RtspState.NormalHeader;
                        goto case RtspState.NormalHeader;
                    case RtspState.Playload:
                        if (_rtpData)
                        {
                            if (InboundConnectivity != null)
                            {
                                if (!InboundConnectivity.FeedData(
                                    _rtpDataChanel, InputBuffer, _rtpDataLength))
                                {
                                    FATAL("Unable to handle raw RTP packet");
                                    return false;
                                }
                            }
                            else
                            {
                                InputBuffer.Ignore(_rtpDataLength);
                            }
                            _state = RtspState.Header;
                        }
                        else
                        {
                            if (!HandleRTSPMessage())
                            {
                                FATAL("Unable to handle content");
                                return false;
                            }
                        }
                        break;
                  
                }
            }
            return false;
        }
예제 #6
0
 public RtspProtocol()
 {
     _state   = RtspState.Header;
     _rtpData = false;
 }
예제 #7
0
        private bool ParseNormalHeaders()
        {
            _inboundHeaders.SetValue();
            _inboundContent = "";
            if (InputBuffer.AvaliableByteCounts < 4)
            {
                return(true);
            }
            //2. Detect the headers boundaries
            var headersSize = 0;
            var markerFound = false;
            var pos         = InputBuffer.Position;

            while (InputBuffer.AvaliableByteCounts >= 4)
            {
                if (InputBuffer.Position - pos >= RTSP_MAX_HEADERS_SIZE)
                {
                    FATAL("Headers section too long");
                    return(false);
                }
                if (InputBuffer.ReadByte() != 0x0d || InputBuffer.ReadByte() != 0x0a || InputBuffer.ReadByte() != 0x0d || InputBuffer.ReadByte() != 0x0a)
                {
                    continue;
                }

                markerFound = true;
                headersSize = (int)(InputBuffer.Position - pos - 4);
                break;
            }

            //3. Are the boundaries correct?
            //Do we have enough data to parse the headers?
            if (headersSize == 0)
            {
                return(!markerFound);
            }
            InputBuffer.Position = pos;
            var rawHeaders = Encoding.ASCII.GetString(InputBuffer.Reader.ReadBytes(headersSize));

            System.Diagnostics.Debug.WriteLine(rawHeaders);
            var lines = rawHeaders.Split(new [] { "\r\n" }, StringSplitOptions.None);

            if (lines.Length == 0)
            {
                FATAL("Incorrect RTSP request");
                return(false);
            }

            //4. Get the fisrt line and parse it. This is either a status code
            //for a previous request made by us, or the request that we just received
            if (!ParseFirstLine(lines[0]))
            {
                FATAL("Unable to parse the first line");
                return(false);
            }
            _inboundHeaders[RTSP_HEADERS] = Variant.Get();
            foreach (var line in lines.Skip(1))
            {
                string splitter = ": ";
                if (line.StartsWith(splitter) || line.EndsWith(splitter))
                {
                    splitter = ":";
                    if (line.StartsWith(splitter) || line.EndsWith(splitter))
                    {
                        WARN("Invalid header line: {0}", (line));
                        continue;
                    }
                }

                _inboundHeaders[RTSP_HEADERS][line.Substring(0, line.IndexOf(splitter, StringComparison.Ordinal))] =
                    line.Substring(line.IndexOf(splitter, StringComparison.Ordinal) + splitter.Length);
            }
            //6. default a transfer type to Content-Length: 0 if necessary
            if (_inboundHeaders[RTSP_HEADERS, RTSP_HEADERS_CONTENT_LENGTH] == null)
            {
                _inboundHeaders[RTSP_HEADERS, RTSP_HEADERS_CONTENT_LENGTH] = "0";
            }

            //7. read the transfer type and set this request or response flags
            string contentLengthString = _inboundHeaders[RTSP_HEADERS, RTSP_HEADERS_CONTENT_LENGTH];

            contentLengthString = contentLengthString.Replace(" ", "");
            try
            {
                _contentLength = Convert.ToUInt32(contentLengthString);
            }
            catch
            {
                FATAL("Invalid RTSP headers:\n{0}", (_inboundHeaders.ToString()));
                return(false);
            }

            //7. Advance the state and ignore the headers part from the buffer
            _state   = RtspState.Playload;
            _rtpData = false;
            InputBuffer.Ignore(4);
            return(true);
        }
예제 #8
0
        public override bool SignalInputData(int recAmount)
        {
            while (InputBuffer.AvaliableByteCounts > 0)
            {
                switch (_state)
                {
                case RtspState.InterleavedHeader:
                    //6. Do we have enough data?
                    if (InputBuffer.AvaliableByteCounts < _rtpDataLength)
                    {
                        return(true);
                    }
                    _state = RtspState.Playload;
                    goto case RtspState.Playload;

                case RtspState.NormalHeader:
                    ParseNormalHeaders();
                    if (_state != RtspState.Playload)
                    {
                        return(true);
                    }
                    goto case RtspState.Playload;

                case RtspState.Header:

                    if (InputBuffer.Reader.PeekChar() == '$')
                    {
                        //1. Marl this as a interleaved content
                        _rtpData = true;
                        //2. Do we have at least 4 bytes ($ sign, channel byte an 2-bytes length)?
                        var bufferLength = InputBuffer.AvaliableByteCounts;
                        if (bufferLength < 4)
                        {
                            return(true);
                        }
                        //3. Get the buffer
                        InputBuffer.Reader.ReadByte();
                        //4. Get the channel id
                        _rtpDataChanel = InputBuffer.Reader.ReadByte();
                        //5. Get the packet length
                        _rtpDataLength = InputBuffer.Reader.ReadUInt16();

                        if (_rtpDataLength > 8192)
                        {
                            FATAL("RTP data length too big");
                            return(false);
                        }
                        //6. Do we have enough data?
                        if (_rtpDataLength + 4 > bufferLength)
                        {
                            _state = RtspState.InterleavedHeader;
                            return(true);
                        }
                        _state = RtspState.Playload;
                        goto case RtspState.Playload;
                    }
                    _state = RtspState.NormalHeader;
                    goto case RtspState.NormalHeader;

                case RtspState.Playload:
                    if (_rtpData)
                    {
                        if (InboundConnectivity != null)
                        {
                            if (!InboundConnectivity.FeedData(
                                    _rtpDataChanel, InputBuffer, _rtpDataLength))
                            {
                                FATAL("Unable to handle raw RTP packet");
                                return(false);
                            }
                        }
                        else
                        {
                            InputBuffer.Ignore(_rtpDataLength);
                        }
                        _state = RtspState.Header;
                    }
                    else
                    {
                        if (!HandleRTSPMessage())
                        {
                            FATAL("Unable to handle content");
                            return(false);
                        }
                    }
                    break;
                }
            }
            return(false);
        }