コード例 #1
0
        private void RTSP_ProcessAuthorization(RtspRequest message, RtspListener listener)
        {
            bool authorized = false;

            if (message.Headers.ContainsKey("Authorization") == true)
            {
                // The Header contained Authorization
                // Check the message has the correct Authorization
                // If it does not have the correct Authorization then close the RTSP connection
                authorized = _auth.IsValid(message);

                if (authorized == false)
                {
                    // Send a 401 Authentication Failed reply, then close the RTSP Socket
                    Rtsp.Messages.RtspResponse authorization_response = message.CreateResponse(_logger);
                    authorization_response.AddHeader("WWW-Authenticate: " + _auth.GetHeader());
                    authorization_response.ReturnCode = 401;
                    listener.SendMessage(authorization_response);

                    CloseConnection("unauthorized");
                    listener.Dispose();
                    return;
                }
            }
            if ((message.Headers.ContainsKey("Authorization") == false))
            {
                // Send a 401 Authentication Failed with extra info in WWW-Authenticate
                // to tell the Client if we are using Basic or Digest Authentication
                Rtsp.Messages.RtspResponse authorization_response = message.CreateResponse(_logger);
                authorization_response.AddHeader("WWW-Authenticate: " + _auth.GetHeader()); // 'Basic' or 'Digest'
                authorization_response.ReturnCode = 401;
                listener.SendMessage(authorization_response);
                return;
            }
        }
コード例 #2
0
ファイル: RTSPClient.cs プロジェクト: Metrilus/MetriCam2
        public void Connect()
        {
            _client.Start();

            // Send first setup messge: OPTIONS
            RtspRequest optionsMessage = new RtspRequestOptions();

            optionsMessage.RtspUri = new Uri(_url);
            _client.SendMessage(optionsMessage);
        }
コード例 #3
0
        private void RTSP_ProcessPlayRequest(RtspRequestPlay message, RtspListener listener)
        {
            OnPlay?.Invoke(Id);

            Play = true;  // ACTUALLY YOU COULD PAUSE JUST THE VIDEO (or JUST THE AUDIO)
            _logger.Info($"Connection {Id} play started");

            string range    = "npt=0-";                                                  // Playing the 'video' from 0 seconds until the end
            string rtp_info = "url=" + message.RtspUri + ";seq=" + _videoSequenceNumber; // TODO Add rtptime  +";rtptime="+session.rtp_initial_timestamp;

            // Send the reply
            Rtsp.Messages.RtspResponse play_response = message.CreateResponse(_logger);
            play_response.AddHeader("Range: " + range);
            play_response.AddHeader("RTP-Info: " + rtp_info);
            listener.SendMessage(play_response);



            //TODO: find a p[lace for this check]
            // Session ID was not found in the list of Sessions. Send a 454 error

            /*   Rtsp.Messages.RtspResponse play_failed_response = (e.Message as Rtsp.Messages.RtspRequestPlay).CreateResponse();
             * play_failed_response.ReturnCode = 454; // Session Not Found
             * listener.SendMessage(play_failed_response);*/
        }
コード例 #4
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);
                    }
                }
            }
        }
コード例 #5
0
        public void SendMessage()
        {
            MemoryStream stream = new MemoryStream();

            _mockTransport.GetStream().Returns(stream);

            // Setup test object.
            RtspListener testedListener = new RtspListener(_mockTransport);

            testedListener.MessageReceived += new EventHandler <RtspChunkEventArgs>(MessageReceived);
            testedListener.DataReceived    += new EventHandler <RtspChunkEventArgs>(DataReceived);

            RtspMessage message = new RtspRequestOptions();

            // Run
            var isSuccess = testedListener.SendMessage(message);

            Assert.That(isSuccess, Is.True);
            string result = Encoding.UTF8.GetString(stream.GetBuffer());

            result = result.TrimEnd('\0');
            Assert.That(result, Does.StartWith("OPTIONS * RTSP/1.0\r\n"));
            // packet without payload must end with double return
            Assert.That(result, Does.EndWith("\r\n\r\n"));
        }
コード例 #6
0
        private void RTSP_ProcessTeardownRequest(RtspRequestTeardown message, RtspListener listener)
        {
            if (message.Session == _videoSessionId) // SHOULD HAVE AN AUDIO TEARDOWN AS WELL
            {
                // If this is UDP, close the transport
                // For TCP there is no transport to close (as RTP packets were interleaved into the RTSP connection)

                Rtsp.Messages.RtspResponse teardown_response = message.CreateResponse(_logger);
                listener.SendMessage(teardown_response);

                CloseConnection("teardown");
            }
        }
コード例 #7
0
        private void RTSP_ProcessDescribeRequest(RtspRequestDescribe message, RtspListener listener)
        {
            String requested_url = message.RtspUri.ToString();

            Task <byte[]> sdpDataTask = _videoSource != null?
                                        OnProvideSdpData?.Invoke(Id, _videoSource)
                                            : Task.FromResult <byte[]>(null);

            byte[] sdpData = sdpDataTask.Result;

            if (sdpData != null)
            {
                Rtsp.Messages.RtspResponse describe_response = message.CreateResponse(_logger);

                describe_response.AddHeader("Content-Base: " + requested_url);
                describe_response.AddHeader("Content-Type: application/sdp");
                describe_response.Data = sdpData;
                describe_response.AdjustContentLength();

                // Create the reponse to DESCRIBE
                // This must include the Session Description Protocol (SDP)

                describe_response.Headers.TryGetValue(RtspHeaderNames.ContentBase, out contentBase);

                using (StreamReader sdp_stream = new StreamReader(new MemoryStream(describe_response.Data)))
                {
                    _sdpFile = Rtsp.Sdp.SdpFile.Read(sdp_stream);
                }

                listener.SendMessage(describe_response);
            }
            else
            {
                Rtsp.Messages.RtspResponse describe_response = (message as Rtsp.Messages.RtspRequestDescribe).CreateResponse(_logger);
                //Method Not Valid In This State"
                describe_response.ReturnCode = 455;
                listener.SendMessage(describe_response);
            }
        }
コード例 #8
0
        private void RTSP_ProcessOptionsRequest(RtspRequestOptions message, RtspListener listener)
        {
            String requested_url = message.RtspUri.ToString();

            _logger.Info($"Connection {listener.ConnectionId} requested for url: {requested_url}");

            _videoSource = _requestUrlVideoSourceResolverStrategy.ResolveVideoSource(requested_url);
            OnConnectionAdded?.Invoke(Id, _videoSource); //treat connection useful when VideoSource determined

            // Create the reponse to OPTIONS
            Rtsp.Messages.RtspResponse options_response = message.CreateResponse(_logger);
            // Rtsp.Messages.RtspResponse options_response = OnRtspMessageReceived?.Invoke(message as Rtsp.Messages.RtspRequest,targetConnection);
            listener.SendMessage(options_response);
        }
コード例 #9
0
        private void RTSP_ProcessPauseRequest(RtspRequestPause message, RtspListener listener)
        {
            if (message.Session == _videoSessionId /* OR AUDIO SESSION ID */)
            {
                OnStop?.Invoke(Id);

                // found the session
                Play = false; // COULD HAVE PLAY/PAUSE FOR VIDEO AND AUDIO
            }


            // ToDo - only send back the OK response if the Session in the RTSP message was found
            Rtsp.Messages.RtspResponse pause_response = message.CreateResponse(_logger);
            listener.SendMessage(pause_response);
        }
コード例 #10
0
 private void RTSP_ProcessGetParameterRequest(RtspRequestGetParameter message, RtspListener listener)
 {
     // Create the reponse to GET_PARAMETER
     Rtsp.Messages.RtspResponse getparameter_response = message.CreateResponse(_logger);
     listener.SendMessage(getparameter_response);
 }
コード例 #11
0
        private void RTSP_ProcessSetupRequest(RtspRequestSetup message, RtspListener listener)
        {
            //
            var setupMessage = message;

            // Check the RTSP transport
            // If it is UDP or Multicast, create the sockets
            // If it is RTP over RTSP we send data via the RTSP Listener

            // FIXME client may send more than one possible transport.
            // very rare
            RtspTransport transport = setupMessage.GetTransports()[0];


            // Construct the Transport: reply from the Server to the client
            Rtsp.UDPSocket udp_pair;
            RtspTransport  transport_reply   = RTSP_ConstructReplyTransport(transport, out udp_pair);
            bool           mediaTransportSet = false;

            if (transport_reply != null)
            {
                // Update the session with transport information
                String copy_of_session_id = "";

                // ToDo - Check the Track ID to determine if this is a SETUP for the Video Stream
                // or a SETUP for an Audio Stream.
                // In the SDP the H264 video track is TrackID 0

                // Add the transports to the connection

                if (contentBase != null)
                {
                    string controlTrack = setupMessage.RtspUri.AbsoluteUri.Replace(contentBase, string.Empty);
                    var    requestMedia = _sdpFile.Medias.FirstOrDefault(media =>
                                                                         media.Attributs.FirstOrDefault(a => a.Key == "control" &&
                                                                                                        (a.Value == controlTrack || "/" + a.Value == controlTrack)) != null);

                    if (requestMedia != null)
                    {
                        if (requestMedia.MediaType == Media.MediaTypes.video)
                        {
                            _videoClientTransport = transport;
                            _videoTransportReply  = transport_reply;

                            // If we are sending in UDP mode, add the UDP Socket pair and the Client Hostname
                            if (_videoUdpPair != null)
                            {
                                ReleaseUDPSocket(_videoUdpPair);
                            }
                            _videoUdpPair     = udp_pair;
                            mediaTransportSet = true;

                            if (setupMessage.Session == null)
                            {
                                _videoSessionId = _sessionHandle.ToString();
                                _sessionHandle++;
                            }
                            else
                            {
                                _videoSessionId = setupMessage.Session;
                            }



                            // Copy the Session ID
                            copy_of_session_id = _videoSessionId;
                        }

                        if (requestMedia.MediaType == Media.MediaTypes.audio)
                        {
                            _audioClientTransport = transport;
                            _audioTransportReply  = transport_reply;

                            // If we are sending in UDP mode, add the UDP Socket pair and the Client Hostname
                            if (_audioUdpPair != null)
                            {
                                ReleaseUDPSocket(_audioUdpPair);
                            }
                            _audioUdpPair     = udp_pair;
                            mediaTransportSet = true;


                            if (setupMessage.Session == null)
                            {
                                _audioSessionId = _sessionHandle.ToString();
                                _sessionHandle++;
                            }
                            else
                            {
                                _audioSessionId = setupMessage.Session;
                            }

                            // Copy the Session ID
                            copy_of_session_id = _audioSessionId;
                        }
                    }
                }

                if (false == mediaTransportSet)
                {
                    Rtsp.Messages.RtspResponse setup_response = setupMessage.CreateResponse(_logger);
                    // unsuported mediatime
                    setup_response.ReturnCode = 415;
                    listener.SendMessage(setup_response);
                }
                else
                {
                    Rtsp.Messages.RtspResponse setup_response = setupMessage.CreateResponse(_logger);
                    setup_response.Headers[Rtsp.Messages.RtspHeaderNames.Transport] = transport_reply.ToString();
                    setup_response.Session = copy_of_session_id;
                    setup_response.Timeout = timeout_in_seconds;
                    listener.SendMessage(setup_response);
                }
            }
            else
            {
                Rtsp.Messages.RtspResponse setup_response = setupMessage.CreateResponse(_logger);
                // unsuported transport
                setup_response.ReturnCode = 461;
                listener.SendMessage(setup_response);
            }

            if (false == mediaTransportSet)
            {
                if (udp_pair != null)
                {
                    ReleaseUDPSocket(udp_pair);
                    udp_pair = null;
                }
            }
        }
コード例 #12
0
        public void SendMessage()
        {
            MemoryStream stream = new MemoryStream();
            _mockTransport.GetStream().Returns(stream);

            // Setup test object.
            RtspListener testedListener = new RtspListener(_mockTransport);
            testedListener.MessageReceived += new EventHandler<RtspChunkEventArgs>(MessageReceived);
            testedListener.DataReceived += new EventHandler<RtspChunkEventArgs>(DataReceived);

            RtspMessage message = new RtspRequestOptions();

            // Run
            var isSuccess = testedListener.SendMessage(message);

            Assert.That(isSuccess, Is.True);
            string result = Encoding.UTF8.GetString(stream.GetBuffer());
            result = result.TrimEnd('\0');
            Assert.That(result, Does.StartWith("OPTIONS * RTSP/1.0\r\n"));
            // packet without payload must end with double return
            Assert.That(result, Does.EndWith("\r\n\r\n"));
        }