From 75cabb6f47d7403c2c3b9fd58f9529f79191b4b1 Mon Sep 17 00:00:00 2001 From: Thomas Wiedebusch Date: Mon, 13 Nov 2023 13:49:06 +0100 Subject: [PATCH] CUST: - FwUpdateSw: - LUT check and logging Common/.../GenesisFile/MeterLutFile: - LUT file analyze function --- .../Genesis/GenesisFile/MeterLutFile.cs | 50 +++++++ .../Genesis/GenesisFile/MeterLutUpdate.cs | 36 +---- .../ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs | 134 +++++++++--------- .../Properties/Resources.Designer.cs | 36 +++-- .../Properties/Resources.de.resx | 10 +- .../Properties/Resources.resx | 10 +- 6 files changed, 170 insertions(+), 106 deletions(-) diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterLutFile.cs b/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterLutFile.cs index 0995270e..eeb640af 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterLutFile.cs +++ b/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterLutFile.cs @@ -1,6 +1,8 @@ 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 { @@ -93,6 +95,11 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile /// public UInt16 CalculatedCrc; + /// + /// FileCRC and calculated CRC are different + /// + public Boolean CrcError; + /// /// Validation of LUT file /// @@ -107,5 +114,48 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile /// Meter size /// public MeterSize MeterSize; + + /// + /// Verifies the LUT format based on its contents + /// + /// true if valid + public Boolean ValidateLutFormat() + { + IsValid = false; + + if (BinData == null || BinData.Count < SizeLutFile) + 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, + MeterLutFile.LutFileDataLength + MeterLutFile.LengthVersion)); + CalculatedCrc = Crc16Ccitt.CalculateMsb1021(payload.ToArray()); + if (CalculatedCrc != FileCrc) + { + CrcError = true; + return false; + } + + CrcError = false; + IsValid = true; + return true; + } } } diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterLutUpdate.cs b/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterLutUpdate.cs index acee8408..395c213d 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterLutUpdate.cs +++ b/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterLutUpdate.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; using System.Threading; using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore; using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Consts; @@ -10,7 +9,6 @@ using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.Consts; using Xylem.Common.Hardware.WaterMeter.Genesis.Registers; using Xylem.Common.Hardware.WaterMeter.WaterMeterCore.Consts; using Xylem.Common.Logic.ProductionOrderCore.OrderData; -using Xylem.Common.Utils.Crc16Ccitt; using Xylem.Common.Utils.ProcessExec; using Xylem.Common.Utils.ProcessExec.EventArguments; @@ -483,6 +481,9 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile /// /// - Initial /// + /// + /// - LUT file validation exported to + /// private Boolean ValidateLutFile() { // check if LUT file contains data @@ -492,38 +493,15 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile return false; } - LutFile.IsValid = false; - // extract the identifier and check, if this is a LUT file - LutFile.StrLutFileId = Encoding.UTF8.GetString(LutFile.BinData.ToArray(), MeterLutFile.IndexLutFileId, - MeterLutFile.IndexDataLength); - if (LutFile.StrLutFileId != MeterLutFile.StrLutMeterFileId) - return false; - - LutFile.MeterSize = (MeterSize)LutFile.BinData[MeterLutFile.IndexMeterSize]; - LutFile.FileCrc = (UInt16)(LutFile.BinData[MeterLutFile.IndexCrc] + - (LutFile.BinData[MeterLutFile.IndexCrc + 1] << 8)); - LutFile.Version = (UInt16)(LutFile.BinData[MeterLutFile.IndexVersion] + - (LutFile.BinData[MeterLutFile.IndexVersion + 1] << 8)); - LutFile.DataLength = (UInt32)(LutFile.BinData[MeterLutFile.IndexDataLength] - + (LutFile.BinData[MeterLutFile.IndexDataLength + 1] << 8) - + (LutFile.BinData[MeterLutFile.IndexDataLength + 2] << 16) - + (LutFile.BinData[MeterLutFile.IndexDataLength + 3] << 24)); - // calculate CRC and compare this with the file CRC - var entireFile = new List(); - entireFile.AddRange(LutFile.BinData); - var payload = new List(); - payload.AddRange(entireFile.GetRange(MeterLutFile.IndexVersion, - MeterLutFile.LutFileDataLength + MeterLutFile.LengthVersion)); - var calculatedCrc = Crc16Ccitt.CalculateMsb1021(payload.ToArray()); - if (calculatedCrc != LutFile.FileCrc) + // Take the file content to validate the format based + var lutFileFormatValid = LutFile.ValidateLutFormat(); + if (LutFile.CrcError) { ErrorMessage = "CRC mismatch!"; return false; } - LutFile.CalculatedCrc = calculatedCrc; - LutFile.IsValid = true; - return true; + return lutFileFormatValid; } /// diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs index 2176d602..f2fe8130 100644 --- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs +++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs @@ -24,6 +24,7 @@ using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisPwd; using Xylem.Common.Hardware.WaterMeter.Genesis.Registers; using Xylem.Common.Hardware.WaterMeter.Genesis.Registers.DataTypes; using Xylem.Common.Hardware.WaterMeter.WaterMeterCore; +using Xylem.Common.Logic.ProductionOrderCore.OrderData; using Xylem.Common.Utils.Logging; using Xylem.Common.Utils.ProcessExec; using Xylem.Common.Utils.ProcessExec.EventArguments; @@ -53,7 +54,6 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw private readonly MeterBatch _meterBatch; private Byte[] _fwUpdateSafePwdFile; private MeterLutFile _fwUpdateSafeLutFile; - private MeterLutFile _meterLutFile; private String _passwordLvl8; private String _skeletonKey; @@ -1689,7 +1689,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw /// /// Logging of LUT file read from meter. /// - /// + /// /// - Initial. /// private Boolean ReadLogAndCompareMeterLutFile() @@ -1702,66 +1702,56 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw { // Read the meter LUT file var meterFile = new MeterFile(_currentGenesis); - retVal = meterFile.ReadMeterFile(MeterLutFile.StrLutMeterFileName, out var meterLutFile); + var meterLutFile = new MeterLutFile(); + retVal = meterFile.ReadMeterFile(MeterLutFile.StrLutMeterFileName, out meterLutFile.BinData); - // Separate to maximum line length of 16 bytes + // Extract information from read meter LUT file var lutLineList = new List(); if (retVal) { - for (var idx = 0; idx < meterLutFile.Count; idx += 16) + // Validate the meter LUT file format + var lutFileFormatValid = meterLutFile.ValidateLutFormat(); + var lutLine = $@"LUT Version: {meterLutFile.Version}"; + lutLineList.Add(lutLine); + lutLine = $@"LUT {Resources.StrMessageMeterSize} " + + $@"{MeterSizeConverter.ConvertMeterSizeEnumToSizeName(meterLutFile.MeterSize)}"; + lutLineList.Add(lutLine); + lutLine = $@"{Resources.StrMessageLutCrc} 0x{meterLutFile.FileCrc:X4}"; + lutLineList.Add(lutLine); + if (lutFileFormatValid) { - // limit the length at the end to the remaining bytes - var length = idx + 16 > meterLutFile.Count ? meterLutFile.Count - idx : 16; - var lutLine = BitConverter.ToString(meterLutFile.GetRange(idx, length).ToArray()); - lutLineList.Add(lutLine); - } - } + if (_fwUpdateSafeLutFile == null || _fwUpdateSafeLutFile.BinData.Count != MeterLutFile.SizeLutFile) + { + LogStringList(Resources.StrMessageLutFile, lutLineList, + Resources.StrLutFileFromMeterValid); + } + else + { + for (var c = 0; c < MeterLutFile.SizeLutFile; c++) + { + // If one byte is different the comparison failed + if (_fwUpdateSafeLutFile.BinData[c] != meterLutFile.BinData[c]) + { + LogStringList(Resources.StrMessageLutFile, lutLineList, + errorMessage: Resources.StrLutFileCompareFailed); + retVal = false; + } + } - // Analyze the read out of LUT file - if (meterLutFile == null || meterLutFile.Count == 0) - { - // Log information about LUT file is not installed - if (_fwUpdateSafeLutFile == null) - { - LogText(Resources.StrLutFileNotNeeded); - return true; - } - - // Here the LUT file should be installed but is not - InfoProcessFailed(null, Resources.StrLutFileNotInstalled); - retVal = false; - } - - // If the FW-Update safe does not contain a LUT file this cannot be compared - if (_fwUpdateSafeLutFile == null) - { - // If the FW-Update safe does not contain a LUT file just log the read out - if (lutLineList.Count != MeterLutFile.SizeLutFile ) - { - LogStringList(Resources.StrMessageHashedPwdFile, lutLineList, - errorMessage: Resources.StrLutFileNotDelivered); + // Here all bytes are identical + if (!retVal) + { + LogStringList(Resources.StrMessageLutFile, lutLineList, + Resources.StrLutFileCompareSucceeded); + } + } } + // Here the LUT file format is invalid else - { - LogErrorText(Resources.StrLutFileNotDelivered); - } - } - else if (!_passwordFileIsCorrupted) - { - // Compare the installed LUT file with the LUT file from FW update safe - retVal = !meterFile.VerifyMeterFile(MeterLutFile.StrLutMeterFileName, - _fwUpdateSafeLutFile.BinData.ToArray()); - - if (!retVal) { LogStringList(Resources.StrMessageLutFile, lutLineList, - Resources.StrLutFileCompareSucceeded); - } - else - { - // LUT file is suspicious - LogStringList(Resources.StrMessageLutFile, lutLineList, - errorMessage: Resources.StrLutFileCompareFailed); + errorMessage: Resources.StrLutFileFromMeterInvalid); + retVal = false; } } } @@ -3269,7 +3259,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw // the pulse mode OFF before reading all installed apps, which will be unpredictable on activated // pulse module. retVal = _currentGenesis.Login(password, skipReadMeterFwAndAssignRegisters: true); - + if (!retVal) { return false; @@ -3958,23 +3948,25 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw /// /// /// - /// + /// /// - Initial. /// private void RestoreLutFile(ProcessState successExitState, ProcessState errorExitState = ProcessState.Error) { // Remind the invoker being able to generate error messages based on the last state _invokerProcessState = _processState; + InfoProcessActive(lblLutFileCheck, Resources.StrLutFileRestoreActive); - - //TODO THW implement the installation of the LUT - // If meter LUT CRC is not set and the meter files do not report the LUT, the meter does not have an - // installed LUT + // 1. LUT file NOT installed: + // If meter LUT CRC is not set and the meter files do not report the LUT, the meter does not have an + // installed LUT if ((string.IsNullOrEmpty(_currentGenesis.LutCrc) || - _currentGenesis.LutCrc.Equals(Constants.StrUnknown)) && + _currentGenesis.LutCrc.Equals(Constants.StrUnknown)) && _readMeterFiles != null && !_readMeterFiles.Any(f => f.Contains(MeterLutFile.StrLutMeterFileName))) { - // if the safe contains a LUT file, the installation of it has failed or it got lost during update + // 1. a) LUT file not installed but required by the FW update safe: + // If the safe contains a LUT file, the installation of it has failed or it got lost during + // update if (_fwUpdateSafeLutFile != null) { LogErrorText(Resources.StrLutFileNotInstalled); @@ -3982,15 +3974,29 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw return; } - // this FW version does not require a LUT file + // 1. b) LUT file not installed and not delivered by the FW update safe + // This FW version does not require a LUT file LogText(Resources.StrLutFileNotNeeded); _processState = successExitState; return; } - // if the LUT is not in the safe it cannot be restored but can be logged - ReadLogAndCompareMeterLutFile(); - _processState = errorExitState; + // 2. LUT file is installed: + // 2.a) Lut file is installed but NOT in the safe: + // If the LUT is not in the safe it cannot be restored or compared to the required content but can + // be analyzed and logged + // 2.b) LUT file is installed and delivered by the FW update safe: + // On validated installed LUT file in meter this can be compared with the required LUT file + if (!ReadLogAndCompareMeterLutFile()) + { + InfoProcessFailed(lblLutFileCheck, Resources.StrLutFileFromMeterInvalid); + _processState = errorExitState; + } + else + { + InfoProcessSuccess(lblLutFileCheck, Resources.StrLutFileFromMeterValid); + _processState = successExitState; + } // Change first the process state, otherwise the timer may switch the bar on again SetOverallProgressDisplayOff(); diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.Designer.cs b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.Designer.cs index 243b6f3d..6f027369 100644 --- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.Designer.cs +++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.Designer.cs @@ -601,6 +601,24 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw.Properties { } } + /// + /// Looks up a localized string similar to ERROR: LUT installed in meter is invalid!. + /// + internal static string StrLutFileFromMeterInvalid { + get { + return ResourceManager.GetString("StrLutFileFromMeterInvalid", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to LUT installed in meter is valid.. + /// + internal static string StrLutFileFromMeterValid { + get { + return ResourceManager.GetString("StrLutFileFromMeterValid", resourceCulture); + } + } + /// /// Looks up a localized string similar to ERROR: LUT from FW update safe invalid!. /// @@ -610,6 +628,15 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw.Properties { } } + /// + /// Looks up a localized string similar to LUT from FW update safe is valid.. + /// + internal static string StrLutFileFromSafeValid { + get { + return ResourceManager.GetString("StrLutFileFromSafeValid", resourceCulture); + } + } + /// /// Looks up a localized string similar to ERROR: LUT is not in FW updae safe!. /// @@ -700,15 +727,6 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw.Properties { } } - /// - /// Looks up a localized string similar to LUT successfully validated.. - /// - internal static string StrLutFileValid { - get { - return ResourceManager.GetString("StrLutFileValid", resourceCulture); - } - } - /// /// Looks up a localized string similar to Not installed. /// diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.de.resx b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.de.resx index 5d6497fc..478c3c4c 100644 --- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.de.resx +++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.de.resx @@ -646,10 +646,16 @@ LUT wiederherstellen. - - LUT ist gültig. + + LUT installiert im Meter is gültig. LUT: + + FEHLER:LUT installiert im Meter ist ungültig! + + + LUT im FW Update Safe ist gültig. + \ No newline at end of file diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.resx b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.resx index 88a18247..ef6456d4 100644 --- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.resx +++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.resx @@ -613,8 +613,8 @@ LUT not required for this FW. - - LUT successfully validated. + + LUT installed in meter is valid. ERROR: Installed LUT is unequal to required! @@ -652,4 +652,10 @@ LUT: + + ERROR: LUT installed in meter is invalid! + + + LUT from FW update safe is valid. + \ No newline at end of file