Exemplo n.º 1
0
        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];
                }
            }
        }
Exemplo n.º 3
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);
        }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 5
0
        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);
        }
Exemplo n.º 8
0
        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;
        }
Exemplo n.º 9
0
            public IRtspInvoker Transport(TransportHeader transport)
            {
                _builder.AddHeader(RtspHeaders.Names.TRANSPORT, transport.ToString());

                return(this);
            }
Exemplo n.º 10
0
        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)
            };
        }
Exemplo n.º 11
0
        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);
                }
            }
        }