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;
}
}
}