Exemplo n.º 1
0
        /// <summary>
        /// Factory method parsing <see cref="BaseBandHeader"/>.
        /// </summary>
        /// <param name="reader"><see cref="PDUStreamReader"/> for stream from which the <see cref="BaseBandHeader"/>
        /// should be parsed.</param>
        /// <exception cref="InvalidPacketFormatException">If DFL (Data Field Length) field is not in range [0,58112].</exception>
        /// <returns>Parsed <see cref="BaseBandHeader"/> object.</returns>
        public static BaseBandHeader Parse(PDUStreamReader reader)
        {
            // Byte 0, MATYPE-1
            var matype1 = Matype1.Parse(reader.ReadByte());

            // Byte 1, MATYPE-2
            var matype2 = reader.ReadByte();

            // Byte 2-3, UPL
            var userPacketLenght = reader.ReadUInt16();

            // Byte 4-5, DFL
            var dataFieldLength = reader.ReadUInt16();

            // http://www.etsi.org/deliver/etsi_en/302300_302399/302307/01.01.02_60/en_302307v010102p.pdf#page=18
            if (dataFieldLength > 58112)
            {
                throw new InvalidPacketFormatException(
                          $"DFL (Data Field Length) field has be in range [0,58112]. {dataFieldLength} > 58112");
            }

            // Byte 6, SYNC
            var sync = reader.ReadByte();

            // Byte 7-8, SYNCD
            var syncD = reader.ReadUInt16();

            // Byte 9, CRC-8
            var crc8 = reader.ReadByte();

            // NOTE: DVB-S2 base band frame, base band header, CRC-8 is not validated.

            return(new BaseBandHeader(matype1, matype2, userPacketLenght, dataFieldLength, sync, syncD, crc8));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Factory method parsing <see cref="GseHeader"/>.
        /// </summary>
        /// <param name="reader"><see cref="PDUStreamReader"/> for stream from which the <see cref="GseHeader"/>
        /// should be parsed.</param>
        /// <exception cref="InvalidPacketFormatException">If read data does not correspond to valid format.</exception>
        /// <returns>Parsed <see cref="GseHeader"/> object.</returns>
        /// <remarks>
        /// For complete syntax of GSE Packet structure, see Table 2 in
        /// <a href="http://www.etsi.org/deliver/etsi_ts/102600_102699/10260601/01.02.01_60/ts_10260601v010201p.pdf#page=13">
        /// ETSI TS 102 606-1 V1.2.1.</a>
        /// </remarks>
        public static GseHeader Parse(PDUStreamReader reader)
        {
            var b = reader.ReadByte();

            // Byte 0-1, Fixed Header Fields
            // Bit 15: S
            var startIndicator = (b & 0b1000_0000) == 0b1000_0000;
            // Bit 14: E
            var endIndicator = (b & 0b0100_0000) == 0b0100_0000;
            // Bit 13-12: LT
            // LabelType enum has 4 values, therefore we use Enum.Parse instead of Enum.TryParse.
            var labelTypeIndicator = (LabelType)Enum.Parse(typeof(LabelType), ((b & 0b0011_0000) >> 4).ToString());

            // possibly null values which might not be present in packet
            ushort?gseLength = null;
            ushort?bytesAfterGseLengthField = null;
            byte?  fragmentID   = null;
            ushort?totalLength  = null;
            ushort?protocolType = null;

            byte[] label = null;

            long?gseLengthFieldStreamPosition = null;

            // Bit 11-0
            if (!startIndicator && !endIndicator && labelTypeIndicator == LabelType.Byte6)
            {
                // 4 padding bits
                if ((b & 0b0000_1111) != 0b0000_0000)
                {
                    throw new InvalidPacketFormatException($"Expected 4 zero-padding bits.");
                }

                // N1 Padding bytes (N1 is the number of bytes until the end of the Base-Band frame.)
                while (!reader.EndOfPDU)
                {
                    if (reader.ReadByte() != 0)
                    {
                        throw new InvalidPacketFormatException(
                                  $"Expected zero-padding bits until the end of the Base-Band frame.");
                    }
                }
            }
            else
            {
                // 12 bits
                byte[] tmpMaskedBytes =
                {
                    reader.ReadByte(),
                    (byte)(b & 0b0000_1111)
                }; // BigEndian
                gseLength = BitConverter.ToUInt16(tmpMaskedBytes, 0);
                gseLengthFieldStreamPosition = reader.PDUStreamBasedProvider.Position;

                if (!startIndicator || !endIndicator)
                {
                    fragmentID = reader.ReadByte();
                }

                if (startIndicator && !endIndicator)
                {
                    totalLength = reader.ReadUInt16();
                }

                if (startIndicator)
                {
                    protocolType = reader.ReadUInt16();
                    if (labelTypeIndicator == LabelType.Byte6)
                    {
                        label = new byte[6];
                        if (reader.Read(label, 0, 6) != 6)
                        {
                            throw new InvalidPacketFormatException("Reader could not read 6 bytes.");
                        }
                    }
                    else if (labelTypeIndicator == LabelType.Byte3)
                    {
                        label = new byte[3];
                        if (reader.Read(label, 0, 3) != 3)
                        {
                            throw new InvalidPacketFormatException("Reader could not read 3 bytes.");
                        }
                    }
                }
            }