Esempio n. 1
0
        public DataBlock(byte[] data, DataInformationField dataInformationField, List <DataInformationExtensionField> dataInformationFieldExtensions, PrimaryValueInformationField valueInformationField, List <ValueInformationExtensionField> valueInformationFieldExtensions)
        {
            _data = data ?? throw new ArgumentNullException(nameof(data));
            DataInformationField            = dataInformationField ?? throw new ArgumentNullException(nameof(dataInformationField));
            DataInformationFieldExtensions  = dataInformationFieldExtensions ?? throw new ArgumentNullException(nameof(dataInformationFieldExtensions));
            ValueInformationField           = valueInformationField ?? throw new ArgumentNullException(nameof(valueInformationField));
            ValueInformationFieldExtensions = valueInformationFieldExtensions ?? throw new ArgumentNullException(nameof(valueInformationFieldExtensions));

            Parse();
        }
Esempio n. 2
0
        public static DataInformationField Parse(int dif)
        {
            if (dif == 0x0f || dif == 0x1f)
            {
                return(null);
            }
            var result = new DataInformationField
            {
                HasExtendedBlock  = (dif & 0x80) == 0x80,
                StorageNumberLsb  = (dif & 0x40) << 6,
                    FunctionValue = (FunctionValueType)((dif & 30) >> 4),
                    DataType      = (DataType)(dif & 0x0f)
            };


            return(result);
        }
Esempio n. 3
0
        /// <summary>
        /// parse the records.
        /// </summary>
        /// <param name="header">the mbus header. Useful for manufacturer specific parsing.</param>
        /// <param name="payload">the payload.</param>
        /// <param name="decryptionKey">the decryption key.</param>
        /// <param name="initializationVector">the initialization vector.</param>
        /// <returns>a IList<MbusRecord> containing the parse records.</returns>
        private IList <VariableDataRecord> ParseRecords(MBusHeader header, IList <byte> payload, byte[] decryptionKey)
        {
            List <byte> payloadBody;

            // Todo find out whats wrong with this.
            if (header.ExtendedLinkLayer != null)
            {
                payloadBody = payload.Skip(header.PayloadStartsAtIndex - 2).ToList();
            }
            else
            {
                payloadBody = payload.Skip(header.PayloadStartsAtIndex).ToList();
            }


            if (decryptionKey != null)
            {
                payloadBody = DecryptPayload(header, payloadBody, decryptionKey);
            }

            if (payloadBody == null)
            {
                return(null);
            }


            if (header.ExtendedLinkLayer != null)
            {
                var frameType = ControlInformationLookup.Find(payloadBody.First()).frameType;


                if (frameType != FrameType.Full)
                {
                    return(null);
                }

                payloadBody = payloadBody.Skip(1).ToList();
            }

            while (payloadBody.Last() == 0x2F)
            {
                payloadBody.RemoveAt(payloadBody.Count() - 1);
            }

            var list = new List <VariableDataRecord>();

            // MBus has a maximum length of 255.
            byte indexer = 0;

            while (indexer < payloadBody.Count)
            {
                var difFieldByte = payloadBody[indexer++];

                // TODO Handle special case stuff
                if (difFieldByte == 0x1F || difFieldByte == 0x0F)
                {
                    break;
                }

                var dataInformationField           = new DataInformationField(difFieldByte);
                var dataInformationFieldExtensions = new List <DataInformationExtensionField>();

                var difesAvailable = dataInformationField.HasExtensionBit;
                while (difesAvailable)
                {
                    var extension = new DataInformationExtensionField(payloadBody[indexer++]);
                    dataInformationFieldExtensions.Add(extension);

                    difesAvailable = extension.HasExtensionBit;
                }

                var valueInformationField           = new PrimaryValueInformationField(payloadBody[indexer++], dataInformationField.DataField);
                var valueInformationFieldExtensions = new List <ValueInformationExtensionField>();

                var vifesAvailable = valueInformationField.HasExtensionBit;
                while (vifesAvailable)
                {
                    ValueInformationExtensionField?extension = null;
                    if (!valueInformationFieldExtensions.Any())
                    {
                        switch (valueInformationField.Type)
                        {
                        case PrimaryValueInformation.FBValueInformationExtension:
                            extension = new FBValueInformationExtensionField(payloadBody[indexer++]);
                            break;

                        case PrimaryValueInformation.FDValueInformationExtension:
                            extension = new FDValueInformationExtensionField(payloadBody[indexer++]);
                            break;

                        case PrimaryValueInformation.ManufacturerSpecific:
                            switch (header.ManufacturerName.ToLowerInvariant())
                            {
                            case "kam":
                                extension = new KamstrupValueInformationExtensionField(payloadBody[indexer++]);
                                break;
                            }

                            break;

                        default:
                            extension = new UnknownValueInformationExtensionField(payloadBody[indexer++]);
                            break;
                        }
                    }
                    else
                    {
                        extension = new OrthogonalValueInformationExtensionField(payloadBody[indexer++]);
                    }

                    valueInformationFieldExtensions.Add(extension);

                    vifesAvailable = extension.HasExtensionBit;
                }

                // is LVAR, the length of the data is in the first byte of the "real" data.
                if (dataInformationField.DataLength == null && dataInformationField.DataField == DataField.VariableLength)
                {
                    dataInformationField.DataLength = payloadBody[indexer++];
                }

                var dataBlock = new DataBlock(payloadBody.Skip(indexer).Take(dataInformationField.DataLength.Value).ToArray(), dataInformationField, dataInformationFieldExtensions, valueInformationField, valueInformationFieldExtensions);
                indexer = (byte)(indexer + dataInformationField.DataLength.Value);

                list.Add(new VariableDataRecord(dataBlock));
            }


            return(list);
        }