Пример #1
0
            /// <summary>
            /// This test case is added to demonstrate the risk of handing a byte array to a constructor.
            /// A ctor can only return a single object even if the byte array it is given may contain more
            /// than one object.
            /// This violates OO as the caller is burdened with having to now about what should be a feature
            /// of using the class it is calling.
            /// </summary>
            public static void BackToBackRtspMessages()
            {
                System.Console.Clear();
                Console.WriteLine("TestProcessFrameData Case3(): Two back to back RTSP Responses");
                Console.WriteLine("Correct output would be 2 'ProcessInterleaveData():...' detailing RTSP responses CSeq 34 and 35:");
                Console.WriteLine("");

                TestFramework tf = new TestFramework();

                Media.Rtsp.RtspMessage keepAlive = new Media.Rtsp.RtspMessage(Media.Rtsp.RtspMessageType.Response);
                keepAlive.RtspStatusCode = Media.Rtsp.RtspStatusCode.OK;
                keepAlive.CSeq           = 34;
                keepAlive.SetHeader(Media.Rtsp.RtspHeaders.Session, "A9B8C7D6");
                keepAlive.SetHeader(Media.Rtsp.RtspHeaders.Date, DateTime.Now.ToUniversalTime().ToString("r"));
                byte[] buffer = keepAlive.Prepare().ToArray();
                tf.Send(buffer);

                keepAlive = new Media.Rtsp.RtspMessage(Media.Rtsp.RtspMessageType.Response);
                keepAlive.RtspStatusCode = Media.Rtsp.RtspStatusCode.OK;
                keepAlive.CSeq           = 35;
                keepAlive.SetHeader(Media.Rtsp.RtspHeaders.Session, "A9B8C7D6");
                keepAlive.SetHeader(Media.Rtsp.RtspHeaders.Date, DateTime.Now.ToUniversalTime().ToString("r"));
                buffer = keepAlive.Prepare().ToArray();
                tf.Send(buffer);

                //  Kick of the processing eventually ending up in RtpClient.ProcessFrameData()
                tf.HaveRtpClientWorkerThreadProcessSocketData();
            }
Пример #2
0
            private static void Issue17245_Case2(int breakingPaketLength)
            {
                int sequenceNumber = 0x3030;   //  "00"

                System.Console.Clear();
                Console.WriteLine("TestProcessFrameData Issue17245_Case2(): Interleaved RTSPResponse");
                Console.WriteLine("breakingPaketLength = " + breakingPaketLength);
                Console.WriteLine("Correct output is 3 rows saying 'ProcessRtpPacket()...', 1 yellow row, and finaly a single row 'ProcessRtpPacket()...':");
                Console.WriteLine("");

                TestFramework tf = new TestFramework();

                //Console.WriteLine(line + sequenceNumber);
                byte[] buffer          = GeneratePayload(1400);
                Media.Rtp.RtpPacket p1 = new Media.Rtp.RtpPacket(2, false, false, false, 0, 0, _senderSSRC, sequenceNumber++, _timeStamp, buffer);
                buffer = p1.Prepare().ToArray();
                tf.Send(GenerateEncapsulatingHeader(buffer.Length));
                tf.Send(buffer);

                //Console.WriteLine(line + sequenceNumber);
                buffer = GeneratePayload(1400);
                Media.Rtp.RtpPacket p2 = new Media.Rtp.RtpPacket(2, false, false, false, 0, 0, _senderSSRC, sequenceNumber++, _timeStamp, buffer);
                buffer = p2.Prepare().ToArray();
                tf.Send(GenerateEncapsulatingHeader(buffer.Length));
                tf.Send(buffer);

                //Console.WriteLine(line + sequenceNumber);
                buffer = GeneratePayload(breakingPaketLength);
                Media.Rtp.RtpPacket p3 = new Media.Rtp.RtpPacket(2, false, false, false, 0, 0, _senderSSRC, sequenceNumber++, _timeStamp, buffer);
                buffer = p3.Prepare().ToArray();
                tf.Send(GenerateEncapsulatingHeader(buffer.Length));
                tf.Send(buffer);

                Media.Rtsp.RtspMessage keepAlive = new Media.Rtsp.RtspMessage(Media.Rtsp.RtspMessageType.Response);
                keepAlive.RtspStatusCode = Media.Rtsp.RtspStatusCode.OK;
                keepAlive.CSeq           = 34;
                keepAlive.SetHeader(Media.Rtsp.RtspHeaders.Session, "A9B8C7D6");
                keepAlive.SetHeader(Media.Rtsp.RtspHeaders.UserAgent, "Testing $UserAgent $009\r\n$\0:\0");
                keepAlive.SetHeader("Ignore", "$UserAgent $009\r\n$\0\0\aRTSP/1.0");
                keepAlive.SetHeader("$", string.Empty);
                keepAlive.SetHeader(Media.Rtsp.RtspHeaders.Date, DateTime.Now.ToUniversalTime().ToString("r"));
                buffer = keepAlive.Prepare().ToArray();
                tf.Send(buffer);

                //Console.WriteLine(line + sequenceNumber);
                buffer = GeneratePayload(1400);
                Media.Rtp.RtpPacket p4 = new Media.Rtp.RtpPacket(2, false, false, false, 0, 0, _senderSSRC, sequenceNumber++, _timeStamp, buffer);
                buffer = p4.Prepare().ToArray();
                tf.Send(GenerateEncapsulatingHeader(buffer.Length));
                tf.Send(buffer);

                //  Kick of the processing eventually ending up in RtpClient.ProcessFrameData()
                tf.HaveRtpClientWorkerThreadProcessSocketData();
            }
Пример #3
0
        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");
                    }
                }
            }
        }
Пример #4
0
                void ProcessInterleaveData(object sender, byte[] data, int offset, int length)
                {
                    ConsoleColor previousForegroundColor = Console.ForegroundColor;

                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("ProcessInterleaveData(): offset = " + offset + ", length = :" + length);

                    byte[] buffer = new byte[length];
                    Array.Copy(data, offset, buffer, 0, length);
                    //  Using ASCII instead of UTF8 to get all bytes printed.
                    Console.ForegroundColor = ConsoleColor.DarkYellow;
                    Console.WriteLine("'" + System.Text.Encoding.ASCII.GetString(buffer) + "'");


GetMessage:

                    try
                    {
                        Media.Rtsp.RtspMessage interleaved = new Media.Rtsp.RtspMessage(data, offset, length);

                        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, length))
                            {
                                lastInterleaved.CompleteFrom(null, memory);

                                if (lastLength == lastInterleaved.Length)
                                {
                                    return;
                                }
                            }
                        }
                        else
                        {
                            lastInterleaved = interleaved;
                        }

                        //If the last message was complete then show it in green
                        if (lastInterleaved.IsComplete)
                        {
                            Console.ForegroundColor = ConsoleColor.Green;
                        }

                        Console.WriteLine("ProcessInterleaveData() RtspMessage.MessageType = " + lastInterleaved.RtspMessageType.ToString());
                        Console.WriteLine("ProcessInterleaveData() RtspMessage.CSeq = " + lastInterleaved.CSeq);
                        Console.WriteLine("ProcessInterleaveData() RtspMessage = '" + lastInterleaved.ToString() + "'");

                        Console.ForegroundColor = previousForegroundColor;

                        int totalLength = lastInterleaved.Length;

                        if (totalLength < length)
                        {
                            offset += totalLength;
                            length -= totalLength;
                            goto GetMessage;
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("ProcessInterleaveData() exception:" + ex.ToString());
                        Console.WriteLine("");
                        //throw;
                    }
                }
                void ProcessInterleaveData(object sender, byte[] data, int offset, int length)
                {
                    ConsoleColor previousForegroundColor = Console.ForegroundColor;
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("ProcessInterleaveData(): offset = " + offset + ", length = :" + length);

                    byte[] buffer = new byte[length];
                    Array.Copy(data, offset, buffer, 0, length);
                    //  Using ASCII instead of UTF8 to get all bytes printed.
                    Console.ForegroundColor = ConsoleColor.DarkYellow;
                    Console.WriteLine("'" + System.Text.Encoding.ASCII.GetString(buffer) + "'");

                    GetMessage:

                    try
                    {
                        Media.Rtsp.RtspMessage interleaved = new Media.Rtsp.RtspMessage(data, offset, length);

                        if (interleaved.MessageType == Media.Rtsp.RtspMessageType.Invalid && lastInterleaved != null)
                        {

                            interleaved.Dispose();

                            interleaved = null;

                            int lastLength = lastInterleaved.Length;

                            using (var memory = new Media.Common.MemorySegment(data, offset, length))
                            {
                                lastInterleaved.CompleteFrom(null, memory);

                                if (lastLength == lastInterleaved.Length) return;
                            }

                        }
                        else lastInterleaved = interleaved;

                        //If the last message was complete then show it in green
                        if (lastInterleaved.IsComplete) Console.ForegroundColor = ConsoleColor.Green;

                        Console.WriteLine("ProcessInterleaveData() RtspMessage.MessageType = " + lastInterleaved.MessageType.ToString());
                        Console.WriteLine("ProcessInterleaveData() RtspMessage.CSeq = " + lastInterleaved.CSeq);
                        Console.WriteLine("ProcessInterleaveData() RtspMessage = '" + lastInterleaved.ToString() + "'");

                        Console.ForegroundColor = previousForegroundColor;

                        int totalLength = lastInterleaved.Length;

                        if (totalLength < length)
                        {
                            offset += totalLength;
                            length -= totalLength;
                            goto GetMessage;
                        }

                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("ProcessInterleaveData() exception:" + ex.ToString());
                        Console.WriteLine("");
                        //throw;
                    }
                }
            private static void Issue17245_Case2(int breakingPaketLength)
            {
                int sequenceNumber = 0x3030;   //  "00"

                System.Console.Clear();
                Console.WriteLine("TestProcessFrameData Issue17245_Case2(): Interleaved RTSPResponse");
                Console.WriteLine("breakingPaketLength = " + breakingPaketLength);
                Console.WriteLine("Correct output is 3 rows saying 'ProcessRtpPacket()...', 1 yellow row, and finaly a single row 'ProcessRtpPacket()...':");
                Console.WriteLine("");

                TestFramework tf = new TestFramework();
                //Console.WriteLine(line + sequenceNumber);
                byte[] buffer = GeneratePayload(1400);
                Media.Rtp.RtpPacket p1 = new Media.Rtp.RtpPacket(2, false, false, false, 0, 0, _senderSSRC, sequenceNumber++, _timeStamp, buffer);
                buffer = p1.Prepare().ToArray();
                tf.Send(GenerateEncapsulatingHeader(buffer.Length));
                tf.Send(buffer);

                //Console.WriteLine(line + sequenceNumber);
                buffer = GeneratePayload(1400);
                Media.Rtp.RtpPacket p2 = new Media.Rtp.RtpPacket(2, false, false, false, 0, 0, _senderSSRC, sequenceNumber++, _timeStamp, buffer);
                buffer = p2.Prepare().ToArray();
                tf.Send(GenerateEncapsulatingHeader(buffer.Length));
                tf.Send(buffer);

                //Console.WriteLine(line + sequenceNumber);
                buffer = GeneratePayload(breakingPaketLength);
                Media.Rtp.RtpPacket p3 = new Media.Rtp.RtpPacket(2, false, false, false, 0, 0, _senderSSRC, sequenceNumber++, _timeStamp, buffer);
                buffer = p3.Prepare().ToArray();
                tf.Send(GenerateEncapsulatingHeader(buffer.Length));
                tf.Send(buffer);

                Media.Rtsp.RtspMessage keepAlive = new Media.Rtsp.RtspMessage(Media.Rtsp.RtspMessageType.Response);
                keepAlive.StatusCode = Media.Rtsp.RtspStatusCode.OK;
                keepAlive.CSeq = 34;
                keepAlive.SetHeader(Media.Rtsp.RtspHeaders.Session, "A9B8C7D6");
                keepAlive.SetHeader(Media.Rtsp.RtspHeaders.UserAgent, "Testing $UserAgent $009\r\n$\0:\0");
                keepAlive.SetHeader("Ignore", "$UserAgent $009\r\n$\0\0\aRTSP/1.0");
                keepAlive.SetHeader("$", string.Empty);
                keepAlive.SetHeader(Media.Rtsp.RtspHeaders.Date, DateTime.Now.ToUniversalTime().ToString("r"));
                buffer = keepAlive.Prepare().ToArray();
                tf.Send(buffer);

                //Console.WriteLine(line + sequenceNumber);
                buffer = GeneratePayload(1400);
                Media.Rtp.RtpPacket p4 = new Media.Rtp.RtpPacket(2, false, false, false, 0, 0, _senderSSRC, sequenceNumber++, _timeStamp, buffer);
                buffer = p4.Prepare().ToArray();
                tf.Send(GenerateEncapsulatingHeader(buffer.Length));
                tf.Send(buffer);

                //  Kick of the processing eventually ending up in RtpClient.ProcessFrameData()
                tf.HaveRtpClientWorkerThreadProcessSocketData();
            }
            /// <summary>
            /// This test case is added to demonstrate the risk of handing a byte array to a constructor.
            /// A ctor can only return a single object even if the byte array it is given may contain more
            /// than one object.
            /// This violates OO as the caller is burdened with having to now about what should be a feature
            /// of using the class it is calling.
            /// </summary>
            public static void BackToBackRtspMessages()
            {
                System.Console.Clear();
                Console.WriteLine("TestProcessFrameData Case3(): Two back to back RTSP Responses");
                Console.WriteLine("Correct output would be 2 'ProcessInterleaveData():...' detailing RTSP responses CSeq 34 and 35:");
                Console.WriteLine("");

                TestFramework tf = new TestFramework();

                Media.Rtsp.RtspMessage keepAlive = new Media.Rtsp.RtspMessage(Media.Rtsp.RtspMessageType.Response);
                keepAlive.StatusCode = Media.Rtsp.RtspStatusCode.OK;
                keepAlive.CSeq = 34;
                keepAlive.SetHeader(Media.Rtsp.RtspHeaders.Session, "A9B8C7D6");
                keepAlive.SetHeader(Media.Rtsp.RtspHeaders.Date, DateTime.Now.ToUniversalTime().ToString("r"));
                byte[] buffer = keepAlive.Prepare().ToArray();
                tf.Send(buffer);

                keepAlive = new Media.Rtsp.RtspMessage(Media.Rtsp.RtspMessageType.Response);
                keepAlive.StatusCode = Media.Rtsp.RtspStatusCode.OK;
                keepAlive.CSeq = 35;
                keepAlive.SetHeader(Media.Rtsp.RtspHeaders.Session, "A9B8C7D6");
                keepAlive.SetHeader(Media.Rtsp.RtspHeaders.Date, DateTime.Now.ToUniversalTime().ToString("r"));
                buffer = keepAlive.Prepare().ToArray();
                tf.Send(buffer);

                //  Kick of the processing eventually ending up in RtpClient.ProcessFrameData()
                tf.HaveRtpClientWorkerThreadProcessSocketData();
            }
        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");
                    }
                }
            }
        }