public STUNAttribute(STUNAttributeTypesEnum attributeType, ushort value) { AttributeType = attributeType; if (BitConverter.IsLittleEndian) { Value = BitConverter.GetBytes(NetConvert.DoReverseEndian(value)); } else { Value = BitConverter.GetBytes(value); } }
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] }); }
/// <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); }
/// <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) { } }
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); } }
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); }
/// <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); }
/// <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); }
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); }
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); }
/// <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. }
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)); } }
/// <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); } }
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)); }
/// <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); }
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); }
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); }
/// <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); } }
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); }
/// <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); }
/// <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); } }
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); }
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); } }
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."); }
/// <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); }
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); }