diff --git a/Common/Docu/SoftwareDesign/Genesis Login and password generation.docm b/Common/Docu/SoftwareDesign/Genesis Login and password generation.docm new file mode 100644 index 00000000..8456cd63 Binary files /dev/null and b/Common/Docu/SoftwareDesign/Genesis Login and password generation.docm differ diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterLutFile.cs b/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterLutFile.cs index c0832e27..6501f9a7 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterLutFile.cs +++ b/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterLutFile.cs @@ -9,11 +9,28 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile /// public class MeterLutFile { + /// + /// Disk number and name 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"; + /// /// File name of the file on PC /// public String LutPcFileName; + /// + /// Ctor file applications + /// + public MeterLutFile() + { + } + /// /// Ctor file applications /// diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterLutUpdate.cs b/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterLutUpdate.cs index b58a4e47..0a97cd3b 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterLutUpdate.cs +++ b/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterLutUpdate.cs @@ -31,12 +31,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile //error mask for unsuccessfully written LUT CRC private const UInt32 LutCrcErrorMask = 0x8000000; - //disk and name of lookup file - private const String StrLutMeterFileName = "1\\mettbl"; - - //disk and name of lookup file - private const String StrLutBackupMeterFileName = "1\\mettbl_b"; - // identifier for Genesis lookup table private const String StrLutFileId = "GEN_LUT\0"; private const Int32 IndexLutFileId = 0; @@ -455,8 +449,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile case LutUpdateState.StartInitial: _updateProcedureRetryCtr = 0; _lutUpdateState = LutUpdateState.DownloadLutFile; - - //_lutUpdateState = LutUpdateState.EraseLutFile; break; case LutUpdateState.EraseLutFile: @@ -757,7 +749,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile { var filesToErase = new[] { //"1\\upg00", "1\\upg01", "1\\upg04","1\\upg08","1\\upg09","1\\upg12","1\\upg14","1\\upg15", - StrLutMeterFileName, StrLutBackupMeterFileName }; + MeterLutFile.StrLutMeterFileName, MeterLutFile.StrLutBackupMeterFileName }; // read all files which are already installed _actualOperation = "Catalogue installed meter files drive 1"; @@ -821,7 +813,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile //write LUT files and retry if not successful do { - var filesToDownload = new[] { StrLutMeterFileName, StrLutBackupMeterFileName }; + var filesToDownload = new[] { MeterLutFile.StrLutMeterFileName, MeterLutFile.StrLutBackupMeterFileName }; foreach (var fileToDownload in filesToDownload) { @@ -910,7 +902,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile //verify LUT files and retry if not successful do { - var filesToUpload = new[] { StrLutMeterFileName, StrLutBackupMeterFileName }; + var filesToUpload = new[] { MeterLutFile.StrLutMeterFileName, MeterLutFile.StrLutBackupMeterFileName }; foreach (var fileToUpload in filesToUpload) { diff --git a/ServiceFwUpdate/Documents/Cordonel Service FW-Update Drawingse.vsd b/ServiceFwUpdate/Documents/Cordonel Service FW-Update Drawingse.vsd index 8c3b9532..9652cd55 100644 Binary files a/ServiceFwUpdate/Documents/Cordonel Service FW-Update Drawingse.vsd and b/ServiceFwUpdate/Documents/Cordonel Service FW-Update Drawingse.vsd differ diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Const/ProcessState.cs b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Const/ProcessState.cs index 8cb321ce..7e38064b 100644 --- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Const/ProcessState.cs +++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Const/ProcessState.cs @@ -116,6 +116,11 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw.Const /// RestorePasswordFile, + /// + /// Restore tho look up table + /// + RestoreLut, + /// /// Firmware update /// diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs index 46755fb8..07f527eb 100644 --- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs +++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs @@ -7,6 +7,7 @@ using System.Globalization; using System.IO; using System.Linq; using System.Reflection; +using System.Runtime.Remoting.Messaging; using System.Text; using System.Threading; using System.Windows.Forms; @@ -52,6 +53,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw private GenesisMeter _currentGenesis; private readonly MeterBatch _meterBatch; private Byte[] _hashedSafePwdFile; + private Byte[] _lutFileBinary; private String _passwordLvl8; private String _skeletonKey; @@ -255,6 +257,9 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw /// /// - Release meter to normal operation after error state. /// + /// + /// - LUT restore. + /// private void FwUpdateSwStateMachine() { while (!_processToken.IsCancellationRequested) @@ -354,8 +359,8 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw case ProcessState.FinalConnect: DisposeGenesis(); - // remind, that the final login with the Level 8 password has to be forced to validate - // the password file + // REMIND: The final login with the Level 8 password has to be forced to validate + // the password file, the skeletonKey is NOT allowed _finalLoginAfterUpdate = true; Connect(ProcessState.RestoreMeterFiles); break; @@ -376,7 +381,11 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw break; case ProcessState.RestorePasswordFile: - RestorePasswordFile(ProcessState.FirmwareUpdateSuccess); + RestorePasswordFile(ProcessState.RestoreLut); + break; + + case ProcessState.RestoreLut: + RestoreLut(ProcessState.FirmwareUpdateSuccess); break; case ProcessState.FirmwareUpdateSuccess: @@ -1685,8 +1694,9 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw /// - Reworked with new information from Joerg Lachenmayer: /// 1. Write 0xff, /// 2. logout, - /// 3. login - /// 4. read if not 0x01. + /// 3. Wait 1000 ms, + /// 4. login + /// 5. read if not 0x01. /// /// /// - Handle SystemState 0 = OFF @@ -3056,6 +3066,8 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw _hashedSafePwdFile = new Byte[MeterPwdDb.PwdFileLength]; _hashedSafePwdFile = device.PwdContainer.EncryptedPasswordFile; + // extract the LUT + _lutFile = new MeterLutFile( _genesisInUpdateList = true; break; } @@ -3806,6 +3818,87 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw SetOverallProgressDisplayOff(); } + /// + /// Reads the LUT and restores it if different from given LUT in FwUpdateSafe. + /// + /// + /// + /// + /// - Initial. + /// + private void RestoreLut(ProcessState successExitState, ProcessState errorExitState = ProcessState.Error) + { + // remind the invoker being able to generate error messages based on the last state + _invokerProcessState = _processState; + + // 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)) && + _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 + if (_lutFileBinary != null) + { + LogErrorText(Resources.StrLutFileNotInstalled); + _processState = errorExitState; + return; + } + + // 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 + + + // read and log the LUT + //if (!_passwordFileIsCorrupted) + //{ + // InfoProcessSuccess(lblPasswordFileCheck, Resources.StrPasswordFileValid); + // _processState = successExitState; + // return; + //} + + //InfoProcessActive(lblPasswordFileCheck, Resources.StrPasswordFileRestoreActive); + //// try to install password, first get the password file from device info + //var pwdFileObject = new MeterPwdFile(_currentGenesis); + //if (_hashedSafePwdFile != null && + // pwdFileObject.CheckHashedPwdFile(_hashedSafePwdFile , _skeletonKey, _passwordLvl8)) + //{ + // SetControlsCommunicationActive(); + // _currentGenesis?.ReLogin(); + // if (pwdFileObject.UnlockEraseWriteMeterPwdFile()) + // { + // if (pwdFileObject.WriteAndVerifyMeterPwdFile(_hashedSafePwdFile) && + // ReadLogAndCompareMeterPwdFile()) + // { + // // a reconnect will check for proper installed password file and check the Level 8 pwd. + // _processState = ProcessState.FinalConnect; + // _passwordFileIsCorrupted = false; + // InfoProcessSuccess(lblPasswordFileCheck, Resources.StrPasswordFileRestoreSucceeded); + // } + // else + // { + // InfoProcessFailed(lblPasswordFileCheck, Resources.StrPasswordFileRestoreFailed); + // _processState = errorExitState; + // } + // } + + // _currentGenesis?.Logout(); + //} + //// the password file is NOT in the password container + //else + //{ + // InfoProcessFailed(lblPasswordFileCheck, Resources.StrPasswordFileFromSafeInvalid); + // _processState = errorExitState; + //} + + // change first the process state, otherwise the timer may switch the bar on again + SetOverallProgressDisplayOff(); + } + #endregion --------------------------------------- File Access ------------------------------------------------ #region ------------------------------------------ Register Recovery ----------------------------------------- diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.Designer.cs b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.Designer.cs index e8426555..6ea9ffbd 100644 --- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.Designer.cs +++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.Designer.cs @@ -583,6 +583,33 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw.Properties { } } + /// + /// Looks up a localized string similar to ERROR: LUT is required but not installed!. + /// + internal static string StrLutFileNotInstalled { + get { + return ResourceManager.GetString("StrLutFileNotInstalled", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to LUT not required for this FW.. + /// + internal static string StrLutFileNotNeeded { + get { + return ResourceManager.GetString("StrLutFileNotNeeded", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to LUT successfully validated.. + /// + internal static string StrLutFileValidatedSuccessfully { + get { + return ResourceManager.GetString("StrLutFileValidatedSuccessfully", 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 4b76865a..3a8df426 100644 --- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.de.resx +++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.de.resx @@ -607,4 +607,13 @@ FEHLER: Paßwortdatei vom FW Update Safe ist ungültig! + + FEHLER: LUT wird benötigt und ist nicht installiert! + + + LUT wird für diese FW nicht benötigt. + + + LUT erfolgreich überprüft. + \ No newline at end of file diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.resx b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.resx index 525e9813..e11228ca 100644 --- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.resx +++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.resx @@ -607,4 +607,13 @@ ERROR: Password file from FW update safe is invalid! + + ERROR: LUT is required but not installed! + + + LUT not required for this FW. + + + LUT successfully validated. + \ No newline at end of file