public void ReceiveMessageInterrupt() { string message = string.Empty; message += "PLAY rtsp://audio.example.com/audio RTSP/1."; MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message)); _mockTransport.GetStream().Returns(stream); // Setup test object. RtspListener testedListener = new RtspListener(_mockTransport); testedListener.MessageReceived += new EventHandler <RtspChunkEventArgs>(MessageReceived); testedListener.DataReceived += new EventHandler <RtspChunkEventArgs>(DataReceived); // Run testedListener.Start(); System.Threading.Thread.Sleep(100); // No exception should be generate. stream.Close(); // Check the transport was closed. _mockTransport.Received().Close(); //Check the message recevied Assert.AreEqual(0, _receivedMessage.Count); Assert.AreEqual(0, _receivedData.Count); }
public void Dispose() { if (_listener != null) { LOG.Info($"Disposing RTSP client connected to '{_connection.Endpoint}'"); _listener?.Stop(); _rtpQueue?.Dispose(); foreach (var cb in _callbacks) { cb.Value.Dispose(); } _callbacks.Clear(); _listener = null; foreach (var src in _sources) { src.Value.Stop(); } _sources.Clear(); GC.SuppressFinalize(this); } }
internal void HandleClientSocketException(SocketException se, RtspListener listener) { if (se == null) { return; } switch (se.SocketErrorCode) { case SocketError.TimedOut: case SocketError.ConnectionAborted: case SocketError.ConnectionReset: case SocketError.Disconnecting: case SocketError.Shutdown: case SocketError.NotConnected: { CloseConnection("socket exception"); return; } default: { _logger.Error(se); return; } } }
private void RTSP_SocketException_Raised(object sender, RtspSocketExceptionEventArgs e) { RtspListener listener = sender as RtspListener; SocketException ex = e.Ex; HandleClientSocketException(ex, listener); }
public void SendDataTooLargeSync() { const int dataLenght = 0x10001; 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); RtspData data = new RtspData(); data.Channel = 12; data.Data = new byte[dataLenght]; TestDelegate test = () => testedListener.SendData(data.Channel, data.Data); Assert.That(test, Throws.InstanceOf <ArgumentException>()); }
/// <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); } } } }
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")); }
/// <summary> /// Accepts the connection. /// </summary> private void AcceptConnection() { try { while (!_Stopping.WaitOne(0)) { // Wait for an incoming TCP Connection TcpClient oneClient = _RTSPServerListener.AcceptTcpClient(); Console.WriteLine("Connection from " + oneClient.Client.RemoteEndPoint.ToString()); // Hand the incoming TCP connection over to the RTSP classes var rtsp_socket = new RtspTcpTransport(oneClient); RtspListener newListener = new RtspListener(rtsp_socket); newListener.MessageReceived += new EventHandler <RtspChunkEventArgs>(async(s, e) => await RTSP_Message_ReceivedAsync(s, e)); //RTSPDispatcher.Instance.AddListener(newListener); // Add the RtspListener to the RTSPConnections List newListener.Start(); } } catch (SocketException error) { // _logger.Warn("Got an error listening, I have to handle the stopping which also throw an error", error); } catch (Exception error) { // _logger.Error("Got an error listening...", error); throw; } }
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);*/ }
/// <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> /// Gets the RTSP listener for destination. /// </summary> /// <param name="destinationUri">The destination URI.</param> /// <returns>An RTSP listener</returns> /// <remarks> /// This method try to get one of openned TCP listener and /// if it does not find it, it create it. /// </remarks> private RtspListener GetRtspListenerForDestination(Uri destinationUri) { Contract.Requires(destinationUri != null); RtspListener destination; string destinationName = destinationUri.Authority; if (_serverListener.ContainsKey(destinationName)) { destination = _serverListener[destinationName]; } else { destination = new RtspListener( new RtspTcpTransport(destinationUri.Host, destinationUri.Port) ); // un peu pourri mais pas d'autre idée... // pour avoir vraiment des clef avec IP.... if (_serverListener.ContainsKey(destination.RemoteAdress)) { destination = _serverListener[destination.RemoteAdress]; } else { AddListener(destination); destination.Start(); } } return(destination); }
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; } }
/// <summary> /// Accepts the connection. /// </summary> private void AcceptConnection() { try { while (!_Stopping.WaitOne(0)) { TcpClient oneClient = _RTSPServerListener.AcceptTcpClient(); Console.WriteLine("Connection from " + oneClient.Client.RemoteEndPoint.ToString()); var rtsp_socket = new RtspTcpTransport(oneClient); RtspListener newListener = new RtspListener(rtsp_socket); newListener.MessageReceived += RTSP_Message_Received; //RTSPDispatcher.Instance.AddListener(newListener); newListener.Start(); } } catch (SocketException error) { // _logger.Warn("Got an error listening, I have to handle the stopping which also throw an error", error); } catch (Exception error) { // _logger.Error("Got an error listening...", error); throw; } }
/// <summary> /// Add a listener. /// </summary> /// <param name="listener">A listener.</param> public void AddListener(RtspListener listener) { if (listener == null) { throw new ArgumentNullException("listener"); } Contract.EndContractBlock(); listener.MessageReceived += new EventHandler <RtspChunkEventArgs>(Listener_MessageReceived); _serverListener.Add(listener.RemoteAdress, listener); }
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"); } }
public RTSPClient(string ipAddress, uint port, string username, string password) { _url = $"rtsp://{username}:{password}@{ipAddress}:{port}/Streaming/channels/1/"; RtspUtils.RegisterUri(); RtspTcpTransport socket = new RtspTcpTransport(ipAddress, (int)port); _client = new RtspListener(socket); _client.MessageReceived += MessageReceived; _client.DataReceived += DataReceived; }
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); }
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}"); } }
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); }
// /// <summary> // /// Starts the listen. // /// </summary> // public async Task StartListen() // { // _RTSPServerListener.Start(); // // _Stopping = new ManualResetEvent(false); // _ListenTread = new Thread(new ThreadStart(AcceptConnection)); // _ListenTread.Start(); // // /* // // Initialise the H264 encoder // h264_encoder = new SimpleH264Encoder(h264_width, h264_height, h264_fps); // //h264_encoder = new TinyH264Encoder(); // hard coded to 192x128 // // // Start the VideoSource // video_source = new TestCard(h264_width, h264_height, h264_fps); // video_source.ReceivedYUVFrame += video_source_ReceivedYUVFrame; // */ // } public async Task ListenAsync() { rtspServerListener.Start(); try { while (!stopping) { // Wait for an incoming TCP Connection TcpClient oneClient = await rtspServerListener.AcceptTcpClientAsync(); Console.WriteLine("Connection from " + oneClient.Client.RemoteEndPoint.ToString()); // Hand the incoming TCP connection over to the RTSP classes var rtsp_socket = new RtspTcpTransport(oneClient); RtspListener newListener = new RtspListener(rtsp_socket); newListener.MessageReceived += RTSP_Message_Received; //RTSPDispatcher.Instance.AddListener(newListener); // Add the RtspListener to the RTSPConnections List lock (rtsp_list) { RTSPConnection new_connection = new RTSPConnection(); new_connection.listener = newListener; new_connection.client_hostname = newListener.RemoteAdress.Split(':')[0]; new_connection.ssrc = global_ssrc; new_connection.time_since_last_rtsp_keepalive = DateTime.UtcNow; new_connection.video_time_since_last_rtcp_keepalive = DateTime.UtcNow; rtsp_list.Add(new_connection); } newListener.Start(); await UpdateClients(); } } catch (SocketException error) { // _logger.Warn("Got an error listening, I have to handle the stopping which also throw an error", error); } catch (Exception error) { // _logger.Error("Got an error listening...", error); throw; } }
public void ReceiveOptionsMessage() { string message = string.Empty; message += "OPTIONS * RTSP/1.0\n"; message += "CSeq: 1\n"; message += "Require: implicit-play\n"; message += "Proxy-Require: gzipped-messages\n"; message += "\n"; MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message)); _mockTransport.GetStream().Returns(stream); // Setup test object. RtspListener testedListener = new RtspListener(_mockTransport); testedListener.MessageReceived += new EventHandler <RtspChunkEventArgs>(MessageReceived); testedListener.DataReceived += new EventHandler <RtspChunkEventArgs>(DataReceived); // Run testedListener.Start(); System.Threading.Thread.Sleep(100); testedListener.Stop(); // Check the transport was closed. _mockTransport.Received().Close(); //Check the message recevied Assert.AreEqual(1, _receivedMessage.Count); RtspChunk theMessage = _receivedMessage[0]; Assert.IsInstanceOf <RtspRequest>(theMessage); Assert.AreEqual(0, theMessage.Data.Length); Assert.AreSame(testedListener, theMessage.SourcePort); RtspRequest theRequest = theMessage as RtspRequest; Assert.AreEqual(RtspRequest.RequestType.OPTIONS, theRequest.RequestTyped); Assert.AreEqual(3, theRequest.Headers.Count); Assert.AreEqual(1, theRequest.CSeq); Assert.Contains("Require", theRequest.Headers.Keys); Assert.Contains("Proxy-Require", theRequest.Headers.Keys); Assert.AreEqual(null, theRequest.RtspUri); Assert.AreEqual(0, _receivedData.Count); }
public RtspClient(Uri uri, Credentials creds = null) { _uri = uri ?? throw new ArgumentNullException("Cannot create RTSP client from null uri"); _cseq = 0; _credentials = creds; _defaultTimeout = TimeSpan.FromSeconds(20); _callbacks = new ConcurrentDictionary <int, AsyncResponse>(); _sources = new ConcurrentDictionary <int, RtpInterleaveMediaSource>(); _connection = new RtspConnection(IPAddress.Parse(uri.Host), uri.Port == -1 ? DEFAULT_RTSP_PORT : uri.Port); _listener = new RtspListener(_connection, OnRtspChunk); _rtpQueue = new BlockingCollection <ByteBuffer>(); LOG.Info($"Created RTSP client for '{_connection.Endpoint}'"); Task.Run(() => ProcessInterleavedData()); _listener.Start(); }
public void SendDataAsync() { const int dataLenght = 45; 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); RtspData data = new RtspData(); data.Channel = 12; data.Data = new byte[dataLenght]; for (int i = 0; i < dataLenght; i++) { data.Data[i] = (byte)i; } // Run var asyncResult = testedListener.BeginSendData(data, null, null); testedListener.EndSendData(asyncResult); var result = stream.GetBuffer(); int index = 0; Assert.That(result[index++], Is.EqualTo((byte)'$')); Assert.That(result[index++], Is.EqualTo(data.Channel)); Assert.That(result[index++], Is.EqualTo((dataLenght & 0xFF00) >> 8)); Assert.That(result[index++], Is.EqualTo(dataLenght & 0x00FF)); for (int i = 0; i < dataLenght; i++) { Assert.That(result[index++], Is.EqualTo(data.Data[i])); } }
/// <summary> /// Accepts the connection. /// </summary> private void AcceptConnection() { Console.WriteLine($"Now streaming via RTSP on port {portNumber}"); Console.WriteLine($"Connect with your player to rtsp://127.0.0.1:{portNumber}/"); try { while (!_Stopping.WaitOne(0)) { // Wait for an incoming TCP Connection TcpClient oneClient = _RTSPServerListener.AcceptTcpClient(); Console.WriteLine("Connection from " + oneClient.Client.RemoteEndPoint.ToString()); // Hand the incoming TCP connection over to the RTSP classes var rtsp_socket = new RtspTcpTransport(oneClient); RtspListener newListener = new RtspListener(rtsp_socket); newListener.MessageReceived += RTSP_Message_Received; //RTSPDispatcher.Instance.AddListener(newListener); // Add the RtspListener to the RTSPConnections List lock (rtsp_list) { RTSPConnection new_connection = new RTSPConnection(); new_connection.listener = newListener; new_connection.client_hostname = newListener.RemoteAdress.Split(':')[0]; new_connection.ssrc = global_ssrc; new_connection.time_since_last_rtsp_keepalive = DateTime.UtcNow; //new_connection.video_time_since_last_rtcp_keepalive = DateTime.UtcNow; rtsp_list.Add(new_connection); } newListener.Start(); } } catch (Exception error) { if (!_Stopping.WaitOne(0)) { Console.WriteLine("[AcceptConnection] Error: " + error.ToString()); } } }
public void ReceiveResponseMessage() { string message = string.Empty; message += "RTSP/1.0 551 Option not supported\n"; message += "CSeq: 302\n"; message += "Unsupported: funky-feature\n"; message += "\r\n"; MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message)); _mockTransport.GetStream().Returns(stream); // Setup test object. RtspListener testedListener = new RtspListener(_mockTransport); testedListener.MessageReceived += new EventHandler <RtspChunkEventArgs>(MessageReceived); testedListener.DataReceived += new EventHandler <RtspChunkEventArgs>(DataReceived); // Run testedListener.Start(); System.Threading.Thread.Sleep(100); testedListener.Stop(); // Check the transport was closed. _mockTransport.Received().Close(); //Check the message recevied Assert.AreEqual(1, _receivedMessage.Count); RtspChunk theMessage = _receivedMessage[0]; Assert.IsInstanceOf <RtspResponse>(theMessage); Assert.AreEqual(0, theMessage.Data.Length); Assert.AreSame(testedListener, theMessage.SourcePort); RtspResponse theResponse = theMessage as RtspResponse; Assert.AreEqual(551, theResponse.ReturnCode); Assert.AreEqual("Option not supported", theResponse.ReturnMessage); Assert.AreEqual(2, theResponse.Headers.Count); Assert.AreEqual(302, theResponse.CSeq); Assert.AreEqual(0, _receivedData.Count); }
public void ReceiveData() { Random rnd = new Random(); byte[] data = new byte[0x0234]; rnd.NextBytes(data); byte[] buffer = new byte[data.Length + 4]; buffer[0] = 0x24; // $ buffer[1] = 11; buffer[2] = 0x02; buffer[3] = 0x34; Buffer.BlockCopy(data, 0, buffer, 4, data.Length); MemoryStream stream = new MemoryStream(buffer); _mockTransport.GetStream().Returns(stream); // Setup test object. RtspListener testedListener = new RtspListener(_mockTransport); testedListener.MessageReceived += new EventHandler <RtspChunkEventArgs>(MessageReceived); testedListener.DataReceived += new EventHandler <RtspChunkEventArgs>(DataReceived); // Run testedListener.Start(); System.Threading.Thread.Sleep(500); testedListener.Stop(); // Check the transport was closed. _mockTransport.Received().Close(); //Check the message recevied Assert.AreEqual(0, _receivedMessage.Count); Assert.AreEqual(1, _receivedData.Count); Assert.IsInstanceOf <RtspData>(_receivedData[0]); RtspData dataMessage = _receivedData[0] as RtspData; Assert.AreEqual(11, dataMessage.Channel); Assert.AreSame(testedListener, dataMessage.SourcePort); Assert.AreEqual(data, dataMessage.Data); }
public void ReceivePlayMessage() { string message = string.Empty; message += "PLAY rtsp://audio.example.com/audio RTSP/1.0\r\n"; message += "CSeq: 835\r\n"; message += "\r\n"; MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message)); _mockTransport.GetStream().Returns(stream); // Setup test object. RtspListener testedListener = new RtspListener(_mockTransport); testedListener.MessageReceived += new EventHandler <RtspChunkEventArgs>(MessageReceived); testedListener.DataReceived += new EventHandler <RtspChunkEventArgs>(DataReceived); // Run testedListener.Start(); System.Threading.Thread.Sleep(100); testedListener.Stop(); // Check the transport was closed. _mockTransport.Received().Close(); //Check the message recevied Assert.AreEqual(1, _receivedMessage.Count); RtspChunk theMessage = _receivedMessage[0]; Assert.IsInstanceOf <RtspRequest>(theMessage); Assert.AreEqual(0, theMessage.Data.Length); Assert.AreSame(testedListener, theMessage.SourcePort); RtspRequest theRequest = theMessage as RtspRequest; Assert.AreEqual(RtspRequest.RequestType.PLAY, theRequest.RequestTyped); Assert.AreEqual(1, theRequest.Headers.Count); Assert.AreEqual(835, theRequest.CSeq); Assert.AreEqual("rtsp://audio.example.com/audio", theRequest.RtspUri.ToString()); Assert.AreEqual(0, _receivedData.Count); }
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); } }
private void Accept(object state) { while (!_stop.WaitOne(0)) { try { var client = _listener.AcceptTcpClient(); var conn = new RtspConnection(client); var listener = new RtspListener(conn, OnRtspRequest); LOG.Debug($"Accepted client connection from '{conn.RemoteAddress}'"); listener.Start(); _listeners.Add(conn.RemoteAddress, listener); } catch (Exception e) { LOG.Error(e, $"Caught exception while accepting client connection, message={e.Message}"); } } }
public void ReceiveData() { Random rnd = new Random(); byte[] data = new byte[0x0234]; rnd.NextBytes(data); byte[] buffer = new byte[data.Length + 4]; buffer[0] = 0x24; // $ buffer[1] = 11; buffer[2] = 0x02; buffer[3] = 0x34; Buffer.BlockCopy(data, 0, buffer, 4, data.Length); MemoryStream stream = new MemoryStream(buffer); _mockTransport.GetStream().Returns(stream); // Setup test object. RtspListener testedListener = new RtspListener(_mockTransport); testedListener.MessageReceived += new EventHandler<RtspChunkEventArgs>(MessageReceived); testedListener.DataReceived += new EventHandler<RtspChunkEventArgs>(DataReceived); // Run testedListener.Start(); System.Threading.Thread.Sleep(500); testedListener.Stop(); // Check the transport was closed. _mockTransport.Received().Close(); //Check the message recevied Assert.AreEqual(0, _receivedMessage.Count); Assert.AreEqual(1, _receivedData.Count); Assert.IsInstanceOf<RtspData>(_receivedData[0]); RtspData dataMessage = _receivedData[0] as RtspData; Assert.AreEqual(11, dataMessage.Channel); Assert.AreSame(testedListener, dataMessage.SourcePort); Assert.AreEqual(data, dataMessage.Data); }
/// <summary> /// Accepts the connection. /// </summary> private void AcceptConnection() { try { while (!_Stopping.WaitOne(0)) { TcpClient oneClient = _RTSPServerListener.AcceptTcpClient(); RtspListener newListener = new RtspListener( new RtspTcpTransport(oneClient)); RTSPDispatcher.Instance.AddListener(newListener); newListener.Start(); } } catch (SocketException error) { _logger.Warn("Got an error listening, I have to handle the stopping which also throw an error", error); } catch (Exception error) { _logger.Error("Got an error listening...", error); throw; } }
public void SendDataTooLarge() { const int dataLenght = 0x10001; 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); RtspData data = new RtspData(); data.Channel = 12; data.Data = new byte[dataLenght]; ActualValueDelegate<object> test = () => testedListener.BeginSendData(data,null,null); Assert.That(test, Throws.InstanceOf<ArgumentException>()); }
public void ReceiveOptionsMessage() { string message = string.Empty; message += "OPTIONS * RTSP/1.0\n"; message += "CSeq: 1\n"; message += "Require: implicit-play\n"; message += "Proxy-Require: gzipped-messages\n"; message += "\n"; MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message)); _mockTransport.GetStream().Returns(stream); // Setup test object. RtspListener testedListener = new RtspListener(_mockTransport); testedListener.MessageReceived += new EventHandler<RtspChunkEventArgs>(MessageReceived); testedListener.DataReceived += new EventHandler<RtspChunkEventArgs>(DataReceived); // Run testedListener.Start(); System.Threading.Thread.Sleep(100); testedListener.Stop(); // Check the transport was closed. _mockTransport.Received().Close(); //Check the message recevied Assert.AreEqual(1, _receivedMessage.Count); RtspChunk theMessage = _receivedMessage[0]; Assert.IsInstanceOf<RtspRequest>(theMessage); Assert.AreEqual(0, theMessage.Data.Length); Assert.AreSame(testedListener, theMessage.SourcePort); RtspRequest theRequest = theMessage as RtspRequest; Assert.AreEqual(RtspRequest.RequestType.OPTIONS, theRequest.RequestTyped); Assert.AreEqual(3, theRequest.Headers.Count); Assert.AreEqual(1, theRequest.CSeq); Assert.Contains("Require", theRequest.Headers.Keys); Assert.Contains("Proxy-Require", theRequest.Headers.Keys); Assert.AreEqual(null, theRequest.RtspUri); Assert.AreEqual(0, _receivedData.Count); }
public void ReceivePlayMessage() { string message = string.Empty; message += "PLAY rtsp://audio.example.com/audio RTSP/1.0\r\n"; message += "CSeq: 835\r\n"; message += "\r\n"; MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message)); _mockTransport.GetStream().Returns(stream); // Setup test object. RtspListener testedListener = new RtspListener(_mockTransport); testedListener.MessageReceived += new EventHandler<RtspChunkEventArgs>(MessageReceived); testedListener.DataReceived += new EventHandler<RtspChunkEventArgs>(DataReceived); // Run testedListener.Start(); System.Threading.Thread.Sleep(100); testedListener.Stop(); // Check the transport was closed. _mockTransport.Received().Close(); //Check the message recevied Assert.AreEqual(1, _receivedMessage.Count); RtspChunk theMessage = _receivedMessage[0]; Assert.IsInstanceOf<RtspRequest>(theMessage); Assert.AreEqual(0, theMessage.Data.Length); Assert.AreSame(testedListener, theMessage.SourcePort); RtspRequest theRequest = theMessage as RtspRequest; Assert.AreEqual(RtspRequest.RequestType.PLAY, theRequest.RequestTyped); Assert.AreEqual(1, theRequest.Headers.Count); Assert.AreEqual(835, theRequest.CSeq); Assert.AreEqual("rtsp://audio.example.com/audio", theRequest.RtspUri.ToString()); Assert.AreEqual(0, _receivedData.Count); }
public void ReceiveResponseMessage() { string message = string.Empty; message += "RTSP/1.0 551 Option not supported\n"; message += "CSeq: 302\n"; message += "Unsupported: funky-feature\n"; message += "\r\n"; MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message)); _mockTransport.GetStream().Returns(stream); // Setup test object. RtspListener testedListener = new RtspListener(_mockTransport); testedListener.MessageReceived += new EventHandler<RtspChunkEventArgs>(MessageReceived); testedListener.DataReceived += new EventHandler<RtspChunkEventArgs>(DataReceived); // Run testedListener.Start(); System.Threading.Thread.Sleep(100); testedListener.Stop(); // Check the transport was closed. _mockTransport.Received().Close(); //Check the message recevied Assert.AreEqual(1, _receivedMessage.Count); RtspChunk theMessage = _receivedMessage[0]; Assert.IsInstanceOf<RtspResponse>(theMessage); Assert.AreEqual(0, theMessage.Data.Length); Assert.AreSame(testedListener, theMessage.SourcePort); RtspResponse theResponse = theMessage as RtspResponse; Assert.AreEqual(551, theResponse.ReturnCode); Assert.AreEqual("Option not supported", theResponse.ReturnMessage); Assert.AreEqual(2, theResponse.Headers.Count); Assert.AreEqual(302, theResponse.CSeq); Assert.AreEqual(0, _receivedData.Count); }
public void ReceiveMessageInterrupt() { string message = string.Empty; message += "PLAY rtsp://audio.example.com/audio RTSP/1."; MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message)); _mockTransport.GetStream().Returns(stream); // Setup test object. RtspListener testedListener = new RtspListener(_mockTransport); testedListener.MessageReceived += new EventHandler<RtspChunkEventArgs>(MessageReceived); testedListener.DataReceived += new EventHandler<RtspChunkEventArgs>(DataReceived); // Run testedListener.Start(); System.Threading.Thread.Sleep(100); // No exception should be generate. stream.Close(); // Check the transport was closed. _mockTransport.Received().Close(); //Check the message recevied Assert.AreEqual(0, _receivedMessage.Count); Assert.AreEqual(0, _receivedData.Count); }
public void ReceiveNoMessage() { string message = string.Empty; MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message)); _mockTransport.GetStream().Returns(stream); // Setup test object. RtspListener testedListener = new RtspListener(_mockTransport); testedListener.MessageReceived += new EventHandler<RtspChunkEventArgs>(MessageReceived); testedListener.DataReceived += new EventHandler<RtspChunkEventArgs>(DataReceived); // Run testedListener.Start(); System.Threading.Thread.Sleep(100); testedListener.Stop(); // Check the transport was closed. _mockTransport.Received().Close(); Assert.AreEqual(0, _receivedMessage.Count); Assert.AreEqual(0, _receivedData.Count); }
public void SendData() { const int dataLenght = 45; 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); RtspData data = new RtspData(); data.Channel = 12; data.Data = new byte[dataLenght]; for (int i = 0; i < dataLenght; i++) { data.Data[i] = (byte)i; } // Run var asyncResult = testedListener.BeginSendData(data, null, null); testedListener.EndSendData(asyncResult); var result = stream.GetBuffer(); int index = 0; Assert.That(result[index++], Is.EqualTo((byte)'$')); Assert.That(result[index++], Is.EqualTo(data.Channel)); Assert.That(result[index++], Is.EqualTo((dataLenght & 0xFF00) >> 8)); Assert.That(result[index++], Is.EqualTo(dataLenght & 0x00FF)); for (int i = 0; i < dataLenght; i++) { Assert.That(result[index++], Is.EqualTo(data.Data[i])); } }
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")); }