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); }
public RtspProtocol() { _state = RtspState.Header; _rtpData = false; }
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; }
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; }
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; }
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); }
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); }