From 21dafc97fcae98fc159ae354fcda95c306c61679 Mon Sep 17 00:00:00 2001 From: Thomas Wiedebusch Date: Thu, 12 Oct 2023 01:00:28 +0200 Subject: [PATCH] Common: - password checks extended, CUST: - password file read out and logged, - password write and verify implemented, - initial login avoid marking of password file not installed before switching OFF the pulse adaptor --- .../Genesis/GenesisFile/MeterPwdFile.cs | 16 +- .../Genesis/GenesisPwd/MeterPwdDb.cs | 2 +- .../ServiceFwUpdate.sln.DotSettings | 1 + .../ServiceFwUpdateSw/FrmHistory.Designer.cs | 46 +---- .../Ui/ServiceFwUpdateSw/FrmHistory.de.resx | 74 ++++++- .../Ui/ServiceFwUpdateSw/FrmHistory.resx | 187 +++++++++++++++-- .../ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs | 193 ++++++++++++------ .../Properties/Resources.Designer.cs | 36 ++++ .../Properties/Resources.de.resx | 12 ++ .../Properties/Resources.resx | 12 ++ 10 files changed, 447 insertions(+), 132 deletions(-) diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterPwdFile.cs b/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterPwdFile.cs index b83e823e..a4ac5252 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterPwdFile.cs +++ b/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterPwdFile.cs @@ -12,7 +12,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile /// public class MeterPwdFile { - private const String StrPasswordFileName = "0\\password"; + // The FwUpdateSw references this string + public const String StrPasswordFileName = "0\\password"; private readonly GenesisMeter _genesisMeter; private readonly MeterFile _meterFile; private Byte[] _hashedPasswordFile; @@ -286,16 +287,21 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile /// - /// Verify Meter password file - /// generated password file has to be present + /// Verify Meter password file. + /// optional hashed password file with constant length as byte array + /// true if the read value is identical with the preset or given hashed value /// /// - /// + /// /// - Initial. /// - public Boolean VerifyMeterPwdFile() + public Boolean VerifyMeterPwdFile(Byte[] hashedPwdFile = null) { + if (hashedPwdFile != null) + { + if (!SetHashedPwdFile(hashedPwdFile)) return false; + } if (_hashedPasswordFile == null) { return false; diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisPwd/MeterPwdDb.cs b/Common/Hardware/WaterMeter/Genesis/GenesisPwd/MeterPwdDb.cs index 9004555d..591379e8 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisPwd/MeterPwdDb.cs +++ b/Common/Hardware/WaterMeter/Genesis/GenesisPwd/MeterPwdDb.cs @@ -23,7 +23,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisPwd /// /// Each password will generate a 20 bytes hash constant due to SHA1 algorithm /// - private const Int32 HashedPwdLength = 20; + public const Int32 HashedPwdLength = 20; /// /// password file length is 160 bytes (8 passwords a 20 bytes hashed) diff --git a/ServiceFwUpdate/ServiceFwUpdate.sln.DotSettings b/ServiceFwUpdate/ServiceFwUpdate.sln.DotSettings index 85f77d86..2b1818a2 100644 --- a/ServiceFwUpdate/ServiceFwUpdate.sln.DotSettings +++ b/ServiceFwUpdate/ServiceFwUpdate.sln.DotSettings @@ -1,5 +1,6 @@  PCB + True True True True diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmHistory.Designer.cs b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmHistory.Designer.cs index 4e4c19aa..5a80e07e 100644 --- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmHistory.Designer.cs +++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmHistory.Designer.cs @@ -40,73 +40,37 @@ // // rtbHistory // - this.rtbHistory.Dock = System.Windows.Forms.DockStyle.Fill; - this.rtbHistory.Location = new System.Drawing.Point(3, 53); + resources.ApplyResources(this.rtbHistory, "rtbHistory"); this.rtbHistory.Name = "rtbHistory"; - this.rtbHistory.Size = new System.Drawing.Size(378, 673); - this.rtbHistory.TabIndex = 31; - this.rtbHistory.Text = ""; this.rtbHistory.TextChanged += new System.EventHandler(this.rtbHistory_TextChanged); // // tableLayoutPanel1 // - this.tableLayoutPanel1.ColumnCount = 1; - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + resources.ApplyResources(this.tableLayoutPanel1, "tableLayoutPanel1"); this.tableLayoutPanel1.Controls.Add(this.rtbHistory, 0, 1); this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel2, 0, 0); - this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; - this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; - this.tableLayoutPanel1.RowCount = 2; - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 50F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 111F)); - this.tableLayoutPanel1.Size = new System.Drawing.Size(384, 729); - this.tableLayoutPanel1.TabIndex = 38; // // tableLayoutPanel2 // - this.tableLayoutPanel2.ColumnCount = 2; - this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + resources.ApplyResources(this.tableLayoutPanel2, "tableLayoutPanel2"); this.tableLayoutPanel2.Controls.Add(this.picBoxLogo, 1, 0); - this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; - this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 3); this.tableLayoutPanel2.Name = "tableLayoutPanel2"; - this.tableLayoutPanel2.RowCount = 1; - this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); - this.tableLayoutPanel2.Size = new System.Drawing.Size(378, 44); - this.tableLayoutPanel2.TabIndex = 36; // // picBoxLogo // + resources.ApplyResources(this.picBoxLogo, "picBoxLogo"); this.picBoxLogo.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; - this.picBoxLogo.Dock = System.Windows.Forms.DockStyle.Right; - this.picBoxLogo.ErrorImage = null; - this.picBoxLogo.Image = ((System.Drawing.Image)(resources.GetObject("picBoxLogo.Image"))); - this.picBoxLogo.ImeMode = System.Windows.Forms.ImeMode.NoControl; - this.picBoxLogo.InitialImage = null; - this.picBoxLogo.Location = new System.Drawing.Point(270, 3); this.picBoxLogo.Name = "picBoxLogo"; - this.picBoxLogo.Size = new System.Drawing.Size(105, 38); - this.picBoxLogo.TabIndex = 35; this.picBoxLogo.TabStop = false; // // FrmHistory // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + resources.ApplyResources(this, "$this"); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.ClientSize = new System.Drawing.Size(384, 729); this.Controls.Add(this.tableLayoutPanel1); - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MaximizeBox = false; - this.MinimumSize = new System.Drawing.Size(400, 768); this.Name = "FrmHistory"; - this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; - this.Text = "FW-Update Process History"; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FrmHistory_FormClosing); this.tableLayoutPanel1.ResumeLayout(false); this.tableLayoutPanel2.ResumeLayout(false); diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmHistory.de.resx b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmHistory.de.resx index bba31d09..f9baba62 100644 --- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmHistory.de.resx +++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmHistory.de.resx @@ -118,14 +118,69 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - 428, 673 - - - 434, 729 - - - 434, 729 + + + /9j/4AAQSkZJRgABAQEAYABgAAD/4QC8RXhpZgAATU0AKgAAAAgABAESAAMAAAABAAEAAAE7AAIAAAAH + AAAAPodpAAQAAAABAAAARpydAAEAAAAOAAAApgAAAABUaG9tYXMAAAAEkAMAAgAAABQAAAB8kAQAAgAA + ABQAAACQkpEAAgAAAAM1MwAAkpIAAgAAAAM1MwAAAAAAADIwMjE6MDQ6MDEgMTQ6NTk6MjkAMjAyMTow + NDowMSAxNDo1OToyOQAAAFQAaABvAG0AYQBzAAAA/9sAQwACAQECAQECAgICAgICAgMFAwMDAwMGBAQD + BQcGBwcHBgcHCAkLCQgICggHBwoNCgoLDAwMDAcJDg8NDA4LDAwM/9sAQwECAgIDAwMGAwMGDAgHCAwM + DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM/8AAEQgAIwBkAwEi + AAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAAB + fQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNE + RUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1 + tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEA + AAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRC + kaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpz + dHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ + 2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A/fi5vYbML50scW7gb2C5p28Yrzr9qv8AZm0H + 9rX4Map4O8QK0cV0vm2d5GP32nXKg+XOnuMkEfxKWXoa/M7wp8XfjF8ZtT0j9j288SafptxpGsz6Xqvi + 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 + wxRrtSJFACqo7AAAAUUUVhvqzsSSVkf/2Q== + @@ -144,7 +199,4 @@ AB/+AAAf/AAAD/gAAA/4AAAf+AAAP/wYDH/+OA7///gP///4D///+A///////w== - - FW-Update Info - \ No newline at end of file diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmHistory.resx b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmHistory.resx index f9baba62..3bb793b9 100644 --- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmHistory.resx +++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmHistory.resx @@ -117,7 +117,125 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Right + + + System.Windows.Forms.RichTextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + FW-Update Info + + + + 38 + + + 6, 13 + + + + + + Fill + + + + AAABAAEAICAQAAAAAADoAgAAFgAAACgAAAAgAAAAQAAAAAEABAAAAAAAgAIAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP// + AAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB3d3cAAAAAAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAA + AAAABwAAAAAAAAAAAAAAAAB3cAcAAAAAAAAAAAAHcHAAd3AHAABwAAAAAAAAdwAHAHhwAAAABwAAAAAA + B3CAAAd4dwAAcABwAAAAAAcIiAd3d3d3B3cABwAAAAAAj4iHf///B3iHcAcAAAAAAAiIiPiIiP8IhwBw + AAAAAAAAiAiIh3d48HAAcAAAAAd3CIiIiAAHd493AHd3cABwAAjwiAB3dwd/BwAAAHAHAACPCIgIAAd3 + ePdwAABwBwiIjwiA8I+AcHj3d3cAcAcI+I8HgPBw8HB494h3AHAHCIiPB4Dwd4BwiPd3dwBwBwAAjweI + /wAICIj3cAAAcAAAAAjweA//8AiPdwBwAAAAAAAI8HeIAAiIiHcAcAAAAAAAAI8HeIiIiAhwAHAAAAAA + AAiP8Ad3iAiIhwAHAAAAAACPiI/wAAD4eIdwBwAAAAAHCPgIj///iAeHAHAAAAAAB3CAAAiIiAAAcAcA + AAAAAAB3AHAAiIAHAABwAAAAAAAAB3cAAI+ABwAHAAAAAAAAAAAAAACIgAcAAAAAAAAAAAAAAAAAAAAH + AAAAAAAAAAAAAAAAB3d3dwAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////wP///8D///+A////gP//4Y + Dn/8AAQ/+AAAH/gAAA/4AAAP/AAAH/4AAB/gAAABwAAAAYAAAAGAAAABgAAAAYAAAAGAAAAB/AAAH/wA + AB/+AAAf/AAAD/gAAA/4AAAf+AAAP/wYDH/+OA7///gP///4D///+A///////w== + + + + 31 + + + 578, 673 + + + Fill + + + 0 + + + + + + System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 584, 729 + + + FrmHistory + + + 3, 53 + + + 400, 768 + + + 1 + + + + + + 105, 38 + + + tableLayoutPanel2 + + + 584, 729 + + + NoControl + + + 3, 3 + + + Manual + + + rtbHistory + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + picBoxLogo + + + 470, 3 + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 0, 0 + + + tableLayoutPanel2 + /9j/4AAQSkZJRgABAQEAYABgAAD/4QC8RXhpZgAATU0AKgAAAAgABAESAAMAAAABAAEAAAE7AAIAAAAH @@ -182,21 +300,58 @@ wxRrtSJFACqo7AAAAUUUVhvqzsSSVkf/2Q== - - - AAABAAEAICAQAAAAAADoAgAAFgAAACgAAAAgAAAAQAAAAAEABAAAAAAAgAIAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP// - AAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB3d3cAAAAAAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAA - AAAABwAAAAAAAAAAAAAAAAB3cAcAAAAAAAAAAAAHcHAAd3AHAABwAAAAAAAAdwAHAHhwAAAABwAAAAAA - B3CAAAd4dwAAcABwAAAAAAcIiAd3d3d3B3cABwAAAAAAj4iHf///B3iHcAcAAAAAAAiIiPiIiP8IhwBw - AAAAAAAAiAiIh3d48HAAcAAAAAd3CIiIiAAHd493AHd3cABwAAjwiAB3dwd/BwAAAHAHAACPCIgIAAd3 - ePdwAABwBwiIjwiA8I+AcHj3d3cAcAcI+I8HgPBw8HB494h3AHAHCIiPB4Dwd4BwiPd3dwBwBwAAjweI - /wAICIj3cAAAcAAAAAjweA//8AiPdwBwAAAAAAAI8HeIAAiIiHcAcAAAAAAAAI8HeIiIiAhwAHAAAAAA - AAiP8Ad3iAiIhwAHAAAAAACPiI/wAAD4eIdwBwAAAAAHCPgIj///iAeHAHAAAAAAB3CAAAiIiAAAcAcA - AAAAAAB3AHAAiIAHAABwAAAAAAAAB3cAAI+ABwAHAAAAAAAAAAAAAACIgAcAAAAAAAAAAAAAAAAAAAAH - AAAAAAAAAAAAAAAAB3d3dwAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////wP///8D///+A////gP//4Y - Dn/8AAQ/+AAAH/gAAA/4AAAP/AAAH/4AAB/gAAABwAAAAYAAAAGAAAABgAAAAYAAAAGAAAAB/AAAH/wA - AB/+AAAf/AAAD/gAAA/4AAAf+AAAP/wYDH/+OA7///gP///4D///+A///////w== - + + 1 + + 35 + + + 578, 44 + + + 1 + + + tableLayoutPanel1 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="rtbHistory" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="tableLayoutPanel2" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100,Absolute,20" /><Rows Styles="Absolute,50,Percent,100,Absolute,111" /></TableLayoutSettings> + + + 2 + + + 0 + + + 0 + + + tableLayoutPanel1 + + + System.Windows.Forms.PictureBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + GrowAndShrink + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="picBoxLogo" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,50,Percent,50" /><Rows Styles="Percent,100,Absolute,20" /></TableLayoutSettings> + + + Fill + + + 2 + + + 36 + + + tableLayoutPanel1 + + + True + \ No newline at end of file diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs index d72359c0..ef830b28 100644 --- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs +++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs @@ -52,6 +52,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw // Genesis (legacy and program internal name for Cordonel) private GenesisMeter _currentGenesis; private readonly MeterBatch _meterBatch; + private Byte[] _hashedPwdFile; // port settings private MeterPortScanner _serialPortScanner; @@ -163,6 +164,9 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw // directory information private List _readMeterFiles; + // remind customer serial number for logging + private String _customerSerialNumber = "?"; + /// /// Timer for progress update /// @@ -365,7 +369,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw case ProcessState.FirmwareUpdateSuccess: ReleaseDisplay(); - RestoreRegisters(); + RestorePulseModeRegisters(); FwUpdateSuccessMessage(); _processState = ProcessState.Idle; break; @@ -1533,6 +1537,43 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw #endregion --------------------------------------- User Interaction ------------------------------------------- #region ------------------------------------------ Tools ------------------------------------------------------ + /// + /// Logging of password file read from meter. + /// + /// + /// - Initial. + /// + private Boolean ReadAndLogHashedPasswordFileFromMeter() + { + if (_currentGenesis == null) + return false; + _currentGenesis.ReLogin(); + Boolean retVal; + try + { + // log the password file content + var meterFile = new MeterFile(_currentGenesis); + retVal = meterFile.ReadMeterFile(MeterPwdFile.StrPasswordFileName, out var hashedMeterPwdFile); + if (retVal) + { + LogText(Resources.StrMessageHashedPwdFile); + for (var idx = 0; idx < hashedMeterPwdFile.Count; idx += MeterPwdDb.HashedPwdLength ) + { + var hashedPwd = BitConverter.ToString(hashedMeterPwdFile.GetRange(idx, + MeterPwdDb.HashedPwdLength).ToArray()); + LogText(hashedPwd); + } + } + } + catch (Exception) + { + LogErrorText(Resources.StrPasswordFileReadoutFailed); + retVal = false; + } + _currentGenesis.Logout(); + return retVal; + } + /// /// Set data and time. /// @@ -1605,7 +1646,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw _currentGenesis.Logout(); // give the radio app the time to store and restart in customer mode - Thread.Sleep(500); + Thread.Sleep(1000); // login for read back of new mode which shouldn't be 0x01 _currentGenesis.ReLogin(); @@ -1690,12 +1731,12 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw return retVal; } /// - /// Restore all listed registers. + /// Restore all listed pulse mode registers. /// /// /// - Initial. /// - private Boolean RestoreRegisters() + private Boolean RestorePulseModeRegisters() { var retVal = true; try @@ -1754,7 +1795,8 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw /// - Initial. /// /// - /// - Store configuration genesisflow after display release. + /// - Store configuration genesisflow after display release. This is essential if a reboot will occure + /// to have the correct display of the accumulated volume and flow rate! /// private void ReleaseDisplay() { @@ -1810,6 +1852,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw return; LogText(StrSeparator); LogText($"PCB ID: {_currentGenesis.PcbId}"); + LogText($"{Resources.StrMessageCustomerSerialNumber} {_customerSerialNumber}"); LogText($"FW Version: {_currentGenesis.FwVersion}"); LogText($"{Resources.StrMessageSystemCoreRevision} {GenesisMeter.BuildFwVersionString(_currentGenesis.CoreRevision)}"); LogText($"{Resources.StrMessageSystemRegion} {_currentGenesis.Region}"); @@ -2799,9 +2842,11 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw /// and for login with skeleton key: /// - Initial login without register readout being able to quick switch off the pulse mode, /// - Switch off the pulse mode on initial connection, - /// - Activate the radio, + /// - Activate the radio in customer mode, /// - Release the display to normal operation, - /// - Store all configurations on initial connection. + /// - Setup date and time, + /// - Store all configurations on initial connection, + /// - Logs the password file content if not initial connected. /// /// lvl8 or skeleton /// initial connection @@ -2818,26 +2863,22 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw // the pulse mode OFF before reading all installed apps, which will be unpredictable on activated // pulse module var retVal = _currentGenesis.Login(password, skipReadMeterFwAndAssignRegisters: initialLogin); - if (!retVal) - return false; + if (!retVal) return false; // switch the pulse module inactive - if (initialLogin) - DeactivatePulseModule(); + if (initialLogin) DeactivatePulseModule(); // login with reading out all installed applications retVal = _currentGenesis.Login(password); - if (_currentGenesis.RadioFrequencyMhz != null) - ActivateRadio(); + if (_currentGenesis.RadioFrequencyMhz != null) ActivateRadio(); // display to normal operation ReleaseDisplay(); - SetDateTime(); - // safe all settings from RAM to FLASH to keep those for reboot if (initialLogin) { + // safe all settings from RAM to FLASH to keep those for reboot StoreConfigurations(); } @@ -2845,6 +2886,21 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw } /// /// Execution of connect to water-meter. + /// Sequence: + /// - Check if pcbId of meter is set, if not this is an initial login. On initial login it has to require + /// the pcbId (read it from the meter) and mark this initial access as this will execute some special + /// steps , + /// - Create the report files for the detected pcbId, + /// - Searches for update information extracted from the FW update safe and extract password level 8 and + /// the skeleton key, + /// - Delays 3s as a previous login may have failed to avoid blocking of login procedure, + /// - Tries to login with password ( this is the level 8 pwd), exit here if successfully logged in, + /// + /// - If login with password level 8 failed: + /// - If this is not the initial login, the password file may be corrupted or not installed - sets reminder + /// for this, + /// - Delays 5s, + /// - Tries to login with skeletonKey and exit if successfully logged in, else mark procedure as failed. /// /// true if successfully executed /// @@ -2887,10 +2943,18 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw /// /// - Create report file early to catch radio and pulse mode activity. /// + /// + /// - AVOID marking of _passwordFile is corrupted on initial login as the pulse output may be active + /// and needs to be switched OFF first in the , + /// - Verifies password file of meter by reading it out and comparing it with the password file + /// from the FW update safe, remind the hashedPwdFile being able to restore it if not installed, + /// - Additional logging of password login or skeleton login, + /// - Report customer serial number. + /// private Boolean ExecConnect() { var initialLogin = false; - // read out the PCB ID from water-meter to open the password container of this device + // Read out the PCB ID from water-meter needed to open the password container of this device if (string.IsNullOrEmpty(_currentGenesis.PcbId)) { // if the PcbId is unknown, it is an initial login @@ -2898,10 +2962,10 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw _currentGenesis.GetPcbId(); } - // create report file + // Create report file BuildReportFiles(); - // search the PCB ID and extract password for login + // Search the PCB ID and extract password for login String password = null; String skeletonKey = null; _genesisInUpdateList = false; @@ -2911,6 +2975,12 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw { skeletonKey = device.PwdContainer.SkeletonKey; password = device.PwdContainer.PasswordLvl8; + if (!string.IsNullOrEmpty(device.CustomerSerialNumber)) + _customerSerialNumber = device.CustomerSerialNumber; + + _hashedPwdFile = new Byte[MeterPwdDb.PwdFileLength]; + _hashedPwdFile = device.PwdContainer.EncryptedPasswordFile; + _genesisInUpdateList = true; break; } @@ -2922,35 +2992,47 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw return false; } - // delay needed if repeated login trial given by Cordonel, the next communication has to + // Delay needed if repeated login trial given by Cordonel, the next communication has to // wait that long, otherwise the Cordonel locks for 2s, 4s, 8s, 16s and so on on every retry! Thread.Sleep(3000); - // this login may be time consuming on readout of application information + // This login may be time consuming on readout of application information // first try to login with password Level 8, this is needed if the password file is installed if (LoginAndSpecialSetupProcedure(password, initialLogin)) { + LogText(Resources.StrLoginPwdLevel8); + ReadAndLogHashedPasswordFileFromMeter(); + SetDateTime(); _passwordFileIsCorrupted = false; return true; } - // here the password file is corrupted or not installed, try to login with skeletonKey - _passwordFileIsCorrupted = true; + // ATTENTION: + // AVOID marking of _passwordFile is corrupted on initial login as the pulse output may be active + // and needs to be switched OFF first using the LoginAndSpecialSetupProcedure + if (!initialLogin) + { + // Here the password file may be corrupted or not installed, read it out and compare it with + // the content specified in the FW update safe + var pwdFile = new MeterPwdFile(_currentGenesis); + _passwordFileIsCorrupted = _hashedPwdFile == null || !pwdFile.VerifyMeterPwdFile(_hashedPwdFile); + } - // On final login EXPLICIT login with password level 8 to validate password file + // On final login EXPLICIT login with password level 8 to validate password file, log password file if (_finalLoginAfterUpdate) { _processState = ProcessState.Error; return false; } - // delay needed if repeated login trial given by Cordonel, the next communication has to + // Delay needed if repeated login trial given by Cordonel, the next communication has to // wait that long, otherwise the Cordonel locks for 2s, 4s, 8s, 16s and so on on every retry! Thread.Sleep(5000); - // use the skeleton key for login as the password file may not be installed or invalid + // Use the skeleton key for login as the password file may not be installed or invalid if (LoginAndSpecialSetupProcedure(skeletonKey, initialLogin)) { + LogText(Resources.StrLoginSkeletonKey); return true; } @@ -3526,6 +3608,9 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw /// /// - Release display removed. /// + /// + /// - Hashed password file read on connect from FW update safe. + /// private void PwdFileRestore(ProcessState successExitState, ProcessState errorExitState = ProcessState.Error) { // remind the invoker being able to generate error messages based on the last state @@ -3542,49 +3627,41 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw return; } + //TODO THW avoid installation of password file if hash of level 3 equals level 8 + //TODO THW avoid installation if password file level 3 is unequal hashed skeletonKey + //TODO THW avoid installation if password file level 8 is unequal hashed password InfoProcessActive(lblPasswordFileCheck, Resources.StrPasswordFileRestoreActive); // try to install password, first get the password file from device info var pwdFileObject = new MeterPwdFile(_currentGenesis); - var hashedPwdFile = new Byte[MeterPwdDb.PwdFileLength]; - if (_cordonelDeviceInfos != null) + if (_hashedPwdFile != null && _hashedPwdFile.Length == MeterPwdDb.PwdFileLength) { - foreach (var device in _cordonelDeviceInfos.Where(device => _currentGenesis.PcbId == device.PcbId)) + SetControlsCommunicationActive(); + _currentGenesis?.ReLogin(); + if (pwdFileObject.UnlockEraseWriteMeterPwdFile()) { - hashedPwdFile = device.PwdContainer.EncryptedPasswordFile; - break; - } - - if (hashedPwdFile != null && hashedPwdFile.Length == MeterPwdDb.PwdFileLength) - { - SetControlsCommunicationActive(); - _currentGenesis?.ReLogin(); - if (pwdFileObject.UnlockEraseWriteMeterPwdFile()) + if (pwdFileObject.WriteAndVerifyMeterPwdFile(_hashedPwdFile)) { - if (pwdFileObject.WriteMeterPwdFile(hashedPwdFile)) - { - // a reconnect will check for proper installed password file and check the Level 8 pwd. - _processState = ProcessState.Connect; - _passwordFileIsCorrupted = false; - InfoProcessSuccess(lblPasswordFileCheck, Resources.StrPasswordFileRestoreSucceeded); - } + // a reconnect will check for proper installed password file and check the Level 8 pwd. + _processState = ProcessState.Connect; + _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.StrPasswordNotDelivered); - _processState = errorExitState; } - // change first the process state, otherwise the timer may switch the bar on again - SetOverallProgressDisplayOff(); - return; + _currentGenesis?.Logout(); + } + // the password file is NOT in the password container + else + { + InfoProcessFailed(lblPasswordFileCheck, Resources.StrPasswordNotDelivered); + _processState = errorExitState; } - InfoProcessFailed(lblPasswordFileCheck, Resources.StrPasswordFileRestoreFailed); - _processState = errorExitState; // change first the process state, otherwise the timer may switch the bar on again SetOverallProgressDisplayOff(); } @@ -3891,7 +3968,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw var customerOrderSplit = _basePath.CustomerAndOrderNumber.Split(FwUpdateConfig.FwUpdateFileFieldSeparator); LogText(StrSeparator); - InfoProcessSuccess(null, $"{Resources.StrTestReportDate} {DateTime.Now.ToShortDateString()}"); + InfoProcessSuccess(null, $"{Resources.StrTestReportDate} {DateTime.UtcNow:dddd, dd-MMM-yyyy HH:mm:ss} UTC"); InfoProcessSuccess(null, $"{Resources.StrTestReportSwNameVersion} " + $"{_version.Major}.{_version.Minor}.{_version.Build}"); InfoProcessSuccess(null, $"{Resources.StrTestReportCustomerName} {customerOrderSplit[0]}"); diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.Designer.cs b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.Designer.cs index 6cbd720c..2d26c309 100644 --- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.Designer.cs +++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.Designer.cs @@ -556,6 +556,24 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw.Properties { } } + /// + /// Looks up a localized string similar to Successfully logged in with password level 8.. + /// + internal static string StrLoginPwdLevel8 { + get { + return ResourceManager.GetString("StrLoginPwdLevel8", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Successfully logged in with skeletonKey.. + /// + internal static string StrLoginSkeletonKey { + get { + return ResourceManager.GetString("StrLoginSkeletonKey", resourceCulture); + } + } + /// /// Looks up a localized string similar to Not installed. /// @@ -565,6 +583,24 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw.Properties { } } + /// + /// Looks up a localized string similar to Customer serial number:. + /// + internal static string StrMessageCustomerSerialNumber { + get { + return ResourceManager.GetString("StrMessageCustomerSerialNumber", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hashed password file:. + /// + internal static string StrMessageHashedPwdFile { + get { + return ResourceManager.GetString("StrMessageHashedPwdFile", resourceCulture); + } + } + /// /// Looks up a localized string similar to Installed applications:. /// diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.de.resx b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.de.resx index 8fd58f5b..a3e5f87c 100644 --- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.de.resx +++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.de.resx @@ -550,4 +550,16 @@ Datum und Zeit erfolgreich eingestellt + + Erfolgreich angemeldet mit Paßwort Level 8. + + + Erfolgreich angemeldet mit SkeltonKey. + + + Kundenseriennummer: + + + Hashed Paßwortdatei: + \ No newline at end of file diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.resx b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.resx index ade75e3f..d92b1b70 100644 --- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.resx +++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.resx @@ -550,4 +550,16 @@ Date time successfully set + + Successfully logged in with password level 8. + + + Successfully logged in with skeletonKey. + + + Customer serial number: + + + Hashed password file: + \ No newline at end of file