Exemplo n.º 1
0
 public override RtspResponse TearDown(RtspRequest request)
 {
     return RtspResponse.CreateBuilder()
                        .Status(RtspResponse.Status.Ok)
                        .AddHeader(CALLED_METHOD_HEADER, "TEARDOWN")
                        .Build(); ;
 }
Exemplo n.º 2
0
        /// <summary>
        /// Handles the request play.
        /// Do not forward message if already playing
        /// </summary>
        /// <param name="destination">The destination.</param>
        /// <param name="requestPlay">The request play.</param>
        /// <returns>The message to transmit</returns>
        private RtspMessage HandleRequestPlay(ref RtspListener destination, RtspRequestPlay requestPlay)
        {
            Contract.Requires(requestPlay != null);
            Contract.Requires(destination != null);
            Contract.Ensures(Contract.Result <RtspMessage>() != null);
            Contract.Ensures(Contract.ValueAtReturn(out destination) != null);


            string sessionKey = RtspSession.GetSessionName(requestPlay.RtspUri, requestPlay.Session);

            if (_activesSession.ContainsKey(sessionKey))
            {
                RtspSession session = _activesSession[sessionKey];

                // si on est dèjà en play on n'envoie pas la commande a la source.
                if (session.State == RtspSession.SessionState.Playing)
                {
                    session.Start(requestPlay.SourcePort.RemoteAdress);
                    RtspResponse returnValue = requestPlay.CreateResponse();
                    destination = requestPlay.SourcePort;
                    return(returnValue);
                }

                // ajoute un client
                session.Start(requestPlay.SourcePort.RemoteAdress);
            }
            return(requestPlay);
        }
Exemplo n.º 3
0
 /// <summary>
 /// <see cref="IRequestHandler.Describe(RtspRequest)"/>
 /// </summary>
 /// <param name="request"></param>
 /// <returns></returns>
 public override RtspResponse Describe(RtspRequest request)
 {
     return(RtspResponse.CreateBuilder()
            .Status(RtspResponse.Status.Ok)
            .Body(CreateSDP(request))
            .Build());
 }
        public static ValidationStatus ValidateDigest(this RtspResponse response)
        {
            var messages = response.Conversation.GetMessages(ContentType.Rtsp);
            var details  = messages.First(item => item.Response == response).Request.GetDetails();

            var pairs = messages.Where(item => item.Request.GetDetails() == details);

            var responseAuth = Authentication.FromAuthHeader(response.AuthHeader);

            if (pairs.Any(item =>
            {
                String authHeader = item.GetRequest <RtspMessage>().AuthHeader;

                if (String.IsNullOrEmpty(authHeader))
                {
                    return(false);
                }

                var requestAuth = Authentication.FromAuthHeader(authHeader);

                return(requestAuth.Nonce == responseAuth.Nonce &&
                       requestAuth.Realm == responseAuth.Realm &&
                       "200" == item.GetResponse <RtspResponse>().StatusCode);
            }))
            {
                return(ValidationStatus.RtspDigest);
            }


            return(ValidationStatus.Failed);
        }
Exemplo n.º 5
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());
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Handles one message.
        /// </summary>
        /// <param name="message">The message.</param>
        private void HandleOneMessage(RtspMessage message)
        {
            Contract.Requires(message != null);

            RtspListener destination = null;

            if (message is RtspRequest)
            {
                destination = HandleRequest(ref message);
                _logger.Debug("Dispatch message from {0} to {1}",
                              message.SourcePort != null ? message.SourcePort.RemoteAdress : "UNKNOWN", destination != null ? destination.RemoteAdress : "UNKNOWN");

                // HandleRequest can change message type.
                if (message is RtspRequest)
                {
                    var context = new OriginContext();
                    context.OriginCSeq                   = message.CSeq;
                    context.OriginSourcePort             = message.SourcePort;
                    (message as RtspRequest).ContextData = context;
                }
            }
            else if (message is RtspResponse)
            {
                RtspResponse response = message as RtspResponse;

                if (response.OriginalRequest != null)
                {
                    var context = response.OriginalRequest.ContextData as OriginContext;
                    if (context != null)
                    {
                        destination   = context.OriginSourcePort;
                        response.CSeq = context.OriginCSeq;
                        _logger.Debug("Dispatch response back to {0}", destination.RemoteAdress);
                    }
                }

                HandleResponse(response);
            }

            if (destination != null)
            {
                bool isGood = destination.SendMessage(message);

                if (!isGood)
                {
                    destination.Stop();
                    _serverListener.Remove(destination.RemoteAdress);

                    // send back a message because we can't forward.
                    if (message is RtspRequest && message.SourcePort != null)
                    {
                        RtspRequest  request           = message as RtspRequest;
                        RtspResponse theDirectResponse = request.CreateResponse();
                        _logger.Warn("Error during forward : {0}. So sending back a direct error response", message.Command);
                        theDirectResponse.ReturnCode = 500;
                        request.SourcePort.SendMessage(theDirectResponse);
                    }
                }
            }
        }
Exemplo n.º 7
0
        private static RtspListener HandleRequestWithoutUrl(ref RtspMessage message)
        {
            Contract.Requires(message != null);
            Contract.Requires(message is RtspRequest);
            Contract.Ensures(Contract.Result <RtspListener>() != null);
            Contract.Ensures(Contract.ValueAtReturn(out message) != null);


            RtspListener destination;

            destination = message.SourcePort;
            RtspRequest  request           = message as RtspRequest;
            RtspResponse theDirectResponse = request.CreateResponse();

            if (request.RequestTyped == RtspRequest.RequestType.OPTIONS)
            {
                // We know what to do...
                theDirectResponse.ReturnCode = 200;
                // But perhaps it is to prevent timeout !!
                // ARG .....
                _logger.Info("I got an OPTION * message, I reply but I do not forward! The end session may timeout.");
                request.LogMessage();
            }
            else
            {
                _logger.Warn("Do not know how to handle : {0}", message.Command);
                theDirectResponse.ReturnCode = 400;
            }
            message = theDirectResponse;
            return(destination);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Handles the response to a setup message.
        /// </summary>
        /// <param name="message">A response message.</param>
        private void HandleResponseToSetup(RtspResponse message)
        {
            RtspRequest original = message.OriginalRequest;
            string      setupKey = original.SourcePort.RemoteAdress + "SEQ" + message.CSeq.ToString(CultureInfo.InvariantCulture);

            if (message.IsOk)
            {
                Forwarder forwarder = ConfigureTransportAndForwarder(message, _setupForwarder[setupKey]);

                RtspSession newSession;
                string      sessionKey = RtspSession.GetSessionName(original.RtspUri, message.Session);
                if (_activesSession.ContainsKey(sessionKey))
                {
                    newSession = _activesSession[sessionKey];
                    _logger.Info("There was an already a session with ths ID {0}", newSession.Name);
                }
                else
                {
                    _logger.Info("Create a new session with the ID {0}", sessionKey);
                    newSession             = new RtspSession();
                    newSession.Name        = message.Session;
                    newSession.Destination = original.RtspUri.Authority;
                    _activesSession.Add(sessionKey, newSession);
                }

                newSession.AddForwarder(original.RtspUri, forwarder);
                newSession.Timeout = message.Timeout;
            }
            // No needed here anymore.
            _setupForwarder.Remove(setupKey);
        }
Exemplo n.º 9
0
        public static RtspResponse CreateResponse(this RtspRequestOptions t, string options)
        {
            RtspResponse response = t.CreateResponse();

            response.Headers[RtspHeaderNames.Public] = options;
            return(response);
        }
Exemplo n.º 10
0
 public override RtspResponse SetUp(RtspRequest request)
 {
     return RtspResponse.CreateBuilder()
                        .Status(RtspResponse.Status.Ok)
                        .AddHeader(CALLED_METHOD_HEADER, "SETUP")
                        .Build();
 }
Exemplo n.º 11
0
        private void ProcessSetupRequest(RtspResponse message)
        {
            // If we get a reply to SETUP (which was our third command), then process then send PLAY

            // Got Reply to SETUP
            Logger.Info("Got reply from Setup. Session is " + message.Session);

            session = message.Session; // Session value used with Play, Pause, Teardown

            // Check the Transport header
            if (message.Headers.ContainsKey(RtspHeaderNames.Transport))
            {
                RtspTransport transport = RtspTransport.Parse(message.Headers[RtspHeaderNames.Transport]);
                // Check if Transport header includes Multicast
                if (transport.IsMulticast)
                {
                    String multicastAddress = transport.Destination;
                    videoDataChannel = transport.Port.First;
                    videoRTCPChannel = transport.Port.Second;

                    // Create the Pair of UDP Sockets in Multicast mode
                    udpPair = new UDPSocketPair(multicastAddress, videoDataChannel, multicastAddress, videoRTCPChannel);
                    udpPair.DataReceived += RtpDataReceived;
                    udpPair.Start();
                }
            }

            RtspRequest play_message = new RtspRequestPlay
            {
                RtspUri = new Uri(url),
                Session = session
            };

            rtspListener.SendMessage(play_message);
        }
Exemplo n.º 12
0
        // RTSP Messages are OPTIONS, DESCRIBE, SETUP, PLAY etc
        private void RtspMessageReceived(object sender, Rtsp.RtspChunkEventArgs e)
        {
            RtspResponse message = e.Message as RtspResponse;

            if (message.OriginalRequest == null)
            {
                return;
            }

            Logger.Info("Received " + message.OriginalRequest.ToString());

            if (message.OriginalRequest is RtspRequestOptions)
            {
                ProcessOptionsRequest(message);
            }
            else if (message.OriginalRequest is RtspRequestDescribe)
            {
                ProcessDescribeRequest(message);
            }
            else if (message.OriginalRequest is RtspRequestSetup)
            {
                ProcessSetupRequest(message);
            }
            else if (message.OriginalRequest is RtspRequestPlay)
            {
                ProcessPlayRequest(message);
            }
        }
Exemplo n.º 13
0
 public RtspResponse Options(RtspRequest request)
 {
     return(RtspResponse.CreateBuilder()
            .Status(RtspResponse.Status.Ok)
            .AddHeader(RtspHeaders.Names.PUBLIC, "OPTIONS, DESCRIBE, GET_PARAMETER, SETUP, PLAY, TEARDOWN")
            .Build());
 }
Exemplo n.º 14
0
 public AsyncResponse(int cseq)
 {
     _cseq     = cseq;
     _response = null;
     _callback = null;
     _event    = new ManualResetEvent(false);
 }
Exemplo n.º 15
0
        public void SetSession()
        {
            RtspResponse testObject = new RtspResponse();

            testObject.Session = "12345";

            Assert.AreEqual("12345", testObject.Headers[RtspHeaderNames.Session]);
        }
Exemplo n.º 16
0
 public override RtspResponse GetParamater(RtspRequest request)
 {
     return RtspResponse.CreateBuilder()
                        .Status(RtspResponse.Status.Ok)
                        .AddHeader(RtspHeaders.Names.SESSION, request.Session)
                        .AddHeader(CALLED_METHOD_HEADER, "GET_PARAMATER")
                        .Build();
 }
Exemplo n.º 17
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());
        }
Exemplo n.º 18
0
        /// <summary>
        /// Gets the assiociate OK response with the request.
        /// </summary>
        /// <returns>
        /// an Rtsp response corresponding to request.
        /// </returns>
        public override RtspResponse CreateResponse()
        {
            RtspResponse response = base.CreateResponse();

            // Add genric suported operations.
            response.Headers.Add(RtspHeaderNames.Public, "OPTIONS,DESCRIBE,ANNOUNCE,SETUP,PLAY,PAUSE,TEARDOWN,GET_PARAMETER,SET_PARAMETER,REDIRECT");

            return(response);
        }
Exemplo n.º 19
0
        public void ReadSessionAndTimeout()
        {
            RtspResponse testObject = new RtspResponse();

            testObject.Headers[RtspHeaderNames.Session] = "12345;timeout=33";

            Assert.AreEqual("12345", testObject.Session);
            Assert.AreEqual(33, testObject.Timeout);
        }
Exemplo n.º 20
0
        public void SetSessionAndTimeout()
        {
            RtspResponse testObject = new RtspResponse();

            testObject.Session = "12345";
            testObject.Timeout = 10;

            Assert.AreEqual("12345;timeout=10", testObject.Headers[RtspHeaderNames.Session]);
        }
Exemplo n.º 21
0
        private RtspResponse CheckResponse(RtspResponse response, RtspRequest.RtspMethod method)
        {
            var status = response.ResponseStatus;

            if (status.Code >= RtspResponse.Status.BadRequest.Code)
            {
                throw new RtspClientException($"{method} received response status {status.Code} {status.ReasonPhrase}");
            }

            return(response);
        }
Exemplo n.º 22
0
        public void GetRtspMessageResponse(string requestLine, int returnCode, string returnMessage)
        {
            RtspMessage oneMessage = RtspMessage.GetRtspMessage(requestLine);

            Assert.IsInstanceOfType(typeof(RtspResponse), oneMessage);

            RtspResponse oneResponse = oneMessage as RtspResponse;

            Assert.AreEqual(returnCode, oneResponse.ReturnCode);
            Assert.AreEqual(returnMessage, oneResponse.ReturnMessage);
        }
Exemplo n.º 23
0
        public void ChangeSession()
        {
            RtspResponse testObject = new RtspResponse();

            testObject.Headers[RtspHeaderNames.Session] = "12345;timeout=33";

            testObject.Session = "456";

            Assert.AreEqual("456", testObject.Session);
            Assert.AreEqual(33, testObject.Timeout);
            Assert.AreEqual("456;timeout=33", testObject.Headers[RtspHeaderNames.Session]);
        }
Exemplo n.º 24
0
 public void HandleResponse(RtspResponse response)
 {
     if (_callback != null)
     {
         _callback.Invoke(response);
     }
     else
     {
         _response = response;
         _event.Set();
     }
 }
Exemplo n.º 25
0
        private void ProcessDescribeResponse(RtspResponse message)
        {
            // Got a reply for DESCRIBE
            // Examine the SDP
            Logger.Info(System.Text.Encoding.UTF8.GetString(message.Data));

            Rtsp.Sdp.SdpFile sdpData;
            using (StreamReader sdpStream = new StreamReader(new MemoryStream(message.Data)))
            {
                sdpData = Rtsp.Sdp.SdpFile.Read(sdpStream);
            }

            // Process each 'Media' Attribute in the SDP (each sub-stream)
            // If the attribute is for Video, then carry out a SETUP and a PLAY
            // Only do this for the first Video attribute in case there is more than one in the SDP
            for (int x = 0; x < sdpData.Medias.Count; x++)
            {
                if (sdpData.Medias[x].MediaType == Media.MediaTypes.video)
                {
                    // We only want the first video sub-stream
                    if (videoPayloadType != -1)
                    {
                        return;
                    }

                    // search the attributes for control, fmtp and rtpmap
                    ParseAttributes(sdpData, x, out string control, out Rtsp.Sdp.AttributFmtp fmtp, out Rtsp.Sdp.AttributRtpMap rtpmap);

                    // Split the fmtp to get the sprop-parameter-sets which hold the SPS and PPS in base64
                    if (fmtp != null)
                    {
                        var param = Rtsp.Sdp.H264Parameters.Parse(fmtp.FormatParameter);
                        OutputNal(param.SpropParameterSets); // output SPS and PPS
                    }

                    // Split the rtpmap to get the Payload Type
                    videoPayloadType = 0;
                    if (rtpmap != null)
                    {
                        videoPayloadType = rtpmap.PayloadNumber;
                    }

                    RtspRequestSetup setupMessage = new RtspRequestSetup();
                    setupMessage.RtspUri = new Uri(rtspUrl + "/" + control);

                    var transport = GetRTSPTransport();
                    setupMessage.AddTransport(transport);

                    PostRequest(setupMessage);
                }
            }
        }
Exemplo n.º 26
0
        /// <summary>
        /// <see cref="IRequestHandler.Play(RtspRequest)"/>
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public override RtspResponse Play(RtspRequest request)
        {
            var builder = RtspResponse.CreateBuilder().Status(RtspResponse.Status.Ok);

            var sessionId = request.Session;

            if (string.IsNullOrEmpty(sessionId) || !_sessionManager.PlaySession(sessionId))
            {
                return(builder.Status(RtspResponse.Status.SessionNotFound).Build());
            }

            return(builder.Build());;
        }
Exemplo n.º 27
0
        private static String GetValidationDetails(RtspRequest request, RtspResponse response)
        {
            //rtsp request validation does not exist
            var sb = new StringBuilder();

            if (null != response && response.Validated)
            {
                sb.AppendLine(String.Format("Second-level validation:"));
                sb.AppendLine(String.Format("\tResponse code of unit:{0}", response.GetStatusString()));
            }

            return(sb.ToString());
        }
Exemplo n.º 28
0
        private async void HandleRequest(RtspRequest request)
        {
            RtspListener listener = null;

            if (_listeners.TryGetValue(request.RemoteEndpoint.ToString(), out listener))
            {
                await Task.Run(() =>
                {
                    try
                    {
                        int receivedCseq = request.CSeq;
                        request.Context  = new RequestContext(listener);
                        var response     = _dispatcher.Dispatch(request);

                        if (response != null)
                        {
                            if (response.HasBody)
                            {
                                response.Headers[RtspHeaders.Names.CONTENT_LENGTH] = response.Body.Length.ToString();
                            }

                            response.Headers[RtspHeaders.Names.CSEQ] = receivedCseq.ToString();
                            listener.SendResponse(response);

                            // Remove listener on teardown.
                            // VLC will terminate the connection and the listener will stop itself properly.
                            // Some clients will send Teardown but keep the connection open, in this type scenario we'll close it.
                            if (request.Method == RtspRequest.RtspMethod.TEARDOWN)
                            {
                                listener.Stop();
                                _listeners.Remove(listener.Endpoint.ToString());
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        LOG.Error(e, $"Caught exception while procesing RTSP request from {request.URI}");

                        listener.SendResponse(RtspResponse.CreateBuilder()
                                              .Status(RtspResponse.Status.InternalServerError)
                                              .Build());
                    }
                });
            }
            else
            {
                LOG.Error($"Unable to process request because no active connection was found for {request.URI}");
            }
        }
Exemplo n.º 29
0
        private void OnRtspChunk(RtspChunk chunk)
        {
            if (chunk is InterleavedData)
            {
                var interleaved = chunk as InterleavedData;
                var buffer      = new ByteBuffer(interleaved.Payload, 0, interleaved.Payload.Length, true);
                buffer.Channel = interleaved.Channel;

                _rtpQueue.Add(buffer);
            }
            else if (chunk is RtspResponse)
            {
                var response = chunk as RtspResponse;

                LOG.Debug($"Received RTSP response from '{_connection.Endpoint}'");
                LOG.Debug(response.ToString());

                int cseq = response.CSeq;
                if (cseq <= 0)
                {
                    LOG.Warn("Receive RTSP response that does not contain cseq header, disgarding.");
                    return;
                }

                AsyncResponse cb = null;
                if (_callbacks.TryRemove(cseq, out cb))
                {
                    cb.HandleResponse(response);
                }
            }
            else
            {
                var msg = chunk as RtspMessage;

                LOG.Debug($"Received RTSP request from '{_connection.Endpoint}'");
                LOG.Debug(msg.ToString());

                // Server sent request.  Since we do not support server side requests lets just
                // respond back with MethodNotAllowed.
                RtspResponse response = new RtspResponse(RtspResponse.Status.MethodNotAllowed);
                response.CSeq = msg.CSeq;

                if (!_connection.WriteMessage(response))
                {
                    LOG.Error("Received RTSP request from server but unable to send response.");
                }
            }
        }
Exemplo n.º 30
0
        public override RtspResponse Play(RtspRequest request)
        {
            var builder = RtspResponse.CreateBuilder().Status(RtspResponse.Status.SessionNotFound);

            if (request.Headers.ContainsKey(RtspHeaders.Names.SESSION))
            {
                var session = request.Headers[RtspHeaders.Names.SESSION];

                if (_sessionMgr.PlaySession(session))
                {
                    builder.Status(RtspResponse.Status.Ok);
                }
            }

            return(builder.Build());
        }