diff --git a/Common/Ui/GenesisToolBox/FrmLowLevelTools.cs b/Common/Ui/GenesisToolBox/FrmLowLevelTools.cs index 38abea75..c4f3b426 100644 --- a/Common/Ui/GenesisToolBox/FrmLowLevelTools.cs +++ b/Common/Ui/GenesisToolBox/FrmLowLevelTools.cs @@ -57,6 +57,7 @@ namespace Xylem.Common.Ui.GenesisToolBox private MeterResetPsu _meterResetPsu; private Boolean _meterResetProcessActive; private Boolean _rebootSucceeded; + private Boolean _repairPasswordEnabled; private Boolean _tryConnectPcb; @@ -178,6 +179,7 @@ namespace Xylem.Common.Ui.GenesisToolBox tbxFileToEraseDrive.Enabled = false; btnUploadPWFile.Enabled = false; btnReadStatus.Enabled = false; + btnRepairPassword.Enabled = false; } /// @@ -203,6 +205,8 @@ namespace Xylem.Common.Ui.GenesisToolBox tbxFileToEraseDrive.Enabled = true; btnUploadPWFile.Enabled = true; btnReadStatus.Enabled = true; + if (_repairPasswordEnabled) + btnRepairPassword.Enabled = true; } /// @@ -266,7 +270,6 @@ namespace Xylem.Common.Ui.GenesisToolBox { return; } - btnRepairPassword.Enabled = false; lblOverall.Text = @"Login to Cordonel..."; lblActualProcess.Text = @"Establish data base connection..."; @@ -292,7 +295,7 @@ namespace Xylem.Common.Ui.GenesisToolBox _meterBatch.MetersLogin(); var retValPwdBuild = MeterPwdHandlerDb.RequestPwdFileFromDb(_currentGenesis.PcbId, out var pwdContainer); - + // CASE 1: - Passwords are generated in database but password file is not installed or doesn't work. // - The production password is the SkeletonKey as the login succeeded. // @@ -301,7 +304,7 @@ namespace Xylem.Common.Ui.GenesisToolBox // file needs to be enabled! if (retValPwdBuild && _currentGenesis.IsLoggedOn && pwdContainer.Skeleton.Equals(pwdContainer.Password)) { - ShowPasswordRepairMessage(@"Password exists on database but the SkeletonKey is valid - Password repair enabled"); + ShowPasswordRepairMessage(@"Password exists on database but the SkeletonKey is valid - [Repair Password] enabled"); } if (!_currentGenesis.IsLoggedOn) @@ -310,15 +313,15 @@ namespace Xylem.Common.Ui.GenesisToolBox Thread.Sleep(2000); // Try to log in with password level 8 which may not be published to the database var retVal = _currentGenesis.Login(Encoding.UTF8.GetString(pwdContainer.ListOfPasswords.Last())); - + // CASE 2: - Passwords are generated in database and correctly installed. The login check will be done // with the generated password, but the production password is still on SkeletonKey. // - The production password is the SkeletonKey as login succeeded. // - The database update of the production password went wrong! if (_currentGenesis.IsLoggedOn && retVal) { - ShowPasswordRepairMessage(@"Password file is installed, login Lvl8 works, password in database not updated" + - "- use password repair"); + ShowPasswordRepairMessage(@"Password file is installed as login Lvl8 works, password in database not updated" + + "- [Repair Password] enabled"); } else { @@ -332,7 +335,7 @@ namespace Xylem.Common.Ui.GenesisToolBox // CASE 3: - The production password didn't work, so the SkeletonKey will be tried. if (_currentGenesis.Login(pwdContainer.Skeleton)) { - ShowPasswordRepairMessage(@"Successfully logged in with SkeletonKey - Password repair enabled"); + ShowPasswordRepairMessage(@"Successfully logged in with SkeletonKey - [Repair Password] enabled"); } else { @@ -352,7 +355,7 @@ namespace Xylem.Common.Ui.GenesisToolBox var retExport = JsonConvert.DeserializeObject>(retStr); if (retExport.Count == 0) { - sb.AppendLine(@"Export entry hasn't be found [E1]"); + sb.AppendLine(@"Export entry hasn't been found [E1]"); //request sb.AppendLine(@"Export returns no password [E2]"); } @@ -463,9 +466,9 @@ namespace Xylem.Common.Ui.GenesisToolBox { LogText(msg); MessageBox.Show(msg); - Invoke(new Action(() => { btnRepairPassword.Enabled = true; })); + _repairPasswordEnabled = true; } - + /// /// Wait for reboot is completed by polling of PcbId /// @@ -2043,88 +2046,129 @@ namespace Xylem.Common.Ui.GenesisToolBox } } + /// + /// Read status + /// + /// + /// + /// + /// - Initial + /// + /// + /// - Check if new password is in the meter with login level 8 even if the file write wasn't successful, + /// - Set new password in production database, + /// - Check password level 3 as all applications need to use this, + /// - Validate production password. + /// private void btnRepairPassword_Click(Object sender, EventArgs e) { + if (_currentGenesis == null) + { + return; + } + + // Reset timer + _startTime = DateTimeOffset.UtcNow; LowLevelActionControl(true); - var ret = MeterPwdHandlerDb.RequestPwdFileFromDb(_currentGenesis.GetPcbId(), out var pwdContainer); - if (pwdContainer?.ListOfHashes == null || pwdContainer.ListOfPasswords == null || !ret) + + var msg = "Repair password"; + LogText(msg); + lblOverall.Text = msg; + + Task.Factory.StartNew(() => { - LogText(@"Password file from server corrupted [M3]!"); + // Request password file and force generation + SetActualProcessAndLog("Request password files from database"); + var ret = MeterPwdHandlerDb.RequestPwdFileFromDb(_currentGenesis.GetPcbId(), out var pwdContainer); + if (pwdContainer?.ListOfHashes == null || pwdContainer.ListOfPasswords == null || !ret) + { + LogText(@"Password file from server corrupted [M3]!"); + LowLevelActionControl(false); + return; + } + + // Build password file + SetActualProcessAndLog("Build password file"); + var _meterPwdFile = new MeterPwdFile(_currentGenesis); + var retValBol = _meterPwdFile.BuildPwdFile(pwdContainer.ListOfPasswords, 1, pwdContainer.Skeleton); + if (!retValBol) + { + LogText(@"Unable to build password file [M3]!"); + LowLevelActionControl(false); + return; + } + + // Install password file and verify byte wise + SetActualProcessAndLog("Install and verify password file into meter"); + _currentGenesis.ReLogin(); + retValBol = _meterPwdFile.UnlockEraseWriteMeterPwdFile(); + retValBol &= _meterPwdFile.WriteMeterPwdFile() && _meterPwdFile.VerifyMeterPwdFile(); + + if (!retValBol) + { + LogText(@"Installed password file check failed [M4]!"); + return; + } + + // Check if new password is in the meter with login level 8 even if the file write wasn't successful + SetActualProcessAndLog("Validate Lvl8 password from password file"); + _currentGenesis.Logout(); + retValBol = _currentGenesis.Login(Encoding.UTF8.GetString(pwdContainer.ListOfPasswords.Last())); + if (!retValBol) + { + LogText(@"Login with new password failed [M4]!"); + return; + } + LogText(@"Password was successfully installed."); + + // Set new password in production database + SetActualProcessAndLog("Replace SkeletonKey with Lvl8 password as production password in database"); + retValBol = MeterPwdHandlerDb.SetPwdFromSkeletonToLvl8inDd(_currentGenesis.PcbId, pwdContainer); + if (!retValBol) + { + LogText(@"Update of production password in database failed [E3]!"); + return; + } + LogText(@"Production password successfully updated in database"); + + // Check password level 3 as all applications need to use this + SetActualProcessAndLog("Validate Lv3 as SkeletonKey in meter"); + retValBol = _currentGenesis.WriteRegister("SYSTEM_ExitReason", new Byte[] { 21 }); + var exitResult = RegisterConverter.ByteArrayToValue(_currentGenesis.ReadRegister("SYSTEM_ExitReason")); + if (exitResult != 0 || !retValBol) + { + LogText(@"Meter reports wrong SkeletonKey at Lvl3 [M4]!"); + return; + } + LogText(@"Meter reports correct SkeletonKey at Lvl3."); + + // Clear intermediate stored password to force password collection from DB on simple login without + // given new password. Then the password will be taken from the DB or offline file. + SetActualProcessAndLog("Crosscheck production password with meter password Lvl8"); + _currentGenesis.Logout(); + _currentGenesis.ClearPassword(); + + // If the password is not set (Meter.ClearPassword) the actual valid production password will be + // requested from the DB in the GenesisMeter Login() without parameter. + Thread.Sleep(1000); + // Validate production password + retValBol = _currentGenesis.Login(); + + if (!retValBol) + { + LogText(@"Invalid password in production database [E3]!"); + return; + } + LogText(@"Password Lvl8 successfully validated with production database."); + _repairPasswordEnabled = false; + }).ContinueWith(delegate + { + //add a blank line to separate next operation + LogText(""); + _currentGenesis.Logout(); LowLevelActionControl(false); - return; - } - // Build password file - var _meterPwdFile = new MeterPwdFile(_currentGenesis); - var retValBol = _meterPwdFile.BuildPwdFile(pwdContainer.ListOfPasswords, 1, pwdContainer.Skeleton); - if (!retValBol) - { - LogText(@"Unable to build password file [M3]!"); - LowLevelActionControl(false); - return; - } + }); - _currentGenesis.ReLogin(); - retValBol = _meterPwdFile.UnlockEraseWriteMeterPwdFile(); - retValBol &= _meterPwdFile.WriteMeterPwdFile() && _meterPwdFile.VerifyMeterPwdFile(); - - if (!retValBol) - { - LogText(@"Installed password file check failed [M4]!"); - LowLevelActionControl(false); - return; - } - - // Check if new password is in the meter with login level 8... even if the file write wasn't successful - _currentGenesis.Logout(); - retValBol = _currentGenesis.Login(Encoding.UTF8.GetString(pwdContainer.ListOfPasswords.Last())); - if (!retValBol) - { - LogText(@"Login with new password failed [M4]!"); - LowLevelActionControl(false); - return; - } - LogText(@"Password was successfully installed."); - - // set new password in production database - retValBol = MeterPwdHandlerDb.SetPwdFromSkeletonToLvl8inDd(_currentGenesis.PcbId, pwdContainer); - if (!retValBol) - { - LogText(@"Update of production password in database failed [E3]!"); - LowLevelActionControl(false); - return; - } - LogText(@"Production password successfully updated in database"); - // Check password level 3 as all applications need to use this - retValBol = _currentGenesis.WriteRegister("SYSTEM_ExitReason", new Byte[] { 21 }); - var exitResult = RegisterConverter.ByteArrayToValue(_currentGenesis.ReadRegister("SYSTEM_ExitReason")); - - _currentGenesis.Logout(); - if (exitResult != 0 || !retValBol) - { - LogText(@"Meter reports wrong SkeletonKey at Lvl3 [M4]!"); - LowLevelActionControl(false); - return; - } - LogText(@"Meter reports correct SkeletonKey at Lvl3."); - - // Clear intermediate stored password to force password collection from DB on simple login without - // given new password. Then the password will be taken from the DB or offline file. - _currentGenesis.ClearPassword(); - - // If the password is not set (Meter.ClearPassword) the actual valid production password will be - // requested from the DB in the GenesisMeter Login() without parameter. - Thread.Sleep(1000); - retValBol = _currentGenesis.Login(); - - if (!retValBol) - { - LogText(@"Invalid password in production database [E3]!"); - LowLevelActionControl(true); - return; - } - LogText(@"Password Lvl8 successfully validated with production database."); - Invoke(new Action(() => { btnRepairPassword.Enabled = false; })); - LowLevelActionControl(false); } private void btnConnectSkeleton_Click(Object sender, EventArgs e)