/// <summary> /// Throws an <see cref="ArgumentException"/> if the given <see cref="RtcpReport"/> is null or disposed or does not have the same <see cref="System.Type"/> which is expected as the <see cref="PayloadType"/> implemented. /// </summary> /// <param name="report">The <see cref="RtcpReport"/> to verify</param> internal static void VerifyPayloadType(this RtcpReport report) { if (RtcpPacket.GetImplementationForPayloadType(report.PayloadType) != report.GetType()) { throw new ArgumentException("RtcpReport Implementation does not match type of report."); } }
public bool Equals(RtcpPacket other) { return(other.Length.Equals(Length) && other.Payload.Equals(Payload) //SequenceEqual... && other.GetHashCode().Equals(GetHashCode())); }
public ReceiversReport(RtcpPacket reference, bool shouldDispose = true) : base(reference.Header, reference.Payload, shouldDispose) { if (Header.PayloadType != PayloadType) { throw new ArgumentException("Header.PayloadType is not equal to the expected type of 201.", "reference"); } }
/// <summary> /// Constructs a GoodbyeReport instance from an existing RtcpPacket reference. /// Throws a ArgumentNullException if reference is null. /// Throws an ArgumentException if the <see cref="RtcpHeader.PayloadType"/> is not GoodbyeReport (203) /// </summary> /// <param name="reference">The packet containing the GoodbyeReport</param> public GoodbyeReport(RtcpPacket reference, bool shouldDispose = true) : base(reference.Header, reference.Payload, shouldDispose) { if (Header.PayloadType != PayloadType) { throw new ArgumentException("Header.PayloadType is not equal to the expected type of 203.", "reference"); } //RtcpReportExtensions.VerifyPayloadType(this); }
/// <summary> /// Parses all RtcpPackets contained in the array using the given paramters. /// </summary> /// <param name="array">The array to parse packets from.</param> /// <param name="offset">The index to start parsing</param> /// <param name="count">The amount of bytes to use in parsing</param> /// <param name="version">The optional <see cref="RtcpPacket.Version"/>version of the packets</param> /// <param name="payloadType">The optional <see cref="RtcpPacket.PayloadType"/> of all packets</param> /// <param name="ssrc">The optional <see cref="RtcpPacket.SynchronizationSourceIdentifier"/> of all packets</param> /// <returns>A pointer to each packet found</returns> public static IEnumerable <RtcpPacket> GetPackets(byte[] array, int offset, int count, int version = 2, //Todo, should possibly be Enumerable int?payloadType = null, //Todo, should be Enumerable int?ssrc = null, //Todo, should be Enumerable bool shouldDispose = true) { //array.GetLowerBound(0) for VB, UpperBound(0) is then the index of the last element int lowerBound = 0, upperBound = array.Length; if (offset < lowerBound || offset > upperBound) { throw new ArgumentOutOfRangeException("index", "Must refer to an accessible position in the given array"); } if (count <= lowerBound) { yield break; } if (count > upperBound) { throw new ArgumentOutOfRangeException("count", "Must refer to an accessible position in the given array"); } //Would overflow the array if (count + offset > upperBound) { throw new ArgumentOutOfRangeException("index", "Count must refer to an accessible position in the given array when deleniated by index"); } int remains = count; //While a 32 bit value remains to be read in the vector while (remains >= RtcpHeader.Length) { //Get the header of the packet to verify if it is wanted or not using (var header = new RtcpHeader(new MemorySegment(array, offset, remains, shouldDispose), shouldDispose)) { //Determine how long the header was int headerSize = header.Size; //Determine the amount of bytes in the packet NOT INCLUDING the RtcpHeader (Which may be 0 or 65535) //16384 is the maximum value which should occupy the LengthInWordsMinusOne in a single IP RTCP packet //Values over this such as 65535 will be truncated to 0 when added with 1 when the result type is not bound to ushort //When LengthInWordsMinusOne == 0 this means there should only be the header, 0 + 1 = 1 * 4 = 4 int lengthInBytes = headerSize > remains ? 0 : Binary.MachineWordsToBytes((ushort)(header.LengthInWordsMinusOne + 1)); //Create a packet using the existing header and the bytes left in the packet using (RtcpPacket newPacket = new RtcpPacket(header, lengthInBytes == 0 ? MemorySegment.Empty : new MemorySegment(array, offset + headerSize, Binary.Clamp(lengthInBytes - headerSize, 0, remains - headerSize)), shouldDispose)) { lengthInBytes = headerSize + newPacket.Payload.Count; remains -= lengthInBytes; offset += lengthInBytes; //Check for the optional parameters before returning the packet if (payloadType.HasValue && payloadType.Value != header.PayloadType || // Check for the given payloadType if provided ssrc.HasValue && ssrc.Value != header.SendersSynchronizationSourceIdentifier) //Check for the given ssrc if provided { //Skip the packet continue; } //Yield the packet, disposed afterwards yield return(newPacket); } } } //Done parsing yield break; }