184 lines
6.1 KiB
C#
184 lines
6.1 KiB
C#
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
|
|
{
|
|
/// <summary>
|
|
/// File for metrology look up table
|
|
/// </summary>
|
|
public class MeterLutFile
|
|
{
|
|
/// <summary>
|
|
/// Meter response on invalid LUT file e.g. 0x8000FFFF
|
|
/// </summary>
|
|
public const String StrLutFileInvalidCrc = "0x8000";
|
|
|
|
/// <summary>
|
|
/// Disk number and name of meter LUT file
|
|
/// </summary>
|
|
public const String StrLutMeterFileName = "1\\mettbl";
|
|
|
|
/// <summary>
|
|
/// Disk number and name of meter LUT file
|
|
/// </summary>
|
|
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;
|
|
|
|
/// <summary>
|
|
/// File name of the file on PC
|
|
/// </summary>
|
|
public String LutPcFileName;
|
|
|
|
/// <summary>
|
|
/// Standard Ctor without name
|
|
/// </summary>
|
|
public MeterLutFile()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ctor for meter lut file
|
|
/// </summary>
|
|
/// <param name="lutPcFileName"></param>
|
|
public MeterLutFile(String lutPcFileName)
|
|
{
|
|
LutPcFileName = lutPcFileName;
|
|
}
|
|
|
|
/// <summary>
|
|
/// File ID for LUT file
|
|
/// </summary>
|
|
public String StrLutFileId;
|
|
|
|
/// <summary>
|
|
/// Data length
|
|
/// </summary>
|
|
private UInt32 _dataLength;
|
|
public UInt32 DataLength
|
|
{
|
|
get => _dataLength;
|
|
set
|
|
{
|
|
SizeLutFile = (Int32)value + LutFileHeaderLength;
|
|
_dataLength = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Version of LUT file
|
|
/// </summary>
|
|
public UInt16 Version;
|
|
|
|
/// <summary>
|
|
/// Check of LUT file for verification and register write, read from file
|
|
/// </summary>
|
|
public UInt16 FileCrc;
|
|
|
|
/// <summary>
|
|
/// Calculated during file processing for verification
|
|
/// </summary>
|
|
public UInt16 CalculatedCrc;
|
|
|
|
/// <summary>
|
|
/// FileCRC and calculated CRC are different
|
|
/// </summary>
|
|
public Boolean CrcError;
|
|
|
|
/// <summary>
|
|
/// Validation of LUT file
|
|
/// </summary>
|
|
public Boolean IsValid;
|
|
|
|
/// <summary>
|
|
/// Binary file content
|
|
/// </summary>
|
|
public List<Byte> BinData = new List<Byte>();
|
|
|
|
/// <summary>
|
|
/// Meter size
|
|
/// </summary>
|
|
public MeterSize MeterSize;
|
|
|
|
/// <summary>
|
|
/// ATTENTION: The file size is dynamic!
|
|
/// Verifies the LUT format based on its contents
|
|
/// </summary>
|
|
/// <returns>true if valid</returns>
|
|
/// <remarks date="2023-Nov-13" author="Thomas Wiedebusch">
|
|
/// - Initial.
|
|
/// </remarks>
|
|
/// <remarks date="2023-Nov-17" author="Thomas Wiedebusch">
|
|
/// - Removed constant size, instead using header to calculate the size of the file.
|
|
/// </remarks>
|
|
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<Byte>();
|
|
entireFile.AddRange(BinData);
|
|
var payload = new List<Byte>();
|
|
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;
|
|
}
|
|
}
|
|
}
|