示例#1
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");
                    }
                }
            }
        }
                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;
                    }
                }
示例#3
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;
                    }
                }
        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");
                    }
                }
            }
        }