public override RtspResponse SetUp(RtspRequest request) { var builder = RtspResponse.CreateBuilder().Status(RtspResponse.Status.Ok); var transport = request.Transport; if (transport == null) { return(builder.Status(RtspResponse.Status.BadRequest).Build()); } else if (transport.Type != TransportType.RtspInterleaved) { return(builder.Status(RtspResponse.Status.UnsupportedTransport).Build()); } lock (this) { PortPair channels = new PortPair(_currentChannel, _currentChannel + 1); _currentChannel += 2; var session = new InterleavedTestSession(request.Context, _spy, channels, PAYLOAD_TYPE); _sessionManager.RegisterSession(session); transport = TransportHeader.CreateBuilder() .Type(TransportType.RtspInterleaved) .InterleavedChannels(channels) .Build(); return(builder.AddHeader(RtspHeaders.Names.TRANSPORT, transport.ToString()) .AddHeader(RtspHeaders.Names.SESSION, session.Id) .Build()); } }
/// <summary> /// Deep copy constructor. /// </summary> /// <exception cref="System.ArgumentNullException">the smbPacket is null.</exception> protected SmbPacket(SmbPacket smbPacket) : base() { if (smbPacket == null) { throw new ArgumentNullException("smbPacket", "the copy constructor of smbpacket can not accept null smbPacket."); } lock (smbPacket) { this.isSignatureCorrect = smbPacket.isSignatureCorrect; this.transportHeader = new TransportHeader(); this.transportHeader.Zero = smbPacket.transportHeader.Zero; this.transportHeader.StreamProtocolLength = new byte[3]; this.transportHeader.StreamProtocolLength = smbPacket.transportHeader.StreamProtocolLength; this.SmbHeader = new SmbHeader(); this.smbHeader.Protocol = smbPacket.smbHeader.Protocol; this.smbHeader.Command = smbPacket.smbHeader.Command; this.smbHeader.Status = smbPacket.smbHeader.Status; this.smbHeader.Flags = smbPacket.smbHeader.Flags; this.smbHeader.Flags2 = smbPacket.smbHeader.Flags2; this.smbHeader.PidHigh = smbPacket.smbHeader.PidHigh; this.smbHeader.SecurityFeatures = smbPacket.smbHeader.SecurityFeatures; this.smbHeader.Reserved = smbPacket.smbHeader.Reserved; this.smbHeader.Tid = smbPacket.smbHeader.Tid; this.smbHeader.PidLow = smbPacket.smbHeader.PidLow; this.smbHeader.Uid = smbPacket.smbHeader.Uid; this.smbHeader.Mid = smbPacket.smbHeader.Mid; this.SmbParametersBlock = new SmbParameters(); this.smbParametersBlock.WordCount = smbPacket.smbParametersBlock.WordCount; if (smbPacket.smbParametersBlock.Words != null) { this.smbParametersBlock.Words = new ushort[smbPacket.smbParametersBlock.Words.Length]; Array.Copy(smbPacket.smbParametersBlock.Words, this.smbParametersBlock.Words, smbPacket.smbParametersBlock.Words.Length); } else { this.smbParametersBlock.Words = new ushort[0]; } this.SmbDataBlock = new SmbData(); this.smbDataBlock.ByteCount = smbPacket.smbDataBlock.ByteCount; if (smbPacket.smbDataBlock.Bytes != null) { this.smbDataBlock.Bytes = new byte[smbPacket.smbDataBlock.Bytes.Length]; Array.Copy(smbPacket.smbDataBlock.Bytes, this.smbDataBlock.Bytes, smbPacket.smbDataBlock.Bytes.Length); } else { this.smbDataBlock.Bytes = new byte[0]; } } }
public void TestParseUnicastTransport() { var transport = TransportHeader.Parse("RTP/AVP;unicast;client_port=8000-8001"); Assert.Equal(TransportType.UdpUnicast, transport.Type); Assert.Equal(8000, transport.ClientPorts.RtpPort); Assert.Equal(8001, transport.ClientPorts.RtcpPort); }
public void TestParseVxSpoofedTransport() { var transport = TransportHeader.Parse("RTP/AVP/TCP;unicast;interleaved=0-1"); Assert.Equal(TransportType.RtspInterleaved, transport.Type); Assert.Equal(0, transport.InterleavedChannels.RtpPort); Assert.Equal(1, transport.InterleavedChannels.RtcpPort); }
public override RtspResponse SetUp(RtspRequest request) { var builder = RtspResponse.CreateBuilder(); var queryParams = HttpUtility.ParseQueryString(request.URI.Query); var sourceId = queryParams["sourceId"]; if (sourceId == null || !_sourceMgr.ContainsSource(sourceId)) { return(builder.Status(RtspResponse.Status.NotFound).Build()); } var transport = request.Transport; if (transport == null) { return(builder.Status(RtspResponse.Status.BadRequest).Build()); } if (transport.Type != Pelco.Media.RTSP.TransportType.UdpUnicast) { return(builder.Status(RtspResponse.Status.UnsupportedTransport).Build()); } if (transport.ClientPorts == null || !transport.ClientPorts.IsSet) { return(builder.Status(RtspResponse.Status.BadRequest).Build()); } var rtpPort = transport.ClientPorts.RtpPort; var address = transport.Destination != null?Dns.GetHostAddresses(transport.Destination)[0] : request.RemoteEndpoint.Address; var rtspSession = new RtspSession(_sourceMgr.GetSource(sourceId).GetPipelineSource(), PAYLOAD_TYPE, new IPEndPoint(address, rtpPort)); if (!_sessionMgr.RegisterSession(rtspSession)) { return(builder.Status(RtspResponse.Status.InternalServerError) .AddHeader(RtspHeaders.Names.CONTENT_TYPE, "text/plain") .Body("Unable to register Rtsp session with system") .Build()); } var session = Session.FromParts(rtspSession.Id, RtspSession.RTSP_SESSION_TIMEOUT); transport = TransportHeader.CreateBuilder() .Type(Pelco.Media.RTSP.TransportType.UdpUnicast) .ClientPorts(transport.ClientPorts) .ServerPorts(rtpPort + 3, rtpPort + 4) // Just create dummy ports. .Build(); return(builder.Status(RtspResponse.Status.Ok) .AddHeader(RtspHeaders.Names.TRANSPORT, transport.ToString()) .AddHeader(RtspHeaders.Names.SESSION, session.ToString()) .Build()); }
public void TestInterleaved() { var transport = TransportHeader.CreateBuilder() .Type(TransportType.RtspInterleaved) .InterleavedChannels(0, 1) .Build(); var response = _fixture.Client.Request().Transport(transport).SetUp(); Assert.True(response.ResponseStatus.Is(RtspResponse.Status.Ok)); transport = response.Transport; Assert.NotNull(transport); Assert.Equal(TransportType.RtspInterleaved, transport.Type); Assert.Equal(0, transport.InterleavedChannels.RtpPort); Assert.Equal(1, transport.InterleavedChannels.RtcpPort); var session = response.Session; Assert.NotNull(session); Assert.NotEmpty(session.ID); Assert.Equal(60u, session.Timeout); var sink = new Sink(); var pipeline = MediaPipeline.CreateBuilder() .Source(_fixture.Client.GetChannelSource(transport.InterleavedChannels.RtpPort)) .Transform(new DefaultRtpDepacketizer()) .Sink(sink) .Build(); pipeline.Start(); _fixture.Client.Request().Session(session.ID).PlayAsync((res) => { Assert.True(res.ResponseStatus.Is(RtspResponse.Status.Ok)); }); sink.WaitForCompletion(TimeSpan.FromSeconds(20)); _fixture.Client.Request().Session(session.ID).TeardownAsync((res) => { }); pipeline.Stop(); var sessData = _spy.GetData(session.ID); Assert.Equal(sessData.Buffers.Count, sink.ReceivedBuffers.Count); Assert.True(Enumerable.SequenceEqual(sessData.Buffers, sink.ReceivedBuffers)); }
private bool GetRedirectUri(RtspClient client, MediaTrack track, out Uri uri) { var transport = TransportHeader.CreateBuilder() .Type(TransportType.RtspInterleaved) .InterleavedChannels(0, 1) .Build(); var method = RtspRequest.RtspMethod.SETUP; var res = CheckResponse(client.Send(RtspRequest.CreateBuilder() .Method(method) .Uri(track.ControlUri) .AddHeader(RtspHeaders.Names.TRANSPORT, transport.ToString()) .Build()), method); if (!res.Headers.ContainsKey(RtspHeaders.Names.SESSION)) { uri = null; return(false); } var rtspSession = Session.Parse(res.Headers[RtspHeaders.Names.SESSION]); method = RtspRequest.RtspMethod.PLAY; res = CheckResponse(client.Send(RtspRequest.CreateBuilder() .Method(method) .Uri(track.ControlUri) .AddHeader(RtspHeaders.Names.SESSION, rtspSession.ID) .Build()), method); var status = res.ResponseStatus; if (status.Is(RtspResponse.Status.MovedPermanently) || status.Is(RtspResponse.Status.MovedTemporarily)) { // We received a redirect lets get the uri and return it. if (res.Headers.ContainsKey(RtspHeaders.Names.LOCATION)) { var value = res.Headers[RtspHeaders.Names.LOCATION]; return(Uri.TryCreate(value, UriKind.RelativeOrAbsolute, out uri)); } } uri = null; return(false); }
private void ParseHeader(ref byte[] data) { TransportHeader header = new TransportHeader { ProtocolVersion = data[0], SecurityKeyId = data[1], Prefix = (byte)((data[2] & (byte)HeaderFlags.PRF) >> 6), Route = (data[2] & (byte)HeaderFlags.RTE) == (byte)HeaderFlags.RTE, Compressed = (data[2] & (byte)HeaderFlags.CMP) == (byte)HeaderFlags.CMP, Priority = (Priority)(data[2] & (byte)HeaderFlags.PR), HeaderLength = data[3], HeaderEncoding = data[4], FrameDataLength = BitConverter.ToUInt16(data, 5), // bytes 5 to 6 PID = BitConverter.ToUInt16(data, 7), // bytes 7 to 8 Type = (PacketType)data[9] }; if (header.Route) { header.RoutingInfo = new RoutingInfo { PeerAddress = BitConverter.ToUInt16(data, 10), // bytes 10 to 11 RecipientAddress = BitConverter.ToUInt16(data, 12), // bytes 12 to 13 TTL = data[14] }; header.CRC = data[15]; } else { header.CRC = data[10]; } Packet.Header = header; }
public IRtspInvoker Transport(TransportHeader transport) { _builder.AddHeader(RtspHeaders.Names.TRANSPORT, transport.ToString()); return(this); }
public void BuildFromProcessingResult(ProcessingResult result) { ResponsePacket response = new ResponsePacket { ResponseTo = result.PacketId, ResultCode = result.Result }; foreach (ProcessingResult.RecordResult recResult in result.RecResults) { // subrecord data SubrecordResponse subrecord = new SubrecordResponse { ConfirmedRecord = recResult.Record.RecordNumber, Result = (byte)recResult.Result }; // record data ServiceDataSubrecord recordData = new ServiceDataSubrecord { Data = subrecord, Length = (ushort)subrecord.GetBytes().Length, Type = SubrecordType.EGTS_SR_RECORD_RESPONSE }; // Record ServiceDataRecord record = new ServiceDataRecord { EventFieldExists = false, ObjectFieldExists = recResult.Record.ObjectFieldExists, ObjectID = recResult.Record.ObjectID, ProcessingPriority = recResult.Record.ProcessingPriority, RecipientService = recResult.Record.SourceService, RecipientServiceOnDevice = recResult.Record.SourceServiceOnDevice, RecordNumber = recResult.Record.RecordNumber, SourceService = recResult.Record.RecipientService, SourceServiceOnDevice = recResult.Record.RecipientServiceOnDevice, TimeFieldExists = false, RecordLength = (ushort)recordData.GetBytes().Length, // only one subrecord ib RecordData }; record.RecordData.Add(recordData); response.ServiceDataRecords.Add(record); } TransportHeader header = new TransportHeader { Compressed = false, HeaderEncoding = 0, PID = result.PacketId, Prefix = 0, Priority = Priority.Highest, ProtocolVersion = 1, Route = false, SecurityKeyId = 0, Type = PacketType.EGTS_PT_RESPONSE, FrameDataLength = (ushort)response.GetBytes().Length, HeaderLength = 11 // TODO: calculate HeaderLength }; header.CRC = Validator.GetCrc8(header.GetBytes(), (ushort)(header.HeaderLength - 1)); Packet = new EgtsPacket { Header = header, ServiceFrameData = response, CRC = Validator.GetCrc16(response.GetBytes(), 0, header.FrameDataLength) }; }
private RtpSession Setup(MediaTrack track, RtpChannelSink sink, bool interleaved) { lock (SourceLock) { IRtpSource rtpSource = null; try { TransportHeader transport = null; if (interleaved) { transport = TransportHeader.CreateBuilder() .Type(Media.RTSP.TransportType.RtspInterleaved) .InterleavedChannels(0, 1) .Build(); } else { // TODO(frank.lamar): Add multicast support. rtpSource = new RtpUdpSource(track.Address); transport = TransportHeader.CreateBuilder() .Type(Media.RTSP.TransportType.UdpUnicast) .ClientPorts(rtpSource.RtpPort, rtpSource.RtcpPort) .Build(); } var response = CheckResponse(_client.Send(RtspRequest.CreateBuilder() .Method(RtspRequest.RtspMethod.SETUP) .Uri(track.ControlUri) .AddHeader(RtspHeaders.Names.TRANSPORT, transport.ToString()) .Build()), RtspRequest.RtspMethod.SETUP); if (!response.Headers.ContainsKey(RtspHeaders.Names.SESSION)) { throw new RtspClientException("Rtsp SETUP response does not contain a session id"); } var rtspSession = Session.Parse(response.Headers[RtspHeaders.Names.SESSION]); transport = response.Transport; if (interleaved) { if (transport.Type != Media.RTSP.TransportType.RtspInterleaved) { throw new RtspClientException($"Server does not support interleaved. Response Transport='{transport}'"); } var channels = transport.InterleavedChannels != null ? transport.InterleavedChannels : new PortPair(0, 1); sink.Channel = channels.RtpPort; // Ensure that the sink contains the correct Interleaved channel id. rtpSource = new RtpInterleavedSource(_client.GetChannelSource(channels.RtpPort), _client.GetChannelSource(channels.RtcpPort)); } var pipeline = MediaPipeline.CreateBuilder() .Source(rtpSource.RtpSource) .TransformIf(transport.SSRC != null, new SsrcFilter(transport.SSRC)) .Sink(sink) .Build(); var session = new RtpSession(track, rtspSession, rtpSource); session.Pipelines.Add(pipeline); session.Start(); CheckAndStartRefreshTimer(session.Session.Timeout); return(session); } catch (Exception e) { if (rtpSource != null) { rtpSource?.Stop(); } if (e is RtspClientException) { throw e; } throw new RtspClientException($"Unable to set up media track {track.ID}", e); } } }