public void TestNull() { //base class? //UnitTestBase Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name); Media.Rtp.RtpClient rtpClient = default(Media.Rtp.RtpClient); try { rtpClient = Media.Rtp.RtpClient.FromSessionDescription(default(Media.Sdp.SessionDescription)); } catch { } System.Diagnostics.Debug.Assert(rtpClient == null, "Must not have created a RtpClient from a null SessionDescription"); //Create a client using (rtpClient = new Media.Rtp.RtpClient()) { //Attempt to find a context Media.Rtp.RtpClient.TransportContext contextAvailable = rtpClient.GetTransportContexts().FirstOrDefault(); System.Diagnostics.Debug.Assert(contextAvailable == null, "Found a Context when there was no Session or Media Description"); using (contextAvailable = new Media.Rtp.RtpClient.TransportContext(0, 1, 0)) { //Usually indicated by the profile bool padding = false, extension = false; //Create a RtpPacket from the using (var rtpPacket = new Media.Rtp.RtpPacket(contextAvailable.Version, padding, extension, null)) { System.Diagnostics.Debug.Assert(rtpClient.SendRtpPacket(rtpPacket) == 0, "Sent a packet when there was no Session or Media Description or TransportContext"); } } } }
public TestFramework() { // Create a receiving socket. _receiving = new System.Net.Sockets.Socket(_rtspServer.AddressFamily, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp); // Connect to the server. System.IAsyncResult connectResult = null; connectResult = _receiving.BeginConnect(_rtspServer, new System.AsyncCallback((iar) => { try { _receiving.EndConnect(iar); } catch { } }), null); // Get the sender socket to be used by the "server". _sender = _listenSocket.Accept(); // RtspClient default size byte[] buffer = new byte[8192]; _client = new Media.Rtp.RtpClient(new Media.Common.MemorySegment(buffer, Media.Rtsp.RtspMessage.MaximumLength, buffer.Length - Media.Rtsp.RtspMessage.MaximumLength)); _client.OutOfBandData += ProcessInterleaveData; _client.RtpPacketReceieved += ProcessRtpPacket; Media.Sdp.MediaDescription md = new Media.Sdp.MediaDescription(Media.Sdp.MediaType.video, 999, "H.264", 0); Media.Rtp.RtpClient.TransportContext tc = new Media.Rtp.RtpClient.TransportContext(0, 1, Media.RFC3550.Random32(9876), md, false, _senderSSRC); // Create a Duplexed reciever using the RtspClient socket. tc.Initialize(_receiving); _client.TryAddContext(tc); }
internal static void TestInterleavedFraming() { Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name); //Create a rtp client to mock the test using (Media.Rtp.RtpClient test = new Media.Rtp.RtpClient()) { Media.Rtsp.RtspMessage lastInterleaved = null; int rtspOut = 0, rtspIn = 0; //Setup an even to see what data was transmited. test.OutOfBandData += (sender, data, offset, count) => { Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("\tInterleaved (@" + offset + ", count=" + count + ") =>" + System.Text.Encoding.ASCII.GetString(data, offset, count)); GetMessage: Media.Rtsp.RtspMessage interleaved = new Media.Rtsp.RtspMessage(data, offset, count); if (interleaved.RtspMessageType == Media.Rtsp.RtspMessageType.Invalid && lastInterleaved != null) { interleaved.Dispose(); interleaved = null; int lastLength = lastInterleaved.Length; using (var memory = new Media.Common.MemorySegment(data, offset, count)) { int used = lastInterleaved.CompleteFrom(null, memory); if (used == 0 || lastLength == lastInterleaved.Length) { return; } Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Added Data (" + used + ") Bytes"); } } else { lastInterleaved = interleaved; ++rtspIn; } if (lastInterleaved.IsComplete) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Complete Message: " + lastInterleaved); } else { Console.ForegroundColor = ConsoleColor.DarkYellow; Console.WriteLine("Incomplete Message: " + lastInterleaved); } int totalLength = lastInterleaved.Length; if (totalLength < count) { offset += totalLength; count -= totalLength; goto GetMessage; } }; //Loop 255 times foreach (var testIndex in Enumerable.Range(byte.MinValue, byte.MaxValue)) { //reset rtsp count rtspOut = rtspIn = 0; //Declare a channel randomly int channel = Media.Utility.Random.Next(byte.MinValue, byte.MaxValue); //Declare a random length int length = Media.Utility.Random.Next(ushort.MinValue, ushort.MaxValue); //Determine an actual length int actualLength = 0; //Make a header var header = new byte[] { Media.Rtp.RtpClient.BigEndianFrameControl, (byte)channel, 0, 0 }; //Write the length in the header Media.Common.Binary.Write16(header, 2, Common.Binary.IsLittleEndian, (short)length); //Get the data indicated //var data = header.Concat(Enumerable.Repeat(default(byte), actualLength)); List <byte> allData = new List <byte>(); //Add more data until actualLength is less then length while (actualLength < length) { //Make a message var rtspBytes = new Media.Rtsp.RtspMessage(Media.Rtsp.RtspMessageType.Response, 1.0, Media.Rtsp.RtspMessage.DefaultEncoding) { RtspStatusCode = Media.Rtsp.RtspStatusCode.OK, CSeq = Media.Utility.Random.Next(byte.MinValue, int.MaxValue), UserAgent = "$UserAgent $007\r\n$\0\0\aRTSP/1.0", Body = "$00Q\r\n$\0:\0" }.Prepare(); byte[] data = new byte[Media.Utility.Random.Next(1, length)]; Media.Utility.Random.NextBytes(data); //determine if there is more space actualLength += data.Length; //Put a message here allData.AddRange(rtspBytes.ToArray()); //Increment the outgoing message count ++rtspOut; //Put some data allData.AddRange(data); //Put a message allData.AddRange(rtspBytes.ToArray()); //Increment the outgoing message count ++rtspOut; //If there is more space put another binary frame if (actualLength < length) { int needed = length - actualLength; //Randomize needed needed = Media.Utility.Random.Next(0, needed); var headerLast = new byte[] { 0x24, (byte)channel, 0, 0 }; Media.Common.Binary.Write16(headerLast, 2, Common.Binary.IsLittleEndian, (short)needed); data = new byte[needed]; Media.Utility.Random.NextBytes(data); allData.AddRange(data); actualLength += needed; } } //Start at 0 int offset = 0; byte[] buffer = allData.ToArray(); int max = buffer.Length, remains = actualLength; //Enumerate the buffer looking for data to parse //TODO Improve test by setting expections of packets to receive while (remains > 0) { //Parse the data "received" which should always be 4 bytes longer then what was actually present. int foundLen = test.ProcessFrameData(buffer, offset, remains, null); Console.WriteLine("Indicated: " + actualLength + " Actual: " + max + " Found: " + foundLen); System.Diagnostics.Debug.Assert(foundLen <= max); if (foundLen > 0) { //Move the offset offset += foundLen; max -= foundLen; remains -= foundLen; } else { ++offset; --max; --remains; } } //Some Rtsp messages may have been hidden by invalid tcp frames which indicated a longer length then they actually had. if (rtspOut > rtspIn) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Missed:" + (rtspOut - rtspIn) + " Messages of" + rtspOut); } else if (rtspIn == 0) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Missed All Messages"); } else { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Missed No Messages"); } } } }
public TestFramework() { // Create a receiving socket. _receiving = new System.Net.Sockets.Socket(_rtspServer.AddressFamily, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp); // Connect to the server. System.IAsyncResult connectResult = null; connectResult = _receiving.BeginConnect(_rtspServer, new System.AsyncCallback((iar) => { try { _receiving.EndConnect(iar); } catch { } }), null); // Get the sender socket to be used by the "server". _sender = _listenSocket.Accept(); // RtspClient default size byte[] buffer = new byte[8192]; _client = new Media.Rtp.RtpClient(new Media.Common.MemorySegment(buffer, Media.Rtsp.RtspMessage.MaximumLength, buffer.Length - Media.Rtsp.RtspMessage.MaximumLength)); _client.InterleavedData += ProcessInterleaveData; _client.RtpPacketReceieved += ProcessRtpPacket; Media.Sdp.MediaDescription md = new Media.Sdp.MediaDescription(Media.Sdp.MediaType.video, 999, "H.264", 0); Media.Rtp.RtpClient.TransportContext tc = new Media.Rtp.RtpClient.TransportContext(0, 1, Media.RFC3550.Random32(9876), md, false, _senderSSRC); // Create a Duplexed reciever using the RtspClient socket. tc.Initialize(_receiving, _receiving); _client.TryAddContext(tc); }
internal static void TestInterleavedFraming() { Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name); //Create a rtp client to mock the test using (Media.Rtp.RtpClient test = new Media.Rtp.RtpClient()) { Media.Rtsp.RtspMessage lastInterleaved = null; int rtspOut = 0, rtspIn = 0; //Setup an even to see what data was transmited. test.InterleavedData += (sender, data, offset, count) => { Console.ForegroundColor = ConsoleColor.Cyan; //Console.WriteLine("\tInterleaved (@" + offset + ", count=" + count + ") =>" + System.Text.Encoding.ASCII.GetString(data, offset, count)); int usedBytes = 0; GetMessage: Media.Rtsp.RtspMessage interleaved = new Media.Rtsp.RtspMessage(data, offset, count); //Todo, revise to create segment then attempt completion if ((interleaved.MessageType == Media.Rtsp.RtspMessageType.Invalid || lastInterleaved != null) && count >= Media.Rtsp.RtspMessage.MinimumStatusLineSize) { interleaved.Dispose(); interleaved = null; using (var memory = new Media.Common.MemorySegment(data, offset, count)) { usedBytes = lastInterleaved.CompleteFrom(null, memory); Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Added Data (" + usedBytes + ") Bytes"); } } else { lastInterleaved = interleaved; ++rtspIn; usedBytes = lastInterleaved.Length; } if (lastInterleaved.IsComplete) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Complete Message: " + lastInterleaved); } else { Console.ForegroundColor = ConsoleColor.DarkYellow; Console.WriteLine("Incomplete Message: " + lastInterleaved); } if (usedBytes > 0 && usedBytes < count) { offset += usedBytes; count -= usedBytes; if(count > 0) goto GetMessage; } }; //Loop 255 times foreach (var testIndex in Enumerable.Range(byte.MinValue, byte.MaxValue)) { //reset rtsp count rtspOut = rtspIn = 0; //Declare a channel randomly int channel = Media.Utility.Random.Next(byte.MinValue, byte.MaxValue); //Declare a random length int length = Media.Utility.Random.Next(ushort.MinValue, ushort.MaxValue); //Determine an actual length int actualLength = 0; //Make a header var header = new byte[] { Media.Rtp.RtpClient.BigEndianFrameControl, (byte)channel, 0, 0 }; //Write the length in the header Media.Common.Binary.Write16(header, 2, BitConverter.IsLittleEndian, (short)length); //Get the data indicated //var data = header.Concat(Enumerable.Repeat(default(byte), actualLength)); List<byte> allData = new List<byte>(); //Add more data until actualLength is less then length while (actualLength < length) { //Make a message var rtspBytes = new Media.Rtsp.RtspMessage(Media.Rtsp.RtspMessageType.Response, 1.0, Media.Rtsp.RtspMessage.DefaultEncoding) { StatusCode = Media.Rtsp.RtspStatusCode.OK, CSeq = Media.Utility.Random.Next(byte.MinValue, int.MaxValue), UserAgent = "$UserAgent $007\r\n$\0\0\aRTSP/1.0", Body = "$00Q\r\n$\0:\0" }.Prepare(); byte[] data = new byte[Media.Utility.Random.Next(1, length)]; Media.Utility.Random.NextBytes(data); //determine if there is more space actualLength += data.Length; //Put a message here allData.AddRange(rtspBytes.ToArray()); //Increment the outgoing message count ++rtspOut; //Put some data allData.AddRange(data); //Put a message allData.AddRange(rtspBytes.ToArray()); //Increment the outgoing message count ++rtspOut; //If there is more space put another binary frame if (actualLength < length) { int needed = length - actualLength; //Randomize needed needed = Media.Utility.Random.Next(0, needed); var headerLast = new byte[] { 0x24, (byte)channel, 0, 0 }; Media.Common.Binary.Write16(headerLast, 2, BitConverter.IsLittleEndian, (short)needed); data = new byte[needed]; Media.Utility.Random.NextBytes(data); allData.AddRange(data); actualLength += needed; } } //Start at 0 int offset = 0; byte[] buffer = allData.ToArray(); int max = buffer.Length; //Enumerate the buffer looking for data to parse //TODO Improve test by setting expections of packets to receive while (offset < max) { //Parse the data "received" which should always be 4 bytes longer then what was actually present. int foundLen = test.ProcessFrameData(buffer, offset, max - offset, null); if (foundLen > max) throw new Exception("TestInterleavedFraming found an invalid length."); //Move the offset offset += foundLen; Console.WriteLine(" Found: " + foundLen); } //Some Rtsp messages may have been hidden by invalid 'tcp' framing which indicated a longer length then they actually had. if (rtspOut > rtspIn) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Missed:" + (rtspOut - rtspIn) + " Messages of" + rtspOut); } else if (rtspIn == 0) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Missed All Messages"); } else { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Missed No Messages"); } } } }