internal RtspResponse HandleSetup(RtspRequestSetup request) { Contract.Requires(request != null); Contract.Ensures(Contract.Result <RtspResponse>() != null); var response = request.CreateResponse(); if (string.IsNullOrEmpty(response.Session)) { // TODO Allocate a real session ID response.Session = sessionGenerator.Next().ToString(); } RtspPushDescription description; if (!PushDescriptions.TryGetValue(request.RtspUri.AbsolutePath, out description)) { response.ReturnCode = 404; return(response); } bool configok = false; foreach (var transport in request.GetTransports()) { if (transport.LowerTransport == RtspTransport.LowerTransportType.UDP && !transport.IsMulticast ) { var forwarder = new UDPForwarder(); description.AddForwarders(response.Session, request.RtspUri.AbsolutePath, forwarder); transport.ServerPort = new PortCouple(forwarder.ListenVideoPort); response.Headers[RtspHeaderNames.Transport] = transport.ToString(); configok = true; } } if (!configok) { response.ReturnCode = 461; } return(response); }
/// <summary> /// Handles a request setup. /// </summary> /// <param name="destination">The destination.</param> /// <param name="requestSetup">The request setup.</param> /// <returns>The rewritten message</returns> /// <remarks> /// The destination can be modified. /// </remarks> private RtspMessage HandleRequestSetup(ref RtspListener destination, RtspRequestSetup requestSetup) { Contract.Requires(requestSetup != null); Contract.Requires(destination != null); Contract.Ensures(Contract.Result<RtspMessage>() != null); Contract.Ensures(Contract.ValueAtReturn(out destination) != null); // look if we already have a multicast streaming playing for this URI. foreach (var session in _activesSession.Values) { if (session.State == RtspSession.SessionState.Playing && session.ListOfForwader.ContainsKey(requestSetup.RtspUri)) { Forwarder existingForwarder = session.ListOfForwader[requestSetup.RtspUri]; if (existingForwarder != null && existingForwarder.ToMulticast) { RtspResponse returnValue = requestSetup.CreateResponse(); returnValue.Headers[RtspHeaderNames.Transport] = new RtspTransport() { IsMulticast = true, Destination = existingForwarder.ForwardHostVideo, Port = new PortCouple(existingForwarder.ForwardPortVideo, existingForwarder.ListenCommandPort), }.ToString(); returnValue.Session = session.Name; destination = requestSetup.SourcePort; return returnValue; } } } string setupKey = requestSetup.SourcePort.RemoteAdress + "SEQ" + requestSetup.CSeq.ToString(CultureInfo.InvariantCulture); RtspTransport selectedTransport = SelectTransport(requestSetup); // We do not handle asked transport so return directly. if (selectedTransport == null) { _logger.Info("No transport asked are supported, sorry"); RtspResponse returnValue = requestSetup.CreateResponse(); // Unsupported transport; returnValue.ReturnCode = 461; destination = requestSetup.SourcePort; return returnValue; } UDPForwarder forwarder = new UDPForwarder(); forwarder.ToMulticast = selectedTransport.IsMulticast; // this part of config is only valid in unicast. if (!selectedTransport.IsMulticast) { forwarder.ForwardPortVideo = selectedTransport.ClientPort.First; forwarder.SourcePortCommand = selectedTransport.ClientPort.Second; // If the client did not set the destination.. get it from TCP source if (!string.IsNullOrEmpty(selectedTransport.Destination)) { forwarder.ForwardHostVideo = selectedTransport.Destination; } else { forwarder.ForwardHostVideo = requestSetup.SourcePort.RemoteAdress.Split(':')[0]; _logger.Debug("Destination get from TCP port {0}", forwarder.ForwardHostVideo); } } // Configured the transport asked. forwarder.ForwardHostCommand = destination.RemoteAdress.Split(':')[0]; RtspTransport firstNewTransport = new RtspTransport() { IsMulticast = false, ClientPort = new PortCouple(forwarder.ListenVideoPort, forwarder.FromForwardCommandPort), }; RtspTransport secondTransport = new RtspTransport() { IsMulticast = false, LowerTransport = RtspTransport.LowerTransportType.TCP, }; requestSetup.Headers[RtspHeaderNames.Transport] = firstNewTransport.ToString() + ", " + secondTransport.ToString(); _setupForwarder.Add(setupKey, forwarder); return requestSetup; }
/// <summary> /// Configures the transport and forwarder. /// </summary> /// <param name="aMessage">A message.</param> /// <param name="forwarder">The preset forwarder.</param> /// <returns>The configured forwarder.</returns> private static Forwarder ConfigureTransportAndForwarder(RtspMessage aMessage, UDPForwarder forwarder) { RtspTransport transport = RtspTransport.Parse(aMessage.Headers[RtspHeaderNames.Transport]); Forwarder resultForwarder; if (transport.LowerTransport == RtspTransport.LowerTransportType.UDP) { if (transport.ServerPort != null) { forwarder.SourcePortVideo = transport.ServerPort.First; forwarder.ForwardPortCommand = transport.ServerPort.Second; } resultForwarder = forwarder; } else { TCPtoUDPForwader TCPForwarder = new TCPtoUDPForwader(); TCPForwarder.ForwardCommand = aMessage.SourcePort; TCPForwarder.SourceInterleavedVideo = transport.Interleaved.First; TCPForwarder.ForwardInterleavedCommand = transport.Interleaved.Second; // we need to transfer already getted values TCPForwarder.ForwardHostVideo = forwarder.ForwardHostVideo; TCPForwarder.ForwardPortVideo = forwarder.ForwardPortVideo; TCPForwarder.SourcePortCommand = forwarder.SourcePortCommand; TCPForwarder.ToMulticast = forwarder.ToMulticast; resultForwarder = TCPForwarder; } if (resultForwarder.ToMulticast) { // Setup port and destination multicast. resultForwarder.ForwardHostVideo = CreateNextMulticastAddress(); resultForwarder.ForwardPortVideo = forwarder.FromForwardVideoPort; RtspTransport newTransport = new RtspTransport() { IsMulticast = true, Destination = resultForwarder.ForwardHostVideo, Port = new PortCouple(resultForwarder.ForwardPortVideo, resultForwarder.ListenCommandPort) }; if ((resultForwarder is UDPForwarder && forwarder.ForwardPortCommand == 0) || (resultForwarder is TCPtoUDPForwader && (resultForwarder as TCPtoUDPForwader).ForwardInterleavedCommand == 0)) { newTransport.Port = null; } aMessage.Headers[RtspHeaderNames.Transport] = newTransport.ToString(); } else { RtspTransport newTransport = new RtspTransport() { IsMulticast = false, Destination = forwarder.ForwardHostVideo, ClientPort = new PortCouple(resultForwarder.ForwardPortVideo, resultForwarder.SourcePortCommand), ServerPort = new PortCouple(resultForwarder.FromForwardVideoPort, resultForwarder.ListenCommandPort) }; if ((resultForwarder is UDPForwarder && forwarder.ForwardPortCommand == 0) || (resultForwarder is TCPtoUDPForwader && (resultForwarder as TCPtoUDPForwader).ForwardInterleavedCommand == 0)) { newTransport.ServerPort = null; } aMessage.Headers[RtspHeaderNames.Transport] = newTransport.ToString(); } return resultForwarder; }
/// <summary> /// Configures the transport and forwarder. /// </summary> /// <param name="aMessage">A message.</param> /// <param name="forwarder">The preset forwarder.</param> /// <returns>The configured forwarder.</returns> private static Forwarder ConfigureTransportAndForwarder(RtspMessage aMessage, UDPForwarder forwarder) { RtspTransport transport = RtspTransport.Parse(aMessage.Headers[RtspHeaderNames.Transport]); Forwarder resultForwarder; if (transport.LowerTransport == RtspTransport.LowerTransportType.UDP) { if (transport.ServerPort != null) { forwarder.SourcePortVideo = transport.ServerPort.First; forwarder.ForwardPortCommand = transport.ServerPort.Second; } resultForwarder = forwarder; } else { TCPtoUDPForwader TCPForwarder = new TCPtoUDPForwader(); TCPForwarder.ForwardCommand = aMessage.SourcePort; TCPForwarder.SourceInterleavedVideo = transport.Interleaved.First; TCPForwarder.ForwardInterleavedCommand = transport.Interleaved.Second; // we need to transfer already getted values TCPForwarder.ForwardHostVideo = forwarder.ForwardHostVideo; TCPForwarder.ForwardPortVideo = forwarder.ForwardPortVideo; TCPForwarder.SourcePortCommand = forwarder.SourcePortCommand; TCPForwarder.ToMulticast = forwarder.ToMulticast; resultForwarder = TCPForwarder; } if (resultForwarder.ToMulticast) { // Setup port and destination multicast. resultForwarder.ForwardHostVideo = CreateNextMulticastAddress(); resultForwarder.ForwardPortVideo = forwarder.FromForwardVideoPort; RtspTransport newTransport = new RtspTransport() { IsMulticast = true, Destination = resultForwarder.ForwardHostVideo, Port = new PortCouple(resultForwarder.ForwardPortVideo, resultForwarder.ListenCommandPort) }; if ((resultForwarder is UDPForwarder && forwarder.ForwardPortCommand == 0) || (resultForwarder is TCPtoUDPForwader && (resultForwarder as TCPtoUDPForwader).ForwardInterleavedCommand == 0)) { newTransport.Port = null; } aMessage.Headers[RtspHeaderNames.Transport] = newTransport.ToString(); } else { RtspTransport newTransport = new RtspTransport() { IsMulticast = false, Destination = forwarder.ForwardHostVideo, ClientPort = new PortCouple(resultForwarder.ForwardPortVideo, resultForwarder.SourcePortCommand), ServerPort = new PortCouple(resultForwarder.FromForwardVideoPort, resultForwarder.ListenCommandPort) }; if ((resultForwarder is UDPForwarder && forwarder.ForwardPortCommand == 0) || (resultForwarder is TCPtoUDPForwader && (resultForwarder as TCPtoUDPForwader).ForwardInterleavedCommand == 0)) { newTransport.ServerPort = null; } aMessage.Headers[RtspHeaderNames.Transport] = newTransport.ToString(); } return(resultForwarder); }
/// <summary> /// Handles a request setup. /// </summary> /// <param name="destination">The destination.</param> /// <param name="requestSetup">The request setup.</param> /// <returns>The rewritten message</returns> /// <remarks> /// The destination can be modified. /// </remarks> private RtspMessage HandleRequestSetup(ref RtspListener destination, RtspRequestSetup requestSetup) { Contract.Requires(requestSetup != null); Contract.Requires(destination != null); Contract.Ensures(Contract.Result <RtspMessage>() != null); Contract.Ensures(Contract.ValueAtReturn(out destination) != null); // look if we already have a multicast streaming playing for this URI. foreach (var session in _activesSession.Values) { if (session.State == RtspSession.SessionState.Playing && session.ListOfForwader.ContainsKey(requestSetup.RtspUri)) { Forwarder existingForwarder = session.ListOfForwader[requestSetup.RtspUri]; if (existingForwarder != null && existingForwarder.ToMulticast) { RtspResponse returnValue = requestSetup.CreateResponse(); returnValue.Headers[RtspHeaderNames.Transport] = new RtspTransport() { IsMulticast = true, Destination = existingForwarder.ForwardHostVideo, Port = new PortCouple(existingForwarder.ForwardPortVideo, existingForwarder.ListenCommandPort), }.ToString(); returnValue.Session = session.Name; destination = requestSetup.SourcePort; return(returnValue); } } } string setupKey = requestSetup.SourcePort.RemoteAdress + "SEQ" + requestSetup.CSeq.ToString(CultureInfo.InvariantCulture); RtspTransport selectedTransport = SelectTransport(requestSetup); // We do not handle asked transport so return directly. if (selectedTransport == null) { _logger.Info("No transport asked are supported, sorry"); RtspResponse returnValue = requestSetup.CreateResponse(); // Unsupported transport; returnValue.ReturnCode = 461; destination = requestSetup.SourcePort; return(returnValue); } UDPForwarder forwarder = new UDPForwarder(); forwarder.ToMulticast = selectedTransport.IsMulticast; // this part of config is only valid in unicast. if (!selectedTransport.IsMulticast) { forwarder.ForwardPortVideo = selectedTransport.ClientPort.First; forwarder.SourcePortCommand = selectedTransport.ClientPort.Second; // If the client did not set the destination.. get it from TCP source if (!string.IsNullOrEmpty(selectedTransport.Destination)) { forwarder.ForwardHostVideo = selectedTransport.Destination; } else { forwarder.ForwardHostVideo = requestSetup.SourcePort.RemoteAdress.Split(':')[0]; _logger.Debug("Destination get from TCP port {0}", forwarder.ForwardHostVideo); } } // Configured the transport asked. forwarder.ForwardHostCommand = destination.RemoteAdress.Split(':')[0]; RtspTransport firstNewTransport = new RtspTransport() { IsMulticast = false, ClientPort = new PortCouple(forwarder.ListenVideoPort, forwarder.FromForwardCommandPort), }; RtspTransport secondTransport = new RtspTransport() { IsMulticast = false, LowerTransport = RtspTransport.LowerTransportType.TCP, }; requestSetup.Headers[RtspHeaderNames.Transport] = firstNewTransport.ToString() + ", " + secondTransport.ToString(); requestSetup.Headers[RtspHeaderNames.Transport] = firstNewTransport.ToString();// +", " + secondTransport.ToString(); _setupForwarder.Add(setupKey, forwarder); return(requestSetup); }