public STUNAttribute(STUNAttributeTypesEnum attributeType, ushort value)
        {
            AttributeType = attributeType;

            if (BitConverter.IsLittleEndian)
            {
                Value = BitConverter.GetBytes(NetConvert.DoReverseEndian(value));
            }
            else
            {
                Value = BitConverter.GetBytes(value);
            }
        }
Example #2
0
        public STUNAddressAttribute(byte[] attributeValue)
            : base(STUNAttributeTypesEnum.MappedAddress, attributeValue)
        {
            if (BitConverter.IsLittleEndian)
            {
                Port = NetConvert.DoReverseEndian(BitConverter.ToUInt16(attributeValue, 2));
            }
            else
            {
                Port = BitConverter.ToUInt16(attributeValue, 2);
            }

            Address = new IPAddress(new byte[] { attributeValue[4], attributeValue[5], attributeValue[6], attributeValue[7] });
        }
Example #3
0
        /// <summary>
        /// Gets the chunk bytes for an unsigned int chunk type.
        /// </summary>
        public static byte[] GetBytes(ChunkTypeEnum chunkType, uint val)
        {
            byte[] buf = InitBuffer(chunkType, MINIMUM_CHUNK_LENGTH + 4);

            if (BitConverter.IsLittleEndian)
            {
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(val)), 0, buf, MINIMUM_CHUNK_LENGTH, 4);
            }
            else
            {
                Buffer.BlockCopy(BitConverter.GetBytes(val), 0, buf, MINIMUM_CHUNK_LENGTH, 4);
            }
            return(buf);
        }
Example #4
0
        /// <summary>
        /// Extract and load the RTP header from an RTP packet.
        /// </summary>
        /// <param name="packet"></param>
        public RTPHeader(byte[] packet)
        {
            if (packet.Length < MIN_HEADER_LEN)
            {
                throw new ApplicationException("The packet did not contain the minimum number of bytes for an RTP header packet.");
            }

            UInt16 firstWord = BitConverter.ToUInt16(packet, 0);

            if (BitConverter.IsLittleEndian)
            {
                firstWord      = NetConvert.DoReverseEndian(firstWord);
                SequenceNumber = NetConvert.DoReverseEndian(BitConverter.ToUInt16(packet, 2));
                Timestamp      = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 4));
                SyncSource     = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 8));
            }
            else
            {
                SequenceNumber = BitConverter.ToUInt16(packet, 2);
                Timestamp      = BitConverter.ToUInt32(packet, 4);
                SyncSource     = BitConverter.ToUInt32(packet, 8);
            }

            Version             = firstWord >> 14;
            PaddingFlag         = (firstWord >> 13) & 0x1;
            HeaderExtensionFlag = (firstWord >> 12) & 0x1;
            CSRCCount           = (firstWord >> 8) & 0xf;
            MarkerBit           = (firstWord >> 7) & 0x1;
            PayloadType         = firstWord & 0x7f;

            try
            {
                if (HeaderExtensionFlag == 1)
                {
                    if (BitConverter.IsLittleEndian)
                    {
                        ExtensionProfile = NetConvert.DoReverseEndian(BitConverter.ToUInt16(packet, 12 + 4 * CSRCCount));
                        ExtensionLength  = NetConvert.DoReverseEndian(BitConverter.ToUInt16(packet, 14 + 4 * CSRCCount));
                    }
                    else
                    {
                        ExtensionProfile = BitConverter.ToUInt16(packet, 8 + 4 * CSRCCount);
                        ExtensionLength  = BitConverter.ToUInt16(packet, 10 + 4 * CSRCCount);
                    }
                }
            }
            catch (Exception ex)
            {
            }
        }
Example #5
0
        public byte[] GetBytes()
        {
            byte[] payload = new byte[RTCPREPORT_BYTES_LENGTH];

            if (BitConverter.IsLittleEndian)
            {
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(SyncSource)), 0, payload, 0, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian((ulong)SampleStartTime.Ticks)), 0, payload, 4, 8);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian((ulong)SampleEndTime.Ticks)), 0, payload, 12, 8);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(StartSequenceNumber)), 0, payload, 20, 2);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(EndSequenceNumber)), 0, payload, 22, 2);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian((uint)TotalPackets)), 0, payload, 24, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian((uint)OutOfOrder)), 0, payload, 28, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian((uint)JitterAverage)), 0, payload, 32, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian((uint)JitterMaximum)), 0, payload, 36, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian((uint)JitterDiscards)), 0, payload, 40, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian((uint)PacketsLost)), 0, payload, 44, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian((uint)Duplicates)), 0, payload, 48, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian((ulong)BytesReceived)), 0, payload, 52, 8);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian((uint)TransmissionRate)), 0, payload, 60, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian((ulong)Duration)), 0, payload, 64, 8);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian((uint)AverageTransitTime)), 0, payload, 72, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian((uint)ReportNumber)), 0, payload, 76, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian((uint)LastReceivedReportNumber)), 0, payload, 80, 4);
            }
            else
            {
                Buffer.BlockCopy(BitConverter.GetBytes(SyncSource), 0, payload, 0, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(SampleStartTime.Ticks), 0, payload, 4, 8);
                Buffer.BlockCopy(BitConverter.GetBytes(SampleEndTime.Ticks), 0, payload, 12, 8);
                Buffer.BlockCopy(BitConverter.GetBytes(StartSequenceNumber), 0, payload, 20, 2);
                Buffer.BlockCopy(BitConverter.GetBytes(EndSequenceNumber), 0, payload, 22, 2);
                Buffer.BlockCopy(BitConverter.GetBytes(TotalPackets), 0, payload, 24, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(OutOfOrder), 0, payload, 28, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(JitterAverage), 0, payload, 32, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(JitterMaximum), 0, payload, 36, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(JitterDiscards), 0, payload, 40, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(PacketsLost), 0, payload, 44, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(Duplicates), 0, payload, 48, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(BytesReceived), 0, payload, 52, 8);
                Buffer.BlockCopy(BitConverter.GetBytes(TransmissionRate), 0, payload, 60, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(Duration), 0, payload, 64, 8);
                Buffer.BlockCopy(BitConverter.GetBytes(AverageTransitTime), 0, payload, 72, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(ReportNumber), 0, payload, 76, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(LastReceivedReportNumber), 0, payload, 76, 4);
            }

            return(payload);
        }
 public STUNXORAddressAttribute(STUNAttributeTypesEnum attributeType, byte[] attributeValue)
     : base(attributeType, attributeValue)
 {
     if (BitConverter.IsLittleEndian)
     {
         Port = NetConvert.DoReverseEndian(BitConverter.ToUInt16(attributeValue, 2)) ^ (UInt16)(STUNHeader.MAGIC_COOKIE >> 16);
         UInt32 address = NetConvert.DoReverseEndian(BitConverter.ToUInt32(attributeValue, 4)) ^ STUNHeader.MAGIC_COOKIE;
         Address = new IPAddress(NetConvert.DoReverseEndian(address));
     }
     else
     {
         Port = BitConverter.ToUInt16(attributeValue, 2) ^ (UInt16)(STUNHeader.MAGIC_COOKIE >> 16);
         UInt32 address = BitConverter.ToUInt32(attributeValue, 4) ^ STUNHeader.MAGIC_COOKIE;
         Address = new IPAddress(address);
     }
 }
Example #7
0
        public byte[] GetBytes()
        {
            byte[] buffer = new byte[RTCPHeader.HEADER_BYTES_LENGTH + SENDER_PAYLOAD_SIZE];
            Header.SetLength((ushort)(buffer.Length / 4 - 1));

            Buffer.BlockCopy(Header.GetBytes(), 0, buffer, 0, RTCPHeader.HEADER_BYTES_LENGTH);
            int payloadIndex = RTCPHeader.HEADER_BYTES_LENGTH;

            // All feedback packets require the Sender and Media SSRC's to be set.
            if (BitConverter.IsLittleEndian)
            {
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(SenderSSRC)), 0, buffer, payloadIndex, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(MediaSSRC)), 0, buffer, payloadIndex + 4, 4);
            }
            else
            {
                Buffer.BlockCopy(BitConverter.GetBytes(SenderSSRC), 0, buffer, payloadIndex, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(MediaSSRC), 0, buffer, payloadIndex + 4, 4);
            }

            switch (Header)
            {
            case var x when x.PacketType == RTCPReportTypesEnum.RTPFB && x.FeedbackMessageType == RTCPFeedbackTypesEnum.RTCP_SR_REQ:
                // PLI feedback reports do no have any additional parameters.
                break;

            case var x when x.PacketType == RTCPReportTypesEnum.RTPFB:
                if (BitConverter.IsLittleEndian)
                {
                    Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(PID)), 0, buffer, payloadIndex + 6, 2);
                    Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(BLP)), 0, buffer, payloadIndex + 8, 2);
                }
                else
                {
                    Buffer.BlockCopy(BitConverter.GetBytes(PID), 0, buffer, payloadIndex + 6, 2);
                    Buffer.BlockCopy(BitConverter.GetBytes(BLP), 0, buffer, payloadIndex + 8, 2);
                }
                break;

            case var x when x.PacketType == RTCPReportTypesEnum.PSFB && x.PayloadFeedbackMessageType == PSFBFeedbackTypesEnum.PLI:
                break;

            default:
                throw new NotImplementedException($"Serialisation for feedback report {Header.PacketType} not yet implemented.");
            }
            return(buffer);
        }
Example #8
0
        /// <summary>
        /// Creates a Luma and Chroma Table in ZigZag order using the default quantizer
        /// </summary>
        /// <param name="Q">The quality factor</param>
        /// <returns>64 luma bytes and 64 chroma</returns>
        static byte[] CreateQuantizationTables(uint type, uint Q, byte precision)
        {
            Q &= 128;

            //Factor restricted to range of 1 and 99
            int factor = (int)Math.Max(Math.Min(1, Q), 99);

            //Seed quantization value
            int q = (Q < 50 ? q = 5000 / factor : 200 - factor * 2);

            //Create 2 quantization tables from Seed quality value using the RFC quantizers
            int tableSize = defaultQuantizers.Length / 2;

            byte[] resultTables = new byte[tableSize * 2];
            for (int i = 0, j = tableSize; i < tableSize; ++i, ++j)
            {
                if (precision == 0)
                {
                    //Clamp with Min, Max
                    //Luma
                    resultTables[i] =
                        (byte)Math.Min(Math.Max((defaultQuantizers[i] * q + 50) / 100, 1), byte.MaxValue);
                    //Chroma
                    resultTables[j] =
                        (byte)Math.Min(Math.Max((defaultQuantizers[j] * q + 50) / 100, 1), byte.MaxValue);
                }
                else
                {
                    //Luma
                    BitConverter
                    .GetBytes(NetConvert.DoReverseEndian(
                                  (ushort)Math.Min(Math.Max((defaultQuantizers[i] * q + 50) / 100, 1), byte.MaxValue)))
                    .CopyTo(resultTables, i);
                    i++;

                    //Chroma
                    BitConverter
                    .GetBytes(NetConvert.DoReverseEndian(
                                  (ushort)Math.Min(Math.Max((defaultQuantizers[j] * q + 50) / 100, 1), byte.MaxValue)))
                    .CopyTo(resultTables, j);
                    j++;
                }
            }

            return(resultTables);
        }
Example #9
0
 /// <summary>
 /// Creates the initial buffer for the HEP packet and sets the vendor, chunk type ID and length fields.
 /// Note: Vendor ID could change and make endianess relevant.
 /// </summary>
 /// <param name="chunkType">The chunk type to set in the serialised chunk.</param>
 /// <param name="length">The value to set in the length field of the serialised chunk.</param>
 /// <returns>A buffer that contains the serialised chunk EXCEPT for the payload.</returns>
 private static byte[] InitBuffer(ChunkTypeEnum chunkType, ushort length)
 {
     byte[] buf = new byte[length];
     if (BitConverter.IsLittleEndian)
     {
         Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(GENERIC_VENDOR_ID)), 0, buf, 0, 2);
         Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian((ushort)chunkType)), 0, buf, 2, 2);
         Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(length)), 0, buf, 4, 2);
     }
     else
     {
         Buffer.BlockCopy(BitConverter.GetBytes(GENERIC_VENDOR_ID), 0, buf, 0, 2);
         Buffer.BlockCopy(BitConverter.GetBytes((ushort)chunkType), 0, buf, 2, 2);
         Buffer.BlockCopy(BitConverter.GetBytes(length), 0, buf, 4, 2);
     }
     return(buf);
 }
Example #10
0
        public byte[] GetBytes()
        {
            byte[] rtcpReportHeader = new byte[HEADER_BYTES_LENGTH];

            if (BitConverter.IsLittleEndian)
            {
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian((ushort)ReportType)), 0, rtcpReportHeader, 0, 2);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(Length)), 0, rtcpReportHeader, 2, 2);
            }
            else
            {
                Buffer.BlockCopy(BitConverter.GetBytes((ushort)ReportType), 0, rtcpReportHeader, 0, 2);
                Buffer.BlockCopy(BitConverter.GetBytes(Length), 0, rtcpReportHeader, 2, 2);
            }

            return(rtcpReportHeader);
        }
Example #11
0
        public byte[] GetBytes()
        {
            byte[] header = new byte[4];

            UInt32 firstWord = Convert.ToUInt32(Version * Math.Pow(2, 30) + PaddingFlag * Math.Pow(2, 29) + ReceptionReportCount * Math.Pow(2, 24) + PacketType * Math.Pow(2, 16) + Length);

            if (BitConverter.IsLittleEndian)
            {
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(firstWord)), 0, header, 0, 4);
            }
            else
            {
                Buffer.BlockCopy(BitConverter.GetBytes(firstWord), 0, header, 0, 4);
            }

            return(header);
        }
Example #12
0
        /// <summary>
        /// Create a new RTCP Report from a serialised byte array.
        /// </summary>
        /// <param name="packet">The byte array holding the serialised feedback report.</param>
        public RTCPFeedback(byte[] packet)
        {
            Header = new RTCPHeader(packet);

            if (BitConverter.IsLittleEndian)
            {
                SenderSSRC = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 4));
                MediaSSRC  = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 8));
            }
            else
            {
                SenderSSRC = BitConverter.ToUInt32(packet, 4);
                MediaSSRC  = BitConverter.ToUInt32(packet, 8);
            }

            // TODO: Depending on the report type additional parameters will need to be deserialised.
        }
Example #13
0
 public RTCPReport(byte[] packet)
 {
     if (BitConverter.IsLittleEndian)
     {
         SyncSource               = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 0));
         SampleStartTime          = new DateTime((long)NetConvert.DoReverseEndian(BitConverter.ToUInt64(packet, 4)));
         SampleEndTime            = new DateTime((long)NetConvert.DoReverseEndian(BitConverter.ToUInt64(packet, 12)));
         StartSequenceNumber      = NetConvert.DoReverseEndian(BitConverter.ToUInt16(packet, 20));
         EndSequenceNumber        = NetConvert.DoReverseEndian(BitConverter.ToUInt16(packet, 22));
         TotalPackets             = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 24));
         OutOfOrder               = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 28));
         JitterAverage            = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 32));
         JitterMaximum            = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 36));
         JitterDiscards           = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 40));
         PacketsLost              = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 44));
         Duplicates               = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 48));
         BytesReceived            = NetConvert.DoReverseEndian(BitConverter.ToUInt64(packet, 52));
         TransmissionRate         = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 60));
         Duration                 = NetConvert.DoReverseEndian(BitConverter.ToUInt64(packet, 64));
         AverageTransitTime       = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 72));
         ReportNumber             = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 76));
         LastReceivedReportNumber = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 80));
     }
     else
     {
         SyncSource               = BitConverter.ToUInt32(packet, 0);
         SampleStartTime          = new DateTime((long)BitConverter.ToUInt64(packet, 4));
         SampleEndTime            = new DateTime((long)BitConverter.ToUInt64(packet, 12));
         StartSequenceNumber      = BitConverter.ToUInt16(packet, 20);
         EndSequenceNumber        = BitConverter.ToUInt16(packet, 22);
         TotalPackets             = BitConverter.ToUInt32(packet, 24);
         OutOfOrder               = BitConverter.ToUInt32(packet, 28);
         JitterAverage            = BitConverter.ToUInt32(packet, 32);
         JitterMaximum            = BitConverter.ToUInt32(packet, 36);
         JitterDiscards           = BitConverter.ToUInt32(packet, 40);
         PacketsLost              = BitConverter.ToUInt32(packet, 44);
         Duplicates               = BitConverter.ToUInt32(packet, 48);
         BytesReceived            = BitConverter.ToUInt64(packet, 52);
         TransmissionRate         = BitConverter.ToUInt32(packet, 60);
         Duration                 = BitConverter.ToUInt64(packet, 64);
         AverageTransitTime       = BitConverter.ToUInt32(packet, 72);
         ReportNumber             = BitConverter.ToUInt32(packet, 76);
         LastReceivedReportNumber = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 80));
     }
 }
Example #14
0
        /// <summary>
        /// Extract and load the RTCPReportHeader from packet.
        /// </summary>
        /// <param name="packet"></param>
        public RTCPReportHeader(byte[] packet)
        {
            if (packet.Length < HEADER_BYTES_LENGTH)
            {
                throw new ApplicationException("The packet did not contain the minimum number of bytes for an RTCP Report Header packet.");
            }

            if (BitConverter.IsLittleEndian)
            {
                ReportType = RTCPReportTypes.GetRTCPReportTypeForId(NetConvert.DoReverseEndian(BitConverter.ToUInt16(packet, 0)));
                Length     = NetConvert.DoReverseEndian(BitConverter.ToUInt16(packet, 2));
            }
            else
            {
                ReportType = RTCPReportTypes.GetRTCPReportTypeForId(BitConverter.ToUInt16(packet, 0));
                Length     = BitConverter.ToUInt16(packet, 2);
            }
        }
Example #15
0
        public void ReverseInt32UnitTest()
        {
            //var b = BitConverter.GetBytes(-923871);
            //logger.LogDebug($"{b[0]:X} {b[1]:X} {b[2]:X} {b[3]:X}");
            //logger.LogDebug($"{b[3]:X} {b[2]:X} {b[1]:X} {b[0]:X}");
            //logger.LogDebug(BitConverter.ToInt32(new byte[] { b[3], b[2], b[1], b[0] }, 0).ToString());

            Assert.Equal(0, NetConvert.DoReverseEndian(0));
            Assert.Equal(-1, NetConvert.DoReverseEndian(-1));
            Assert.Equal(-2, NetConvert.DoReverseEndian(-16777217));
            Assert.Equal(568848895, NetConvert.DoReverseEndian(-923871));
            Assert.Equal(128, NetConvert.DoReverseEndian(Int32.MinValue));
            Assert.Equal(1, NetConvert.DoReverseEndian(16777216));
            Assert.Equal(2, NetConvert.DoReverseEndian(33554432));
            Assert.Equal(4564522, NetConvert.DoReverseEndian(715539712));
            Assert.Equal(-129, NetConvert.DoReverseEndian(Int32.MaxValue));
            Assert.Equal(0x0d0c0b0a, NetConvert.DoReverseEndian(0x0a0b0c0d));
        }
Example #16
0
        /// <summary>
        /// Gets the raw buffer for the event.
        /// </summary>
        /// <returns>A raw byte buffer for the event.</returns>
        public byte[] GetEventPayload()
        {
            byte[] payload = new byte[DTMF_PACKET_LENGTH];

            payload[0]  = EventID;
            payload[1]  = (byte)(EndOfEvent ? 0x80 : 0x00);
            payload[1] += (byte)(Volume & 0xcf);  // The Volume field uses 6 bits.

            if (BitConverter.IsLittleEndian)
            {
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(Duration)), 0, payload, 2, 2);
            }
            else
            {
                Buffer.BlockCopy(BitConverter.GetBytes(Duration), 0, payload, 2, 2);
            }

            return(payload);
        }
        public byte[] GetBytes()
        {
            int rrCount = (ReceptionReports != null) ? ReceptionReports.Count : 0;

            byte[] buffer = new byte[RTCPHeader.HEADER_BYTES_LENGTH + 4 + SENDER_PAYLOAD_SIZE +
                                     rrCount * ReceptionReportSample.PAYLOAD_SIZE];
            Header.SetLength((ushort)(buffer.Length / 4 - 1));

            Buffer.BlockCopy(Header.GetBytes(), 0, buffer, 0, RTCPHeader.HEADER_BYTES_LENGTH);
            int payloadIndex = RTCPHeader.HEADER_BYTES_LENGTH;

            if (BitConverter.IsLittleEndian)
            {
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(SSRC)), 0, buffer, payloadIndex, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(NtpTimestamp)), 0, buffer,
                                 payloadIndex + 4, 8);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(RtpTimestamp)), 0, buffer,
                                 payloadIndex + 12, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(PacketCount)), 0, buffer,
                                 payloadIndex + 16, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(OctetCount)), 0, buffer,
                                 payloadIndex + 20, 4);
            }
            else
            {
                Buffer.BlockCopy(BitConverter.GetBytes(SSRC), 0, buffer, payloadIndex, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(NtpTimestamp), 0, buffer, payloadIndex + 4, 8);
                Buffer.BlockCopy(BitConverter.GetBytes(RtpTimestamp), 0, buffer, payloadIndex + 12, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(PacketCount), 0, buffer, payloadIndex + 16, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(OctetCount), 0, buffer, payloadIndex + 20, 4);
            }

            int bufferIndex = payloadIndex + 24;

            for (int i = 0; i < rrCount; i++)
            {
                var receptionReportBytes = ReceptionReports[i].GetBytes();
                Buffer.BlockCopy(receptionReportBytes, 0, buffer, bufferIndex, ReceptionReportSample.PAYLOAD_SIZE);
                bufferIndex += ReceptionReportSample.PAYLOAD_SIZE;
            }

            return(buffer);
        }
Example #18
0
        public byte[] GetBytes()
        {
            byte[] header = new byte[Length];

            UInt16 firstWord = Convert.ToUInt16(Version * 16384 + PaddingFlag * 8192 + HeaderExtensionFlag * 4096 +
                                                CSRCCount * 256 + MarkerBit * 128 + PayloadType);

            if (BitConverter.IsLittleEndian)
            {
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(firstWord)), 0, header, 0, 2);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(SequenceNumber)), 0, header, 2, 2);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(Timestamp)), 0, header, 4, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(SyncSource)), 0, header, 8, 4);

                if (HeaderExtensionFlag == 1)
                {
                    Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(ExtensionProfile)), 0, header,
                                     12 + 4 * CSRCCount, 2);
                    Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(ExtensionLength)), 0, header,
                                     14 + 4 * CSRCCount, 2);
                }
            }
            else
            {
                Buffer.BlockCopy(BitConverter.GetBytes(firstWord), 0, header, 0, 2);
                Buffer.BlockCopy(BitConverter.GetBytes(SequenceNumber), 0, header, 2, 2);
                Buffer.BlockCopy(BitConverter.GetBytes(Timestamp), 0, header, 4, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(SyncSource), 0, header, 8, 4);

                if (HeaderExtensionFlag == 1)
                {
                    Buffer.BlockCopy(BitConverter.GetBytes(ExtensionProfile), 0, header, 12 + 4 * CSRCCount, 2);
                    Buffer.BlockCopy(BitConverter.GetBytes(ExtensionLength), 0, header, 14 + 4 * CSRCCount, 2);
                }
            }

            if (ExtensionLength > 0 && ExtensionPayload != null)
            {
                Buffer.BlockCopy(ExtensionPayload, 0, header, 16 + 4 * CSRCCount, ExtensionLength * 4);
            }

            return(header);
        }
Example #19
0
        public static STUNMessage ParseSTUNMessage(byte[] buffer, int bufferLength)
        {
            if (buffer != null && buffer.Length > 0 && buffer.Length >= bufferLength)
            {
                STUNMessage stunMessage = new STUNMessage();
                stunMessage._receivedBuffer = buffer.Take(bufferLength).ToArray();
                stunMessage.Header          = STUNHeader.ParseSTUNHeader(buffer);

                if (stunMessage.Header.MessageLength > 0)
                {
                    stunMessage.Attributes =
                        STUNAttribute.ParseMessageAttributes(buffer, STUNHeader.STUN_HEADER_LENGTH, bufferLength);
                }

                if (stunMessage.Attributes.Count > 0 &&
                    stunMessage.Attributes.Last().AttributeType == STUNAttributeTypesEnum.FingerPrint)
                {
                    // Check fingerprint.
                    var fingerprintAttribute = stunMessage.Attributes.Last();

                    var input = buffer.Take(buffer.Length - STUNAttribute.STUNATTRIBUTE_HEADER_LENGTH -
                                            FINGERPRINT_ATTRIBUTE_CRC32_LENGTH).ToArray();

                    uint   crc         = Crc32.Compute(input) ^ FINGERPRINT_XOR;
                    byte[] fingerPrint = (BitConverter.IsLittleEndian)
                        ? BitConverter.GetBytes(NetConvert.DoReverseEndian(crc))
                        : BitConverter.GetBytes(crc);

                    //logger.LogDebug($"STUNMessage supplied fingerprint attribute: {fingerprintAttribute.Value.HexStr()}.");
                    //logger.LogDebug($"STUNMessage calculated fingerprint attribute: {fingerPrint.HexStr()}.");

                    if (fingerprintAttribute.Value.HexStr() == fingerPrint.HexStr())
                    {
                        stunMessage.isFingerprintValid = true;
                    }
                }

                return(stunMessage);
            }

            return(null);
        }
Example #20
0
        /// <summary>
        /// Extract and load an RTP Event from a packet buffer.
        /// </summary>
        /// <param name="packet">The packet buffer containing the RTP Event.</param>
        public RTPEvent(byte[] packet)
        {
            if (packet.Length < DTMF_PACKET_LENGTH)
            {
                throw new ApplicationException("The packet did not contain the minimum number of bytes for an RTP Event packet.");
            }

            EventID    = packet[0];
            EndOfEvent = (packet[1] & 0x80) > 1;
            Volume     = (ushort)(packet[1] & 0xcf);

            if (BitConverter.IsLittleEndian)
            {
                Duration = NetConvert.DoReverseEndian(BitConverter.ToUInt16(packet, 2));
            }
            else
            {
                Duration = BitConverter.ToUInt16(packet, 2);
            }
        }
Example #21
0
        public virtual int ToByteBuffer(byte[] buffer, int startIndex)
        {
            if (BitConverter.IsLittleEndian)
            {
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian((ushort)AttributeType)), 0, buffer,
                                 startIndex, 2);

                if (Value != null && Value.Length > 0)
                {
                    Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(Convert.ToUInt16(Value.Length))),
                                     0, buffer, startIndex + 2, 2);
                }
                else
                {
                    buffer[startIndex + 2] = 0x00;
                    buffer[startIndex + 3] = 0x00;
                }
            }
            else
            {
                Buffer.BlockCopy(BitConverter.GetBytes((ushort)AttributeType), 0, buffer, startIndex, 2);

                if (Value != null && Value.Length > 0)
                {
                    Buffer.BlockCopy(BitConverter.GetBytes(Convert.ToUInt16(Value.Length)), 0, buffer, startIndex + 2,
                                     2);
                }
                else
                {
                    buffer[startIndex + 2] = 0x00;
                    buffer[startIndex + 3] = 0x00;
                }
            }

            if (Value != null && Value.Length > 0)
            {
                Buffer.BlockCopy(Value, 0, buffer, startIndex + 4, Value.Length);
            }

            return(STUNATTRIBUTE_HEADER_LENGTH + PaddedLength);
        }
Example #22
0
        /// <summary>
        /// Check that the message integrity attribute is correct.
        /// </summary>
        /// <param name="messageIntegrityKey">The message integrity key that was used to generate
        /// the HMAC for the original message.</param>
        /// <returns>True if the fingerprint and HMAC of the STUN message are valid. False if not.</returns>
        public bool CheckIntegrity(byte[] messageIntegrityKey)
        {
            bool isHmacValid = false;

            if (isFingerprintValid)
            {
                if (Attributes.Count > 2 && Attributes[Attributes.Count - 2].AttributeType ==
                    STUNAttributeTypesEnum.MessageIntegrity)
                {
                    var messageIntegrityAttribute = Attributes[Attributes.Count - 2];

                    int preImageLength = _receivedBuffer.Length
                                         - STUNAttribute.STUNATTRIBUTE_HEADER_LENGTH * 2
                                         - MESSAGE_INTEGRITY_ATTRIBUTE_HMAC_LENGTH
                                         - FINGERPRINT_ATTRIBUTE_CRC32_LENGTH;

                    // Need to adjust the STUN message length field for to remove the fingerprint.
                    ushort length = (ushort)(Header.MessageLength - STUNAttribute.STUNATTRIBUTE_HEADER_LENGTH -
                                             FINGERPRINT_ATTRIBUTE_CRC32_LENGTH);
                    if (BitConverter.IsLittleEndian)
                    {
                        Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(length)), 0, _receivedBuffer,
                                         2, 2);
                    }
                    else
                    {
                        Buffer.BlockCopy(BitConverter.GetBytes(length), 0, _receivedBuffer, 2, 2);
                    }

                    HMACSHA1 hmacSHA        = new HMACSHA1(messageIntegrityKey, true);
                    byte[]   calculatedHmac = hmacSHA.ComputeHash(_receivedBuffer, 0, preImageLength);

                    //logger.LogDebug($"Received Message integrity HMAC  : {messageIntegrityAttribute.Value.HexStr()}.");
                    //logger.LogDebug($"Calculated Message integrity HMAC: {calculatedHmac.HexStr()}.");

                    isHmacValid = messageIntegrityAttribute.Value.HexStr() == calculatedHmac.HexStr();
                }
            }

            return(isHmacValid);
        }
Example #23
0
        /// <summary>
        /// Extract and load the RTCP header from an RTCP packet.
        /// </summary>
        /// <param name="packet"></param>
        public RTCPHeader(byte[] packet)
        {
            if (packet.Length < HEADER_BYTES_LENGTH)
            {
                throw new ApplicationException(
                          "The packet did not contain the minimum number of bytes for an RTCP header packet.");
            }

            UInt16 firstWord = BitConverter.ToUInt16(packet, 0);

            if (BitConverter.IsLittleEndian)
            {
                firstWord = NetConvert.DoReverseEndian(firstWord);
                Length    = NetConvert.DoReverseEndian(BitConverter.ToUInt16(packet, 2));
            }
            else
            {
                Length = BitConverter.ToUInt16(packet, 2);
            }

            Version     = Convert.ToInt32(firstWord >> 14);
            PaddingFlag = Convert.ToInt32((firstWord >> 13) & 0x1);
            PacketType  = (RTCPReportTypesEnum)(firstWord & 0x00ff);

            if (IsFeedbackReport())
            {
                if (PacketType == RTCPReportTypesEnum.RTPFB)
                {
                    FeedbackMessageType = (RTCPFeedbackTypesEnum)((firstWord >> 8) & 0x1f);
                }
                else
                {
                    PayloadFeedbackMessageType = (PSFBFeedbackTypesEnum)((firstWord >> 8) & 0x1f);
                }
            }
            else
            {
                ReceptionReportCount = Convert.ToInt32((firstWord >> 8) & 0x1f);
            }
        }
Example #24
0
        public override int ToByteBuffer(byte[] buffer, int startIndex)
        {
            if (BitConverter.IsLittleEndian)
            {
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian((UInt16)base.AttributeType)), 0,
                                 buffer, startIndex, 2);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(ADDRESS_ATTRIBUTE_LENGTH)), 0, buffer,
                                 startIndex + 2, 2);
            }
            else
            {
                Buffer.BlockCopy(BitConverter.GetBytes((UInt16)base.AttributeType), 0, buffer, startIndex, 2);
                Buffer.BlockCopy(BitConverter.GetBytes(ADDRESS_ATTRIBUTE_LENGTH), 0, buffer, startIndex + 2, 2);
            }

            buffer[startIndex + 4] = 0x00;
            buffer[startIndex + 5] = (byte)Family;

            if (BitConverter.IsLittleEndian)
            {
                UInt16 xorPort    = Convert.ToUInt16(Convert.ToUInt16(Port) ^ (STUNHeader.MAGIC_COOKIE >> 16));
                UInt32 xorAddress = NetConvert.DoReverseEndian(BitConverter.ToUInt32(Address.GetAddressBytes(), 0)) ^
                                    STUNHeader.MAGIC_COOKIE;
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(xorPort)), 0, buffer, startIndex + 6,
                                 2);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(xorAddress)), 0, buffer,
                                 startIndex + 8, 4);
            }
            else
            {
                UInt16 xorPort    = Convert.ToUInt16(Convert.ToUInt16(Port) ^ (STUNHeader.MAGIC_COOKIE >> 16));
                UInt32 xorAddress = BitConverter.ToUInt32(Address.GetAddressBytes(), 0) ^ STUNHeader.MAGIC_COOKIE;
                Buffer.BlockCopy(BitConverter.GetBytes(xorPort), 0, buffer, startIndex + 6, 2);
                Buffer.BlockCopy(BitConverter.GetBytes(xorAddress), 0, buffer, startIndex + 8, 4);
            }

            return(STUNAttribute.STUNATTRIBUTE_HEADER_LENGTH + ADDRESS_ATTRIBUTE_LENGTH);
        }
        public byte[] GetBytes()
        {
            byte[] payload = new byte[24];

            if (BitConverter.IsLittleEndian)
            {
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(SSRC)), 0, payload, 0, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(NtpTimestamp)), 0, payload, 4, 8);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(RtpTimestamp)), 0, payload, 12, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(PacketCount)), 0, payload, 16, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(OctetCount)), 0, payload, 20, 4);
            }
            else
            {
                Buffer.BlockCopy(BitConverter.GetBytes(SSRC), 0, payload, 0, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(NtpTimestamp), 0, payload, 4, 8);
                Buffer.BlockCopy(BitConverter.GetBytes(RtpTimestamp), 0, payload, 12, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(PacketCount), 0, payload, 16, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(OctetCount), 0, payload, 20, 4);
            }

            return(payload);
        }
Example #26
0
 public ReceptionReportSample(byte[] packet)
 {
     if (BitConverter.IsLittleEndian)
     {
         SSRC         = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 0));
         FractionLost = packet[4];
         PacketsLost  = NetConvert.DoReverseEndian(BitConverter.ToInt32(new byte[] { 0x00, packet[5], packet[6], packet[7] }, 0));
         ExtendedHighestSequenceNumber = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 8));
         Jitter = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 12));
         LastSenderReportTimestamp  = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 16));
         DelaySinceLastSenderReport = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 20));
     }
     else
     {
         SSRC         = BitConverter.ToUInt32(packet, 4);
         FractionLost = packet[4];
         PacketsLost  = BitConverter.ToInt32(new byte[] { 0x00, packet[5], packet[6], packet[7] }, 0);
         ExtendedHighestSequenceNumber = BitConverter.ToUInt32(packet, 8);
         Jitter = BitConverter.ToUInt32(packet, 12);
         LastSenderReportTimestamp = BitConverter.ToUInt32(packet, 16);
         LastSenderReportTimestamp = BitConverter.ToUInt32(packet, 20);
     }
 }
        /// <summary>
        /// Create a new RTCP Sender Report from a serialised byte array.
        /// </summary>
        /// <param name="packet">The byte array holding the serialised sender report.</param>
        public RTCPSenderReport(byte[] packet)
        {
            if (packet.Length < MIN_PACKET_SIZE)
            {
                throw new ApplicationException(
                          "The packet did not contain the minimum number of bytes for an RTCPSenderReport packet.");
            }

            Header           = new RTCPHeader(packet);
            ReceptionReports = new List <ReceptionReportSample>();

            if (BitConverter.IsLittleEndian)
            {
                SSRC         = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 4));
                NtpTimestamp = NetConvert.DoReverseEndian(BitConverter.ToUInt64(packet, 8));
                RtpTimestamp = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 16));
                PacketCount  = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 20));
                OctetCount   = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 24));
            }
            else
            {
                SSRC         = BitConverter.ToUInt32(packet, 4);
                NtpTimestamp = BitConverter.ToUInt64(packet, 8);
                RtpTimestamp = BitConverter.ToUInt32(packet, 16);
                PacketCount  = BitConverter.ToUInt32(packet, 20);
                OctetCount   = BitConverter.ToUInt32(packet, 24);
            }

            int rrIndex = 28;

            for (int i = 0; i < Header.ReceptionReportCount; i++)
            {
                var rr = new ReceptionReportSample(packet.Skip(rrIndex + i * ReceptionReportSample.PAYLOAD_SIZE)
                                                   .ToArray());
                ReceptionReports.Add(rr);
            }
        }
Example #28
0
        public void ReverseUInt32SampleTest()
        {
            logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name);
            logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name);

            uint testNum = 123124;

            byte[] testNumBytes = BitConverter.GetBytes(testNum);

            uint reversed = NetConvert.DoReverseEndian(testNum);

            byte[] reversedNumBytes = BitConverter.GetBytes(reversed);

            uint unReversed = NetConvert.DoReverseEndian(reversed);

            int testNumByteCount = 0;

            foreach (byte testNumByte in testNumBytes)
            {
                logger.LogDebug("original " + testNumByteCount + ": " + testNumByte.ToString("x"));
                testNumByteCount++;
            }

            int reverseNumByteCount = 0;

            foreach (byte reverseNumByte in reversedNumBytes)
            {
                logger.LogDebug("reversed " + reverseNumByteCount + ": " + reverseNumByte.ToString("x"));
                reverseNumByteCount++;
            }

            logger.LogDebug("Original=" + testNum);
            logger.LogDebug("Reversed=" + reversed);
            logger.LogDebug("Unreversed=" + unReversed);

            Assert.True(testNum == unReversed, "Reverse endian operation for uint32 did not work successfully.");
        }
Example #29
0
        /// <summary>
        /// Gets the raw bytes for the SDES item. This packet is ready to be included
        /// directly in an RTCP packet.
        /// </summary>
        /// <returns>A byte array containing the serialised SDES item.</returns>
        public byte[] GetBytes()
        {
            byte[] cnameBytes = Encoding.UTF8.GetBytes(CNAME);
            byte[] buffer     = new byte[RTCPHeader.HEADER_BYTES_LENGTH + GetPaddedLength(cnameBytes.Length)]; // Array automatically initialised with 0x00 values.
            Header.SetLength((ushort)(buffer.Length / 4 - 1));

            Buffer.BlockCopy(Header.GetBytes(), 0, buffer, 0, RTCPHeader.HEADER_BYTES_LENGTH);
            int payloadIndex = RTCPHeader.HEADER_BYTES_LENGTH;

            if (BitConverter.IsLittleEndian)
            {
                Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(SSRC)), 0, buffer, payloadIndex, 4);
            }
            else
            {
                Buffer.BlockCopy(BitConverter.GetBytes(SSRC), 0, buffer, payloadIndex, 4);
            }

            buffer[payloadIndex + 4] = CNAME_ID;
            buffer[payloadIndex + 5] = (byte)cnameBytes.Length;
            Buffer.BlockCopy(cnameBytes, 0, buffer, payloadIndex + 6, cnameBytes.Length);

            return(buffer);
        }
Example #30
0
        public RTCPPacket(byte[] packet)
        {
            Header = new RTCPHeader(packet);

            if (BitConverter.IsLittleEndian)
            {
                SenderSyncSource  = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 4));
                NTPTimestamp      = NetConvert.DoReverseEndian(BitConverter.ToUInt64(packet, 8));
                RTPTimestamp      = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 16));
                SenderPacketCount = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 20));
                SenderOctetCount  = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 24));
            }
            else
            {
                SenderSyncSource  = BitConverter.ToUInt32(packet, 4);
                NTPTimestamp      = BitConverter.ToUInt64(packet, 8);
                RTPTimestamp      = BitConverter.ToUInt32(packet, 16);
                SenderPacketCount = BitConverter.ToUInt32(packet, 20);
                SenderOctetCount  = BitConverter.ToUInt32(packet, 24);
            }

            Reports = new byte[packet.Length - RTCPHeader.HEADER_BYTES_LENGTH - SENDERINFO_BYTES_LENGTH];
            Buffer.BlockCopy(packet, RTCPHeader.HEADER_BYTES_LENGTH + SENDERINFO_BYTES_LENGTH, Reports, 0, Reports.Length);
        }