using System; using System.Collections.Generic; using System.Text; using Xylem.Common.Logic.ProductionOrderCore.OrderData; using Xylem.Common.Utils.Crc16Ccitt; namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile { /// /// File for metrology look up table /// public class MeterLutFile { /// /// Meter response on invalid LUT file e.g. 0x8000FFFF /// public const String StrLutFileInvalidCrc = "0x8000"; /// /// Disk number and name of meter LUT file /// public const String StrLutMeterFileName = "1\\mettbl"; /// /// Disk number and name of meter LUT file /// public const String StrLutBackupMeterFileName = "1\\mettbl_b"; // identifier for Genesis lookup table public const String StrLutMeterFileId = "GEN_LUT\0"; public const Int32 IndexLutFileId = 0; public const Int32 LengthLutFileId = 8; // data length, calculated from version field to the end of the data section public const Int32 IndexDataLength = 8; public const Int32 LengthDataLength = 4; // CCITT-CRC-16 , calculated from version field to the end of the data section public const Int32 IndexCrc = 12; public const Int32 LengthCrc = 2; // version public const Int32 IndexVersion = 14; public const Int32 LengthVersion = 2; // meter size as enumeration public const Int32 IndexMeterSize = 16; // header size of file public const Int32 LutFileHeaderLength = LengthLutFileId + LengthDataLength + LengthCrc + LengthVersion; // data size of file is variable found 730, 5840, 13140, so it has to be read using the header // public const Int32 LutFileDataLength = 730; // LUT file entire file size public Int32 SizeLutFile; /// /// File name of the file on PC /// public String LutPcFileName; /// /// Standard Ctor without name /// public MeterLutFile() { } /// /// Ctor for meter lut file /// /// public MeterLutFile(String lutPcFileName) { LutPcFileName = lutPcFileName; } /// /// File ID for LUT file /// public String StrLutFileId; /// /// Data length /// private UInt32 _dataLength; public UInt32 DataLength { get => _dataLength; set { SizeLutFile = (Int32)value + LutFileHeaderLength; _dataLength = value; } } /// /// Version of LUT file /// public UInt16 Version; /// /// Check of LUT file for verification and register write, read from file /// public UInt16 FileCrc; /// /// Calculated during file processing for verification /// public UInt16 CalculatedCrc; /// /// FileCRC and calculated CRC are different /// public Boolean CrcError; /// /// Validation of LUT file /// public Boolean IsValid; /// /// Binary file content /// public List BinData = new List(); /// /// Meter size /// public MeterSize MeterSize; /// /// ATTENTION: The file size is dynamic! /// Verifies the LUT format based on its contents /// /// true if valid /// /// - Initial. /// /// /// - Removed constant size, instead using header to calculate the size of the file. /// public Boolean ValidateLutFormat() { IsValid = false; if (BinData == null || BinData.Count < LutFileHeaderLength) return false; // extract the identifier and check, if this is a LUT file StrLutFileId = Encoding.UTF8.GetString(BinData.ToArray(), MeterLutFile.IndexLutFileId, MeterLutFile.IndexDataLength); if (StrLutFileId != MeterLutFile.StrLutMeterFileId) return false; MeterSize = (MeterSize)BinData[MeterLutFile.IndexMeterSize]; FileCrc = (UInt16)(BinData[MeterLutFile.IndexCrc] + (BinData[MeterLutFile.IndexCrc + 1] << 8)); Version = (UInt16)(BinData[MeterLutFile.IndexVersion] + (BinData[MeterLutFile.IndexVersion + 1] << 8)); DataLength = (UInt32)(BinData[MeterLutFile.IndexDataLength] + (BinData[MeterLutFile.IndexDataLength + 1] << 8) + (BinData[MeterLutFile.IndexDataLength + 2] << 16) + (BinData[MeterLutFile.IndexDataLength + 3] << 24)); // calculate CRC and compare this with the file CRC var entireFile = new List(); entireFile.AddRange(BinData); var payload = new List(); payload.AddRange(entireFile.GetRange(MeterLutFile.IndexVersion, (Int32)DataLength + MeterLutFile.LengthVersion)); CalculatedCrc = Crc16Ccitt.CalculateMsb1021(payload.ToArray()); if (CalculatedCrc != FileCrc) { CrcError = true; return false; } CrcError = false; IsValid = true; return true; } } }