/// <summary> /// Constructs a new GoodbyeReport from the given values. /// </summary> /// <param name="version">The version of the report</param> /// <param name="padding"></param> /// <param name="ssrc">The id of the senders of the report</param> /// <param name="sourcesLeaving">The SourceList which describes the sources who are leaving</param> /// <param name="reasonForLeaving">An optional reason for leaving(only the first 255 octets will be used)</param> internal GoodbyeReport(int version, int padding, int ssrc, Media.RFC3550.SourceList sourcesLeaving, byte[] reasonForLeaving) : this(version, padding, ssrc, sourcesLeaving.Count + 1, //BlockCount, + 1 because the ssrc is present. 0, // 0 is extensionSize which is assigned by the size of reasonForLeaving in the constructor via ref. sourcesLeaving.Count *RFC3550.SourceList.ItemSize, //bytesInSourceList reasonForLeaving) { sourcesLeaving.TryCopyTo(m_OwnedOctets, Payload.Offset); }
/// <summary> /// Constructs a new GoodbyeReport from the given values. /// </summary> /// <param name="version">The version of the report</param> /// <param name="padding"></param> /// <param name="ssrc">The id of the senders of the report</param> /// <param name="sourcesLeaving">The SourceList which describes the sources who are leaving</param> /// <param name="reasonForLeaving">An optional reason for leaving(only the first 255 octets will be used)</param> public GoodbyeReport(int version, int padding, int ssrc, Media.RFC3550.SourceList sourcesLeaving, byte[] reasonForLeaving) : base(version, PayloadType, padding, ssrc, sourcesLeaving != null ? sourcesLeaving.Count : 0, //BlockCount Media.RFC3550.SourceList.ItemSize, //Size in bytes of each block Media.Common.Extensions.Array.ArrayExtensions.IsNullOrEmpty(reasonForLeaving) ? 0 : 1 + reasonForLeaving.Length) //Extension size in bytes { //The working offset in the payload int offset = Payload.Offset; //Copy the source list (IMHO it should be before the reason...) if (sourcesLeaving != null) { sourcesLeaving.TryCopyTo(Payload.Array, offset); offset += sourcesLeaving.Size; } #region Babble /* If I won't have a participant list then I sure as shit won't make thing as they shouldn't be here just for [Wireshark, et al] * 6.6 BYE: Goodbye RTCP Packet * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |V=2|P| SC | PT=BYE=203 | length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | SSRC/CSRC | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | : ... : (THIS IS WHERE THE SOURCE LIST GOES FYI) +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | (opt) | length | reason for leaving ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | * When SC = 0 the packet is useless. * When SC >= 1 the SourceList appears BEFORE the (opt) Length, The id there may be different from SSRC/CSRC * Length is optional and a 0 value should not HAVE to be present as including a 0 value forces you to inlcude 3 more 0's to octet align the payload */ #endregion //If a reason was given there will be extension data if (HasExtensionData) { int extensionLength = Media.Common.Extensions.Array.ArrayExtensions.IsNullOrEmpty(reasonForLeaving) ? 0 : reasonForLeaving.Length; if (extensionLength > 0) { //Ensure it will fit if (extensionLength > byte.MaxValue) { throw new InvalidOperationException("Only 255 octets can occupy the ReasonForLeaving in a GoodbyeReport."); } //The length before the string Payload.Array[offset++] = (byte)extensionLength; //Copy it to the payload reasonForLeaving.CopyTo(Payload.Array, offset); } } }