/// <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); }
/// <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); }
/// <summary> /// Updates the state of the session. /// </summary> /// <param name="message">A response message.</param> private void UpdateSessionState(RtspResponse message) { // if no session can be found if (message.OriginalRequest == null || (message.Session == null && message.OriginalRequest.Session == null) || message.OriginalRequest.RtspUri == null) { return; } // voir a mettre dans la message.... string curentSession = message.Session != null ? message.Session : message.OriginalRequest.Session; //Update session state and handle special message string sessionKey = RtspSession.GetSessionName(message.OriginalRequest.RtspUri, curentSession); if (_activesSession.ContainsKey(sessionKey)) { if (message.ReturnCode >= 300 && message.ReturnCode < 400) { _activesSession[sessionKey].State = RtspSession.SessionState.Init; } else if (message.ReturnCode < 300) { switch (message.OriginalRequest.RequestTyped) { case RtspRequest.RequestType.SETUP: if (_activesSession[sessionKey].State == RtspSession.SessionState.Init) { _activesSession[sessionKey].State = RtspSession.SessionState.Ready; } break; case RtspRequest.RequestType.PLAY: if (_activesSession[sessionKey].State == RtspSession.SessionState.Ready) { _activesSession[sessionKey].State = RtspSession.SessionState.Playing; } break; case RtspRequest.RequestType.RECORD: if (_activesSession[sessionKey].State == RtspSession.SessionState.Ready) { _activesSession[sessionKey].State = RtspSession.SessionState.Recording; } break; case RtspRequest.RequestType.PAUSE: if (_activesSession[sessionKey].State == RtspSession.SessionState.Playing || _activesSession[sessionKey].State == RtspSession.SessionState.Recording) { _activesSession[sessionKey].State = RtspSession.SessionState.Ready; } break; case RtspRequest.RequestType.TEARDOWN: _activesSession[sessionKey].State = RtspSession.SessionState.Init; break; } } } else { _logger.Warn("Command {0} for session {1} which was not found", message.OriginalRequest.RequestTyped, sessionKey); } }
/// <summary> /// Handles request message. /// </summary> /// <param name="message">A message, can be rewriten.</param> /// <returns>The destination</returns> private RtspListener HandleRequest(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); RtspRequest request = message as RtspRequest; RtspListener destination; // Do not forward, direct respond because we do not know where to send. if (request.RtspUri == null || request.RtspUri.AbsolutePath.Split(new char[] { '/' }, 3).Length < 3) { destination = HandleRequestWithoutUrl(ref message); } else { try { // get the real destination request.RtspUri = RewriteUri(request.RtspUri); destination = GetRtspListenerForDestination(request.RtspUri); // Handle setup RtspRequestSetup requestSetup = request as RtspRequestSetup; if (requestSetup != null) { message = HandleRequestSetup(ref destination, requestSetup); } //Handle Play Reques RtspRequestPlay requestPlay = request as RtspRequestPlay; if (requestPlay != null) { message = HandleRequestPlay(ref destination, requestPlay); } //Update session state and handle special message if (request.Session != null && request.RtspUri != null) { string sessionKey = RtspSession.GetSessionName(request.RtspUri, request.Session); if (_activesSession.ContainsKey(sessionKey)) { _activesSession[sessionKey].Handle(request); switch (request.RequestTyped) { // start here to start early //case RtspRequest.RequestType.PLAY: // _activesSession[sessionKey].Start(request.SourcePort.RemoteAdress); // break; case RtspRequest.RequestType.TEARDOWN: _activesSession[sessionKey].Stop(request.SourcePort.RemoteAdress); if (!_activesSession[sessionKey].IsNeeded) { _activesSession.Remove(sessionKey); } else { // system still need the server to send data do not send him the message. // reponds to client directly. destination = request.SourcePort; message = request.CreateResponse(); } break; } } else { _logger.Warn("Command {0} for session {1} which was not found", request.RequestTyped, sessionKey); } } } catch (Exception error) { _logger.Error("Error during handle of request", error); destination = request.SourcePort; RtspResponse theDirectResponse = request.CreateResponse(); theDirectResponse.ReturnCode = 500; message = theDirectResponse; } } return(destination); }