From 216cd968ffcf5be23c5b51a129adf58c9eca63e8 Mon Sep 17 00:00:00 2001 From: amikot <3470285+amikot@users.noreply.github.com> Date: Sun, 30 Oct 2022 21:00:31 +0000 Subject: [PATCH 0001/1079] Update riello_usb.c Added driver setting flag `localcalculation`. When enabled, driver will calculate values of battery.runtime and battery.load locally. This is for some Riello models (iPlug and iDialog series) that provides incorrect values. Local calculation is done according to nominal battery capacity, nominal battery voltage, actual battery charge, maximum and actual UPS load. Added condition to filter off situation when battery temperature variable is incorrectly set to variable type maximum (255) - which is typical issue of some Riello models (iPlug and iDialog series). If incorrect value is detected temperature is set to 0. --- drivers/riello_usb.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/drivers/riello_usb.c b/drivers/riello_usb.c index cec64f5ae4..7c5b00265a 100644 --- a/drivers/riello_usb.c +++ b/drivers/riello_usb.c @@ -833,7 +833,7 @@ void upsdrv_help(void) void upsdrv_makevartable(void) { - + addvar(VAR_FLAG, "localcalculation", "Calculate battery charge and runtime locally"); } void upsdrv_initups(void) @@ -1045,6 +1045,9 @@ void upsdrv_updateinfo(void) uint8_t getextendedOK; static int countlost = 0; int stat; + int battcharge; + float battruntime; + float upsloadfactor; upsdebugx(1, "countlost %d",countlost); @@ -1079,14 +1082,33 @@ void upsdrv_updateinfo(void) dstate_setinfo("input.bypass.frequency", "%.2f", DevData.Fbypass/10.0); dstate_setinfo("output.frequency", "%.2f", DevData.Fout/10.0); dstate_setinfo("battery.voltage", "%.1f", DevData.Ubat/10.0); - if ((DevData.BatCap < 0xFFFF) && (DevData.BatTime < 0xFFFF)) { + if (testvar("localcalculation")) { + battcharge = ((DevData.Ubat <= 129) && (DevData.Ubat >=107)) ? (((DevData.Ubat-107)*100)/22) : ((DevData.Ubat < 107) ? 0 : 100); + battruntime = (DevData.NomBatCap * DevData.NomUbat * 3600.0/DevData.NomPowerKW) * (battcharge/100.0); + upsloadfactor = (DevData.Pout1 > 0) ? (DevData.Pout1/100.0) : 1; + + dstate_setinfo("battery.charge", "%u", battcharge ); + dstate_setinfo("battery.runtime", "%.0f", battruntime/upsloadfactor); + } + else if ((DevData.BatCap < 0xFFFF) && (DevData.BatTime < 0xFFFF)) { + upsdebugx(0, "\n If you don't see values for battery.charge and battery.runtime or values are incorrect," + "try setting \"localcalculation\" flag in \"ups.conf\" " + "options section for this driver!\n"); dstate_setinfo("battery.charge", "%u", DevData.BatCap); - dstate_setinfo("battery.runtime", "%u", DevData.BatTime*60); - } - - if (DevData.Tsystem < 0xFF) - dstate_setinfo("ups.temperature", "%u", DevData.Tsystem); - + dstate_setinfo("battery.runtime", "%u", DevData.BatTime*60); + } + else { + upsdebugx(0, "\n If you don't see values for battery.charge and battery.runtime or values are incorrect," + "try setting \"localcalculation\" flag in \"ups.conf\" " + "options section for this driver!\n"); + } + + if (DevData.Tsystem == 255) { + dstate_setinfo("ups.temperature", "%u", 0 ); + } + else if (DevData.Tsystem < 0xFF) { + dstate_setinfo("ups.temperature", "%u", DevData.Tsystem); + } if (input_monophase) { dstate_setinfo("input.voltage", "%u", DevData.Uinp1); From f2ee6ad6e6d01074b6f43c33678a4aca1ad62f3c Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 31 Oct 2022 01:48:31 +0100 Subject: [PATCH 0002/1079] NEWS: added localcalculation flag for riello_usb --- NEWS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS b/NEWS index c16e1cbce3..5dc9361987 100644 --- a/NEWS +++ b/NEWS @@ -80,6 +80,10 @@ https://github.com/networkupstools/nut/milestone/8 to `battery.mfr.date` (not `battery.date` which is the maintenance replacement date) [#1644] + - riello_usb updates: + * added `localcalculation` option to compute `battery.runtime` and + `battery.load` if the device provides bogus values [#1692, #1685] + - NUT for Windows: * Ability to build NUT for Windows, last tackled with a branch based on NUT v2.6.5 a decade ago, has been revived with the 2.8.x era codebase [#5]. From 72fe9d5fd5b60b754ab671489c3e81aa76c9d0a9 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 31 Oct 2022 01:54:00 +0100 Subject: [PATCH 0003/1079] Update riello_usb.txt Added localcalculation flag description --- docs/man/riello_usb.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/man/riello_usb.txt b/docs/man/riello_usb.txt index 1c4ffd6e43..92e42743bb 100644 --- a/docs/man/riello_usb.txt +++ b/docs/man/riello_usb.txt @@ -25,6 +25,23 @@ riello_usb supports all recent Riello UPS with USB. Older Riello UPS products are not supported. +EXTRA ARGUMENTS +--------------- + +You may need to tweak some settings, depending on the make and model of your UPS +(see linkman:ups.conf[5]): + +*localcalculation*:: +When enabled, driver will calculate values of `battery.runtime` and `battery.load` +locally. This is for some Riello models (iPlug and iDialog series) that provide +incorrect values. Local calculation is done according to nominal battery capacity, +nominal battery voltage, actual battery charge, maximum and actual UPS load. ++ +Lead battery charge graph is not linear, so estimated charge value may not be +perfectly accurate. However it should be good enough to determine battery +actual status and roughly estimate the time it can power the system. + + AUTHOR ------ From 7d7a17855aa455f71f9410123254073740edf06c Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 31 Oct 2022 02:21:05 +0100 Subject: [PATCH 0004/1079] Update nut.dict --- docs/nut.dict | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/nut.dict b/docs/nut.dict index 1670fe4b85..4d19315e93 100644 --- a/docs/nut.dict +++ b/docs/nut.dict @@ -1,4 +1,4 @@ -personal_ws-1.1 en 3043 utf-8 +personal_ws-1.1 en 3044 utf-8 AAS ABI ACFAIL @@ -2141,6 +2141,7 @@ lk lm ln loadPercentage +localcalculation localhost localtime lockf From f1b69932e3bfbce0a1dcac7ddb31a42146446352 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 31 Oct 2022 08:45:44 +0100 Subject: [PATCH 0005/1079] Update nut.dict --- docs/nut.dict | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/nut.dict b/docs/nut.dict index 4d19315e93..cdd1ef87d3 100644 --- a/docs/nut.dict +++ b/docs/nut.dict @@ -1,4 +1,4 @@ -personal_ws-1.1 en 3044 utf-8 +personal_ws-1.1 en 3046 utf-8 AAS ABI ACFAIL @@ -1965,8 +1965,10 @@ hunnox hypervisor hypervisors iBox +iDialog iDowell iManufacturer +iPlug iSerial iUSB ib From 2d78d92cf4e4ce2df961935a14635ff14058b392 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 3 Nov 2022 14:05:17 +0100 Subject: [PATCH 0006/1079] drivers/riello_usb.c: fix indentation [#1692] --- drivers/riello_usb.c | 54 ++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/riello_usb.c b/drivers/riello_usb.c index 7c5b00265a..4848061182 100644 --- a/drivers/riello_usb.c +++ b/drivers/riello_usb.c @@ -1045,9 +1045,9 @@ void upsdrv_updateinfo(void) uint8_t getextendedOK; static int countlost = 0; int stat; - int battcharge; - float battruntime; - float upsloadfactor; + int battcharge; + float battruntime; + float upsloadfactor; upsdebugx(1, "countlost %d",countlost); @@ -1082,33 +1082,33 @@ void upsdrv_updateinfo(void) dstate_setinfo("input.bypass.frequency", "%.2f", DevData.Fbypass/10.0); dstate_setinfo("output.frequency", "%.2f", DevData.Fout/10.0); dstate_setinfo("battery.voltage", "%.1f", DevData.Ubat/10.0); - if (testvar("localcalculation")) { - battcharge = ((DevData.Ubat <= 129) && (DevData.Ubat >=107)) ? (((DevData.Ubat-107)*100)/22) : ((DevData.Ubat < 107) ? 0 : 100); - battruntime = (DevData.NomBatCap * DevData.NomUbat * 3600.0/DevData.NomPowerKW) * (battcharge/100.0); - upsloadfactor = (DevData.Pout1 > 0) ? (DevData.Pout1/100.0) : 1; - - dstate_setinfo("battery.charge", "%u", battcharge ); - dstate_setinfo("battery.runtime", "%.0f", battruntime/upsloadfactor); - } - else if ((DevData.BatCap < 0xFFFF) && (DevData.BatTime < 0xFFFF)) { - upsdebugx(0, "\n If you don't see values for battery.charge and battery.runtime or values are incorrect," - "try setting \"localcalculation\" flag in \"ups.conf\" " - "options section for this driver!\n"); + if (testvar("localcalculation")) { + battcharge = ((DevData.Ubat <= 129) && (DevData.Ubat >=107)) ? (((DevData.Ubat-107)*100)/22) : ((DevData.Ubat < 107) ? 0 : 100); + battruntime = (DevData.NomBatCap * DevData.NomUbat * 3600.0/DevData.NomPowerKW) * (battcharge/100.0); + upsloadfactor = (DevData.Pout1 > 0) ? (DevData.Pout1/100.0) : 1; + + dstate_setinfo("battery.charge", "%u", battcharge ); + dstate_setinfo("battery.runtime", "%.0f", battruntime/upsloadfactor); + } + else if ((DevData.BatCap < 0xFFFF) && (DevData.BatTime < 0xFFFF)) { + upsdebugx(0, "\n If you don't see values for battery.charge and battery.runtime or values are incorrect," + "try setting \"localcalculation\" flag in \"ups.conf\" " + "options section for this driver!\n"); dstate_setinfo("battery.charge", "%u", DevData.BatCap); - dstate_setinfo("battery.runtime", "%u", DevData.BatTime*60); - } - else { - upsdebugx(0, "\n If you don't see values for battery.charge and battery.runtime or values are incorrect," - "try setting \"localcalculation\" flag in \"ups.conf\" " - "options section for this driver!\n"); - } + dstate_setinfo("battery.runtime", "%u", DevData.BatTime*60); + } + else { + upsdebugx(0, "\n If you don't see values for battery.charge and battery.runtime or values are incorrect," + "try setting \"localcalculation\" flag in \"ups.conf\" " + "options section for this driver!\n"); + } if (DevData.Tsystem == 255) { - dstate_setinfo("ups.temperature", "%u", 0 ); - } - else if (DevData.Tsystem < 0xFF) { - dstate_setinfo("ups.temperature", "%u", DevData.Tsystem); - } + dstate_setinfo("ups.temperature", "%u", 0 ); + } + else if (DevData.Tsystem < 0xFF) { + dstate_setinfo("ups.temperature", "%u", DevData.Tsystem); + } if (input_monophase) { dstate_setinfo("input.voltage", "%u", DevData.Uinp1); From 2b2a886f74dd914ef76851302715b43e2b166f50 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 3 Nov 2022 14:08:09 +0100 Subject: [PATCH 0007/1079] drivers/riello_usb.c: deduplicate message about possibly missing battery.charge and battery.runtime [#1692] --- drivers/riello_usb.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/riello_usb.c b/drivers/riello_usb.c index 4848061182..15df617e1e 100644 --- a/drivers/riello_usb.c +++ b/drivers/riello_usb.c @@ -1087,20 +1087,18 @@ void upsdrv_updateinfo(void) battruntime = (DevData.NomBatCap * DevData.NomUbat * 3600.0/DevData.NomPowerKW) * (battcharge/100.0); upsloadfactor = (DevData.Pout1 > 0) ? (DevData.Pout1/100.0) : 1; - dstate_setinfo("battery.charge", "%u", battcharge ); + dstate_setinfo("battery.charge", "%u", battcharge); dstate_setinfo("battery.runtime", "%.0f", battruntime/upsloadfactor); } - else if ((DevData.BatCap < 0xFFFF) && (DevData.BatTime < 0xFFFF)) { - upsdebugx(0, "\n If you don't see values for battery.charge and battery.runtime or values are incorrect," - "try setting \"localcalculation\" flag in \"ups.conf\" " - "options section for this driver!\n"); - dstate_setinfo("battery.charge", "%u", DevData.BatCap); - dstate_setinfo("battery.runtime", "%u", DevData.BatTime*60); - } else { - upsdebugx(0, "\n If you don't see values for battery.charge and battery.runtime or values are incorrect," + upsdebugx(0, "\n If you don't see values for battery.charge and " + "battery.runtime or values are incorrect," "try setting \"localcalculation\" flag in \"ups.conf\" " "options section for this driver!\n"); + if ((DevData.BatCap < 0xFFFF) && (DevData.BatTime < 0xFFFF)) { + dstate_setinfo("battery.charge", "%u", DevData.BatCap); + dstate_setinfo("battery.runtime", "%u", DevData.BatTime*60); + } } if (DevData.Tsystem == 255) { From 8aaea69e0183d8714412a1afbfe34014fd298b41 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 3 Nov 2022 14:22:09 +0100 Subject: [PATCH 0008/1079] NEWS, docs/man/riello_usb.txt: fix "docs/man/riello_usb.txt" description [#1692] --- NEWS | 2 +- docs/man/riello_usb.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 5dc9361987..6893f43698 100644 --- a/NEWS +++ b/NEWS @@ -82,7 +82,7 @@ https://github.com/networkupstools/nut/milestone/8 - riello_usb updates: * added `localcalculation` option to compute `battery.runtime` and - `battery.load` if the device provides bogus values [#1692, #1685] + `battery.charge` if the device provides bogus values [#1692, #1685] - NUT for Windows: * Ability to build NUT for Windows, last tackled with a branch based on diff --git a/docs/man/riello_usb.txt b/docs/man/riello_usb.txt index 92e42743bb..3ac3b796a6 100644 --- a/docs/man/riello_usb.txt +++ b/docs/man/riello_usb.txt @@ -32,7 +32,7 @@ You may need to tweak some settings, depending on the make and model of your UPS (see linkman:ups.conf[5]): *localcalculation*:: -When enabled, driver will calculate values of `battery.runtime` and `battery.load` +When enabled, driver will calculate values of `battery.runtime` and `battery.charge` locally. This is for some Riello models (iPlug and iDialog series) that provide incorrect values. Local calculation is done according to nominal battery capacity, nominal battery voltage, actual battery charge, maximum and actual UPS load. From 73d2530508ae134734fddc7bb7ecb6f79a0ae86c Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 3 Nov 2022 14:23:20 +0100 Subject: [PATCH 0009/1079] drivers/riello_usb.c: only log once about possibly missing battery.charge and battery.runtime [#1692] --- drivers/riello_usb.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/riello_usb.c b/drivers/riello_usb.c index 15df617e1e..fe3cd7f4cd 100644 --- a/drivers/riello_usb.c +++ b/drivers/riello_usb.c @@ -70,6 +70,8 @@ static USBDevice_t usbdevice; static USBDeviceMatcher_t *reopen_matcher = NULL; static USBDeviceMatcher_t *regex_matcher = NULL; +static int localcalculation_logged = 0; + static int (*subdriver_command)(uint8_t *cmd, uint8_t *buf, uint16_t length, uint16_t buflen) = NULL; static void ussleep(useconds_t usec) @@ -1091,10 +1093,13 @@ void upsdrv_updateinfo(void) dstate_setinfo("battery.runtime", "%.0f", battruntime/upsloadfactor); } else { - upsdebugx(0, "\n If you don't see values for battery.charge and " + if (!localcalculation_logged) { + upsdebugx(0, "\nIf you don't see values for battery.charge and " "battery.runtime or values are incorrect," "try setting \"localcalculation\" flag in \"ups.conf\" " "options section for this driver!\n"); + localcalculation_logged = 1; + } if ((DevData.BatCap < 0xFFFF) && (DevData.BatTime < 0xFFFF)) { dstate_setinfo("battery.charge", "%u", DevData.BatCap); dstate_setinfo("battery.runtime", "%u", DevData.BatTime*60); From 786b5aeffe014f94e8994e70b0f0cd0fe0a821fb Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 3 Nov 2022 14:24:11 +0100 Subject: [PATCH 0010/1079] drivers/riello_usb.c: do not set bogus "ups.temperature" as 0, log low-prio message instead [#1692] --- drivers/riello_usb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/riello_usb.c b/drivers/riello_usb.c index fe3cd7f4cd..cecf12600d 100644 --- a/drivers/riello_usb.c +++ b/drivers/riello_usb.c @@ -1107,7 +1107,10 @@ void upsdrv_updateinfo(void) } if (DevData.Tsystem == 255) { - dstate_setinfo("ups.temperature", "%u", 0 ); + /*dstate_setinfo("ups.temperature", "%u", 0);*/ + upsdebugx(4, "Reported temperature value is 0xFF, " + "probably meaning \"-1\" for error or " + "missing sensor - ignored"); } else if (DevData.Tsystem < 0xFF) { dstate_setinfo("ups.temperature", "%u", DevData.Tsystem); From 5372bce7fb8510b3519d79832072e14467e282f1 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 3 Nov 2022 14:31:19 +0100 Subject: [PATCH 0011/1079] drivers/riello_usb.c: testvar("localcalculation") only once, use cached int in the loop [#1692] --- drivers/riello_usb.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/riello_usb.c b/drivers/riello_usb.c index cecf12600d..e2c4694d8b 100644 --- a/drivers/riello_usb.c +++ b/drivers/riello_usb.c @@ -70,6 +70,8 @@ static USBDevice_t usbdevice; static USBDeviceMatcher_t *reopen_matcher = NULL; static USBDeviceMatcher_t *regex_matcher = NULL; +/* Flag for estimation of battery.runtime and battery.charge */ +static int localcalculation = 0; static int localcalculation_logged = 0; static int (*subdriver_command)(uint8_t *cmd, uint8_t *buf, uint16_t length, uint16_t buflen) = NULL; @@ -941,6 +943,11 @@ void upsdrv_initinfo(void) else upsdebugx(2, "Communication with UPS established"); + if (testvar("localcalculation")) { + localcalculation = 1; + } + dstate_setinfo("driver.parameter.localcalculation", "%d", localcalculation); + riello_parse_gi(&bufIn[0], &DevData); gpser_error_control = DevData.Identif_bytes[4]-0x30; @@ -1084,7 +1091,7 @@ void upsdrv_updateinfo(void) dstate_setinfo("input.bypass.frequency", "%.2f", DevData.Fbypass/10.0); dstate_setinfo("output.frequency", "%.2f", DevData.Fout/10.0); dstate_setinfo("battery.voltage", "%.1f", DevData.Ubat/10.0); - if (testvar("localcalculation")) { + if (localcalculation) { battcharge = ((DevData.Ubat <= 129) && (DevData.Ubat >=107)) ? (((DevData.Ubat-107)*100)/22) : ((DevData.Ubat < 107) ? 0 : 100); battruntime = (DevData.NomBatCap * DevData.NomUbat * 3600.0/DevData.NomPowerKW) * (battcharge/100.0); upsloadfactor = (DevData.Pout1 > 0) ? (DevData.Pout1/100.0) : 1; From 6c405af2d9b425590f3433937e92edc6ff9b052f Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 3 Nov 2022 18:35:54 +0100 Subject: [PATCH 0012/1079] Update riello_usb.txt Use "guesstimate" as common NUT term for future searches --- docs/man/riello_usb.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/man/riello_usb.txt b/docs/man/riello_usb.txt index 3ac3b796a6..d3123d912c 100644 --- a/docs/man/riello_usb.txt +++ b/docs/man/riello_usb.txt @@ -37,7 +37,7 @@ locally. This is for some Riello models (iPlug and iDialog series) that provide incorrect values. Local calculation is done according to nominal battery capacity, nominal battery voltage, actual battery charge, maximum and actual UPS load. + -Lead battery charge graph is not linear, so estimated charge value may not be +Lead battery charge graph is not linear, so guesstimated charge value may not be perfectly accurate. However it should be good enough to determine battery actual status and roughly estimate the time it can power the system. From cc122106cad7ba543b16023b713355f7aebb8bc0 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 3 Nov 2022 18:38:07 +0100 Subject: [PATCH 0013/1079] Update riello_usb.c Log that guesstimation will be used instead of device readings (if any) --- drivers/riello_usb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/riello_usb.c b/drivers/riello_usb.c index e2c4694d8b..019feae62b 100644 --- a/drivers/riello_usb.c +++ b/drivers/riello_usb.c @@ -945,6 +945,8 @@ void upsdrv_initinfo(void) if (testvar("localcalculation")) { localcalculation = 1; + upsdebugx(1, "Will guesstimate battery charge and runtime " + "instead of trusting device readings (if any)"); } dstate_setinfo("driver.parameter.localcalculation", "%d", localcalculation); From f494b25ebff8eadaf56da3e7172dc977b748902b Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 28 Jan 2023 15:31:26 +0100 Subject: [PATCH 0014/1079] Update riello_usb.txt --- docs/man/riello_usb.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/man/riello_usb.txt b/docs/man/riello_usb.txt index 73037bf8a3..b5328bfeb8 100644 --- a/docs/man/riello_usb.txt +++ b/docs/man/riello_usb.txt @@ -44,7 +44,10 @@ nominal battery voltage, actual battery charge, maximum and actual UPS load. Lead battery charge graph is not linear, so guesstimated charge value may not be perfectly accurate. However it should be good enough to determine battery actual status and roughly estimate the time it can power the system. - ++ +NOTE: This keyword may be deprecated in future releases of the driver, in favor of +`runtimecal` and other settings which it requires (as seen in linkman:nutdrv_qx[8], +linkman:blazer_ser[8] and linkman:blazer_usb[8] drivers). AUTHOR ------ From bfc93479b2f05561ef5859a78f8cf0b2fae64792 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 28 Jan 2023 15:32:43 +0100 Subject: [PATCH 0015/1079] Update NEWS --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index 65fae6f7c2..853f832dac 100644 --- a/NEWS +++ b/NEWS @@ -101,6 +101,8 @@ https://github.com/networkupstools/nut/milestone/8 - riello_usb updates: * added `localcalculation` option to compute `battery.runtime` and `battery.charge` if the device provides bogus values [#1692, #1685] + (similar to `runtimecal` in some other drivers, may be refactored + to that configuration and logic model in later NUT releases) - powercom driver should now try harder to refresh data from device [#356] From 3c5c0019f7afc1adcc71809dfc1c3b151bf3aac5 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 28 Jan 2023 15:46:23 +0100 Subject: [PATCH 0016/1079] Update riello_usb.txt --- docs/man/riello_usb.txt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/man/riello_usb.txt b/docs/man/riello_usb.txt index b5328bfeb8..3b35bc6053 100644 --- a/docs/man/riello_usb.txt +++ b/docs/man/riello_usb.txt @@ -45,9 +45,12 @@ Lead battery charge graph is not linear, so guesstimated charge value may not be perfectly accurate. However it should be good enough to determine battery actual status and roughly estimate the time it can power the system. + -NOTE: This keyword may be deprecated in future releases of the driver, in favor of +WARNING: This keyword may be deprecated in future releases of the driver, in favor of `runtimecal` and other settings which it requires (as seen in linkman:nutdrv_qx[8], linkman:blazer_ser[8] and linkman:blazer_usb[8] drivers). ++ +NOTE: In this release, such an option is not offered for the sibling +linkman:riello_ser[8] driver. AUTHOR ------ @@ -57,8 +60,13 @@ Massimo Zampieri SEE ALSO -------- +Related drivers +~~~~~~~~~~~~~~~ + +linkman:riello_ser[8] + The core driver -~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~ linkman:nutupsdrv[8] From 7a8430dc160bd5821a3a2f9e09dd739ce9164fc5 Mon Sep 17 00:00:00 2001 From: Axel Gembe Date: Tue, 14 Nov 2023 01:47:38 +0700 Subject: [PATCH 0017/1079] apc_modbus: Updates, command, writable variables and outlet group support This adds support for commands, writable variables and outlet groups. - For commands there is a new table called `apc_modbus_command_map` which defines the supported commands as a tuple of command name, register offset and value to write. This also adds a new instcmd status called `STAT_INSTCMD_CONVERSION_FAILED` for when conversion of values fails. On startup all the commands are registered using `dstate_addcmd`. This also adds support for the `upsdrv_shutdown` function. - For writable variables we added a new flag called `APC_VF_RW` to the existing variables that indicates a writable variable. We added code to convert from a string to UINT/INT/STRING variables with output in APCs register format. There is a new `_apc_modbus_setvar` function that handles setting variables and rereading them from the device. This also adds a new setvar status called `STAT_SET_CONVERSION_FAILED` for when conversion of values fails. Variables are now correctly set as `ST_FLAG_STRING` and `ST_FLAG_RW` and we call `dstate_setaux` to give a maximum length for strings. - For outlet groups, we now have names, configurable delays and commands per outlet group. Devices have an outlet group called MOG (Main outlet group) that switches all the outputs of the UPS and 1-3 SOGs (Switched outlet groups) that can be controlled independently. Note that MOG is `outlet.group.0` and the SOGs start at `outlet.group.1`. The outlet groups should have markings with the same index at the back of the unit. - This also reduces the length of some of the defines to make the variable maps more readable. - It also adds a comment to when the reopen matcher is created that clarifies why we create it. Signed-off-by: Axel Gembe --- drivers/apc_modbus.c | 544 +++++++++++++++++++++++++++++++++++++------ drivers/apc_modbus.h | 78 +++++++ drivers/upshandler.h | 18 +- 3 files changed, 562 insertions(+), 78 deletions(-) create mode 100644 drivers/apc_modbus.h diff --git a/drivers/apc_modbus.c b/drivers/apc_modbus.c index 7e437e2fce..27ffe244e0 100644 --- a/drivers/apc_modbus.c +++ b/drivers/apc_modbus.c @@ -24,6 +24,7 @@ #endif /* defined NUT_MODBUS_HAS_USB */ #include "timehead.h" #include "nut_stdint.h" +#include "apc_modbus.h" #include #include @@ -31,7 +32,7 @@ #include #define DRIVER_NAME "NUT APC Modbus driver" -#define DRIVER_VERSION "0.01" +#define DRIVER_VERSION "0.10" #if defined NUT_MODBUS_HAS_USB @@ -89,23 +90,30 @@ upsdrv_info_t upsdrv_info = { }; typedef enum { - APC_MODBUS_VALUE_TYPE_INT = 0, - APC_MODBUS_VALUE_TYPE_UINT, - APC_MODBUS_VALUE_TYPE_STRING + APC_VT_INT = 0, + APC_VT_UINT, + APC_VT_STRING } apc_modbus_value_types; -static const apc_modbus_value_types apc_modbus_value_types_max = APC_MODBUS_VALUE_TYPE_STRING; +typedef enum { + APC_VF_NONE = 0, + APC_VF_RW = (1 << 0) +} apc_modbus_value_flags; + +static const apc_modbus_value_types apc_modbus_value_types_max = APC_VT_STRING; + +typedef union { + int64_t int_value; + uint64_t uint_value; + char *string_value; +} apc_modbus_value_data_t; typedef struct { apc_modbus_value_types type; const char *format; int scale; void *variable_ptr; - union { - int64_t int_value; - uint64_t uint_value; - char *string_value; - } data; + apc_modbus_value_data_t data; } apc_modbus_value_t; typedef struct { @@ -178,6 +186,37 @@ static int _apc_modbus_to_string(const uint16_t *value, const size_t value_len, return 1; } +static int _apc_modbus_from_string(const char *value, uint16_t *output, size_t output_len) +{ + size_t value_len, vi, oi; + uint16_t tmp; + + if (value == NULL || output == NULL) { + /* Invalid parameters */ + return 0; + } + + value_len = strlen(value); + + if (value_len > (output_len * sizeof(uint16_t))) { + /* Output buffer too small */ + return 0; + } + + for (vi = 0, oi = 0; vi < value_len && oi < output_len; vi += 2, oi++) { + tmp = value[vi] << 8; + if (vi + 1 < value_len) + tmp |= value[vi + 1]; + output[oi] = tmp; + } + + for (; oi < output_len; oi++) { + output[oi] = 0; + } + + return 1; +} + /* Converts a Modbus integer to a uint64_t. * See MPAO-98KJ7F_EN section 1.3.1 Numbers. */ static int _apc_modbus_to_uint64(const uint16_t *value, const size_t value_len, uint64_t *output) @@ -197,6 +236,51 @@ static int _apc_modbus_to_uint64(const uint16_t *value, const size_t value_len, return 1; } +static int _apc_modbus_from_uint64(uint64_t value, uint16_t *output, size_t output_len) +{ + ssize_t oi; + size_t bits; + + if (output == NULL) { + /* Invalid parameters */ + return 0; + } + + bits = output_len * sizeof(uint16_t) * 8; + if (bits < 64) { + if (value > ((1ULL << bits) - 1)) { + /* Overflow */ + return 0; + } + } + + for (oi = output_len - 1; oi >= 0; oi--) { + output[oi] = (uint16_t)(value & 0xFFFF); + value >>= 16; + } + + return 1; +} + +static int _apc_modbus_from_uint64_string(const char *value, uint16_t *output, size_t output_len) +{ + uint64_t value_uint; + char *endptr; + + if (value == NULL || output == NULL) { + /* Invalid parameters */ + return 0; + } + + errno = 0; + value_uint = strtoull(value, &endptr, 0); + if (endptr == value || *endptr != '\0' || errno > 0) { + return 0; + } + + return _apc_modbus_from_uint64(value_uint, output, output_len); +} + static int _apc_modbus_to_int64(const uint16_t *value, const size_t value_len, int64_t *output) { size_t shiftval; @@ -212,6 +296,50 @@ static int _apc_modbus_to_int64(const uint16_t *value, const size_t value_len, i return 1; } +static int _apc_modbus_from_int64(int64_t value, uint16_t *output, size_t output_len) +{ + ssize_t oi; + size_t bits; + + if (output == NULL) { + /* Invalid parameters */ + return 0; + } + + bits = output_len * sizeof(uint16_t) * 8; + if (value > ((1LL << (bits - 1)) - 1) || + value < -(1LL << (bits - 1))) { + /* Overflow */ + return 0; + } + + for (oi = output_len - 1; oi >= 0; oi--) { + output[oi] = (uint16_t)(value & 0xFFFF); + value >>= 16; + } + + return 1; +} + +static int _apc_modbus_from_int64_string(const char *value, uint16_t *output, size_t output_len) +{ + int64_t value_int; + char *endptr; + + if (value == NULL || output == NULL) { + /* Invalid parameters */ + return 0; + } + + errno = 0; + value_int = strtoll(value, &endptr, 0); + if (endptr == value || *endptr != '\0' || errno > 0) { + return 0; + } + + return _apc_modbus_from_int64(value_int, output, output_len); +} + static int _apc_modbus_to_double(const apc_modbus_value_t *value, double *output) { int factor; @@ -225,13 +353,13 @@ static int _apc_modbus_to_double(const apc_modbus_value_t *value, double *output assert(value->type <= apc_modbus_value_types_max); switch (value->type) { - case APC_MODBUS_VALUE_TYPE_INT: + case APC_VT_INT: *output = (double)value->data.int_value / factor; break; - case APC_MODBUS_VALUE_TYPE_UINT: + case APC_VT_UINT: *output = (double)value->data.uint_value / factor; break; - case APC_MODBUS_VALUE_TYPE_STRING: + case APC_VT_STRING: return 0; } @@ -332,7 +460,7 @@ static int _apc_modbus_voltage_to_nut(const apc_modbus_value_t *value, char *out return 0; } - if (value->type != APC_MODBUS_VALUE_TYPE_UINT) { + if (value->type != APC_VT_UINT) { return 0; } @@ -360,7 +488,7 @@ static int _apc_modbus_efficiency_to_nut(const apc_modbus_value_t *value, char * return 0; } - if (value->type != APC_MODBUS_VALUE_TYPE_INT) { + if (value->type != APC_VT_INT) { return 0; } @@ -413,7 +541,7 @@ static int _apc_modbus_status_change_cause_to_nut(const apc_modbus_value_t *valu return 0; } - if (value->type != APC_MODBUS_VALUE_TYPE_UINT) { + if (value->type != APC_VT_UINT) { return 0; } @@ -526,35 +654,62 @@ static int _apc_modbus_status_change_cause_to_nut(const apc_modbus_value_t *valu static apc_modbus_converter_t _apc_modbus_status_change_cause_conversion = { _apc_modbus_status_change_cause_to_nut, NULL }; +static const time_t apc_date_start_offset = 946684800; /* 2000-01-01 00:00 */ + static int _apc_modbus_date_to_nut(const apc_modbus_value_t *value, char *output, size_t output_len) { struct tm *tm_info; time_t time_stamp; - const time_t start_offset = 946684800; /* 2000-01-01 00:00 */ if (value == NULL || output == NULL || output_len == 0) { /* Invalid parameters */ return 0; } - if (value->type != APC_MODBUS_VALUE_TYPE_UINT) { + if (value->type != APC_VT_UINT) { return 0; } - time_stamp = ((int64_t)value->data.uint_value * 86400) + start_offset; + time_stamp = ((int64_t)value->data.uint_value * 86400) + apc_date_start_offset; tm_info = gmtime(&time_stamp); strftime(output, output_len, "%Y-%m-%d", tm_info); return 1; } -static apc_modbus_converter_t _apc_modbus_date_conversion = { _apc_modbus_date_to_nut, NULL }; +static int _apc_modbus_date_from_nut(const char *value, uint16_t *output, size_t output_len) +{ + struct tm tm_struct; + time_t epoch_time; + uint64_t uint_value; + + if (value == NULL || output == NULL || output_len == 0) { + /* Invalid parameters */ + return 0; + } + + memset(&tm_struct, 0, sizeof(tm_struct)); + if (strptime(value, "%Y-%m-%d", &tm_struct) == NULL) { + return 0; + } + + if ((epoch_time = mktime(&tm_struct)) == -1) { + return 0; + } + + uint_value = (epoch_time - apc_date_start_offset) / 86400; + + return _apc_modbus_from_uint64(uint_value, output, output_len); +} + +static apc_modbus_converter_t _apc_modbus_date_conversion = { _apc_modbus_date_to_nut, _apc_modbus_date_from_nut }; typedef struct { const char *nut_variable_name; size_t modbus_addr; size_t modbus_len; /* Number of uint16_t registers */ apc_modbus_value_types value_type; + apc_modbus_value_flags value_flags; apc_modbus_converter_t *value_converter; const char *value_format; int value_scale; @@ -563,50 +718,73 @@ typedef struct { /* Values that only need to be updated once on startup */ static apc_modbus_register_t apc_modbus_register_map_inventory[] = { - { "ups.firmware", 516, 8, APC_MODBUS_VALUE_TYPE_STRING, NULL, "%s", 0, NULL }, - { "ups.model", 532, 16, APC_MODBUS_VALUE_TYPE_STRING, NULL, "%s", 0, NULL }, /* also device.model, filled automatically */ - { "ups.serial", 564, 8, APC_MODBUS_VALUE_TYPE_STRING, NULL, "%s", 0, NULL }, /* also device.serial, filled automatically */ - { "ups.power.nominal", 588, 1, APC_MODBUS_VALUE_TYPE_UINT, &_apc_modbus_double_conversion, "%.0f", 0, &power_nominal }, - { "ups.realpower.nominal", 589, 1, APC_MODBUS_VALUE_TYPE_UINT, &_apc_modbus_double_conversion, "%.0f", 0, &realpower_nominal }, - { "ups.mfr.date", 591, 1, APC_MODBUS_VALUE_TYPE_UINT, &_apc_modbus_date_conversion, NULL, 0, NULL }, - { "battery.date", 595, 1, APC_MODBUS_VALUE_TYPE_UINT, &_apc_modbus_date_conversion, NULL, 0, NULL }, - { "ups.id", 596, 8, APC_MODBUS_VALUE_TYPE_STRING, NULL, "%s", 0, NULL }, - { NULL, 0, 0, 0, NULL, NULL, 0.0f, NULL } + { "ups.firmware", 516, 8, APC_VT_STRING, 0, NULL, "%s", 0, NULL }, + { "ups.model", 532, 16, APC_VT_STRING, 0, NULL, "%s", 0, NULL }, /* also device.model, filled automatically */ + { "ups.serial", 564, 8, APC_VT_STRING, 0, NULL, "%s", 0, NULL }, /* also device.serial, filled automatically */ + { "ups.power.nominal", 588, 1, APC_VT_UINT, 0, &_apc_modbus_double_conversion, "%.0f", 0, &power_nominal }, + { "ups.realpower.nominal", 589, 1, APC_VT_UINT, 0, &_apc_modbus_double_conversion, "%.0f", 0, &realpower_nominal }, + { "ups.mfr.date", 591, 1, APC_VT_UINT, 0, &_apc_modbus_date_conversion, NULL, 0, NULL }, + { "battery.date", 595, 1, APC_VT_UINT, APC_VF_RW, &_apc_modbus_date_conversion, NULL, 0, NULL }, + { "ups.id", 596, 8, APC_VT_STRING, APC_VF_RW, NULL, "%s", 0, NULL }, + { "outlet.group.0.name", 604, 8, APC_VT_STRING, APC_VF_RW, NULL, "%s", 0, NULL }, + { "outlet.group.1.name", 612, 8, APC_VT_STRING, APC_VF_RW, NULL, "%s", 0, NULL }, + { "outlet.group.2.name", 620, 8, APC_VT_STRING, APC_VF_RW, NULL, "%s", 0, NULL }, + { "outlet.group.3.name", 628, 8, APC_VT_STRING, APC_VF_RW, NULL, "%s", 0, NULL }, + { NULL, 0, 0, 0, 0, NULL, NULL, 0.0f, NULL } }; static apc_modbus_register_t apc_modbus_register_map_status[] = { - { "input.transfer.reason", 2, 1, APC_MODBUS_VALUE_TYPE_UINT, &_apc_modbus_status_change_cause_conversion, NULL, 0, NULL }, - { NULL, 0, 0, 0, NULL, NULL, 0.0f, NULL } + { "input.transfer.reason", 2, 1, APC_VT_UINT, 0, &_apc_modbus_status_change_cause_conversion, NULL, 0, NULL }, + { NULL, 0, 0, 0, 0, NULL, NULL, 0.0f, NULL } }; static apc_modbus_register_t apc_modbus_register_map_dynamic[] = { - { "battery.runtime", 128, 2, APC_MODBUS_VALUE_TYPE_UINT, NULL, "%u", 0, NULL }, - { "battery.charge", 130, 1, APC_MODBUS_VALUE_TYPE_UINT, &_apc_modbus_double_conversion, "%.2f", 9, NULL }, - { "battery.voltage", 131, 1, APC_MODBUS_VALUE_TYPE_INT, &_apc_modbus_double_conversion, "%.2f", 5, NULL }, - { "battery.date.maintenance", 133, 1, APC_MODBUS_VALUE_TYPE_UINT, &_apc_modbus_date_conversion, NULL, 0, NULL }, - { "battery.temperature", 135, 1, APC_MODBUS_VALUE_TYPE_INT, &_apc_modbus_double_conversion, "%.2f", 7, NULL }, - { "ups.load", 136, 1, APC_MODBUS_VALUE_TYPE_UINT, &_apc_modbus_double_conversion, "%.2f", 8, NULL }, - { "ups.realpower", 136, 1, APC_MODBUS_VALUE_TYPE_UINT, &_apc_modbus_power_conversion, "%.2f", 8, &realpower_nominal }, - { "ups.power", 138, 1, APC_MODBUS_VALUE_TYPE_UINT, &_apc_modbus_power_conversion, "%.2f", 8, &power_nominal }, - { "output.current", 140, 1, APC_MODBUS_VALUE_TYPE_UINT, &_apc_modbus_double_conversion, "%.2f", 5, NULL }, - { "output.voltage", 142, 1, APC_MODBUS_VALUE_TYPE_UINT, &_apc_modbus_double_conversion, "%.2f", 6, NULL }, - { "output.frequency", 144, 1, APC_MODBUS_VALUE_TYPE_UINT, &_apc_modbus_double_conversion, "%.2f", 7, NULL }, - { "experimental.output.energy", 145, 2, APC_MODBUS_VALUE_TYPE_UINT, NULL, "%u", 0, NULL }, - { "input.voltage", 151, 1, APC_MODBUS_VALUE_TYPE_UINT, &_apc_modbus_voltage_conversion, "%.2f", 6, NULL }, - { "ups.efficiency", 154, 1, APC_MODBUS_VALUE_TYPE_INT, &_apc_modbus_efficiency_conversion, "%.1f", 7, NULL }, - { "ups.timer.shutdown", 155, 1, APC_MODBUS_VALUE_TYPE_INT, NULL, "%d", 0, NULL }, - { "ups.timer.start", 156, 1, APC_MODBUS_VALUE_TYPE_INT, NULL, "%d", 0, NULL }, - { "ups.timer.reboot", 157, 2, APC_MODBUS_VALUE_TYPE_INT, NULL, "%d", 0, NULL }, - { NULL, 0, 0, 0, NULL, NULL, 0.0f, NULL } + { "battery.runtime", 128, 2, APC_VT_UINT, 0, NULL, "%u", 0, NULL }, + { "battery.charge", 130, 1, APC_VT_UINT, 0, &_apc_modbus_double_conversion, "%.2f", 9, NULL }, + { "battery.voltage", 131, 1, APC_VT_INT, 0, &_apc_modbus_double_conversion, "%.2f", 5, NULL }, + { "battery.date.maintenance", 133, 1, APC_VT_UINT, 0, &_apc_modbus_date_conversion, NULL, 0, NULL }, + { "battery.temperature", 135, 1, APC_VT_INT, 0, &_apc_modbus_double_conversion, "%.2f", 7, NULL }, + { "ups.load", 136, 1, APC_VT_UINT, 0, &_apc_modbus_double_conversion, "%.2f", 8, NULL }, + { "ups.realpower", 136, 1, APC_VT_UINT, 0, &_apc_modbus_power_conversion, "%.2f", 8, &realpower_nominal }, + { "ups.power", 138, 1, APC_VT_UINT, 0, &_apc_modbus_power_conversion, "%.2f", 8, &power_nominal }, + { "output.current", 140, 1, APC_VT_UINT, 0, &_apc_modbus_double_conversion, "%.2f", 5, NULL }, + { "output.voltage", 142, 1, APC_VT_UINT, 0, &_apc_modbus_double_conversion, "%.2f", 6, NULL }, + { "output.frequency", 144, 1, APC_VT_UINT, 0, &_apc_modbus_double_conversion, "%.2f", 7, NULL }, + { "experimental.output.energy", 145, 2, APC_VT_UINT, 0, NULL, "%u", 0, NULL }, + { "input.voltage", 151, 1, APC_VT_UINT, 0, &_apc_modbus_voltage_conversion, "%.2f", 6, NULL }, + { "ups.efficiency", 154, 1, APC_VT_INT, 0, &_apc_modbus_efficiency_conversion, "%.1f", 7, NULL }, + { "ups.timer.shutdown", 155, 1, APC_VT_INT, 0, NULL, "%d", 0, NULL }, + { "ups.timer.start", 156, 1, APC_VT_INT, 0, NULL, "%d", 0, NULL }, + { "ups.timer.reboot", 157, 2, APC_VT_INT, 0, NULL, "%d", 0, NULL }, + { NULL, 0, 0, 0, 0, NULL, NULL, 0.0f, NULL } }; static apc_modbus_register_t apc_modbus_register_map_static[] = { - { "input.transfer.high", 1026, 1, APC_MODBUS_VALUE_TYPE_UINT, NULL, "%u", 0, NULL }, - { "input.transfer.low", 1027, 1, APC_MODBUS_VALUE_TYPE_UINT, NULL, "%u", 0, NULL }, - { "ups.delay.shutdown", 1029, 1, APC_MODBUS_VALUE_TYPE_INT, NULL, "%d", 0, NULL }, - { "ups.delay.start", 1030, 1, APC_MODBUS_VALUE_TYPE_INT, NULL, "%d", 0, NULL }, - { "ups.delay.reboot", 1031, 2, APC_MODBUS_VALUE_TYPE_INT, NULL, "%d", 0, NULL }, - { NULL, 0, 0, 0, NULL, NULL, 0.0f, NULL } + { "input.transfer.high", 1026, 1, APC_VT_UINT, APC_VF_RW, NULL, "%u", 0, NULL }, + { "input.transfer.low", 1027, 1, APC_VT_UINT, APC_VF_RW, NULL, "%u", 0, NULL }, + { "ups.delay.shutdown", 1029, 1, APC_VT_INT, APC_VF_RW, NULL, "%d", 0, NULL }, + { "ups.delay.start", 1030, 1, APC_VT_INT, APC_VF_RW, NULL, "%d", 0, NULL }, + { "ups.delay.reboot", 1031, 2, APC_VT_INT, APC_VF_RW, NULL, "%d", 0, NULL }, + { "outlet.group.0.delay.shutdown", 1029, 1, APC_VT_INT, APC_VF_RW, NULL, "%d", 0, NULL }, + { "outlet.group.0.delay.start", 1030, 1, APC_VT_INT, APC_VF_RW, NULL, "%d", 0, NULL }, + { "outlet.group.0.delay.reboot", 1031, 2, APC_VT_INT, APC_VF_RW, NULL, "%d", 0, NULL }, + { "outlet.group.1.delay.shutdown", 1034, 1, APC_VT_INT, APC_VF_RW, NULL, "%d", 0, NULL }, + { "outlet.group.1.delay.start", 1035, 1, APC_VT_INT, APC_VF_RW, NULL, "%d", 0, NULL }, + { "outlet.group.1.delay.reboot", 1036, 2, APC_VT_INT, APC_VF_RW, NULL, "%d", 0, NULL }, + { "outlet.group.2.delay.shutdown", 1039, 1, APC_VT_INT, APC_VF_RW, NULL, "%d", 0, NULL }, + { "outlet.group.2.delay.start", 1040, 1, APC_VT_INT, APC_VF_RW, NULL, "%d", 0, NULL }, + { "outlet.group.2.delay.reboot", 1041, 2, APC_VT_INT, APC_VF_RW, NULL, "%d", 0, NULL }, + { "outlet.group.3.delay.shutdown", 1044, 1, APC_VT_INT, APC_VF_RW, NULL, "%d", 0, NULL }, + { "outlet.group.3.delay.start", 1045, 1, APC_VT_INT, APC_VF_RW, NULL, "%d", 0, NULL }, + { "outlet.group.3.delay.reboot", 1046, 2, APC_VT_INT, APC_VF_RW, NULL, "%d", 0, NULL }, + { NULL, 0, 0, 0, 0, NULL, NULL, 0.0f, NULL } +}; + +static apc_modbus_register_t* apc_modbus_register_maps[] = { + apc_modbus_register_map_inventory, + apc_modbus_register_map_status, + apc_modbus_register_map_dynamic, + apc_modbus_register_map_static }; static void _apc_modbus_close(int free_modbus) @@ -757,6 +935,7 @@ static int _apc_modbus_update_value(apc_modbus_register_t *regs_info, const uint { apc_modbus_value_t value; char strbuf[33], nutvbuf[128]; + int dstate_flags; if (regs_info == NULL || regs == NULL || regs_len == 0) { /* Invalid parameters */ @@ -770,19 +949,19 @@ static int _apc_modbus_update_value(apc_modbus_register_t *regs_info, const uint assert(regs_info->value_type <= apc_modbus_value_types_max); switch (regs_info->value_type) { - case APC_MODBUS_VALUE_TYPE_STRING: + case APC_VT_STRING: _apc_modbus_to_string(regs, regs_info->modbus_len, strbuf, sizeof(strbuf)); value.data.string_value = strbuf; break; - case APC_MODBUS_VALUE_TYPE_INT: + case APC_VT_INT: _apc_modbus_to_int64(regs, regs_info->modbus_len, &value.data.int_value); break; - case APC_MODBUS_VALUE_TYPE_UINT: + case APC_VT_UINT: _apc_modbus_to_uint64(regs, regs_info->modbus_len, &value.data.uint_value); break; } - if (regs_info->value_converter != NULL) { + if (regs_info->value_converter != NULL && regs_info->value_converter->apc_to_nut != NULL) { /* If we have a converter, use it and set the value as a string */ if (!regs_info->value_converter->apc_to_nut(&value, nutvbuf, sizeof(nutvbuf))) { upslogx(LOG_ERR, "%s: Failed to convert register %" PRIuSIZE ":%" PRIuSIZE, __func__, @@ -799,13 +978,13 @@ static int _apc_modbus_update_value(apc_modbus_register_t *regs_info, const uint #endif assert(regs_info->value_type <= apc_modbus_value_types_max); switch (regs_info->value_type) { - case APC_MODBUS_VALUE_TYPE_STRING: + case APC_VT_STRING: dstate_setinfo(regs_info->nut_variable_name, regs_info->value_format, value.data.string_value); break; - case APC_MODBUS_VALUE_TYPE_INT: + case APC_VT_INT: dstate_setinfo(regs_info->nut_variable_name, regs_info->value_format, value.data.int_value); break; - case APC_MODBUS_VALUE_TYPE_UINT: + case APC_VT_UINT: dstate_setinfo(regs_info->nut_variable_name, regs_info->value_format, value.data.uint_value); break; } @@ -814,6 +993,18 @@ static int _apc_modbus_update_value(apc_modbus_register_t *regs_info, const uint #endif } + dstate_flags = 0; + if (regs_info->value_type == APC_VT_STRING) { + dstate_flags |= ST_FLAG_STRING; + } + if ((regs_info->value_flags & APC_VF_RW)) { + dstate_flags |= ST_FLAG_RW; + } + dstate_setflags(regs_info->nut_variable_name, dstate_flags); + if (regs_info->value_type == APC_VT_STRING) { + dstate_setaux(regs_info->nut_variable_name, regs_info->modbus_len * sizeof(uint16_t)); + } + return 1; } @@ -837,11 +1028,38 @@ static int _apc_modbus_process_registers(apc_modbus_register_t* values, const ui static int _apc_modbus_read_inventory(void) { - uint16_t regbuf[88]; + uint16_t regbuf[120]; + int start_addr; + uint16_t sog_relay_config; + int outlet_group_count; /* Inventory Information */ - if (_apc_modbus_read_registers(modbus_ctx, 516, 88, regbuf)) { - _apc_modbus_process_registers(apc_modbus_register_map_inventory, regbuf, 88, 516); + start_addr = apc_modbus_register_map_inventory[0].modbus_addr; + if (_apc_modbus_read_registers(modbus_ctx, start_addr, SIZEOF_ARRAY(regbuf), regbuf)) { + sog_relay_config = regbuf[APC_MODBUS_SOGRELAYCONFIGSETTING_BF_REG - start_addr]; + + outlet_group_count = 0; + if ((sog_relay_config & APC_MODBUS_SOGRELAYCONFIGSETTING_BF_MOG_PRESENT)) { + outlet_group_count++; + } + if ((sog_relay_config & APC_MODBUS_SOGRELAYCONFIGSETTING_BF_SOG_0_PRESENT)) { + outlet_group_count++; + } + if ((sog_relay_config & APC_MODBUS_SOGRELAYCONFIGSETTING_BF_SOG_1_PRESENT)) { + outlet_group_count++; + } + if ((sog_relay_config & APC_MODBUS_SOGRELAYCONFIGSETTING_BF_SOG_2_PRESENT)) { + outlet_group_count++; + } + /* Documentation says there is a bit for SOG3, but everything else does not have it */ + if ((sog_relay_config & APC_MODBUS_SOGRELAYCONFIGSETTING_BF_SOG_3_PRESENT)) { + upslogx(LOG_WARNING, "%s: SOG3 present, but we don't know how to use it", __func__); + outlet_group_count++; + } + + dstate_setinfo("outlet.group.count", "%d", outlet_group_count); + + _apc_modbus_process_registers(apc_modbus_register_map_inventory, regbuf, SIZEOF_ARRAY(regbuf), start_addr); } else { return 0; } @@ -849,8 +1067,185 @@ static int _apc_modbus_read_inventory(void) return 1; } +static int _apc_modbus_setvar(const char *nut_varname, const char *str_value) +{ + size_t mi, i; + int addr, nb, r; + apc_modbus_register_t *apc_map = NULL, *apc_value = NULL; + uint16_t reg_value[16]; + + for (mi = 0; mi < SIZEOF_ARRAY(apc_modbus_register_maps); mi++) { + apc_map = apc_modbus_register_maps[mi]; + + for (i = 0; apc_map[i].nut_variable_name; i++) { + if (!strcasecmp(nut_varname, apc_map[i].nut_variable_name)) { + apc_value = &apc_map[i]; + break; + } + } + } + + if (!apc_map || !apc_value) { + upslogx(LOG_WARNING, "%s: [%s] is unknown", __func__, nut_varname); + return STAT_SET_UNKNOWN; + } + + if (!(apc_value->value_flags & APC_VF_RW)) { + upslogx(LOG_WARNING, "%s: [%s] is not writable", __func__, nut_varname); + return STAT_SET_INVALID; + } + + assert(apc_value->modbus_len < SIZEOF_ARRAY(reg_value)); + + if (apc_value->value_converter && apc_value->value_converter->nut_to_apc) { + if (!apc_value->value_converter->nut_to_apc(str_value, reg_value, apc_value->modbus_len)) { + upslogx(LOG_WARNING, "%s: [%s] failed to convert value", __func__, nut_varname); + return STAT_SET_CONVERSION_FAILED; + } + } else { + assert(apc_value->value_type <= apc_modbus_value_types_max); + switch (apc_value->value_type) { + case APC_VT_STRING: + r = _apc_modbus_from_string(str_value, reg_value, apc_value->modbus_len); + break; + case APC_VT_INT: + r = _apc_modbus_from_int64_string(str_value, reg_value, apc_value->modbus_len); + break; + case APC_VT_UINT: + r = _apc_modbus_from_uint64_string(str_value, reg_value, apc_value->modbus_len); + break; + } + + if (!r) { + upslogx(LOG_WARNING, "%s: [%s] failed to convert value", __func__, nut_varname); + return STAT_SET_CONVERSION_FAILED; + } + } + + addr = apc_value->modbus_addr; + nb = apc_value->modbus_len; + if (modbus_write_registers(modbus_ctx, addr, nb, reg_value) < 0) { + upslogx(LOG_ERR, "%s: Write of %d:%d failed: %s (%s)", __func__, addr, addr + nb, modbus_strerror(errno), device_path); + _apc_modbus_handle_error(modbus_ctx); + return STAT_SET_FAILED; + } + + /* There seem to be some communication problems if we don't wait after writing. + * Maybe there is some register we need to poll for write completion? + */ + usleep(100000); + + upslogx(LOG_INFO, "SET %s='%s'", nut_varname, str_value); + + if (_apc_modbus_read_registers(modbus_ctx, addr, nb, reg_value)) { + _apc_modbus_process_registers(apc_map, reg_value, nb, addr); + } + + return STAT_SET_HANDLED; +} + +typedef struct { + const char *nut_command_name; + size_t modbus_addr; + size_t modbus_len; /* Number of uint16_t registers */ + uint64_t value; +} apc_modbus_command_t; + +static apc_modbus_command_t apc_modbus_command_map[] = { + { "test.battery.start", APC_MODBUS_REPLACEBATTERYTESTCOMMAND_BF_REG, 1, APC_MODBUS_REPLACEBATTERYTESTCOMMAND_BF_START }, + { "test.battery.stop", APC_MODBUS_REPLACEBATTERYTESTCOMMAND_BF_REG, 1, APC_MODBUS_REPLACEBATTERYTESTCOMMAND_BF_ABORT }, + { "test.panel.start", APC_MODBUS_USERINTERFACECOMMAND_BF_REG, 1, APC_MODBUS_USERINTERFACECOMMAND_BF_SHORT_TEST }, + { "calibrate.start", APC_MODBUS_RUNTIMECALIBRATIONCOMMAND_BF_REG, 1, APC_MODBUS_RUNTIMECALIBRATIONCOMMAND_BF_START }, + { "calibrate.stop", APC_MODBUS_RUNTIMECALIBRATIONCOMMAND_BF_REG, 1, APC_MODBUS_RUNTIMECALIBRATIONCOMMAND_BF_ABORT }, + { "bypass.start", APC_MODBUS_UPSCOMMAND_BF_REG, 2, APC_MODBUS_UPSCOMMAND_BF_OUTPUT_INTO_BYPASS }, + { "bypass.stop", APC_MODBUS_UPSCOMMAND_BF_REG, 2, APC_MODBUS_UPSCOMMAND_BF_OUTPUT_OUT_OF_BYPASS }, + { "load.off", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_OFF }, + { "load.on", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_ON }, + { "load.off.delay", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_OFF | APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_OFF_DELAY }, + { "load.on.delay", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_ON | APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_ON_DELAY }, + { "shutdown.return", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_SHUTDOWN | APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_OFF_DELAY }, + { "shutdown.stayoff", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_OFF | APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_OFF_DELAY }, + { "shutdown.reboot", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_REBOOT }, + { "shutdown.reboot.graceful", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_REBOOT | APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_OFF_DELAY }, + { "beeper.mute", APC_MODBUS_USERINTERFACECOMMAND_BF_REG, 1, APC_MODBUS_USERINTERFACECOMMAND_BF_MUTE_ALL_ACTIVE_AUDIBLE_ALARMS }, + { "outlet.0.shutdown.return", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_SHUTDOWN | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_MAIN_OUTLET_GROUP | APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_OFF_DELAY }, + { "outlet.0.load.off", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_OFF | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_MAIN_OUTLET_GROUP }, + { "outlet.0.load.on", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_ON | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_MAIN_OUTLET_GROUP }, + { "outlet.0.load.cycle", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_REBOOT | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_MAIN_OUTLET_GROUP }, + { "outlet.1.shutdown.return", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_SHUTDOWN | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_SWITCHED_OUTLET_GROUP_0 | APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_OFF_DELAY }, + { "outlet.1.load.off", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_OFF | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_SWITCHED_OUTLET_GROUP_0 }, + { "outlet.1.load.on", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_ON | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_SWITCHED_OUTLET_GROUP_0 }, + { "outlet.1.load.cycle", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_REBOOT | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_SWITCHED_OUTLET_GROUP_0 }, + { "outlet.2.shutdown.return", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_SHUTDOWN | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_SWITCHED_OUTLET_GROUP_1 | APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_OFF_DELAY }, + { "outlet.2.load.off", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_OFF | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_SWITCHED_OUTLET_GROUP_1 }, + { "outlet.2.load.on", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_ON | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_SWITCHED_OUTLET_GROUP_1 }, + { "outlet.2.load.cycle", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_REBOOT | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_SWITCHED_OUTLET_GROUP_1 }, + { "outlet.3.shutdown.return", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_SHUTDOWN | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_SWITCHED_OUTLET_GROUP_2 | APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_OFF_DELAY }, + { "outlet.3.load.off", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_OFF | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_SWITCHED_OUTLET_GROUP_2 }, + { "outlet.3.load.on", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_ON | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_SWITCHED_OUTLET_GROUP_2 }, + { "outlet.3.load.cycle", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_REBOOT | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_SWITCHED_OUTLET_GROUP_2 }, + { NULL, 0, 0, 0 } +}; + +static int _apc_modbus_instcmd(const char *nut_cmdname, const char *extra) +{ + size_t i; + int addr, nb; + apc_modbus_command_t *apc_command = NULL; + uint16_t value[4]; /* Max 64-bit */ + + NUT_UNUSED_VARIABLE(extra); + + for (i = 0; apc_modbus_command_map[i].nut_command_name; i++) { + if (!strcasecmp(nut_cmdname, apc_modbus_command_map[i].nut_command_name)) { + apc_command = &apc_modbus_command_map[i]; + break; + } + } + + if (!apc_command) { + upslogx(LOG_WARNING, "%s: [%s] is unknown", __func__, nut_cmdname); + return STAT_INSTCMD_UNKNOWN; + } + + assert(apc_command->modbus_len <= SIZEOF_ARRAY(value)); + + if (!_apc_modbus_from_uint64(apc_command->value, value, apc_command->modbus_len)) { + upslogx(LOG_WARNING, "%s: [%s] failed to convert value", __func__, nut_cmdname); + return STAT_INSTCMD_CONVERSION_FAILED; + } + + addr = apc_command->modbus_addr; + nb = apc_command->modbus_len; + if (modbus_write_registers(modbus_ctx, addr, nb, value) < 0) { + upslogx(LOG_ERR, "%s: Write of %d:%d failed: %s (%s)", __func__, addr, addr + nb, modbus_strerror(errno), device_path); + _apc_modbus_handle_error(modbus_ctx); + return STAT_INSTCMD_FAILED; + } + + return STAT_INSTCMD_HANDLED; +} + void upsdrv_initinfo(void) { + size_t i; + if (!_apc_modbus_read_inventory()) { fatalx(EXIT_FAILURE, "Can't read inventory information from the UPS"); } @@ -858,6 +1253,14 @@ void upsdrv_initinfo(void) dstate_setinfo("ups.mfr", "American Power Conversion"); /* also device.mfr, filled automatically */ dstate_setinfo("device.type", "ups"); + + for (i = 0; apc_modbus_command_map[i].nut_command_name; i++) { + dstate_addcmd(apc_modbus_command_map[i].nut_command_name); + } + + upsh.setvar = _apc_modbus_setvar; + upsh.instcmd = _apc_modbus_instcmd; + } void upsdrv_updateinfo(void) @@ -950,8 +1353,8 @@ void upsdrv_updateinfo(void) } /* Static Data */ - if (_apc_modbus_read_registers(modbus_ctx, 1026, 7, regbuf)) { - _apc_modbus_process_registers(apc_modbus_register_map_static, regbuf, 7, 1026); + if (_apc_modbus_read_registers(modbus_ctx, 1026, 22, regbuf)) { + _apc_modbus_process_registers(apc_modbus_register_map_static, regbuf, 22, 1026); } else { dstate_datastale(); return; @@ -964,9 +1367,7 @@ void upsdrv_updateinfo(void) void upsdrv_shutdown(void) { - /* TODO: replace with a proper shutdown function */ - upslogx(LOG_ERR, "shutdown not supported"); - set_exit_flag(-1); + modbus_write_register(modbus_ctx, APC_MODBUS_OUTLETCOMMAND_BF_REG, APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_SHUTDOWN); } void upsdrv_help(void) @@ -1341,6 +1742,9 @@ void upsdrv_initups(void) } #if defined NUT_MODBUS_HAS_USB + /* This creates an exact matcher after the first connection so that on + * reconnect we are more likely to match the exact device we connected to + * the first time. */ _apc_modbus_create_reopen_matcher(); #endif /* defined NUT_MODBUS_HAS_USB */ diff --git a/drivers/apc_modbus.h b/drivers/apc_modbus.h new file mode 100644 index 0000000000..d537b7ca00 --- /dev/null +++ b/drivers/apc_modbus.h @@ -0,0 +1,78 @@ +/* apc_modbus.h - Driver for APC Modbus UPS + * Copyright © 2023 Axel Gembe + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef APC_MODBUS_H +#define APC_MODBUS_H + +#define APC_MODBUS_SOGRELAYCONFIGSETTING_BF_REG 590 +#define APC_MODBUS_SOGRELAYCONFIGSETTING_BF_MOG_PRESENT (1 << 0) +#define APC_MODBUS_SOGRELAYCONFIGSETTING_BF_SOG_0_PRESENT (1 << 1) +#define APC_MODBUS_SOGRELAYCONFIGSETTING_BF_SOG_1_PRESENT (1 << 2) +#define APC_MODBUS_SOGRELAYCONFIGSETTING_BF_SOG_2_PRESENT (1 << 3) +#define APC_MODBUS_SOGRELAYCONFIGSETTING_BF_SOG_3_PRESENT (1 << 4) + +#define APC_MODBUS_UPSCOMMAND_BF_REG 1536 +/* 0 - 2 are reserved */ +#define APC_MODBUS_UPSCOMMAND_BF_RESTORE_FACTORY_SETTINGS (1 << 3) +#define APC_MODBUS_UPSCOMMAND_BF_OUTPUT_INTO_BYPASS (1 << 4) +#define APC_MODBUS_UPSCOMMAND_BF_OUTPUT_OUT_OF_BYPASS (1 << 5) +/* 6 - 8 are reserved */ +#define APC_MODBUS_UPSCOMMAND_BF_CLEAR_FAULTS (1 << 9) +/* 10 - 12 are reserved */ +#define APC_MODBUS_UPSCOMMAND_BF_RESET_STRINGS (1 << 13) +#define APC_MODBUS_UPSCOMMAND_BF_RESET_LOGS (1 << 14) + +#define APC_MODBUS_OUTLETCOMMAND_BF_REG 1538 +#define APC_MODBUS_OUTLETCOMMAND_BF_CMD_CANCEL (1 << 0) +#define APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_ON (1 << 1) +#define APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_OFF (1 << 2) +#define APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_SHUTDOWN (1 << 3) +#define APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_REBOOT (1 << 4) +#define APC_MODBUS_OUTLETCOMMAND_BF_MOD_COLD_BOOT_ALLOWED (1 << 5) +#define APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_ON_DELAY (1 << 6) +#define APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_OFF_DELAY (1 << 7) +#define APC_MODBUS_OUTLETCOMMAND_BF_TARGET_MAIN_OUTLET_GROUP (1 << 8) +#define APC_MODBUS_OUTLETCOMMAND_BF_TARGET_SWITCHED_OUTLET_GROUP_0 (1 << 9) +#define APC_MODBUS_OUTLETCOMMAND_BF_TARGET_SWITCHED_OUTLET_GROUP_1 (1 << 10) +#define APC_MODBUS_OUTLETCOMMAND_BF_TARGET_SWITCHED_OUTLET_GROUP_2 (1 << 11) +#define APC_MODBUS_OUTLETCOMMAND_BF_SOURCE_USB_PORT (1 << 12) +#define APC_MODBUS_OUTLETCOMMAND_BF_SOURCE_LOCAL_USER (1 << 13) +#define APC_MODBUS_OUTLETCOMMAND_BF_SOURCE_RJ45_PORT (1 << 14) +#define APC_MODBUS_OUTLETCOMMAND_BF_SOURCE_SMART_SLOT_1 (1 << 15) +#define APC_MODBUS_OUTLETCOMMAND_BF_SOURCE_SMART_SLOT_2 (1 << 16) +#define APC_MODBUS_OUTLETCOMMAND_BF_SOURCE_INTERNAL_NETWORK_1 (1 << 17) +#define APC_MODBUS_OUTLETCOMMAND_BF_SOURCE_INTERNAL_NETWORK_2 (1 << 18) + +#define APC_MODBUS_REPLACEBATTERYTESTCOMMAND_BF_REG 1541 +#define APC_MODBUS_REPLACEBATTERYTESTCOMMAND_BF_START (1 << 0) +#define APC_MODBUS_REPLACEBATTERYTESTCOMMAND_BF_ABORT (1 << 1) + +#define APC_MODBUS_RUNTIMECALIBRATIONCOMMAND_BF_REG 1542 +#define APC_MODBUS_RUNTIMECALIBRATIONCOMMAND_BF_START (1 << 0) +#define APC_MODBUS_RUNTIMECALIBRATIONCOMMAND_BF_ABORT (1 << 1) + +#define APC_MODBUS_USERINTERFACECOMMAND_BF_REG 1543 +#define APC_MODBUS_USERINTERFACECOMMAND_BF_SHORT_TEST (1 << 0) +#define APC_MODBUS_USERINTERFACECOMMAND_BF_CONTINUOUS_TEST (1 << 1) +#define APC_MODBUS_USERINTERFACECOMMAND_BF_MUTE_ALL_ACTIVE_AUDIBLE_ALARMS (1 << 2) +#define APC_MODBUS_USERINTERFACECOMMAND_BF_CANCEL_MUTE (1 << 3) +/* 4 is reserved */ +#define APC_MODBUS_USERINTERFACECOMMAND_BF_ACKNOWLEDGE_BATTERY_ALARMS (1 << 5) +#define APC_MODBUS_USERINTERFACECOMMAND_BF_ACKNOWLEDGE_SITE_WIRING_ALARM (1 << 6) + +#endif /* APC_MODBUS_H */ diff --git a/drivers/upshandler.h b/drivers/upshandler.h index fea10bc20c..78e6ffef0a 100644 --- a/drivers/upshandler.h +++ b/drivers/upshandler.h @@ -22,18 +22,20 @@ /* return values for instcmd */ enum { - STAT_INSTCMD_HANDLED = 0, /* completed successfully */ - STAT_INSTCMD_UNKNOWN, /* unspecified error */ - STAT_INSTCMD_INVALID, /* invalid command */ - STAT_INSTCMD_FAILED /* command failed */ + STAT_INSTCMD_HANDLED = 0, /* completed successfully */ + STAT_INSTCMD_UNKNOWN, /* unspecified error */ + STAT_INSTCMD_INVALID, /* invalid command */ + STAT_INSTCMD_FAILED, /* command failed */ + STAT_INSTCMD_CONVERSION_FAILED /* could not convert value */ }; /* return values for setvar */ enum { - STAT_SET_HANDLED = 0, /* completed successfully */ - STAT_SET_UNKNOWN, /* unspecified error */ - STAT_SET_INVALID, /* not writeable */ - STAT_SET_FAILED /* writing failed */ + STAT_SET_HANDLED = 0, /* completed successfully */ + STAT_SET_UNKNOWN, /* unspecified error */ + STAT_SET_INVALID, /* not writeable */ + STAT_SET_FAILED, /* writing failed */ + STAT_SET_CONVERSION_FAILED /* could not convert value from string */ }; /* structure for funcs that get called by msg parse routine */ From 16ce37009a904e9a5d05b7f10e2e79bd079155b7 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 16 Nov 2023 09:04:50 +0100 Subject: [PATCH 0018/1079] drivers/Makefile.am: dist the apc_modbus.h file Signed-off-by: Jim Klimov --- drivers/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/Makefile.am b/drivers/Makefile.am index f6c369dd6d..03efb37bf6 100644 --- a/drivers/Makefile.am +++ b/drivers/Makefile.am @@ -343,7 +343,8 @@ nutdrv_qx_SOURCES += $(NUTDRV_QX_SUBDRIVERS) # tracking (which is automatic), but to ensure these files are # distributed by "make dist". -dist_noinst_HEADERS = apc-mib.h apc-iem-mib.h apc-hid.h arduino-hid.h baytech-mib.h bcmxcp.h bcmxcp_ser.h \ +dist_noinst_HEADERS = \ + apc_modbus.h apc-mib.h apc-iem-mib.h apc-hid.h arduino-hid.h baytech-mib.h bcmxcp.h bcmxcp_ser.h \ bcmxcp_io.h belkin.h belkin-hid.h bestpower-mib.h blazer.h cps-hid.h dstate.h \ dummy-ups.h explore-hid.h gamatronic.h genericups.h \ generic_gpio_common.h generic_gpio_libgpiod.h \ From 8ee9cbca34c4202df76b7746ca55e75a6cae10d1 Mon Sep 17 00:00:00 2001 From: Axel Gembe Date: Thu, 23 Nov 2023 00:56:09 +0700 Subject: [PATCH 0019/1079] apc_modbus: Add ups.test.result This outputs the test result, the source of the start of the test and a result modifier. Signed-off-by: Axel Gembe --- drivers/apc_modbus.c | 89 ++++++++++++++++++++++++++++++++++++++++++++ drivers/apc_modbus.h | 13 +++++++ 2 files changed, 102 insertions(+) diff --git a/drivers/apc_modbus.c b/drivers/apc_modbus.c index 27ffe244e0..1974f12ab9 100644 --- a/drivers/apc_modbus.c +++ b/drivers/apc_modbus.c @@ -654,6 +654,94 @@ static int _apc_modbus_status_change_cause_to_nut(const apc_modbus_value_t *valu static apc_modbus_converter_t _apc_modbus_status_change_cause_conversion = { _apc_modbus_status_change_cause_to_nut, NULL }; +static int _apc_modbus_string_join(const char *values[], size_t values_len, const char *separator, char *output, size_t output_len) +{ + size_t i; + size_t output_idx; + int res; + + if (values == NULL || values_len == 0 || separator == NULL || output == NULL || output_len == 0) { + /* Invalid parameters */ + return 0; + } + + output_idx = 0; + + for (i = 0; i < values_len && output_idx < output_len; i++) { + if (values[i] == NULL) + continue; + + if (i == 0) { + res = snprintf(output + output_idx, output_len - output_idx, "%s", values[i]); + } else { + res = snprintf(output + output_idx, output_len - output_idx, "%s%s", separator, values[i]); + } + + if (res < 0 || (size_t)res >= output_len) { + return 0; + } + + output_idx += res; + } + + return 1; +} + +static int _apc_modbus_battery_test_status_to_nut(const apc_modbus_value_t *value, char *output, size_t output_len) +{ + const char *result, *source, *modifier; + const char *values[3]; + + if (value == NULL || output == NULL || output_len == 0) { + /* Invalid parameters */ + return 0; + } + + if (value->type != APC_VT_UINT) { + return 0; + } + + result = NULL; + if ((value->data.uint_value & APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_PENDING)) { + result = "Pending"; + } else if ((value->data.uint_value & APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_INPROGRESS)) { + result = "InProgress"; + } else if ((value->data.uint_value & APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_PASSED)) { + result = "Passed"; + } else if ((value->data.uint_value & APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_FAILED)) { + result = "Failed"; + } else if ((value->data.uint_value & APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_REFUSED)) { + result = "Refused"; + } else if ((value->data.uint_value & APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_ABORTED)) { + result = "Aborted"; + } + + source = NULL; + if ((value->data.uint_value & APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_SOURCE_PROTOCOL)) { + source = "Source: Protocol"; + } else if ((value->data.uint_value & APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_SOURCE_LOCALUI)) { + source = "Source: LocalUI"; + } else if ((value->data.uint_value & APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_SOURCE_INTERNAL)) { + source = "Source: Internal"; + } + + modifier = NULL; + if ((value->data.uint_value & APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_MOD_INVALIDSTATE)) { + modifier = "Modifier: InvalidState"; + } else if ((value->data.uint_value & APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_MOD_INTERNALFAULT)) { + modifier = "Modifier: InternalFault"; + } else if ((value->data.uint_value & APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_MOD_STATEOFCHARGENOTACCEPTABLE)) { + modifier = "Modifier: StateOfChargeNotAcceptable"; + } + + values[0] = result; + values[1] = source; + values[2] = modifier; + return _apc_modbus_string_join(values, SIZEOF_ARRAY(values), ", ", output, output_len); +} + +static apc_modbus_converter_t _apc_modbus_battery_test_status_conversion = { _apc_modbus_battery_test_status_to_nut, NULL }; + static const time_t apc_date_start_offset = 946684800; /* 2000-01-01 00:00 */ static int _apc_modbus_date_to_nut(const apc_modbus_value_t *value, char *output, size_t output_len) @@ -735,6 +823,7 @@ static apc_modbus_register_t apc_modbus_register_map_inventory[] = { static apc_modbus_register_t apc_modbus_register_map_status[] = { { "input.transfer.reason", 2, 1, APC_VT_UINT, 0, &_apc_modbus_status_change_cause_conversion, NULL, 0, NULL }, + { "ups.test.result", 23, 1, APC_VT_UINT, 0, &_apc_modbus_battery_test_status_conversion, NULL, 0, NULL }, { NULL, 0, 0, 0, 0, NULL, NULL, 0.0f, NULL } }; diff --git a/drivers/apc_modbus.h b/drivers/apc_modbus.h index d537b7ca00..d175eb4974 100644 --- a/drivers/apc_modbus.h +++ b/drivers/apc_modbus.h @@ -19,6 +19,19 @@ #ifndef APC_MODBUS_H #define APC_MODBUS_H +#define APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_PENDING (1 << 0) +#define APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_INPROGRESS (1 << 1) +#define APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_PASSED (1 << 2) +#define APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_FAILED (1 << 3) +#define APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_REFUSED (1 << 4) +#define APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_ABORTED (1 << 5) +#define APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_SOURCE_PROTOCOL (1 << 6) +#define APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_SOURCE_LOCALUI (1 << 7) +#define APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_SOURCE_INTERNAL (1 << 8) +#define APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_MOD_INVALIDSTATE (1 << 9) +#define APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_MOD_INTERNALFAULT (1 << 10) +#define APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_MOD_STATEOFCHARGENOTACCEPTABLE (1 << 11) + #define APC_MODBUS_SOGRELAYCONFIGSETTING_BF_REG 590 #define APC_MODBUS_SOGRELAYCONFIGSETTING_BF_MOG_PRESENT (1 << 0) #define APC_MODBUS_SOGRELAYCONFIGSETTING_BF_SOG_0_PRESENT (1 << 1) From 0df06e91bfa3c825e9d6cb2c886158a42c7b9c69 Mon Sep 17 00:00:00 2001 From: Axel Gembe Date: Thu, 23 Nov 2023 02:04:09 +0700 Subject: [PATCH 0020/1079] apc_modbus: Fix re-read of values at the end of setvar The for loop searching for the correct register map kept on looping after finding the value which caused the `apc_map` mariable to potentially point to the wrong register map. This can cause the re-read of the set value at the end of the function to fail. Signed-off-by: Axel Gembe --- drivers/apc_modbus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/apc_modbus.c b/drivers/apc_modbus.c index 1974f12ab9..1831a145f6 100644 --- a/drivers/apc_modbus.c +++ b/drivers/apc_modbus.c @@ -1163,7 +1163,7 @@ static int _apc_modbus_setvar(const char *nut_varname, const char *str_value) apc_modbus_register_t *apc_map = NULL, *apc_value = NULL; uint16_t reg_value[16]; - for (mi = 0; mi < SIZEOF_ARRAY(apc_modbus_register_maps); mi++) { + for (mi = 0; mi < SIZEOF_ARRAY(apc_modbus_register_maps) && apc_value == NULL; mi++) { apc_map = apc_modbus_register_maps[mi]; for (i = 0; apc_map[i].nut_variable_name; i++) { From b66881ac58926bbb80c59475eac7c93be32ad7ac Mon Sep 17 00:00:00 2001 From: Axel Gembe Date: Fri, 24 Nov 2023 14:03:14 +0700 Subject: [PATCH 0021/1079] build: Add a fallback for timegm on Windows / MINGW MINGW headers do not provide a `timegm` implementation but there is a `_mkgmtime` which does the same: https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/mkgmtime-mkgmtime32-mkgmtime64 Signed-off-by: Axel Gembe --- configure.ac | 10 +++++++++- include/timehead.h | 8 ++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 7013806812..b038ffd803 100644 --- a/configure.ac +++ b/configure.ac @@ -752,7 +752,7 @@ AC_CHECK_FUNCS(strtok_r fileno sigemptyset sigaction, dnl For these we have a fallback implementation via the other, dnl if at least one is available, so initial check is quiet. dnl This typically pops up in POSIX vs. Windows builds: -AC_CHECK_FUNCS(localtime_r localtime_s gmtime_r gmtime_s, +AC_CHECK_FUNCS(localtime_r localtime_s gmtime_r gmtime_s timegm _mkgmtime, [], []) AC_MSG_CHECKING([for at least one gmtime implementation]) @@ -771,6 +771,14 @@ AS_IF([test x"${ac_cv_func_localtime_s}-${ac_cv_func_localtime_r}" = "xno-no"], AC_MSG_RESULT([yes]) ]) +AC_MSG_CHECKING([for at least one timegm implementation]) +AS_IF([test x"${ac_cv_func_timegm}-${ac_cv_func__mkgmtime}" = "xno-no"], [ + AC_MSG_RESULT([no]) + AC_MSG_WARN([Required C library routine timegm nor _mkgmtime was not found]) + ],[ + AC_MSG_RESULT([yes]) + ]) + AC_LANG_PUSH([C]) AC_CHECK_HEADER([string.h], diff --git a/include/timehead.h b/include/timehead.h index 7a5d989a7d..ed36d1b168 100644 --- a/include/timehead.h +++ b/include/timehead.h @@ -73,6 +73,14 @@ static inline struct tm *gmtime_r( const time_t *timer, struct tm *buf ) { # endif #endif +#ifndef HAVE_TIMEGM +# ifdef HAVE__MKGMTIME +# define timegm(tm) _mkgmtime(tm) +# else +# error "No fallback implementation for timegm" +# endif +#endif + #ifdef __cplusplus /* *INDENT-OFF* */ } From 15948981e5e6c1c32962bd763bcd95116b165f8d Mon Sep 17 00:00:00 2001 From: Axel Gembe Date: Thu, 23 Nov 2023 02:05:45 +0700 Subject: [PATCH 0022/1079] apc_modbus: Always store times in UTC This changes `_apc_modbus_date_from_nut` to use `timegm` instead of `mktime` which does not add the current time zone information. This fixes dates that are off-by-one compared to what was set. Signed-off-by: Axel Gembe --- drivers/apc_modbus.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/apc_modbus.c b/drivers/apc_modbus.c index 1831a145f6..9939794ff5 100644 --- a/drivers/apc_modbus.c +++ b/drivers/apc_modbus.c @@ -746,7 +746,7 @@ static const time_t apc_date_start_offset = 946684800; /* 2000-01-01 00:00 */ static int _apc_modbus_date_to_nut(const apc_modbus_value_t *value, char *output, size_t output_len) { - struct tm *tm_info; + struct tm tm_info; time_t time_stamp; if (value == NULL || output == NULL || output_len == 0) { @@ -759,8 +759,8 @@ static int _apc_modbus_date_to_nut(const apc_modbus_value_t *value, char *output } time_stamp = ((int64_t)value->data.uint_value * 86400) + apc_date_start_offset; - tm_info = gmtime(&time_stamp); - strftime(output, output_len, "%Y-%m-%d", tm_info); + gmtime_r(&time_stamp, &tm_info); + strftime(output, output_len, "%Y-%m-%d", &tm_info); return 1; } @@ -781,7 +781,7 @@ static int _apc_modbus_date_from_nut(const char *value, uint16_t *output, size_t return 0; } - if ((epoch_time = mktime(&tm_struct)) == -1) { + if ((epoch_time = timegm(&tm_struct)) == -1) { return 0; } From e52658cce4d4c004faab9ce712bb472d7a9d4b48 Mon Sep 17 00:00:00 2001 From: Axel Gembe Date: Thu, 23 Nov 2023 02:12:35 +0700 Subject: [PATCH 0023/1079] apc_modbus: Add target outlet group to load.* and shutdown.* commands Maybe this is needed, needs to be confirmed. Signed-off-by: Axel Gembe --- drivers/apc_modbus.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/apc_modbus.c b/drivers/apc_modbus.c index 9939794ff5..8aafce1479 100644 --- a/drivers/apc_modbus.c +++ b/drivers/apc_modbus.c @@ -1248,15 +1248,23 @@ static apc_modbus_command_t apc_modbus_command_map[] = { { "calibrate.stop", APC_MODBUS_RUNTIMECALIBRATIONCOMMAND_BF_REG, 1, APC_MODBUS_RUNTIMECALIBRATIONCOMMAND_BF_ABORT }, { "bypass.start", APC_MODBUS_UPSCOMMAND_BF_REG, 2, APC_MODBUS_UPSCOMMAND_BF_OUTPUT_INTO_BYPASS }, { "bypass.stop", APC_MODBUS_UPSCOMMAND_BF_REG, 2, APC_MODBUS_UPSCOMMAND_BF_OUTPUT_OUT_OF_BYPASS }, - { "load.off", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_OFF }, - { "load.on", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_ON }, - { "load.off.delay", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_OFF | APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_OFF_DELAY }, - { "load.on.delay", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_ON | APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_ON_DELAY }, - { "shutdown.return", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_SHUTDOWN | APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_OFF_DELAY }, - { "shutdown.stayoff", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_OFF | APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_OFF_DELAY }, - { "shutdown.reboot", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_REBOOT }, - { "shutdown.reboot.graceful", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_REBOOT | APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_OFF_DELAY }, { "beeper.mute", APC_MODBUS_USERINTERFACECOMMAND_BF_REG, 1, APC_MODBUS_USERINTERFACECOMMAND_BF_MUTE_ALL_ACTIVE_AUDIBLE_ALARMS }, + { "load.off", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_OFF | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_MAIN_OUTLET_GROUP }, + { "load.on", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_ON | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_MAIN_OUTLET_GROUP }, + { "load.off.delay", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_OFF | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_MAIN_OUTLET_GROUP | APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_OFF_DELAY }, + { "load.on.delay", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_ON | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_MAIN_OUTLET_GROUP | APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_ON_DELAY }, + { "shutdown.return", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_SHUTDOWN | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_MAIN_OUTLET_GROUP | APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_OFF_DELAY }, + { "shutdown.stayoff", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_OFF | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_MAIN_OUTLET_GROUP | APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_OFF_DELAY }, + { "shutdown.reboot", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_REBOOT | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_MAIN_OUTLET_GROUP }, + { "shutdown.reboot.graceful", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, + APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_REBOOT | APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_OFF_DELAY }, { "outlet.0.shutdown.return", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_SHUTDOWN | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_MAIN_OUTLET_GROUP | APC_MODBUS_OUTLETCOMMAND_BF_MOD_USE_OFF_DELAY }, { "outlet.0.load.off", APC_MODBUS_OUTLETCOMMAND_BF_REG, 2, @@ -1456,7 +1464,7 @@ void upsdrv_updateinfo(void) void upsdrv_shutdown(void) { - modbus_write_register(modbus_ctx, APC_MODBUS_OUTLETCOMMAND_BF_REG, APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_SHUTDOWN); + modbus_write_register(modbus_ctx, APC_MODBUS_OUTLETCOMMAND_BF_REG, APC_MODBUS_OUTLETCOMMAND_BF_CMD_OUTPUT_SHUTDOWN | APC_MODBUS_OUTLETCOMMAND_BF_TARGET_MAIN_OUTLET_GROUP); } void upsdrv_help(void) From fdb122509383b1913547fb4fb4e6b4e0ff77d066 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Fri, 19 Jan 2024 14:30:24 +0100 Subject: [PATCH 0024/1079] drivers/belkin-hid.c: fix Liebert GXT4 UPS productid Follow-up to 3e1b00ec3ff105a05e67ae8602996cf7436f816b which intended to add the ID after NUT v2.7.4 release, but fell prey to copy-paste typo (got 0x0004 instead of intended 0x0000): commit 3e1b00ec3ff105a05e67ae8602996cf7436f816b Author: Charles Lepple Date: Sat Jun 3 12:24:15 2017 -0400 usbhid-ups: add Liebert GXT4 USB VID:PID [10AF:0000] Source: http://lists.alioth.debian.org/pipermail/nut-upsuser/2017-June/010682.html Voltage and ConfigVoltage appear to be scaled improperly per the debug output. Signed-off-by: Jim Klimov --- drivers/belkin-hid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/belkin-hid.c b/drivers/belkin-hid.c index 686dc92612..3b63f89455 100644 --- a/drivers/belkin-hid.c +++ b/drivers/belkin-hid.c @@ -31,7 +31,7 @@ #include /* for fabs() */ -#define BELKIN_HID_VERSION "Belkin/Liebert HID 0.18" +#define BELKIN_HID_VERSION "Belkin/Liebert HID 0.19" /* Belkin */ #define BELKIN_VENDORID 0x050d @@ -68,7 +68,7 @@ static usb_device_id_t belkin_usb_device_table[] = { { USB_DEVICE(BELKIN_VENDORID, 0x1100), NULL }, /* Liebert GXT4 UPS */ - { USB_DEVICE(LIEBERT_VENDORID, 0x0004), NULL }, + { USB_DEVICE(LIEBERT_VENDORID, 0x0000), NULL }, /* Liebert PowerSure PSA UPS */ { USB_DEVICE(LIEBERT_VENDORID, 0x0001), NULL }, /* Liebert PowerSure PSI 1440 */ From 8fb60dec07fcb87ca0141508d9f747f3c690d3c5 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Fri, 19 Jan 2024 14:42:26 +0100 Subject: [PATCH 0025/1079] drivers/belkin-hid.c: add Liebert PowerSure PST UPS productid [#2271] Signed-off-by: Jim Klimov --- drivers/belkin-hid.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/belkin-hid.c b/drivers/belkin-hid.c index 3b63f89455..f1d4083afa 100644 --- a/drivers/belkin-hid.c +++ b/drivers/belkin-hid.c @@ -71,6 +71,8 @@ static usb_device_id_t belkin_usb_device_table[] = { { USB_DEVICE(LIEBERT_VENDORID, 0x0000), NULL }, /* Liebert PowerSure PSA UPS */ { USB_DEVICE(LIEBERT_VENDORID, 0x0001), NULL }, + /* Liebert PowerSure PST UPS */ + { USB_DEVICE(LIEBERT_VENDORID, 0x0002), NULL }, /* Liebert PowerSure PSI 1440 */ { USB_DEVICE(LIEBERT_VENDORID, 0x0004), NULL }, /* Liebert GXT3 */ From ac522f1da1a11f8c29935d7289521eebeb984f30 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 20 Jan 2024 12:28:34 +0100 Subject: [PATCH 0026/1079] scripts/upower/95-upower-hid.hwdb: update for recent changes in drivers/belkin-hid.c [#2271] Signed-off-by: Jim Klimov --- scripts/upower/95-upower-hid.hwdb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/upower/95-upower-hid.hwdb b/scripts/upower/95-upower-hid.hwdb index c8e6356607..88c668c152 100644 --- a/scripts/upower/95-upower-hid.hwdb +++ b/scripts/upower/95-upower-hid.hwdb @@ -152,7 +152,9 @@ usb:v0D9Fp00A6* UPOWER_VENDOR=PowerCOM # Liebert +usb:v10AFp0000* usb:v10AFp0001* +usb:v10AFp0002* usb:v10AFp0004* usb:v10AFp0008* UPOWER_BATTERY_TYPE=ups From ea86d9af544743b1309e361e633726963a8e6ba3 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Tue, 27 Feb 2024 09:47:56 +0000 Subject: [PATCH 0027/1079] Makefile.am: fix out-of-tree build of ChangeLog file Signed-off-by: Jim Klimov --- Makefile.am | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Makefile.am b/Makefile.am index bac4f8eb2b..af266fb0b1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -321,14 +321,22 @@ GITLOG_START_POINT=v2.6.0 # the current dir, and defaults to generate a "ChangeLog" in the current dir. # The script itself is generated from a template, so resides in builddir. dummy-stamp: -ChangeLog: tools/gitlog2changelog.py dummy-stamp +# Be sure to not confuse with a DIST'ed file (and try to overwrite it): +ChangeLog: $(abs_top_builddir)/ChangeLog +$(abs_top_builddir)/ChangeLog: tools/gitlog2changelog.py dummy-stamp cd $(abs_top_srcdir) && \ if test -e .git ; then \ CHANGELOG_FILE="$@" $(abs_top_builddir)/tools/gitlog2changelog.py $(GITLOG_START_POINT) || \ { printf "gitlog2changelog.py failed to generate the ChangeLog.\n\nNOTE: See https://github.com/networkupstools/nut/commits/master for change history.\n\n" > "$@" ; } ; \ else \ - if ! test -s "$@" ; then \ - printf "Failed to generate the ChangeLog.\n\nNOTE: See https://github.com/networkupstools/nut/commits/master for change history.\n\n" > "$@" ; \ + if x"$(abs_top_srcdir)" != x"$(abs_top_builddir)" -a -s ./ChangeLog ; then \ + echo "Using distributed ChangeLog file from sources" >&2 ; \ + rm -f "$@" || true ; \ + cat ./ChangeLog > "$@" ; \ + else \ + if ! test -s "$@" ; then \ + printf "Failed to generate the ChangeLog.\n\nNOTE: See https://github.com/networkupstools/nut/commits/master for change history.\n\n" > "$@" ; \ + fi ; \ fi ; \ fi From f8359cf2ac20475fa0f7e74aa04c3b2b96e8cb0b Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Tue, 27 Feb 2024 12:34:17 +0100 Subject: [PATCH 0028/1079] docs/Makefile.am: produce proper asciidoc markup for ChangeLog.adoc if "FAILED to resolve input or output filename with this make implementation..." Signed-off-by: Jim Klimov --- docs/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Makefile.am b/docs/Makefile.am index 33f0ff5d77..c2fba72854 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -240,7 +240,7 @@ $(top_builddir)/ChangeLog.adoc: $(top_builddir)/ChangeLog || { \ MSG="FAILED to resolve input or output filename with this make implementation, or input was not generated!"; \ echo " DOC-CHANGELOG-ASCIIDOC SKIP: $${MSG}" >&2; \ - test -n "$@" && echo "$${MSG}" > "$@" ; \ + test -n "$@" && { printf '=== Failed to generate the ChangeLog\n\n%s\n\nNOTE: See https://github.com/networkupstools/nut/commits/master for change history.\n\n' "$${MSG}" > "$@" ; } ; \ exit ; \ } ; \ echo " DOC-CHANGELOG-ASCIIDOC $${INPUT} => $@" \ From b43ad592362e705bafc3124a9c139e094a343e39 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Tue, 27 Feb 2024 12:59:22 +0100 Subject: [PATCH 0029/1079] Makefile.am: make sure "make ChangeLog" does some work ...even with OpenBSD make implementation Signed-off-by: Jim Klimov --- Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index af266fb0b1..dda908e7f1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -323,8 +323,10 @@ GITLOG_START_POINT=v2.6.0 dummy-stamp: # Be sure to not confuse with a DIST'ed file (and try to overwrite it): ChangeLog: $(abs_top_builddir)/ChangeLog + +@$(MAKE) $(AM_MAKEFLAGS) $(abs_top_builddir)/ChangeLog + $(abs_top_builddir)/ChangeLog: tools/gitlog2changelog.py dummy-stamp - cd $(abs_top_srcdir) && \ + @cd $(abs_top_srcdir) && \ if test -e .git ; then \ CHANGELOG_FILE="$@" $(abs_top_builddir)/tools/gitlog2changelog.py $(GITLOG_START_POINT) || \ { printf "gitlog2changelog.py failed to generate the ChangeLog.\n\nNOTE: See https://github.com/networkupstools/nut/commits/master for change history.\n\n" > "$@" ; } ; \ From 7ad56ab778031ad060939f441d9203af0ba639f8 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Tue, 27 Feb 2024 13:20:13 +0100 Subject: [PATCH 0030/1079] Makefile.am: avoid what some makes see as a loop for ChangeLog Signed-off-by: Jim Klimov --- Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index dda908e7f1..b1835af9ae 100644 --- a/Makefile.am +++ b/Makefile.am @@ -321,10 +321,10 @@ GITLOG_START_POINT=v2.6.0 # the current dir, and defaults to generate a "ChangeLog" in the current dir. # The script itself is generated from a template, so resides in builddir. dummy-stamp: -# Be sure to not confuse with a DIST'ed file (and try to overwrite it): -ChangeLog: $(abs_top_builddir)/ChangeLog +ChangeLog: dummy-stamp +@$(MAKE) $(AM_MAKEFLAGS) $(abs_top_builddir)/ChangeLog +# Be sure to not confuse with a DIST'ed file (and so try to overwrite it): $(abs_top_builddir)/ChangeLog: tools/gitlog2changelog.py dummy-stamp @cd $(abs_top_srcdir) && \ if test -e .git ; then \ From 6743126f2d8b97ef514c2541eb7946214ba73344 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Tue, 27 Feb 2024 13:38:21 +0100 Subject: [PATCH 0031/1079] configure.ac: revise detection of LN_S_R Signed-off-by: Jim Klimov --- configure.ac | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 640c715840..36b2b1986c 100644 --- a/configure.ac +++ b/configure.ac @@ -1108,13 +1108,32 @@ AC_MSG_CHECKING([whether ln -sr works]) dnl We need to relative-symlink some files. Or hardlink. Or copy... LN_S_R="cp -pR" if test "$as_ln_s" = "ln -s" ; then - LN_S_R="ln" + _abs_srcdir="`cd "${srcdir}" && pwd`" || _abs_srcdir="" + _abs_builddir="`pwd`" + dnl AC_MSG_NOTICE([srcdir='${srcdir}' _abs_srcdir='${_abs_srcdir}' _abs_builddir='${_abs_builddir}']) + if test x"${_abs_srcdir}" = x"${_abs_builddir}" ; then + LN_S_R="ln" + else + _fs_srcdir="`df "${_abs_srcdir}" | tail -1 | awk '{print $1}'`" || fs_srcdir="XXXs" + _fs_builddir="`df "${_abs_builddir}" | tail -1 | awk '{print $1}'`" || fs_builddir="XXXb" + dnl AC_MSG_NOTICE([_fs_srcdir='${_fs_srcdir}' _fs_builddir='${_fs_builddir}']) + if test x"${_fs_srcdir}" = x"${_fs_builddir}" ; then + LN_S_R="ln" + fi + dnl ELSE Source and build areas are in different filesystems, + dnl can not hardlink - keep copying approach in place + unset _fs_srcdir _fs_builddir + fi + unset _abs_srcdir _abs_builddir + + dnl Explore GNU ln (or compatible) with relative symlink support DIR1="$(mktemp -d "dir1.XXXXXXX")" && \ DIR2="$(mktemp -d "dir2.XXXXXXX")" && \ touch "${DIR1}/a" && \ $as_ln_s -r "${DIR1}/a" "${DIR2}/b" && \ ls -la "${DIR2}/b" | grep '\.\./' > /dev/null && \ LN_S_R="$as_ln_s -r" + rm -rf "${DIR1}" "${DIR2}" fi AC_SUBST([LN_S_R], [${LN_S_R}]) From 0831ae08f7d4a117a3b5e279f121f3303f89d3c3 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Tue, 27 Feb 2024 14:59:32 +0100 Subject: [PATCH 0032/1079] ci_build.sh: support CI_FAILFAST also to bail out from parallel/sequential build_to_only_catch_errors_target() logic - ensure parallel builds succeed "as is" Signed-off-by: Jim Klimov --- ci_build.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ci_build.sh b/ci_build.sh index 83e395e447..141c2a603b 100755 --- a/ci_build.sh +++ b/ci_build.sh @@ -585,7 +585,12 @@ build_to_only_catch_errors_target() { default) $CI_TIME $MAKE -k $PARMAKE_FLAGS "$@" ;; esac ) && echo "`date`: SUCCESS" ; ) || \ - ( echo "`date`: Starting the sequential build attempt (to list remaining files with errors considered fatal for this build configuration) for '$@'..."; \ + ( RET=$? + if [ "$CI_FAILFAST" = true ]; then + echo "===== Aborting after parallel build attempt failure for '$*' because CI_FAILFAST=$CI_FAILFAST" >&2 + exit $RET + fi + echo "`date`: Starting the sequential build attempt (to list remaining files with errors considered fatal for this build configuration) for '$@'..."; \ $CI_TIME $MAKE $MAKE_FLAGS_VERBOSE "$@" -k ) || return $? return 0 } From 07283646cbfe06fefbb6b816b90d6cad9e9213dd Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Tue, 27 Feb 2024 15:29:31 +0100 Subject: [PATCH 0033/1079] configure.ac: report if deliberately avoiding hardlinks for LN_S_R implementation Signed-off-by: Jim Klimov --- configure.ac | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 36b2b1986c..e00d2bfb87 100644 --- a/configure.ac +++ b/configure.ac @@ -1119,9 +1119,11 @@ if test "$as_ln_s" = "ln -s" ; then dnl AC_MSG_NOTICE([_fs_srcdir='${_fs_srcdir}' _fs_builddir='${_fs_builddir}']) if test x"${_fs_srcdir}" = x"${_fs_builddir}" ; then LN_S_R="ln" + else + dnl Source and build areas are in different filesystems, + dnl can not hardlink - keep copying approach in place + AC_MSG_NOTICE([Source and build areas are in different filesystems, or we could not detect this for sure - avoiding hardlinks]) fi - dnl ELSE Source and build areas are in different filesystems, - dnl can not hardlink - keep copying approach in place unset _fs_srcdir _fs_builddir fi unset _abs_srcdir _abs_builddir From b6cc4e24b1007066522df06fdb91f590e0658599 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Tue, 27 Feb 2024 14:40:02 +0000 Subject: [PATCH 0034/1079] Makefile.am: ChangeLog: fix shell-scripting typo Signed-off-by: Jim Klimov --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index b1835af9ae..e1c62d90c6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -331,7 +331,7 @@ $(abs_top_builddir)/ChangeLog: tools/gitlog2changelog.py dummy-stamp CHANGELOG_FILE="$@" $(abs_top_builddir)/tools/gitlog2changelog.py $(GITLOG_START_POINT) || \ { printf "gitlog2changelog.py failed to generate the ChangeLog.\n\nNOTE: See https://github.com/networkupstools/nut/commits/master for change history.\n\n" > "$@" ; } ; \ else \ - if x"$(abs_top_srcdir)" != x"$(abs_top_builddir)" -a -s ./ChangeLog ; then \ + if test x"$(abs_top_srcdir)" != x"$(abs_top_builddir)" -a -s ./ChangeLog ; then \ echo "Using distributed ChangeLog file from sources" >&2 ; \ rm -f "$@" || true ; \ cat ./ChangeLog > "$@" ; \ From c7f800952b05affe2b8d04f5cfeb78763b8cd1bd Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Tue, 27 Feb 2024 16:31:00 +0100 Subject: [PATCH 0035/1079] include/state.h: include time headers (we use timespec/timeval here) Signed-off-by: Jim Klimov --- include/state.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/state.h b/include/state.h index 60dc3433fe..9857e4d584 100644 --- a/include/state.h +++ b/include/state.h @@ -32,6 +32,8 @@ extern "C" { #define ST_SOCK_BUF_LEN 512 +#include "timehead.h" + #if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_CLOCK_MONOTONIC) && HAVE_CLOCK_GETTIME && HAVE_CLOCK_MONOTONIC typedef struct timespec st_tree_timespec_t; #else From e3a040f86a20d49388ebded05f40977eb6e2076d Mon Sep 17 00:00:00 2001 From: Denny Page Date: Tue, 27 Feb 2024 07:47:02 -0800 Subject: [PATCH 0036/1079] Correct access method used for flag battery_voltage_reports_one_pack --- drivers/nutdrv_qx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/nutdrv_qx.c b/drivers/nutdrv_qx.c index 177a659d22..e346cdb235 100644 --- a/drivers/nutdrv_qx.c +++ b/drivers/nutdrv_qx.c @@ -370,8 +370,7 @@ static void qx_initbattery(void) batt_packs_known = 1; } - val = getval("battery_voltage_reports_one_pack"); - if (val) { + if (testvar("battery_voltage_reports_one_pack")) { battery_voltage_reports_one_pack = 1; /* If we already have a battery.voltage reading from the device, * it is not yet "adjusted" to consider the multiplication for From 7123ac69debba7173cc61bc2c835dd7c25b8174f Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 28 Feb 2024 12:40:52 +0000 Subject: [PATCH 0037/1079] scripts/HP-UX/makedepot.sh: fix whitespace Signed-off-by: Jim Klimov --- scripts/HP-UX/makedepot.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/HP-UX/makedepot.sh b/scripts/HP-UX/makedepot.sh index 698bccf44b..73fbcfdbee 100755 --- a/scripts/HP-UX/makedepot.sh +++ b/scripts/HP-UX/makedepot.sh @@ -1,6 +1,6 @@ #!/bin/bash -set -x +set -x CUR_DIR=$(pwd) TOP_DIR=$CUR_DIR/../.. @@ -26,5 +26,4 @@ cd $CUR_DIR swpackage -s nut.psf -d $CUR_DIR/nut.depot; \ #tar cvf nut.depot.tar nut.depot #gzip nut.depot.tar -echo "Execution completed" - +echo "Execution completed" From f7132923d5b8054e89bfdf3449de77fece65245a Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 28 Feb 2024 12:39:52 +0000 Subject: [PATCH 0038/1079] NUT shell scripts: use a better portable shebang for bash interpreter discovery NOTE: Some scripts require BASH syntax; maybe not all of them do (did not revise at this time) Signed-off-by: Jim Klimov --- indent.sh | 2 +- scripts/HP-UX/makedepot.sh | 2 +- scripts/Windows/build-mingw-nut.sh | 2 +- scripts/installer/make_package.sh | 2 +- scripts/subdriver/gen-snmp-subdriver.sh | 2 +- scripts/subdriver/gen-usbhid-subdriver.sh | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/indent.sh b/indent.sh index 0aaf571f32..67cfd72352 100755 --- a/indent.sh +++ b/indent.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Filter NUT C source file style to conform to recommendations of # https://www.networkupstools.org/docs/developer-guide.chunked/ar01s03.html#_coding_style diff --git a/scripts/HP-UX/makedepot.sh b/scripts/HP-UX/makedepot.sh index 73fbcfdbee..82a47db2c0 100755 --- a/scripts/HP-UX/makedepot.sh +++ b/scripts/HP-UX/makedepot.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -x diff --git a/scripts/Windows/build-mingw-nut.sh b/scripts/Windows/build-mingw-nut.sh index a39765fb00..bafccc0ab4 100755 --- a/scripts/Windows/build-mingw-nut.sh +++ b/scripts/Windows/build-mingw-nut.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # NOTE: bash syntax (non-POSIX script) is used below! # diff --git a/scripts/installer/make_package.sh b/scripts/installer/make_package.sh index acccf35314..2ebc08bf77 100755 --- a/scripts/installer/make_package.sh +++ b/scripts/installer/make_package.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # make_package.sh # Copyright (c) 2013-2015, by Eaton (R) Corporation. All rights reserved. diff --git a/scripts/subdriver/gen-snmp-subdriver.sh b/scripts/subdriver/gen-snmp-subdriver.sh index 0fba35e5d8..9d7a24e064 100755 --- a/scripts/subdriver/gen-snmp-subdriver.sh +++ b/scripts/subdriver/gen-snmp-subdriver.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # # an auxiliary script to produce a "stub" snmp-ups subdriver from # SNMP data from a real agent or from dump files diff --git a/scripts/subdriver/gen-usbhid-subdriver.sh b/scripts/subdriver/gen-usbhid-subdriver.sh index 35b8311e15..75f3ec269b 100755 --- a/scripts/subdriver/gen-usbhid-subdriver.sh +++ b/scripts/subdriver/gen-usbhid-subdriver.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # an auxiliary script to produce a "stub" usbhid-ups subdriver from # the output of From 2827e839c1759db8167608d35bbac326610841a4 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 28 Feb 2024 15:54:57 +0100 Subject: [PATCH 0039/1079] docs/config-prereqs.txt: clarify how to get pip on OpenBSD Signed-off-by: Jim Klimov --- docs/config-prereqs.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/config-prereqs.txt b/docs/config-prereqs.txt index 600f822952..b9f87bf8ef 100644 --- a/docs/config-prereqs.txt +++ b/docs/config-prereqs.txt @@ -798,9 +798,9 @@ default site. # NOTE: For python, you may eventually have to specify a variant like this # (numbers depending on default or additional packages of your distro): -# :; pkg_add python-2.7.15p0 +# :; pkg_add python-2.7.15p0 py-pip # and/or: -# :; pkg_add python-3.6.6p1 +# :; pkg_add python-3.6.6p1 py3-pip # although you might succeed specifying shorter names and the packager # will offer a list of matching variants (as it does for "python" above). # NOTE: "perl" is not currently a package, but seemingly part of base OS. From 14beb45c6dfee3b18d2385ab8431127caf409efb Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 28 Feb 2024 14:49:31 +0100 Subject: [PATCH 0040/1079] m4/nut_check_libltdl.m4: fix detection on OpenBSD Signed-off-by: Jim Klimov --- m4/nut_check_libltdl.m4 | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/m4/nut_check_libltdl.m4 b/m4/nut_check_libltdl.m4 index 8c6857ecfe..9c67e93eef 100644 --- a/m4/nut_check_libltdl.m4 +++ b/m4/nut_check_libltdl.m4 @@ -50,12 +50,19 @@ if test -z "${nut_have_libltdl_seen}"; then ], [])dnl No fallback here - we probe suitable libs below AC_MSG_RESULT([${LIBS}]) - AC_CHECK_HEADERS(ltdl.h, [nut_have_libltdl=yes], [nut_have_libltdl=no], [AC_INCLUDES_DEFAULT]) + AC_CHECK_HEADERS(ltdl.h, [nut_have_libltdl=yes], [ + dnl Double-check if we stashed include paths to try above + AS_IF([test -n "$myCFLAGS"], [ + CFLAGS="$myCFLAGS" + AS_UNSET([ac_cv_header_ltdl_h]) + AC_CHECK_HEADERS(ltdl.h, [nut_have_libltdl=yes], [nut_have_libltdl=no], [AC_INCLUDES_DEFAULT]) + ],[nut_have_libltdl=no] + )], [AC_INCLUDES_DEFAULT]) AS_IF([test x"$nut_have_libltdl" = xyes], [ dnl ltdl-number may help find it for MingW DLLs naming AC_SEARCH_LIBS(lt_dlinit, ltdl ltdl-7, [], [ nut_have_libltdl=no - AS_IF([test -n "$myCFLAGS"], [ + AS_IF([test -n "$myCFLAGS" -a x"$myCFLAGS" != x"$CFLAGS"], [ CFLAGS="$myCFLAGS" dnl No ltdl-7 here, this codepath is unlikely on Windows where that matters: AC_SEARCH_LIBS(lt_dlinit, ltdl, [nut_have_libltdl=yes], []) From 12e1499029e291cf68160521f561ed29f8836e84 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 29 Feb 2024 12:43:09 +0100 Subject: [PATCH 0041/1079] NEWS.adoc: fix for battery_voltage_reports_one_pack flag handling [#2324] Signed-off-by: Jim Klimov --- NEWS.adoc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NEWS.adoc b/NEWS.adoc index 10319c9cd2..7e60297950 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -187,6 +187,11 @@ https://github.com/networkupstools/nut/milestone/10 is not reported by the device (should be frequent by default, in case the UPS-reported state combination does reflect a bad power condition). + - nutdrv_qx driver: + * Fixed handling of `battery_voltage_reports_one_pack` configuration flag + introduced in NUT v2.8.1. [originally by PR #1279; fixed by PR #2324, + issue #2325] + - Various code and documentation fixes for NSS crypto support. [#2274, #2268] - Laid foundations for the SmartNUT effort (aiming to integrate drivers with From 32c71bb30e31f88f9c3cc1a5576d3a6d8169377a Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 29 Feb 2024 12:43:36 +0000 Subject: [PATCH 0042/1079] */*.h: use NUT_NETVERSION as a header guard for #include "config.h" Signed-off-by: Jim Klimov --- drivers/hidparser.h | 9 ++++++++- drivers/libhid.h | 8 +++++++- drivers/nutdrv_qx.h | 9 ++++++++- drivers/serial.h | 8 +++++++- drivers/snmp-ups.h | 8 ++++++++ drivers/usb-common.h | 8 +++++++- drivers/usbhid-ups.h | 10 +++++++++- include/common.h | 8 +++++++- include/nut_float.h | 8 +++++++- include/nut_stdint.h | 8 +++++++- include/proto.h | 8 +++++++- 11 files changed, 82 insertions(+), 10 deletions(-) diff --git a/drivers/hidparser.h b/drivers/hidparser.h index 07b9f267aa..9f604565e5 100644 --- a/drivers/hidparser.h +++ b/drivers/hidparser.h @@ -32,7 +32,14 @@ extern "C" { /* *INDENT-ON* */ #endif /* __cplusplus */ -#include "config.h" +/* "config.h" is generated by autotools and lacks a header guard, so + * we use an unambiguously named macro we know we must have, as one. + * It must be the first header: be sure to know all about system config. + */ +#ifndef NUT_NETVERSION +# include "config.h" +#endif + #include "hidtypes.h" /* Include "usb-common.h" or "libshut.h" as appropriate, to define the diff --git a/drivers/libhid.h b/drivers/libhid.h index 613fda9aae..52feeb2601 100644 --- a/drivers/libhid.h +++ b/drivers/libhid.h @@ -29,7 +29,13 @@ #ifndef NUT_LIBHID_H_SEEN #define NUT_LIBHID_H_SEEN -#include "config.h" +/* "config.h" is generated by autotools and lacks a header guard, so + * we use an unambiguously named macro we know we must have, as one. + * It must be the first header: be sure to know all about system config. + */ +#ifndef NUT_NETVERSION +# include "config.h" +#endif #include #include "nut_stdint.h" diff --git a/drivers/nutdrv_qx.h b/drivers/nutdrv_qx.h index 0c5f20688a..faffe717cc 100644 --- a/drivers/nutdrv_qx.h +++ b/drivers/nutdrv_qx.h @@ -26,11 +26,18 @@ #ifndef NUTDRV_QX_H #define NUTDRV_QX_H +/* "config.h" is generated by autotools and lacks a header guard, so + * we use an unambiguously named macro we know we must have, as one. + * It must be the first header: be sure to know all about system config. + */ +#ifndef NUT_NETVERSION +# include "config.h" +#endif + #include #include #include #include -#include "config.h" /* For testing purposes */ /*#define TESTING*/ diff --git a/drivers/serial.h b/drivers/serial.h index 7987cb385d..cd8aa0fbe4 100644 --- a/drivers/serial.h +++ b/drivers/serial.h @@ -1,7 +1,13 @@ #ifndef SERIAL_H_SEEN #define SERIAL_H_SEEN 1 -#include "config.h" /* should be first */ +/* "config.h" is generated by autotools and lacks a header guard, so + * we use an unambiguously named macro we know we must have, as one. + * It must be the first header: be sure to know all about system config. + */ +#ifndef NUT_NETVERSION +# include "config.h" +#endif #include "attribute.h" diff --git a/drivers/snmp-ups.h b/drivers/snmp-ups.h index 83a3a25b98..fa6e495448 100644 --- a/drivers/snmp-ups.h +++ b/drivers/snmp-ups.h @@ -52,6 +52,14 @@ #ifndef SNMP_UPS_H #define SNMP_UPS_H +/* "config.h" is generated by autotools and lacks a header guard, so + * we use an unambiguously named macro we know we must have, as one. + * It must be the first header: be sure to know all about system config. + */ +#ifndef NUT_NETVERSION +# include "config.h" +#endif + #include "nut_stdint.h" /* uint32_t */ /* FIXME: still needed? diff --git a/drivers/usb-common.h b/drivers/usb-common.h index 4f151ee8ac..ba75091f75 100644 --- a/drivers/usb-common.h +++ b/drivers/usb-common.h @@ -57,7 +57,13 @@ #ifndef NUT_USB_COMMON_H #define NUT_USB_COMMON_H -#include "config.h" /* be sure to know all about the system config */ +/* "config.h" is generated by autotools and lacks a header guard, so + * we use an unambiguously named macro we know we must have, as one. + * It must be the first header: be sure to know all about system config. + */ +#ifndef NUT_NETVERSION +# include "config.h" +#endif /* Note: usb-common.h (this file) is included by nut_libusb.h, * so not looping the includes ;) diff --git a/drivers/usbhid-ups.h b/drivers/usbhid-ups.h index 2e8a3fcedd..679ea7de7c 100644 --- a/drivers/usbhid-ups.h +++ b/drivers/usbhid-ups.h @@ -26,11 +26,19 @@ #ifndef USBHID_UPS_H #define USBHID_UPS_H +/* "config.h" is generated by autotools and lacks a header guard, so + * we use an unambiguously named macro we know we must have, as one. + * It must be the first header: be sure to know all about system config. + */ +#ifndef NUT_NETVERSION +# include "config.h" +#endif + #include #include #include #include -#include "config.h" + #include "libhid.h" extern hid_dev_handle_t udev; diff --git a/include/common.h b/include/common.h index 407b8425aa..db1168b80d 100644 --- a/include/common.h +++ b/include/common.h @@ -20,7 +20,13 @@ #ifndef NUT_COMMON_H_SEEN #define NUT_COMMON_H_SEEN 1 -#include "config.h" /* must be the first header */ +/* "config.h" is generated by autotools and lacks a header guard, so + * we use an unambiguously named macro we know we must have, as one. + * It must be the first header: be sure to know all about system config. + */ +#ifndef NUT_NETVERSION +# include "config.h" +#endif #ifdef WIN32 # ifndef __POSIX_VISIBLE diff --git a/include/nut_float.h b/include/nut_float.h index 290edb4909..0b89974b62 100644 --- a/include/nut_float.h +++ b/include/nut_float.h @@ -22,7 +22,13 @@ #ifndef NUT_FLOAT_H_SEEN #define NUT_FLOAT_H_SEEN 1 -#include "config.h" +/* "config.h" is generated by autotools and lacks a header guard, so + * we use an unambiguously named macro we know we must have, as one. + * It must be the first header: be sure to know all about system config. + */ +#ifndef NUT_NETVERSION +# include "config.h" +#endif #if defined HAVE_FLOAT_H # include diff --git a/include/nut_stdint.h b/include/nut_stdint.h index 5f173191ae..9d64a061b4 100644 --- a/include/nut_stdint.h +++ b/include/nut_stdint.h @@ -21,7 +21,13 @@ #ifndef NUT_STDINT_H_SEEN #define NUT_STDINT_H_SEEN 1 -#include "config.h" +/* "config.h" is generated by autotools and lacks a header guard, so + * we use an unambiguously named macro we know we must have, as one. + * It must be the first header: be sure to know all about system config. + */ +#ifndef NUT_NETVERSION +# include "config.h" +#endif #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 diff --git a/include/proto.h b/include/proto.h index f88dd61f1c..68c251a118 100644 --- a/include/proto.h +++ b/include/proto.h @@ -24,7 +24,13 @@ #ifndef NUT_PROTO_H_SEEN #define NUT_PROTO_H_SEEN 1 -#include "config.h" +/* "config.h" is generated by autotools and lacks a header guard, so + * we use an unambiguously named macro we know we must have, as one. + * It must be the first header: be sure to know all about system config. + */ +#ifndef NUT_NETVERSION +# include "config.h" +#endif #include "attribute.h" From d31b8c2e5764aad20244ecb6afc9ae4b81879f1d Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 29 Feb 2024 12:19:40 +0000 Subject: [PATCH 0043/1079] */Makefile.am: fix comment referring to "$(top_builddir)/install-sh" Signed-off-by: Jim Klimov --- conf/Makefile.am | 2 +- data/Makefile.am | 2 +- data/html/Makefile.am | 2 +- docs/man/Makefile.am | 2 +- scripts/Makefile.am | 2 +- scripts/Solaris/Makefile.am | 2 +- scripts/Windows/Makefile.am | 2 +- scripts/devd/Makefile.am | 2 +- scripts/hotplug/Makefile.am | 2 +- scripts/installer/Makefile.am | 2 +- scripts/python/Makefile.am | 2 +- scripts/systemd/Makefile.am | 2 +- scripts/udev/Makefile.am | 2 +- scripts/upsdrvsvcctl/Makefile.am | 2 +- tests/NIT/Makefile.am | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/conf/Makefile.am b/conf/Makefile.am index 873d288324..fd384eebbc 100644 --- a/conf/Makefile.am +++ b/conf/Makefile.am @@ -22,7 +22,7 @@ SPELLCHECK_SRC = $(dist_sysconf_DATA) \ # NOTE: Due to portability, we do not use a GNU percent-wildcard extension. # We also have to export some variables that may be tainted by relative # paths when parsing the other makefile (e.g. MKDIR_P that may be defined -# via expanded $(top_builddir)/install_sh): +# via expanded $(top_builddir)/install-sh): #%-spellchecked: % Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT) # +$(MAKE) -s -f $(top_builddir)/docs/Makefile $(AM_MAKEFLAGS) MKDIR_P="$(MKDIR_P)" builddir="$(builddir)" srcdir="$(srcdir)" top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" SPELLCHECK_SRC_ONE="$<" SPELLCHECK_SRCDIR="$(srcdir)" SPELLCHECK_BUILDDIR="$(builddir)" $@ diff --git a/data/Makefile.am b/data/Makefile.am index 5fba2e442b..29c440bac2 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -9,7 +9,7 @@ EXTRA_DIST = evolution500.seq epdu-managed.dev # NOTE: Due to portability, we do not use a GNU percent-wildcard extension. # We also have to export some variables that may be tainted by relative # paths when parsing the other makefile (e.g. MKDIR_P that may be defined -# via expanded $(top_builddir)/install_sh): +# via expanded $(top_builddir)/install-sh): #%-spellchecked: % Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT) # +$(MAKE) -s -f $(top_builddir)/docs/Makefile $(AM_MAKEFLAGS) MKDIR_P="$(MKDIR_P)" builddir="$(builddir)" srcdir="$(srcdir)" top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" SPELLCHECK_SRC_ONE="$<" SPELLCHECK_SRCDIR="$(srcdir)" SPELLCHECK_BUILDDIR="$(builddir)" $@ diff --git a/data/html/Makefile.am b/data/html/Makefile.am index 19436e12da..1327c724b9 100644 --- a/data/html/Makefile.am +++ b/data/html/Makefile.am @@ -12,7 +12,7 @@ SPELLCHECK_SRC = README.adoc # NOTE: Due to portability, we do not use a GNU percent-wildcard extension. # We also have to export some variables that may be tainted by relative # paths when parsing the other makefile (e.g. MKDIR_P that may be defined -# via expanded $(top_builddir)/install_sh): +# via expanded $(top_builddir)/install-sh): #%-spellchecked: % Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT) # +$(MAKE) -s -f $(top_builddir)/docs/Makefile $(AM_MAKEFLAGS) MKDIR_P="$(MKDIR_P)" builddir="$(builddir)" srcdir="$(srcdir)" top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" SPELLCHECK_SRC_ONE="$<" SPELLCHECK_SRCDIR="$(srcdir)" SPELLCHECK_BUILDDIR="$(builddir)" $@ diff --git a/docs/man/Makefile.am b/docs/man/Makefile.am index 2931bc5252..2f096b7889 100644 --- a/docs/man/Makefile.am +++ b/docs/man/Makefile.am @@ -1123,7 +1123,7 @@ endif !HAVE_ASCIIDOC # NOTE: Due to portability, we do not use a GNU percent-wildcard extension. # We also have to export some variables that may be tainted by relative # paths when parsing the other makefile (e.g. MKDIR_P that may be defined -# via expanded $(top_builddir)/install_sh): +# via expanded $(top_builddir)/install-sh): #%-spellchecked: % Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT) # +$(MAKE) -s -f $(top_builddir)/docs/Makefile $(AM_MAKEFLAGS) MKDIR_P="$(MKDIR_P)" builddir="$(builddir)" srcdir="$(srcdir)" top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" SPELLCHECK_SRC_ONE="$<" SPELLCHECK_SRCDIR="$(srcdir)" SPELLCHECK_BUILDDIR="$(builddir)" $@ diff --git a/scripts/Makefile.am b/scripts/Makefile.am index f0f59aa877..225c10f015 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -35,7 +35,7 @@ SPELLCHECK_SRC = README.adoc RedHat/README.adoc usb_resetter/README.adoc # NOTE: Due to portability, we do not use a GNU percent-wildcard extension. # We also have to export some variables that may be tainted by relative # paths when parsing the other makefile (e.g. MKDIR_P that may be defined -# via expanded $(top_builddir)/install_sh): +# via expanded $(top_builddir)/install-sh): #%-spellchecked: % Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT) # +$(MAKE) -s -f $(top_builddir)/docs/Makefile MKDIR_P="$(MKDIR_P)" builddir="$(builddir)" srcdir="$(srcdir)" top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" SPELLCHECK_SRC_ONE="$<" SPELLCHECK_SRCDIR="$(srcdir)" SPELLCHECK_BUILDDIR="$(builddir)" $@ diff --git a/scripts/Solaris/Makefile.am b/scripts/Solaris/Makefile.am index 3f01ec6034..e142a02f4d 100644 --- a/scripts/Solaris/Makefile.am +++ b/scripts/Solaris/Makefile.am @@ -96,7 +96,7 @@ SPELLCHECK_SRC = README.adoc # NOTE: Due to portability, we do not use a GNU percent-wildcard extension. # We also have to export some variables that may be tainted by relative # paths when parsing the other makefile (e.g. MKDIR_P that may be defined -# via expanded $(top_builddir)/install_sh): +# via expanded $(top_builddir)/install-sh): #%-spellchecked: % Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT) # +$(MAKE) -s -f $(top_builddir)/docs/Makefile $(AM_MAKEFLAGS) MKDIR_P="$(MKDIR_P)" builddir="$(builddir)" srcdir="$(srcdir)" top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" SPELLCHECK_SRC_ONE="$<" SPELLCHECK_SRCDIR="$(srcdir)" SPELLCHECK_BUILDDIR="$(builddir)" $@ diff --git a/scripts/Windows/Makefile.am b/scripts/Windows/Makefile.am index 52e4d927f8..abbfd32a37 100644 --- a/scripts/Windows/Makefile.am +++ b/scripts/Windows/Makefile.am @@ -77,7 +77,7 @@ SPELLCHECK_SRC = README.adoc DriverInstaller/README.adoc Installer/README.adoc # NOTE: Due to portability, we do not use a GNU percent-wildcard extension. # We also have to export some variables that may be tainted by relative # paths when parsing the other makefile (e.g. MKDIR_P that may be defined -# via expanded $(top_builddir)/install_sh): +# via expanded $(top_builddir)/install-sh): #%-spellchecked: % Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT) # +$(MAKE) -s -f $(top_builddir)/docs/Makefile $(AM_MAKEFLAGS) MKDIR_P="$(MKDIR_P)" builddir="$(builddir)" srcdir="$(srcdir)" top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" SPELLCHECK_SRC_ONE="$<" SPELLCHECK_SRCDIR="$(srcdir)" SPELLCHECK_BUILDDIR="$(builddir)" $@ diff --git a/scripts/devd/Makefile.am b/scripts/devd/Makefile.am index e3a9967c2b..b9d9401ad3 100644 --- a/scripts/devd/Makefile.am +++ b/scripts/devd/Makefile.am @@ -36,7 +36,7 @@ SPELLCHECK_SRC = README.adoc # NOTE: Due to portability, we do not use a GNU percent-wildcard extension. # We also have to export some variables that may be tainted by relative # paths when parsing the other makefile (e.g. MKDIR_P that may be defined -# via expanded $(top_builddir)/install_sh): +# via expanded $(top_builddir)/install-sh): #%-spellchecked: % Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT) # +$(MAKE) -s -f $(top_builddir)/docs/Makefile $(AM_MAKEFLAGS) MKDIR_P="$(MKDIR_P)" builddir="$(builddir)" srcdir="$(srcdir)" top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" SPELLCHECK_SRC_ONE="$<" SPELLCHECK_SRCDIR="$(srcdir)" SPELLCHECK_BUILDDIR="$(builddir)" $@ diff --git a/scripts/hotplug/Makefile.am b/scripts/hotplug/Makefile.am index 8888492885..5fa7809f86 100644 --- a/scripts/hotplug/Makefile.am +++ b/scripts/hotplug/Makefile.am @@ -28,7 +28,7 @@ SPELLCHECK_SRC = README.adoc # NOTE: Due to portability, we do not use a GNU percent-wildcard extension. # We also have to export some variables that may be tainted by relative # paths when parsing the other makefile (e.g. MKDIR_P that may be defined -# via expanded $(top_builddir)/install_sh): +# via expanded $(top_builddir)/install-sh): #%-spellchecked: % Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT) # +$(MAKE) -s -f $(top_builddir)/docs/Makefile $(AM_MAKEFLAGS) MKDIR_P="$(MKDIR_P)" builddir="$(builddir)" srcdir="$(srcdir)" top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" SPELLCHECK_SRC_ONE="$<" SPELLCHECK_SRCDIR="$(srcdir)" SPELLCHECK_BUILDDIR="$(builddir)" $@ diff --git a/scripts/installer/Makefile.am b/scripts/installer/Makefile.am index ae236cf88b..10a67121cb 100644 --- a/scripts/installer/Makefile.am +++ b/scripts/installer/Makefile.am @@ -35,7 +35,7 @@ SPELLCHECK_SRC = README.adoc common/README_ipp-os-shutdown.adoc # NOTE: Due to portability, we do not use a GNU percent-wildcard extension. # We also have to export some variables that may be tainted by relative # paths when parsing the other makefile (e.g. MKDIR_P that may be defined -# via expanded $(top_builddir)/install_sh): +# via expanded $(top_builddir)/install-sh): #%-spellchecked: % Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT) # +$(MAKE) -s -f $(top_builddir)/docs/Makefile $(AM_MAKEFLAGS) MKDIR_P="$(MKDIR_P)" builddir="$(builddir)" srcdir="$(srcdir)" top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" SPELLCHECK_SRC_ONE="$<" SPELLCHECK_SRCDIR="$(srcdir)" SPELLCHECK_BUILDDIR="$(builddir)" $@ diff --git a/scripts/python/Makefile.am b/scripts/python/Makefile.am index 56eeaa97f4..0b83249cd5 100644 --- a/scripts/python/Makefile.am +++ b/scripts/python/Makefile.am @@ -199,7 +199,7 @@ SPELLCHECK_SRC = \ # NOTE: Due to portability, we do not use a GNU percent-wildcard extension. # We also have to export some variables that may be tainted by relative # paths when parsing the other makefile (e.g. MKDIR_P that may be defined -# via expanded $(top_builddir)/install_sh): +# via expanded $(top_builddir)/install-sh): #%-spellchecked: % Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT) # +$(MAKE) -s -f $(top_builddir)/docs/Makefile $(AM_MAKEFLAGS) MKDIR_P="$(MKDIR_P)" builddir="$(builddir)" srcdir="$(srcdir)" top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" SPELLCHECK_SRC_ONE="$<" SPELLCHECK_SRCDIR="$(srcdir)" SPELLCHECK_BUILDDIR="$(builddir)" $@ diff --git a/scripts/systemd/Makefile.am b/scripts/systemd/Makefile.am index 7a0f37f7b9..9b19fcee54 100644 --- a/scripts/systemd/Makefile.am +++ b/scripts/systemd/Makefile.am @@ -44,7 +44,7 @@ SPELLCHECK_SRC = README.adoc # NOTE: Due to portability, we do not use a GNU percent-wildcard extension. # We also have to export some variables that may be tainted by relative # paths when parsing the other makefile (e.g. MKDIR_P that may be defined -# via expanded $(top_builddir)/install_sh): +# via expanded $(top_builddir)/install-sh): #%-spellchecked: % Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT) # +$(MAKE) -s -f $(top_builddir)/docs/Makefile $(AM_MAKEFLAGS) MKDIR_P="$(MKDIR_P)" builddir="$(builddir)" srcdir="$(srcdir)" top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" SPELLCHECK_SRC_ONE="$<" SPELLCHECK_SRCDIR="$(srcdir)" SPELLCHECK_BUILDDIR="$(builddir)" $@ diff --git a/scripts/udev/Makefile.am b/scripts/udev/Makefile.am index e0576d952c..7a6e13fcd6 100644 --- a/scripts/udev/Makefile.am +++ b/scripts/udev/Makefile.am @@ -41,7 +41,7 @@ SPELLCHECK_SRC = README.adoc # NOTE: Due to portability, we do not use a GNU percent-wildcard extension. # We also have to export some variables that may be tainted by relative # paths when parsing the other makefile (e.g. MKDIR_P that may be defined -# via expanded $(top_builddir)/install_sh): +# via expanded $(top_builddir)/install-sh): #%-spellchecked: % Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT) # +$(MAKE) -s -f $(top_builddir)/docs/Makefile $(AM_MAKEFILE) MKDIR_P="$(MKDIR_P)" builddir="$(builddir)" srcdir="$(srcdir)" top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" SPELLCHECK_SRC_ONE="$<" SPELLCHECK_SRCDIR="$(srcdir)" SPELLCHECK_BUILDDIR="$(builddir)" $@ diff --git a/scripts/upsdrvsvcctl/Makefile.am b/scripts/upsdrvsvcctl/Makefile.am index 4cb4ad69d2..03adf8e1c4 100644 --- a/scripts/upsdrvsvcctl/Makefile.am +++ b/scripts/upsdrvsvcctl/Makefile.am @@ -17,7 +17,7 @@ SPELLCHECK_SRC = README.adoc # NOTE: Due to portability, we do not use a GNU percent-wildcard extension. # We also have to export some variables that may be tainted by relative # paths when parsing the other makefile (e.g. MKDIR_P that may be defined -# via expanded $(top_builddir)/install_sh): +# via expanded $(top_builddir)/install-sh): #%-spellchecked: % Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT) # +$(MAKE) -s -f $(top_builddir)/docs/Makefile $(AM_MAKEFLAGS) MKDIR_P="$(MKDIR_P)" builddir="$(builddir)" srcdir="$(srcdir)" top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" SPELLCHECK_SRC_ONE="$<" SPELLCHECK_SRCDIR="$(srcdir)" SPELLCHECK_BUILDDIR="$(builddir)" $@ diff --git a/tests/NIT/Makefile.am b/tests/NIT/Makefile.am index 086519757e..f251fa7b1f 100644 --- a/tests/NIT/Makefile.am +++ b/tests/NIT/Makefile.am @@ -36,7 +36,7 @@ SPELLCHECK_SRC = README.adoc # NOTE: Due to portability, we do not use a GNU percent-wildcard extension. # We also have to export some variables that may be tainted by relative # paths when parsing the other makefile (e.g. MKDIR_P that may be defined -# via expanded $(top_builddir)/install_sh): +# via expanded $(top_builddir)/install-sh): #%-spellchecked: % Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT) # +$(MAKE) -s -f $(top_builddir)/docs/Makefile $(AM_MAKEFLAGS) MKDIR_P="$(MKDIR_P)" builddir="$(builddir)" srcdir="$(srcdir)" top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" SPELLCHECK_SRC_ONE="$<" SPELLCHECK_SRCDIR="$(srcdir)" SPELLCHECK_BUILDDIR="$(builddir)" $@ From 78c3921d1c05e604f79fcfb32f1b567717be9f92 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 29 Feb 2024 13:53:20 +0000 Subject: [PATCH 0044/1079] docs/config-prereqs.txt: document hacks to get pip for Python 2.7 ...on systems that only support it partially Courtesy of https://stackoverflow.com/a/65125295/4715872 Signed-off-by: Jim Klimov --- docs/config-prereqs.txt | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/docs/config-prereqs.txt b/docs/config-prereqs.txt index b9f87bf8ef..a298add38d 100644 --- a/docs/config-prereqs.txt +++ b/docs/config-prereqs.txt @@ -21,9 +21,27 @@ Some of the below are alternatives, e.g. compiler toolkits (gcc vs. clang) or SSL implementations (OpenSSL vs Mozilla NSS) -- no problem installing both, at a disk space cost. -NOTE: Some NUT branches may need additional or different software versions +[NOTE] +====== +Some NUT branches may need additional or different software versions that are not yet included into `master` branch dependencies, e.g. the DMF -(Dynamic Mapping Files) sub-project needs LUA 5.1. +(Dynamic Mapping Files) sub-project needs LUA 5.1 for build and run-time, +and some Python modules for build, e.g. using OS packaging or custom call +to `pip install pycparser`. + +In case your system still provides a Python 2.x environment (and for some +reason you want to use it instead of Python 3.x), but does not anymore +provide a `pip` nor `pycparser` packages for it, you may need to use an +external bootstrap first, e.g.: + +------ +# Fetch get-pip.py for python 2.7 +:; curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py +:; python2 get-pip.py +:; python2 -m pip --version +:; python2 -m pip install pycparser +------ +====== More packages and/or system setup may be needed to actually run NUT with all features enabled; chapters below concern just with building it. From 175cbe8098338e63f42ebb54013214e67aa3973a Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 29 Feb 2024 15:37:37 +0100 Subject: [PATCH 0045/1079] common/common.c: get_libname_in_dir(): report first found "related" name (if any), if got no hits Signed-off-by: Jim Klimov --- common/common.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/common/common.c b/common/common.c index 8e20c9607c..987da9ce6d 100644 --- a/common/common.c +++ b/common/common.c @@ -2248,7 +2248,7 @@ static char * get_libname_in_dir(const char* base_libname, size_t base_libname_l */ DIR *dp; struct dirent *dirp; - char *libname_path = NULL; + char *libname_path = NULL, *libname_alias = NULL; char current_test_path[LARGEBUF]; memset(current_test_path, 0, LARGEBUF); @@ -2278,9 +2278,15 @@ static char * get_libname_in_dir(const char* base_libname, size_t base_libname_l upsdebugx(5,"Comparing lib %s with dirpath entry %s", base_libname, dirp->d_name); compres = strncmp(dirp->d_name, base_libname, base_libname_length); - if (compres == 0 - && dirp->d_name[base_libname_length] == '\0' /* avoid "*.dll.a" etc. */ - ) { + if (compres == 0) { + /* avoid "*.dll.a", ".so.1.2.3" etc. */ + if (dirp->d_name[base_libname_length] != '\0') { + if (!libname_alias) { + libname_alias = xstrdup(dirp->d_name); + } + continue; + } + snprintf(current_test_path, LARGEBUF, "%s/%s", dirname, dirp->d_name); #if HAVE_DECL_REALPATH libname_path = realpath(current_test_path, NULL); @@ -2332,6 +2338,17 @@ static char * get_libname_in_dir(const char* base_libname, size_t base_libname_l closedir(dp); + if (libname_alias) { + if (!libname_path) { + upsdebugx(1, "Got no strong candidate path for lib %s in %s" + ", but saw seemingly related names (are you missing" + " a symbolic link, perhaps?) e.g.: %s", + base_libname, dirname, libname_alias); + } + + free(libname_alias); + } + return libname_path; } From b77da2080cceb9a5a20f8bd273eeb2f8aec061fd Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 29 Feb 2024 15:45:42 +0100 Subject: [PATCH 0046/1079] docs/config-prereqs.txt: clarify libneon.so symlink on OpenBSD Signed-off-by: Jim Klimov --- docs/config-prereqs.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/config-prereqs.txt b/docs/config-prereqs.txt index a298add38d..1d8eacc591 100644 --- a/docs/config-prereqs.txt +++ b/docs/config-prereqs.txt @@ -843,10 +843,17 @@ default site. openssl nss \ augeas \ libusb1 \ - neon \ net-snmp \ avahi +# For netxml-ups driver the library should suffice; however for nut-scanner +# you may currently require to add a `libneon.so` symlink (the package seems +# to only deliver a numbered SO library name), e.g.: +:; pkg_add neon && \ + if ! test -s /usr/local/lib/libneon.so ; then + ln -s "`cd /usr/local/lib && ls -1 libneon.so.* | sort -n | tail -1`" /usr/local/lib/libneon.so + fi + # Select a LUA-5.1 (or possibly 5.2?) version :; pkg_add \ lua From 8649ccdb7ab0f6f264cc494ee9734fd383184a53 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Fri, 1 Mar 2024 02:22:49 +0100 Subject: [PATCH 0047/1079] drivers/usb-common.c: free() USB matcher structures if called again [#2309] e.g. when reconnecting after link loss Signed-off-by: Jim Klimov --- drivers/usb-common.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/usb-common.c b/drivers/usb-common.c index 6c10860ef8..56ca016a99 100644 --- a/drivers/usb-common.c +++ b/drivers/usb-common.c @@ -153,6 +153,13 @@ int USBNewExactMatcher(USBDeviceMatcher_t **matcher, USBDevice_t *hd) #ifdef DEBUG_EXACT_MATCH_DEVICE data->Device = hd->Device ? strdup(hd->Device) : NULL; #endif + + /* NOTE: Callers must pre-initialize to NULL! */ + if (matcher && *matcher) { + free(*matcher); + *matcher = NULL; + } + *matcher = m; return 0; @@ -334,6 +341,12 @@ int USBNewRegexMatcher(USBDeviceMatcher_t **matcher, char **regex, int cflags) } } + /* NOTE: Callers must pre-initialize to NULL! */ + if (matcher && *matcher) { + free(*matcher); + *matcher = NULL; + } + *matcher = m; return 0; From 556a99fdb5689b461888e7a0273d6ec5dc2cdf23 Mon Sep 17 00:00:00 2001 From: Yifeng Li Date: Fri, 1 Mar 2024 07:42:51 +0000 Subject: [PATCH 0048/1079] docs/Makefile.am: reminder about missing dictionary when aspell is unavailable When aspell is not unavailable, the cause can either be that aspell itself is not installed, or it has no English dictionary (aspell-en). I've wasted several minutes due to this oversight. Add this reminder in the error message to give clue to future developers. Signed-off-by: Yifeng Li --- docs/Makefile.am | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/Makefile.am b/docs/Makefile.am index c2fba72854..649f98237b 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -597,11 +597,11 @@ spellcheck-interactive: else !HAVE_ASPELL # This rule woulf probably just fail; normally with no ASPELL there are no callers for it */*-spellchecked *-spellchecked: Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT) - @echo " SKIP-ASPELL $@ : Documentation spell check not available since 'aspell' was not found." >&2 + @echo " SKIP-ASPELL $@ : Documentation spell check not available since 'aspell' was not found (or missing its English dictionary)." >&2 spellcheck: - @echo "Documentation spell check not available since 'aspell' was not found." + @echo "Documentation spell check not available since 'aspell' was not found (or missing its English dictionary)." spellcheck-interactive: - @echo "Documentation spell check not available since 'aspell' was not found." + @echo "Documentation spell check not available since 'aspell' was not found (or missing its English dictionary)." endif !HAVE_ASPELL From 749283474b21a24c591fb6d68bfe28632f4661f0 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Fri, 1 Mar 2024 09:07:33 +0100 Subject: [PATCH 0049/1079] docs/Makefile.am: comment typo fix Signed-off-by: Jim Klimov --- docs/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Makefile.am b/docs/Makefile.am index 649f98237b..ee4560246b 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -595,7 +595,7 @@ spellcheck-interactive: echo "------------------------------------------------------------------------" else !HAVE_ASPELL -# This rule woulf probably just fail; normally with no ASPELL there are no callers for it +# This rule would probably just fail; normally with no ASPELL there are no callers for it */*-spellchecked *-spellchecked: Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT) @echo " SKIP-ASPELL $@ : Documentation spell check not available since 'aspell' was not found (or missing its English dictionary)." >&2 spellcheck: From 8d55025fc175e3f8003cfc5afae441d93a4152ea Mon Sep 17 00:00:00 2001 From: Yifeng Li Date: Fri, 1 Mar 2024 07:24:58 +0000 Subject: [PATCH 0050/1079] huawei-ups2000.txt: add UPS2000-G-3KRTL to the confirmed list A user has reported that UPS2000-G-3KRTL is confirmed working, thus this commit adds it to the list of known-working models. A remark about standard and long runtime variants has also been added. Signed-off-by: Yifeng Li --- docs/man/huawei-ups2000.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/man/huawei-ups2000.txt b/docs/man/huawei-ups2000.txt index fadd11c39c..0cbe179a9f 100644 --- a/docs/man/huawei-ups2000.txt +++ b/docs/man/huawei-ups2000.txt @@ -31,9 +31,13 @@ on Linux 5.12 and newer kernels, but there are exceptions, read the section *Cabling* carefully). The UPS2000 series has two variants: UPS2000-A with a tower chassis, -and UPS2000-G with a rack-mount chassis. Both should be equally supported, -but more testers are needed. -Currently, it has been tested on the following models. +and UPS2000-G with a rack-mount chassis. Within these two variants, +there are also two sub-variants: a standard runtime model powered by +an internal battery pack denoted by an "S" suffix, and a long runtime +model powered by an external battery pack denoted by an "L" suffix. + +All of these models should be equally supported, but more testers are +needed. Currently, it has been tested on the following models. * UPS2000-A-1KTTS (firmware: UPS2000A, V2R1C1SPC40, P1.0-D1.0) * UPS2000-A-1KTTS (firmware: UPS2000A, V2R1C1SPC50, P1.0-D1.0) @@ -42,6 +46,7 @@ Currently, it has been tested on the following models. * UPS2000-G-1KRTS (firmware: UPS2000G, V2R1C1SPC50, P1.0-D1.0) * UPS2000-G-3KRTS (firmware: UPS2000A, V2R1C1SPC40, P1.0-D1.0) * UPS2000-G-3KRTS (firmware: UPS2000G, V2R1C1SPC50, P1.0-D1.0) +* UPS2000-G-3KRTL (firmware: UPS2000A, V2R1C1SPC40, P1.0-D1.0) If your model is not in the list, we encourage you to report successful or unsuccessful results to the bug tracker or the mailing list. From bf8245fe9a31a8d903fc7d27d53a2c54b600eb22 Mon Sep 17 00:00:00 2001 From: Yifeng Li Date: Fri, 1 Mar 2024 07:34:09 +0000 Subject: [PATCH 0051/1079] nut.dict: add model "KRTL" to dictionary. Signed-off-by: Yifeng Li --- docs/nut.dict | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/nut.dict b/docs/nut.dict index 96b530f9c3..a7402fe976 100644 --- a/docs/nut.dict +++ b/docs/nut.dict @@ -597,6 +597,7 @@ KNutClient KNutSetting KOLFF KRT +KRTL KRTS KTTS Kain From 66c4e10775c08e122c4257a0b8d4de88f52480a8 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Fri, 1 Mar 2024 04:06:36 +0100 Subject: [PATCH 0052/1079] Multiple USB-capable drivers: add ways to tune USB HID config, report, descriptor indexes and in/out endpoints [#2149] Signed-off-by: Jim Klimov --- NEWS.adoc | 7 +++ conf/ups.conf.sample | 9 ++++ docs/man/nut_usb_addvars.txt | 15 ++++++ docs/man/ups.conf.txt | 15 ++++++ docs/nut.dict | 4 +- drivers/arduino-hid.c | 18 ++++--- drivers/libshut.c | 49 ++++++++++++++++++- drivers/libusb0.c | 93 +++++++++++++++++++++++++++++++++++- drivers/libusb1.c | 91 ++++++++++++++++++++++++++++++++++- drivers/main.c | 5 ++ drivers/powervar-hid.c | 6 ++- tools/nut-scanner/scan_usb.c | 2 + 12 files changed, 300 insertions(+), 14 deletions(-) diff --git a/NEWS.adoc b/NEWS.adoc index 7e60297950..b241fa7f71 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -146,6 +146,13 @@ https://github.com/networkupstools/nut/milestone/10 * Driver programs with debug tracing support via `-D` CLI option and/or the `NUT_DEBUG_LEVEL` environment variable now check those earlier in their life-time, so that initialization routine can be debugged. [#2259] + * Multiple USB-capable drivers got options to customize `usb_config_index` + `usb_hid_rep_index`, `usb_hid_desc_index`, `usb_hid_ep_in` and + `usb_hid_ep_out` hardware connection settings via `ups.conf` options. + This is treated as experimental, not all code paths may be actually + using such values from `struct usb_communication_subdriver_t` rather + than hard-coded defaults. Discovery of correct values is up to the + user at the moment (using `lsusb`, internet search, luck...) [#2149] - nut-driver-enumerator (NDE) service/script: * The optional daemon mode (primarily useful for systems which monitor diff --git a/conf/ups.conf.sample b/conf/ups.conf.sample index 3a37f82ad4..7b68fc2574 100644 --- a/conf/ups.conf.sample +++ b/conf/ups.conf.sample @@ -172,6 +172,15 @@ maxretry = 3 # so it is not called by default. Yet others can be composite # devices which use a non-zero interface to represent the UPS. # +# usb_config_index=hexnum, usb_hid_rep_index=hexnum, +# usb_hid_desc_index=hexnum, usb_hid_ep_in=hexnum, usb_hid_ep_out=hexnum: +# OPTIONAL. Force use of specific interface, endpoint, descriptor +# index etc. numbers, rather than defaulting to 0 (rarely other +# values in certain drivers for some devices known to use non-zero +# numbers). As a rule of thumb for `usb_hid_desc_index` discovery, +# you can see larger `wDescriptorLength` values (roughly 600+ bytes) +# in reports of `lsusb` or similar tools. +# # default.: OPTIONAL. Set a default value for which is # used in case the UPS doesn't provide a value, but which will be # overwritten if a value is available from the UPS, e.g.: diff --git a/docs/man/nut_usb_addvars.txt b/docs/man/nut_usb_addvars.txt index 10479e7697..bc776e241a 100644 --- a/docs/man/nut_usb_addvars.txt +++ b/docs/man/nut_usb_addvars.txt @@ -109,3 +109,18 @@ If you must really know *which* one, it will not! Force redundant call to `usb_set_altinterface()`, especially if needed for devices serving multiple USB roles where the UPS is not represented by the interface number `0` (default). + +*usb_config_index*:: +*usb_hid_rep_index*:: +*usb_hid_desc_index*:: +*usb_hid_ep_in*:: +*usb_hid_ep_out*:: + +Force use of specific interface, endpoint, descriptor index etc. numbers, +rather than defaulting to 0 (rarely other values in certain drivers for +some devices known to use non-zero numbers). Specified as a hexadecimal +number. ++ +As a rule of thumb for `usb_hid_desc_index` discovery, you can see larger +`wDescriptorLength` values (roughly 600+ bytes) in reports of `lsusb` or +similar tools. diff --git a/docs/man/ups.conf.txt b/docs/man/ups.conf.txt index aa98feff1e..2d81d0bd57 100644 --- a/docs/man/ups.conf.txt +++ b/docs/man/ups.conf.txt @@ -272,6 +272,21 @@ certain UPSes from working on Mac OS X. If your UPS requires explicitly setting the alternate interface, include this flag, and email the nut-upsdev list with details about your UPS and operating system. +*usb_config_index*:: +*usb_hid_rep_index*:: +*usb_hid_desc_index*:: +*usb_hid_ep_in*:: +*usb_hid_ep_out*:: + +Optional. Force use of specific interface, endpoint, descriptor index etc. +numbers, rather than defaulting to 0 (rarely other values in certain drivers +for some devices known to use non-zero numbers). Specified as a hexadecimal +number. ++ +As a rule of thumb for `usb_hid_desc_index` discovery, you can see larger +`wDescriptorLength` values (roughly 600+ bytes) in reports of `lsusb` or +similar tools. + *default.*:: Optional. Set a default value for which is used in case the UPS diff --git a/docs/nut.dict b/docs/nut.dict index 96b530f9c3..63b8408de9 100644 --- a/docs/nut.dict +++ b/docs/nut.dict @@ -1,4 +1,4 @@ -personal_ws-1.1 en 3468 utf-8 +personal_ws-1.1 en 3470 utf-8 AAC AAS ABI @@ -2177,6 +2177,7 @@ hasFeature hb hcd hcl +hexnum hg hh hibernate's @@ -2897,6 +2898,7 @@ relicensing remoting renderer renderers +repindex repo reportId reposurgeon diff --git a/drivers/arduino-hid.c b/drivers/arduino-hid.c index 59206cbfd0..c63fff7573 100644 --- a/drivers/arduino-hid.c +++ b/drivers/arduino-hid.c @@ -151,18 +151,24 @@ static int arduino_claim(HIDDevice_t *hd) case POSSIBLY_SUPPORTED: /* by default, reject, unless the productid option is given */ if (getval("productid")) { - usb->hid_ep_in=4; - usb->hid_ep_out=5; - usb->hid_rep_index = 2; + if (!getval("usb_hid_ep_in")) + usb->hid_ep_in=4; + if (!getval("usb_hid_ep_out")) + usb->hid_ep_out=5; + if (!getval("usb_hid_rep_index")) + usb->hid_rep_index = 2; return 1; } possibly_supported("Arduino", hd); return 0; case SUPPORTED: - usb->hid_ep_in=4; - usb->hid_ep_out=5; - usb->hid_rep_index = 2; + if (!getval("usb_hid_ep_in")) + usb->hid_ep_in=4; + if (!getval("usb_hid_ep_out")) + usb->hid_ep_out=5; + if (!getval("usb_hid_rep_index")) + usb->hid_rep_index = 2; return 1; case NOT_SUPPORTED: diff --git a/drivers/libshut.c b/drivers/libshut.c index 3601c0c344..83b0cbe7c4 100644 --- a/drivers/libshut.c +++ b/drivers/libshut.c @@ -43,7 +43,7 @@ #include "common.h" /* for xmalloc, upsdebugx prototypes */ #define SHUT_DRIVER_NAME "SHUT communication driver" -#define SHUT_DRIVER_VERSION "0.88" +#define SHUT_DRIVER_VERSION "0.89" /* communication driver description structure */ upsdrv_info_t comm_upsdrv_info = { @@ -394,6 +394,50 @@ static int libshut_open( * version is at index 1 (in which case, bcdDevice == 0x0202) */ usb_ctrl_descindex hid_desc_index = 0; +#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_UNSIGNED_ZERO_COMPARE) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_TYPE_LIMIT_COMPARE) ) +# pragma GCC diagnostic push +#endif +#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS +# pragma GCC diagnostic ignored "-Wtype-limits" +#endif +#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE +# pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare" +#endif +#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_UNSIGNED_ZERO_COMPARE +# pragma GCC diagnostic ignored "-Wtautological-unsigned-zero-compare" +#endif +#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_TYPE_LIMIT_COMPARE +# pragma GCC diagnostic ignored "-Wtautological-type-limit-compare" +#endif +#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE +#pragma GCC diagnostic ignored "-Wunreachable-code" +#endif +/* Older CLANG (e.g. clang-3.4) seems to not support the GCC pragmas above */ +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunreachable-code" +#pragma clang diagnostic ignored "-Wtautological-compare" +#pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare" +#endif + static int usb_hid_number_opts_parsed = 0; + if (!usb_hid_number_opts_parsed) { + const char *s; + unsigned short us = 0; + if ((s = getval("usb_hid_desc_index"))) { + if (!str_to_ushort(s, &us, 16) || (us > USB_CTRL_DESCINDEX_MAX)) { + fatalx(EXIT_FAILURE, "%s: could not parse usb_hid_desc_index", __func__); + } + hid_desc_index = (usb_ctrl_descindex)us; + } + usb_hid_number_opts_parsed = 1; + } +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_UNSIGNED_ZERO_COMPARE) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_TYPE_LIMIT_COMPARE) ) +# pragma GCC diagnostic pop +#endif + if (!arg_device_path) { fatalx(EXIT_FAILURE, "%s: arg_device_path=null", __func__); } @@ -537,7 +581,8 @@ static int libshut_open( upsdebugx(2, "Device matches"); if ((curDevice->VendorID == 0x463) && (curDevice->bcdDevice == 0x0202)) { - upsdebugx(1, "Eaton device v2.02. Using full report descriptor"); + upsdebugx(1, "Eaton device v2.02. Using full report descriptor"); + if (!getval("usb_hid_desc_index")) hid_desc_index = 1; } diff --git a/drivers/libusb0.c b/drivers/libusb0.c index c713450ba0..cc8e094a80 100644 --- a/drivers/libusb0.c +++ b/drivers/libusb0.c @@ -37,7 +37,7 @@ #endif #define USB_DRIVER_NAME "USB communication driver (libusb 0.1)" -#define USB_DRIVER_VERSION "0.45" +#define USB_DRIVER_VERSION "0.47" /* driver description structure */ upsdrv_info_t comm_upsdrv_info = { @@ -94,6 +94,12 @@ void nut_usb_addvars(void) addvar(VAR_VALUE, "usb_set_altinterface", "Force redundant call to usb_set_altinterface() (value=bAlternateSetting; default=0)"); + addvar(VAR_VALUE, "usb_config_index", "Deeper tuning of USB communications for complex devices"); + addvar(VAR_VALUE, "usb_hid_rep_index", "Deeper tuning of USB communications for complex devices"); + addvar(VAR_VALUE, "usb_hid_desc_index", "Deeper tuning of USB communications for complex devices"); + addvar(VAR_VALUE, "usb_hid_ep_in", "Deeper tuning of USB communications for complex devices"); + addvar(VAR_VALUE, "usb_hid_ep_out", "Deeper tuning of USB communications for complex devices"); + dstate_setinfo("driver.version.usb", "libusb-0.1 (or compat)"); upsdebugx(1, "Using USB implementation: %s", dstate_getinfo("driver.version.usb")); @@ -219,6 +225,76 @@ static int libusb_open(usb_dev_handle **udevp, struct usb_bus *busses; + static int usb_hid_number_opts_parsed = 0; + if (!usb_hid_number_opts_parsed) { + const char *s; + unsigned short us = 0; + +#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_UNSIGNED_ZERO_COMPARE) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_TYPE_LIMIT_COMPARE) ) +# pragma GCC diagnostic push +#endif +#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS +# pragma GCC diagnostic ignored "-Wtype-limits" +#endif +#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE +# pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare" +#endif +#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_UNSIGNED_ZERO_COMPARE +# pragma GCC diagnostic ignored "-Wtautological-unsigned-zero-compare" +#endif +#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_TYPE_LIMIT_COMPARE +# pragma GCC diagnostic ignored "-Wtautological-type-limit-compare" +#endif +#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE +#pragma GCC diagnostic ignored "-Wunreachable-code" +#endif +/* Older CLANG (e.g. clang-3.4) seems to not support the GCC pragmas above */ +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunreachable-code" +#pragma clang diagnostic ignored "-Wtautological-compare" +#pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare" +#endif + if ((s = getval("usb_config_index"))) { + if (!str_to_ushort(s, &us, 16) || (us > USB_CTRL_CFGINDEX_MAX)) { + fatalx(EXIT_FAILURE, "%s: could not parse usb_config_index", __func__); + } + usb_subdriver.usb_config_index = (usb_ctrl_cfgindex)us; + } + if ((s = getval("usb_hid_rep_index"))) { + if (!str_to_ushort(s, &us, 16) || (us > USB_CTRL_REPINDEX_MAX)) { + fatalx(EXIT_FAILURE, "%s: could not parse usb_hid_rep_index", __func__); + } + usb_subdriver.hid_rep_index = (usb_ctrl_repindex)us; + } + if ((s = getval("usb_hid_desc_index"))) { + if (!str_to_ushort(s, &us, 16) || (us > USB_CTRL_DESCINDEX_MAX)) { + fatalx(EXIT_FAILURE, "%s: could not parse usb_hid_desc_index", __func__); + } + usb_subdriver.hid_desc_index = (usb_ctrl_descindex)us; + } + if ((s = getval("usb_hid_ep_in"))) { + if (!str_to_ushort(s, &us, 16) || (us > USB_CTRL_ENDPOINT_MAX)) { + fatalx(EXIT_FAILURE, "%s: could not parse usb_hid_ep_in", __func__); + } + usb_subdriver.hid_ep_in = (usb_ctrl_endpoint)us; + } + if ((s = getval("usb_hid_ep_out"))) { + if (!str_to_ushort(s, &us, 16) || (us > USB_CTRL_ENDPOINT_MAX)) { + fatalx(EXIT_FAILURE, "%s: could not parse usb_hid_ep_out", __func__); + } + usb_subdriver.hid_ep_out = (usb_ctrl_endpoint)us; + } +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_UNSIGNED_ZERO_COMPARE) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_TYPE_LIMIT_COMPARE) ) +# pragma GCC diagnostic pop +#endif + + usb_hid_number_opts_parsed = 1; + } + /* libusb base init */ usb_init(); usb_find_busses(); @@ -374,7 +450,8 @@ static int libusb_open(usb_dev_handle **udevp, /* FIXME: extend to Eaton OEMs (HP, IBM, ...) */ if ((curDevice->VendorID == 0x463) && (curDevice->bcdDevice == 0x0202)) { - usb_subdriver.hid_desc_index = 1; + if (!getval("usb_hid_desc_index")) + usb_subdriver.hid_desc_index = 1; } upsdebugx(2, "Trying to match device"); @@ -618,6 +695,18 @@ static int libusb_open(usb_dev_handle **udevp, "Report descriptor retrieved (Reportlen = %" PRI_NUT_USB_CTRL_CHARBUFSIZE ")", rdlen); upsdebugx(2, "Found HID device"); + + upsdebugx(3, "Using default, detected or customized USB HID numbers: " + "usb_config_index=%d usb_hid_rep_index=%d " + "usb_hid_desc_index=%d " + "usb_hid_ep_in=%d usb_hid_ep_out=%d", + usb_subdriver.usb_config_index, + usb_subdriver.hid_rep_index, + usb_subdriver.hid_desc_index, + usb_subdriver.hid_ep_in, + usb_subdriver.hid_ep_out + ); + fflush(stdout); return rdlen; diff --git a/drivers/libusb1.c b/drivers/libusb1.c index c84a28218a..5bb012eaff 100644 --- a/drivers/libusb1.c +++ b/drivers/libusb1.c @@ -33,7 +33,7 @@ #include "nut_stdint.h" #define USB_DRIVER_NAME "USB communication driver (libusb 1.0)" -#define USB_DRIVER_VERSION "0.46" +#define USB_DRIVER_VERSION "0.47" /* driver description structure */ upsdrv_info_t comm_upsdrv_info = { @@ -88,6 +88,12 @@ void nut_usb_addvars(void) addvar(VAR_VALUE, "usb_set_altinterface", "Force redundant call to usb_set_altinterface() (value=bAlternateSetting; default=0)"); + addvar(VAR_VALUE, "usb_config_index", "Deeper tuning of USB communications for complex devices"); + addvar(VAR_VALUE, "usb_hid_rep_index", "Deeper tuning of USB communications for complex devices"); + addvar(VAR_VALUE, "usb_hid_desc_index", "Deeper tuning of USB communications for complex devices"); + addvar(VAR_VALUE, "usb_hid_ep_in", "Deeper tuning of USB communications for complex devices"); + addvar(VAR_VALUE, "usb_hid_ep_out", "Deeper tuning of USB communications for complex devices"); + #ifdef LIBUSB_API_VERSION dstate_setinfo("driver.version.usb", "libusb-%u.%u.%u (API: 0x%x)", v->major, v->minor, v->micro, LIBUSB_API_VERSION); #else /* no LIBUSB_API_VERSION */ @@ -189,6 +195,76 @@ static int nut_libusb_open(libusb_device_handle **udevp, unsigned char rdbuf[MAX_REPORT_SIZE]; int32_t rdlen; + static int usb_hid_number_opts_parsed = 0; + if (!usb_hid_number_opts_parsed) { + const char *s; + unsigned short us = 0; + +#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_UNSIGNED_ZERO_COMPARE) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_TYPE_LIMIT_COMPARE) ) +# pragma GCC diagnostic push +#endif +#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS +# pragma GCC diagnostic ignored "-Wtype-limits" +#endif +#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE +# pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare" +#endif +#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_UNSIGNED_ZERO_COMPARE +# pragma GCC diagnostic ignored "-Wtautological-unsigned-zero-compare" +#endif +#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_TYPE_LIMIT_COMPARE +# pragma GCC diagnostic ignored "-Wtautological-type-limit-compare" +#endif +#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE +#pragma GCC diagnostic ignored "-Wunreachable-code" +#endif +/* Older CLANG (e.g. clang-3.4) seems to not support the GCC pragmas above */ +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunreachable-code" +#pragma clang diagnostic ignored "-Wtautological-compare" +#pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare" +#endif + if ((s = getval("usb_config_index"))) { + if (!str_to_ushort(s, &us, 16) || (us > USB_CTRL_CFGINDEX_MAX)) { + fatalx(EXIT_FAILURE, "%s: could not parse usb_config_index", __func__); + } + usb_subdriver.usb_config_index = (usb_ctrl_cfgindex)us; + } + if ((s = getval("usb_hid_rep_index"))) { + if (!str_to_ushort(s, &us, 16) || (us > USB_CTRL_REPINDEX_MAX)) { + fatalx(EXIT_FAILURE, "%s: could not parse usb_hid_rep_index", __func__); + } + usb_subdriver.hid_rep_index = (usb_ctrl_repindex)us; + } + if ((s = getval("usb_hid_desc_index"))) { + if (!str_to_ushort(s, &us, 16) || (us > USB_CTRL_DESCINDEX_MAX)) { + fatalx(EXIT_FAILURE, "%s: could not parse usb_hid_desc_index", __func__); + } + usb_subdriver.hid_desc_index = (usb_ctrl_descindex)us; + } + if ((s = getval("usb_hid_ep_in"))) { + if (!str_to_ushort(s, &us, 16) || (us > USB_CTRL_ENDPOINT_MAX)) { + fatalx(EXIT_FAILURE, "%s: could not parse usb_hid_ep_in", __func__); + } + usb_subdriver.hid_ep_in = (usb_ctrl_endpoint)us; + } + if ((s = getval("usb_hid_ep_out"))) { + if (!str_to_ushort(s, &us, 16) || (us > USB_CTRL_ENDPOINT_MAX)) { + fatalx(EXIT_FAILURE, "%s: could not parse usb_hid_ep_out", __func__); + } + usb_subdriver.hid_ep_out = (usb_ctrl_endpoint)us; + } +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_UNSIGNED_ZERO_COMPARE) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_TYPE_LIMIT_COMPARE) ) +# pragma GCC diagnostic pop +#endif + + usb_hid_number_opts_parsed = 1; + } + /* libusb base init */ if (libusb_init(NULL) < 0) { libusb_exit(NULL); @@ -381,6 +457,7 @@ static int nut_libusb_open(libusb_device_handle **udevp, /* FIXME: extend to Eaton OEMs (HP, IBM, ...) */ if ((curDevice->VendorID == 0x463) && (curDevice->bcdDevice == 0x0202)) { + if (!getval("usb_hid_desc_index")) usb_subdriver.hid_desc_index = 1; } @@ -702,6 +779,18 @@ static int nut_libusb_open(libusb_device_handle **udevp, upsdebugx(2, "Report descriptor retrieved (Reportlen = %d)", rdlen); upsdebugx(2, "Found HID device"); + + upsdebugx(3, "Using default, detected or customized USB HID numbers: " + "usb_config_index=%d usb_hid_rep_index=%d " + "usb_hid_desc_index=%d " + "usb_hid_ep_in=%d usb_hid_ep_out=%d", + usb_subdriver.usb_config_index, + usb_subdriver.hid_rep_index, + usb_subdriver.hid_desc_index, + usb_subdriver.hid_ep_in, + usb_subdriver.hid_ep_out + ); + fflush(stdout); libusb_free_device_list(devlist, 1); diff --git a/drivers/main.c b/drivers/main.c index 8eb7b08b5c..cc33fd5f1f 100644 --- a/drivers/main.c +++ b/drivers/main.c @@ -364,6 +364,11 @@ void storeval(const char *var, char *val) || !strcmp(var, "device") || !strcmp(var, "busport") || !strcmp(var, "usb_set_altinterface") + || !strcmp(var, "usb_config_index") + || !strcmp(var, "usb_hid_rep_index") + || !strcmp(var, "usb_hid_desc_index") + || !strcmp(var, "usb_hid_ep_in") + || !strcmp(var, "usb_hid_ep_out") || !strcmp(var, "allow_duplicates") || !strcmp(var, "langid_fix") || !strcmp(var, "noscanlangid") diff --git a/drivers/powervar-hid.c b/drivers/powervar-hid.c index a37978aa48..4821ca88c2 100644 --- a/drivers/powervar-hid.c +++ b/drivers/powervar-hid.c @@ -119,14 +119,16 @@ static int powervar_claim(HIDDevice_t *hd) case POSSIBLY_SUPPORTED: /* by default, reject, unless the productid option is given */ if (getval("productid")) { - usb->hid_rep_index = 1; + if (!getval("usb_hid_rep_index")) + usb->hid_rep_index = 1; return 1; } possibly_supported("Powervar", hd); return 0; case SUPPORTED: - usb->hid_rep_index = 1; + if (!getval("usb_hid_rep_index")) + usb->hid_rep_index = 1; return 1; case NOT_SUPPORTED: diff --git a/tools/nut-scanner/scan_usb.c b/tools/nut-scanner/scan_usb.c index c24dc09a51..dbe2aa5c30 100644 --- a/tools/nut-scanner/scan_usb.c +++ b/tools/nut-scanner/scan_usb.c @@ -612,6 +612,8 @@ nutscan_device_t * nutscan_scan_usb(nutscan_usb_t * scanopts) } #endif /* WITH_LIBUSB_1_0 */ + /* FIXME: Detect and suggest HID index, interface number, etc. */ + if (scanopts->report_bcdDevice) { /* Not currently matched by drivers, hence commented * for now even if requested via scanopts */ From cd4e190c0fbce003f223f01093867b6c2026b5c7 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Fri, 1 Mar 2024 21:33:56 +0100 Subject: [PATCH 0053/1079] tools/nut-scanner/scan_nut_simulation.c: do not abort if CONFPATH is missing [#2235] Signed-off-by: Jim Klimov --- tools/nut-scanner/scan_nut_simulation.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/nut-scanner/scan_nut_simulation.c b/tools/nut-scanner/scan_nut_simulation.c index 402293ad47..b2c4cddabb 100644 --- a/tools/nut-scanner/scan_nut_simulation.c +++ b/tools/nut-scanner/scan_nut_simulation.c @@ -45,10 +45,13 @@ nutscan_device_t * nutscan_scan_nut_simulation(void) pthread_mutex_init(&dev_mutex, NULL); #endif /* HAVE_PTHREAD */ - upsdebugx(1,"Scanning: %s", CONFPATH); + upsdebugx(1, "Scanning: %s", CONFPATH); if ((dp = opendir(CONFPATH)) == NULL) { - fatal_with_errno(EXIT_FAILURE, "Failed to open %s", CONFPATH); + upsdebugx(1, "%s: Failed to open %s: %s (%d)", + __func__, CONFPATH, strerror(errno), errno); + upsdebugx(0, "Failed to open %s, skip NUT simulation scan", + CONFPATH); return NULL; } @@ -63,7 +66,7 @@ nutscan_device_t * nutscan_scan_nut_simulation(void) /* Filter on '.dev' and '.seq' extensions' */ if ((strcmp(ext, ".dev") == 0) || (strcmp(ext, ".seq") == 0)) { - upsdebugx(1,"Found simulation file: %s", dirp->d_name); + upsdebugx(1, "Found simulation file: %s", dirp->d_name); dev = nutscan_new_device(); dev->type = TYPE_NUT_SIMULATION; From 08379e5fc464f79b02c05d64966e6f314f4d1f47 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Fri, 1 Mar 2024 21:46:34 +0100 Subject: [PATCH 0054/1079] tools/nut-scanner/nut-scanner.c: use same conservative base level of USB scan verbosity when scanning all media types (-C) [#2334] Signed-off-by: Jim Klimov --- tools/nut-scanner/nut-scanner.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tools/nut-scanner/nut-scanner.c b/tools/nut-scanner/nut-scanner.c index 500b3d9d59..c26e589373 100644 --- a/tools/nut-scanner/nut-scanner.c +++ b/tools/nut-scanner/nut-scanner.c @@ -239,7 +239,8 @@ static void show_usage(void) printf(" -C, --complete_scan: Scan all available devices except serial ports (default).\n"); if (nutscan_avail_usb) { printf(" -U, --usb_scan: Scan USB devices. Specify twice or more to report different\n" - " detail levels of (change-prone) physical properties.\n"); + " detail levels of (change-prone) physical properties.\n" + " This usage can be combined with '-C' or other scan types.\n"); } else { printf("* Options for USB devices scan not enabled: library not detected.\n"); } @@ -683,7 +684,8 @@ int main(int argc, char *argv[]) goto display_help; } allow_usb = 1; - /* NOTE: Starts as -1, so the first -U sets it to 0 (minimal detail) */ + /* NOTE: Starts as -1, so the first -U sets it to 0 + * (minimal detail); further -U can bump it */ if (cli_link_detail_level < 3) cli_link_detail_level++; break; @@ -809,6 +811,11 @@ int main(int argc, char *argv[]) if (allow_all) { allow_usb = 1; + /* NOTE: Starts as -1, so when we scan everything - set + * it to 0 (minimal detail); further -U can bump it */ + if (cli_link_detail_level < 0) + cli_link_detail_level++; + allow_snmp = 1; allow_xml = 1; allow_oldnut = 1; From 44573388512a1e8633eb4e23c05b3dc711dd2cd5 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 2 Mar 2024 14:28:37 +0000 Subject: [PATCH 0055/1079] tools/nut-scanner/nut-scanner.c: bump (C) years, reconcile with master branch Signed-off-by: Jim Klimov --- tools/nut-scanner/nut-scanner.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/nut-scanner/nut-scanner.c b/tools/nut-scanner/nut-scanner.c index c26e589373..254e6380f3 100644 --- a/tools/nut-scanner/nut-scanner.c +++ b/tools/nut-scanner/nut-scanner.c @@ -1,7 +1,8 @@ /* * Copyright (C) 2011 - 2024 Arnaud Quette * Copyright (C) 2016 Michal Vyskocil - * Copyright (C) 2016 - 2023 Jim Klimov + * Copyright (C) 2016 - 2021 Jim Klimov + * Copyright (C) 2022 - 2024 Jim Klimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,6 +24,7 @@ \author Arnaud Quette \author Michal Vyskocil \author Jim Klimov + \author Jim Klimov */ #include "common.h" /* Must be first include to pull "config.h" */ From 2bae0347a9599e7f9ca77bb5d7368eaf9ca9c6b6 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 2 Mar 2024 13:38:26 +0000 Subject: [PATCH 0056/1079] NEWS.adoc: rephrase the text about Eaton-contributed installer from news prepared in FTY branch Signed-off-by: Jim Klimov --- NEWS.adoc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/NEWS.adoc b/NEWS.adoc index b241fa7f71..0a9ad22394 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -204,11 +204,15 @@ https://github.com/networkupstools/nut/milestone/10 - Laid foundations for the SmartNUT effort (aiming to integrate drivers with some other backends than the networked NUT data server process). - - Eaton contributed recipes and scripts used to create the IPP for Unix bundle - (UPS software companion), delivering NUT packages with an interactive + - Eaton contributed recipes and scripts used to create the IPP for Unix + bundle (aka Eaton IPSS Unix or UPP), a freely available value-added + packaging of NUT distributed as the UPS software companion for OSes + where their more complex UPS monitoring/management tools had not been + ported. This allows for delivery of NUT packages with an interactive installer and some system integration scripts (events, notifications, - status, shutdown daemon...) -- provided "as is" at the moment, and may - later serve as foundation or inspiration for new NUT features. [#2288] + status, shutdown daemon...), and was contributed to the NUT upstream + project by Eaton -- provided "as is" at the moment, and may later serve + as foundation or inspiration for new NUT features. [#2288] - nutconf (C++ library and tool to read and manage NUT configuration files) was started in the open by Eaton employees and used in the IPP installer, From 01b8fdc34e171e8018fd2cde68696509fd3a4f7b Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 2 Mar 2024 13:42:01 +0000 Subject: [PATCH 0057/1079] NEWS.adoc, UPGRADING.adoc: clarify drop of oldmge-shut from NUT codebase Signed-off-by: Jim Klimov --- NEWS.adoc | 1 + UPGRADING.adoc | 1 + 2 files changed, 2 insertions(+) diff --git a/NEWS.adoc b/NEWS.adoc index 0a9ad22394..bb940c62ef 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -1500,6 +1500,7 @@ Release notes for NUT 2.6.5 - what's new since 2.6.4 - mge-shut driver has been replaced by a new implementation (newmge-shut). In case of issue with this new version, users can revert to oldmge-shut. + UPDATE: oldmge-shut was dropped between 2.7.4 and 2.8.0 releases. - First NUT virtualization package: NUT now supports integration with VMware ESXI 5.0, through a native VIB package. This is, for the time diff --git a/UPGRADING.adoc b/UPGRADING.adoc index 2ede05ee5a..cf0f26ea7e 100644 --- a/UPGRADING.adoc +++ b/UPGRADING.adoc @@ -417,6 +417,7 @@ Changes from 2.6.4 to 2.6.5 upssched. - mge-shut driver has been replaced by a new implementation (newmge-shut). In case of issue with this new version, users can revert to oldmge-shut. +UPDATE: oldmge-shut was dropped between 2.7.4 and 2.8.0 releases. Changes from 2.6.3 to 2.6.4 --------------------------- From f30839606b77c03ef3d18a875dbf551f54bd00e2 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 2 Mar 2024 15:41:54 +0100 Subject: [PATCH 0058/1079] UPGRADING.adoc: fix basic asciidoc list markup for releases v2.6.x and older Signed-off-by: Jim Klimov --- UPGRADING.adoc | 174 ++++++++++++++++++++++++++++--------------------- 1 file changed, 98 insertions(+), 76 deletions(-) diff --git a/UPGRADING.adoc b/UPGRADING.adoc index cf0f26ea7e..cb89c907dd 100644 --- a/UPGRADING.adoc +++ b/UPGRADING.adoc @@ -414,18 +414,20 @@ Changes from 2.6.4 to 2.6.5 --------------------------- - users are encouraged to update to NUT 2.6.5, to fix a regression in -upssched. + upssched. + - mge-shut driver has been replaced by a new implementation (newmge-shut). -In case of issue with this new version, users can revert to oldmge-shut. -UPDATE: oldmge-shut was dropped between 2.7.4 and 2.8.0 releases. + In case of issue with this new version, users can revert to oldmge-shut. + UPDATE: oldmge-shut was dropped between 2.7.4 and 2.8.0 releases. Changes from 2.6.3 to 2.6.4 --------------------------- - users are encouraged to update to NUT 2.6.4, to fix upsd vulnerability -(CVE-2012-2944: upsd can be remotely crashed). + (CVE-2012-2944: upsd can be remotely crashed). + - users of the bestups driver are encouraged to switch to blazer_ser, -since bestups will soon be deprecated. + since bestups will soon be deprecated. Changes from 2.6.2 to 2.6.3 --------------------------- @@ -436,7 +438,7 @@ Changes from 2.6.1 to 2.6.2 --------------------------- - apcsmart driver has been replaced by a new implementation. In case of issue -with this new version, users can revert to apcsmart-old. + with this new version, users can revert to apcsmart-old. Changes from 2.6.0 to 2.6.1 --------------------------- @@ -447,9 +449,10 @@ Changes from 2.4.3 to 2.6.0 --------------------------- - users of the megatec and megatec_usb drivers must respectively switch to -blazer_ser and blazer_usb. + blazer_ser and blazer_usb. + - users of the liebertgxt2 driver are advised that the driver name has changed -to liebert-esp2. + to liebert-esp2. Changes from 2.4.2 to 2.4.3 --------------------------- @@ -460,11 +463,12 @@ Changes from 2.4.1 to 2.4.2 --------------------------- - The default subdriver for the blazer_usb driver USB id 06da:0003 has changed. -If you use such a device and it is no longer working with this driver, override -the 'subdriver' default in 'ups.conf' (see man 8 blazer). + If you use such a device and it is no longer working with this driver, + override the 'subdriver' default in 'ups.conf' (see man 8 blazer). + - NUT ACL and the allowfrom mechanism has been replaced in 2.4.0 by the LISTEN -directive and tcp-wrappers respectively. This information was missing below, so -a double note has been added. + directive and tcp-wrappers respectively. This information was missing below, + so a double note has been added. Changes from 2.4.0 to 2.4.1 --------------------------- @@ -475,157 +479,175 @@ Changes from 2.2.2 to 2.4.0 --------------------------- - The nut.conf file has been introduced to standardize startup configuration -across the various systems. + across the various systems. + - The cpsups and nitram drivers have been replaced by the powerpanel driver, -and removed from the tree. The cyberpower driver may suffer the same in the -future. + and removed from the tree. The cyberpower driver may suffer the same in the + future. + - The al175 and energizerups drivers have been removed from the tree, since -these were tagged broken for a long time. + these were tagged broken for a long time. + - Developers of external client application using libupsclient must rename -their "UPSCONN" client structure to "UPSCONN_t". + their "UPSCONN" client structure to "UPSCONN_t". + - The upsd server will now disconnect clients that remain silent for more than -60 seconds. + 60 seconds. + - The files under scripts/python/client are distributed under GPL 3+, whereas -the rest of the files are distributed under GPL 2+. Refer to COPYING for more -information. + the rest of the files are distributed under GPL 2+. Refer to COPYING for more + information. + - The generated udev rules file has been renamed with dash only, no underscore -anymore (ie 52-nut-usbups.rules instead of 52_nut-usbups.rules) + anymore (i.e. 52-nut-usbups.rules instead of 52_nut-usbups.rules) Changes from 2.2.1 to 2.2.2 --------------------------- - The configure option "--with-lib" has been replaced by "--with-dev". -This enable the additional build and distribution of the static -version of libupsclient, along with the pkg-config helper and manual -pages. The default configure option is to distribute only the shared -version of libupsclient. This can be overridden by using the -"--disable-shared" configure option (distribute static only binaries). + This enable the additional build and distribution of the static + version of libupsclient, along with the pkg-config helper and manual + pages. The default configure option is to distribute only the shared + version of libupsclient. This can be overridden by using the + "--disable-shared" configure option (distribute static only binaries). + - The UPS poweroff handling of the usbhid-ups driver has been reworked. -Though regression is not expected, users of this driver are -encouraged to test this feature by calling "upsmon -c fsd" and -report any issue on the NUT mailing lists. + Though regression is not expected, users of this driver are + encouraged to test this feature by calling "upsmon -c fsd" and + report any issue on the NUT mailing lists. Changes from 2.2.0 to 2.2.1 --------------------------- - nothing that affects upgraded systems. -(The below message is repeated due to previous omission) + (The below message is repeated due to previous omission) + - Developers of external client application using libupsclient are -encouraged to rename their "UPSCONN" client structure to "UPSCONN_t" -since the former will disappear by the release of NUT 2.4. + encouraged to rename their "UPSCONN" client structure to "UPSCONN_t" + since the former will disappear by the release of NUT 2.4. Changes from 2.0.5 to 2.2.0 --------------------------- - users of the newhidups driver are advised that the driver name has changed -to usbhid-ups. + to usbhid-ups. + - users of the hidups driver must switch to usbhid-ups. + - users of the following drivers (powermust, blazer, fentonups, mustek, -esupssmart, ippon, sms) must switch to megatec, which replaces -all these drivers. Please refer to doc/megatec.txt for details. + esupssmart, ippon, sms) must switch to megatec, which replaces + all these drivers. Please refer to doc/megatec.txt for details. + - users of the mge-shut driver are encouraged to test newmge-shut, which -is an alternate driver scheduled to replace mge-shut, + is an alternate driver scheduled to replace mge-shut, + - users of the cpsups driver are encouraged to switch to powerpanel which -is scheduled to replace cpsups, + is scheduled to replace cpsups, + - packagers will have to rework the whole nut packaging due to the -major changes in the build system (completely modified, and now using -automake). Refer to packaging/debian/ for an example of migration. + major changes in the build system (completely modified, and now using + automake). Refer to packaging/debian/ for an example of migration. + - specifying '-a ' is now mandatory when starting a driver manually, -ie not using upsdrvctl. + i.e. not using upsdrvctl. + - Developers of external client application using libupsclient are -encouraged to rename the "UPSCONN" client structure to "UPSCONN_t" -since the former will disappear by the release of NUT 2.4. + encouraged to rename the "UPSCONN" client structure to "UPSCONN_t" + since the former will disappear by the release of NUT 2.4. Changes from 2.0.4 to 2.0.5 --------------------------- - users of the newhidups driver: the driver is now more strict about -refusing to connect to unknown devices. If your device was -previously supported, but fails to be recognized now, add -'productid=XXXX' to ups.conf. Please report the device to the NUT -developer's mailing list. + refusing to connect to unknown devices. If your device was + previously supported, but fails to be recognized now, add + 'productid=XXXX' to ups.conf. Please report the device to the NUT + developer's mailing list. Changes from 2.0.3 to 2.0.4 --------------------------- - nothing that affects upgraded systems. + - users of the following drivers (powermust, blazer, fentonups, mustek, -esupssmart, ippon, sms, masterguard) are encouraged to switch to megatec, -which should replace all these drivers by nut 2.2. For more information, -please refer to doc/megatec.txt + esupssmart, ippon, sms, masterguard) are encouraged to switch to megatec, + which should replace all these drivers by nut 2.2. For more information, + please refer to doc/megatec.txt Changes from 2.0.2 to 2.0.3 --------------------------- - nothing that affects upgraded systems. + - hidups users are encouraged to switch to newhidups, as hidups will be -removed by nut 2.2. + removed by nut 2.2. Changes from 2.0.1 to 2.0.2 --------------------------- - The newhidups driver, which is the long run USB support approach, -needs hotplug files installed to setup the right permissions on -device file to operate. Check newhidups manual page for more information. + needs hotplug files installed to setup the right permissions on + device file to operate. Check newhidups manual page for more information. Changes from 2.0.0 to 2.0.1 --------------------------- - The cyberpower1100 driver is now called cpsups since it supports -more than just one model. If you use this driver, be sure to remove -the old binary and update your ups.conf 'driver=' setting with the -new name. + more than just one model. If you use this driver, be sure to remove + the old binary and update your ups.conf 'driver=' setting with the + new name. - The upsstats.html template page has been changed slightly to reflect -better HTML compliance, so you may want to update your installed copy -accordingly. If you've customized your file, don't just copy the new -one over it, or your changes will be lost! + better HTML compliance, so you may want to update your installed copy + accordingly. If you've customized your file, don't just copy the new + one over it, or your changes will be lost! Changes from 1.4.0 to 2.0.0 --------------------------- - The sample config files are no longer installed by default. If you -want to install them, use 'make install-conf' for the main programs, -and 'make install-cgi-conf' for the CGI programs. + want to install them, use 'make install-conf' for the main programs, + and 'make install-cgi-conf' for the CGI programs. - ACCESS is no longer supported in upsd.conf. Use ACCEPT and REJECT. -Old way: + * Old way: ++ ACCESS grant all adminbox ACCESS grant all webserver ACCESS deny all all -New way: - + * New way: ++ ACCEPT adminbox ACCEPT webserver REJECT all -Note that ACCEPT and REJECT can take multiple arguments, so this -will also work: - + * Note that ACCEPT and REJECT can take multiple arguments, so this + will also work: ++ ACCEPT adminbox webserver REJECT all - The drivers no longer support sddelay in ups.conf or -d on the -command line. If you need a delay after calling 'upsdrvctl -shutdown', add a call to sleep in your shutdown script. + command line. If you need a delay after calling 'upsdrvctl + shutdown', add a call to sleep in your shutdown script. - The templates used by upsstats have changed considerably to reflect -the new variable names. If you use upsstats, you will need to -install new copies or edit your existing files to use the new names. + the new variable names. If you use upsstats, you will need to + install new copies or edit your existing files to use the new names. - Nobody needed UDP mode, so it has been removed. The only users -seemed to be a few people like me with ancient asapm-ups binaries. -If you really want to run asapm-ups again, bug me for the new patch -which makes it work with upsclient. + seemed to be a few people like me with ancient asapm-ups binaries. + If you really want to run asapm-ups again, bug me for the new patch + which makes it work with upsclient. - 'make install-misc' is now 'make install-lib'. The misc directory -has been gone for a long time, and the target was ambiguous. + has been gone for a long time, and the target was ambiguous. - The newapc driver has been renamed to apcsmart. If you previously -used newapc, make sure you delete the old binary and fix your -ups.conf. Otherwise, you may run the old driver from 1.4. + used newapc, make sure you delete the old binary and fix your + ups.conf. Otherwise, you may run the old driver from 1.4. File trimmed here on changes from 1.2.2 to 1.4.0 ------------------------------------------------ From da2a9d722a02a24ffbd674753a98fe03ab7c07e3 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 2 Mar 2024 15:46:04 +0100 Subject: [PATCH 0059/1079] autogen.sh: reconcile markup with FTY branch Signed-off-by: Jim Klimov --- autogen.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/autogen.sh b/autogen.sh index afcf3d647b..e5df373fac 100755 --- a/autogen.sh +++ b/autogen.sh @@ -184,6 +184,7 @@ FAILED: did not generate an executable configure script! # scripts, and need you to explicitly say which version you want, e.g. # export AUTOCONF_VERSION=2.65 AUTOMAKE_VERSION=1.13 # If you get issues with AC_DISABLE_STATIC make sure you have libtool. +# # If it complains about "too few" or "excess" "arguments to builtin ifdef", # check the configure.ac line it refers to and un-comment (or comment away) # the third argument for AM_SILENT_RULES check, or comment away the whole From 7511c9741bb34b50c704d0c04638c055cf352fbf Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 2 Mar 2024 15:47:04 +0100 Subject: [PATCH 0060/1079] common/common.c: reconcile markup with FTY branch Signed-off-by: Jim Klimov --- common/common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/common/common.c b/common/common.c index 987da9ce6d..fa6772165c 100644 --- a/common/common.c +++ b/common/common.c @@ -1378,6 +1378,7 @@ static void vupslog(int priority, const char *fmt, va_list va, int use_strerror) * so mark the starting point whenever we first try to log */ if (upslog_start.tv_sec == 0) { struct timeval now; + gettimeofday(&now, NULL); upslog_start = now; } From d3b943755a9d17aad007091bc50d91959d809fc1 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 2 Mar 2024 15:48:49 +0100 Subject: [PATCH 0061/1079] docs/config-notes.txt: reconcile markup with FTY branch Signed-off-by: Jim Klimov --- docs/config-notes.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config-notes.txt b/docs/config-notes.txt index 6451b1c9fb..6fc72d7ddc 100644 --- a/docs/config-notes.txt +++ b/docs/config-notes.txt @@ -25,7 +25,7 @@ Generalities All configuration files within this package are parsed with a common state machine, which means they all can use a number of extras described here. -First, most of the programs use an uppercase word to declare a +First, most of the programs use an upper-case word to declare a configuration directive. This may be something like MONITOR, NOTIFYCMD, or ACCESS. The case does matter here. "monitor" won't be recognized. From 82020a6516eeccd80c6abc97f79ef9558f2ae22a Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 2 Mar 2024 15:53:35 +0100 Subject: [PATCH 0062/1079] docs/config-prereqs.txt: reconcile markup with FTY branch Signed-off-by: Jim Klimov --- docs/config-prereqs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config-prereqs.txt b/docs/config-prereqs.txt index 1d8eacc591..009da51ec3 100644 --- a/docs/config-prereqs.txt +++ b/docs/config-prereqs.txt @@ -859,7 +859,7 @@ default site. lua :; pkg_add \ - dash ksh93 + bash dash ksh93 :; pkg_add \ argp-standalone \ From 43963e89e7f7c627ce96782885110336417a4d6f Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 2 Mar 2024 13:58:25 +0000 Subject: [PATCH 0063/1079] docs/man/nut-scanner.txt: reconcile asciidoc markup with FTY branch Signed-off-by: Jim Klimov --- docs/man/nut-scanner.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/man/nut-scanner.txt b/docs/man/nut-scanner.txt index df635160f3..41d82fa795 100644 --- a/docs/man/nut-scanner.txt +++ b/docs/man/nut-scanner.txt @@ -220,8 +220,8 @@ MISCELLANEOUS OPTIONS Display NUT version. *-a* | *--available*:: -Display available bus that can be scanned, depending on how the nut-scanner -binary program has been compiled. (OLDNUT, USB, SNMP, XML, AVAHI, IPMI). +Display available buses that can be scanned, depending on how the nut-scanner +binary program has been compiled. (e.g. OLDNUT, USB, SNMP, XML, AVAHI, IPMI). *-q* | *--quiet*:: Display only scan result. No information on currently scanned bus is displayed. From a32cdf11a37d480b9337a0c0b4e95dd1cdbec784 Mon Sep 17 00:00:00 2001 From: Arnaud Quette Date: Mon, 4 Jul 2016 16:27:29 +0200 Subject: [PATCH 0064/1079] docs/man/nut-scanner.txt: comment about debugging level for troubleshooting Originates from commit 951f8f8b3 by Author: Arnaud Quette Date: Mon Jul 4 16:27:29 2016 +0200 Signed-off-by: Jim Klimov --- docs/man/nut-scanner.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/man/nut-scanner.txt b/docs/man/nut-scanner.txt index 41d82fa795..dca9b946e3 100644 --- a/docs/man/nut-scanner.txt +++ b/docs/man/nut-scanner.txt @@ -229,6 +229,12 @@ Display only scan result. No information on currently scanned bus is displayed. *-D* | *--nut_debug_level*:: Raise the debugging level. Use this multiple times to see more details. +NOTE: The level of debugging needed depends both on nut-scanner and the +problem you're trying to diagnose. Therefore, first explain the problem you +have with `nut-scanner` to a developer/maintainer, before sending them debugging +output. More often than not, if you just pick a level, the output may be +either too limited or too verbose to be of any use. + EXAMPLES -------- From 06eb050a9e98cd0361a9e70f8bcb443339437be9 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 7 Sep 2016 05:41:05 +0200 Subject: [PATCH 0065/1079] dstate.c : a pedantic compiler warning fix --- drivers/dstate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dstate.c b/drivers/dstate.c index 43b48719d5..518edafa6c 100644 --- a/drivers/dstate.c +++ b/drivers/dstate.c @@ -507,7 +507,7 @@ static void sock_connect(TYPE_FD sock) upsdebugx(0, "%s: keeping default synchronous mode", __func__); } - conn = xcalloc(1, sizeof(*conn)); + conn = (conn_t *)xcalloc(1, sizeof(*conn)); conn->fd = fd; #else /* WIN32 */ From f67ca2f746a280357c4ad7dfa964bd998544f39e Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 2 Mar 2024 16:25:21 +0100 Subject: [PATCH 0066/1079] drivers/dstate.c: apply comments from FTY branch Originally from commits 9723e08096 and 6909e965a9 (Jan 2017) Signed-off-by: Jim Klimov --- drivers/dstate.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/dstate.c b/drivers/dstate.c index 518edafa6c..e91ef7ac4d 100644 --- a/drivers/dstate.c +++ b/drivers/dstate.c @@ -1675,9 +1675,15 @@ void alarm_set(const char *buf) # pragma GCC diagnostic pop #endif -/* write the status_buf into the info array */ +/* write the status_buf into the info array for "ups.alarm" */ void alarm_commit(void) { + /* Note this is a bit different from `device_alarm_commit(0);` + * because here we also increase AND zero out the alarm count. + * alarm_active = 0; device_alarm_commit(0); + * would be equivalent, but too intimate for later maintenance. + */ + if (strlen(alarm_buf) > 0) { dstate_setinfo("ups.alarm", "%s", alarm_buf); alarm_active = 1; @@ -1694,6 +1700,8 @@ void device_alarm_init(void) } /* same as above, but writes to "device.X.ups.alarm" or "ups.alarm" */ +/* Note that 20 chars below just allow for a 2-digit "X" */ +/* FIXME? Shouldn't this be changed to be a LARGEBUF aka sizeof(alarm_buf) ? */ void device_alarm_commit(const int device_number) { char info_name[20]; From 1244d0253bf88dfdb1d3d1d14bcd757b92f09cd0 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 14 Jan 2017 02:14:58 +0100 Subject: [PATCH 0067/1079] drivers/nut-libfreeipmi.c : set the 4 voltage_range variable to unsigned ints Signed-off-by: Jim Klimov --- drivers/nut-libfreeipmi.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/nut-libfreeipmi.c b/drivers/nut-libfreeipmi.c index cdf3d59fb4..9402c9e450 100644 --- a/drivers/nut-libfreeipmi.c +++ b/drivers/nut-libfreeipmi.c @@ -363,6 +363,11 @@ static int libfreeipmi_get_psu_info (const void *areabuf, uint8_t area_length, IPMIDevice_t *ipmi_dev) { + /* FIXME: libfreeipmi headers currently define the 4 voltage_range + * values as "unsigned int". It seems earlier it was "int", but now + * the compiler complains when it is in place - so changed to unsigned. + * The proper fix might be to detect and influence this in configure. */ + /* FIXME: directly use ipmi_dev fields */ unsigned int overall_capacity; input_voltage_range_t low_end_input_voltage_range_1; From adc524efc4396595d1f593d5d900d4495a034b38 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 2 Mar 2024 16:51:29 +0100 Subject: [PATCH 0068/1079] drivers/snmp-ups.c: apply comments and formatting from FTY branch Signed-off-by: Jim Klimov --- drivers/snmp-ups.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/snmp-ups.c b/drivers/snmp-ups.c index 9e7e04ca3a..21dcf6f41d 100644 --- a/drivers/snmp-ups.c +++ b/drivers/snmp-ups.c @@ -259,8 +259,10 @@ void upsdrv_initinfo(void) && !(su_info_p->flags & SU_OUTLET_GROUP)) { /* first check that this OID actually exists */ + /* FIXME: daisychain commands support! */ su_addcmd(su_info_p); + /* if (nut_snmp_get(su_info_p->OID) != NULL) { dstate_addcmd(su_info_p->info_type); @@ -610,6 +612,7 @@ void upsdrv_initups(void) } printf("\nOverall this driver has loaded %d MIB-to-NUT mapping tables\n", i); exit(EXIT_SUCCESS); + /* fatalx(EXIT_FAILURE, "Marking the exit code as failure since the driver is not started now"); */ } /* init SNMP library, etc... */ @@ -1144,7 +1147,6 @@ static struct snmp_pdu **nut_snmp_walk(const char *OID, int max_iteration) break; } - if (!((status == STAT_SUCCESS) && (response->errstat == SNMP_ERR_NOERROR))) { if (mibname == NULL) { /* We are probing for proper mib - ignore errors */ @@ -2921,8 +2923,9 @@ bool_t daisychain_init(void) if (devices_count == -1) { #endif /* WITH_SNMP_LKP_FUN */ - if (nut_snmp_get_int(su_info_p->OID, &devices_count) == TRUE) + if (nut_snmp_get_int(su_info_p->OID, &devices_count) == TRUE) { upsdebugx(1, "There are %ld device(s) present", devices_count); + } else { upsdebugx(1, "Error: can't get the number of device(s) present!"); From 1841d1da50c055138071db0bd7940132a73fed38 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Fri, 1 Mar 2024 10:56:46 +0000 Subject: [PATCH 0069/1079] m4/ax_c_pragmas.m4: comment where "-Wcast-function-type-strict" comes from Signed-off-by: Jim Klimov --- m4/ax_c_pragmas.m4 | 1 + 1 file changed, 1 insertion(+) diff --git a/m4/ax_c_pragmas.m4 b/m4/ax_c_pragmas.m4 index f2cf78f676..d274b129bc 100644 --- a/m4/ax_c_pragmas.m4 +++ b/m4/ax_c_pragmas.m4 @@ -689,6 +689,7 @@ dnl ### [CFLAGS="${CFLAGS_SAVED} -Werror=pragmas -Werror=unknown-warning" AC_DEFINE([HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_CAST_ALIGN_BESIDEFUNC], 1, [define if your compiler has #pragma GCC diagnostic ignored "-Wcast-align" (outside functions)]) ]) + dnl https://reviews.llvm.org/D134831 AC_CACHE_CHECK([for pragma GCC diagnostic ignored "-Wcast-function-type-strict"], [ax_cv__pragma__gcc__diags_ignored_cast_function_type_strict], [AC_COMPILE_IFELSE( From 29e766aa2d635df680c830aaa74a3b0fe54ce431 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 2 Mar 2024 17:06:36 +0100 Subject: [PATCH 0070/1079] scripts/systemd/.gitignore: do not GitIgnore nut-driver.target, it lives in SCM now Signed-off-by: Jim Klimov --- scripts/systemd/.gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/systemd/.gitignore b/scripts/systemd/.gitignore index a39ac8db55..560c249b43 100644 --- a/scripts/systemd/.gitignore +++ b/scripts/systemd/.gitignore @@ -3,7 +3,6 @@ /nut-common-tmpfiles.conf /nut-driver.service /nut-driver@.service -/nut-driver.target /nut-monitor.service /nut-server.service /nutshutdown From 00827a6823dffcc809ab98272efe13c699351418 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 2 Mar 2024 17:12:40 +0100 Subject: [PATCH 0071/1079] tools/nut-usbinfo.pl: quietly skip editor backup files, and those prepared by "git difftool" for comparisons Signed-off-by: Jim Klimov --- tools/nut-usbinfo.pl | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tools/nut-usbinfo.pl b/tools/nut-usbinfo.pl index 080a5e91aa..fa6069b0a2 100755 --- a/tools/nut-usbinfo.pl +++ b/tools/nut-usbinfo.pl @@ -1,9 +1,9 @@ #!/usr/bin/env perl -# Current Version : 1.4 +# Current Version : 1.5 # Copyright (C) 2008 - 2012 dloic (loic.dardant AT gmail DOT com) # Copyright (C) 2008 - 2015 Arnaud Quette # Copyright (C) 2013 - 2014 Charles Lepple -# Copyright (C) 2014 - 2023 Jim Klimov +# Copyright (C) 2014 - 2024 Jim Klimov # # Based on the usbdevice.pl script, made for the Ubuntu Media Center # for the final use of the LIRC project. @@ -353,13 +353,19 @@ sub find_usbdevs # process the driver name my $driver=$nameFile; my $preferDriver=1; - if($nameFile=~/(.+)-hid\.c/) { + if($nameFile=~/(.+)-hid\.c$/) { $driver="usbhid-ups"; } # generic matching rule *.c => * elsif ($nameFile =~ /(.+)\.c$/) { $driver=$1; } + elsif ($nameFile =~ /(.+)\.(orig|bak|tmp)/) { + return; + } + elsif ($nameFile =~ /(.+)_(BACKUP|LOCAL|REMOTE|BASE)_\d*/) { + return; + } else { warn "Unknown driver type: $nameFile"; next; From a52fa2bba23875e02f804a95a6dcea2e37568e5f Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 2 Mar 2024 17:20:36 +0100 Subject: [PATCH 0072/1079] tools/nut-scanner/scan_snmp.c: apply comments from FTY branch Signed-off-by: Jim Klimov --- tools/nut-scanner/scan_snmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/nut-scanner/scan_snmp.c b/tools/nut-scanner/scan_snmp.c index 8a28b8e9b1..89597382e3 100644 --- a/tools/nut-scanner/scan_snmp.c +++ b/tools/nut-scanner/scan_snmp.c @@ -94,7 +94,7 @@ static useconds_t g_usec_timeout ; /* dynamic link library stuff */ static lt_dlhandle dl_handle = NULL; static const char *dl_error = NULL; -#endif +#endif /* WITH_SNMP_STATIC */ static void (*nut_init_snmp)(const char *type); static void (*nut_snmp_sess_init)(netsnmp_session * session); From e946480a79f4a68b24410d83f6abfd50a2bcfd5c Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 20 Apr 2020 19:29:27 +0200 Subject: [PATCH 0073/1079] nut-driver-enumerator-daemon-activator.service.in : disable quick-start throttling --- .../nut-driver-enumerator-daemon-activator.service.in | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/scripts/systemd/nut-driver-enumerator-daemon-activator.service.in b/scripts/systemd/nut-driver-enumerator-daemon-activator.service.in index 86944fc3ff..e94fb197b2 100644 --- a/scripts/systemd/nut-driver-enumerator-daemon-activator.service.in +++ b/scripts/systemd/nut-driver-enumerator-daemon-activator.service.in @@ -26,6 +26,14 @@ Type=oneshot # Non-blocking systemd message posting should not take long, # or should be aborted and retried if it does (system bugs) TimeoutStartSec=10s +# If some process is writing the ups.conf file, it can be interpreted in +# some conditions by .path unit as many events requiring it to start - +# and eventually this gets throttled as a quickly started-restarted unit. +# While it should be permitted for manual start (likely .path trigger too) +# after interval expiration, this might race-condition to not detect some +# latest update into the configuration file if it happens after the main +# script loop has slurped intermediate state of device config. +StartLimitIntervalSec=0 ExecStart=/bin/systemctl reload-or-restart --no-block nut-driver-enumerator-daemon.service [Install] From 020441861e4d3e222575dbbc2e1d09b81a481848 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 2 Mar 2024 17:32:25 +0100 Subject: [PATCH 0074/1079] scripts/systemd/nut-server.service.in: summarize LimitNOFILE increase and ExecStartPost to monitor that it was applied, from FTY branch Originates from FTY commits: * 062d1868fa (Jim Klimov 2018-01-16 13:11:08 +0100) * 0e28cc865c (Jim Klimov 2018-01-16 13:37:39 +0100) * e9a67100a0 (Jim Klimov 2018-01-16 13:41:52 +0100) Signed-off-by: Jim Klimov --- scripts/systemd/nut-server.service.in | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/scripts/systemd/nut-server.service.in b/scripts/systemd/nut-server.service.in index 33f3b313d4..c153c5d307 100644 --- a/scripts/systemd/nut-server.service.in +++ b/scripts/systemd/nut-server.service.in @@ -26,6 +26,21 @@ Before=nut-monitor.service PartOf=nut.target [Service] +# A busy server can be monitoring a lot of devices as well as replying +# to many clients. The "infinity" definition is actually capped by OS +# settings and hardcoded defaults; typically can be 65535+ nowadays. +# On 64-bit distros this can well be set into hundreds of thousands +# as well (though note each connnection has a CPU and RAM overhead +# so one can strike physical limits upon deployment and/or bring the +# poorly sized system to a crawl, or worse). On a running system you +# can check /proc/$MAINPID/limits for active ulimits of the process. +# From my experiments, up to 1048576 can be set, but any larger value +# falls back to 65536. The systemd definition of "infinity" is 65536 +# too (or maybe it falls back to that); though this may be OS/distro +# limitation and not systemd fault specifically. +#LimitNOFILE=infinity +#LimitNOFILE=65535 +LimitNOFILE=1048576 EnvironmentFile=-@CONFPATH@/nut.conf SyslogIdentifier=%N # Note: foreground mode "-F" by default skips writing a PID file (and @@ -34,6 +49,7 @@ SyslogIdentifier=%N ExecStartPre=-@SYSTEMD_TMPFILES_PROGRAM@ --create @systemdtmpfilesdir@/nut-common-tmpfiles.conf ExecStart=@SBINDIR@/upsd @SYSTEMD_DAEMON_ARGS_UPSD@ ExecReload=@SBINDIR@/upsd -c reload -P $MAINPID +ExecStartPost=-/bin/grep -E 'Units|Max open files' /proc/${MAINPID}/limits # No tracking for PIDFile path and service attribute here (it might not # even exist). # If "-FF" or background-daemon mode is used, so that PID file exists From 360514e9067318ff4584edae97f76d30de84fa2d Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 29 Apr 2020 13:47:22 +0200 Subject: [PATCH 0075/1079] nut-driver-enumerator-daemon-activator.service : use older Service/StartLimitInterval for broader compatibility Should help avoid this warning and unachieved functionality on systemd-229 and older: * systemd[1]: [/lib/systemd/system/nut-driver-enumerator-daemon-activator.service:30] Unknown lvalue 'StartLimitIntervalSec' in section 'Service' --- .../nut-driver-enumerator-daemon-activator.service.in | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/systemd/nut-driver-enumerator-daemon-activator.service.in b/scripts/systemd/nut-driver-enumerator-daemon-activator.service.in index e94fb197b2..c7af5be654 100644 --- a/scripts/systemd/nut-driver-enumerator-daemon-activator.service.in +++ b/scripts/systemd/nut-driver-enumerator-daemon-activator.service.in @@ -33,7 +33,10 @@ TimeoutStartSec=10s # after interval expiration, this might race-condition to not detect some # latest update into the configuration file if it happens after the main # script loop has slurped intermediate state of device config. -StartLimitIntervalSec=0 +# Note: Using the older but still supported Service/StartLimitInterval +# see https://lists.freedesktop.org/archives/systemd-devel/2017-July/039255.html +# for broader compatibility. +StartLimitInterval=0 ExecStart=/bin/systemctl reload-or-restart --no-block nut-driver-enumerator-daemon.service [Install] From 5ff77b18b6a3b593235accb63345c5a087cd236e Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sun, 3 Mar 2024 12:04:52 +0100 Subject: [PATCH 0076/1079] README.adoc: update phrasing on DigitalOcean and NUT CI farm Signed-off-by: Jim Klimov --- README.adoc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.adoc b/README.adoc index 2121366665..2164db7f4a 100644 --- a/README.adoc +++ b/README.adoc @@ -825,8 +825,9 @@ endif::env-github[] preview tarballs with binaries). | image:images/ci/DO_Powered_by_Badge_blue_140pxW.png[alt="DigitalOcean logo",width="140",height="29",link="https://www.digitalocean.com/?refcode=d2fbf2b9e082&utm_campaign=Referral_Invite&utm_medium=Referral_Program&utm_source=badge"] -| The link:https://www.digitalocean.com/?refcode=d2fbf2b9e082&utm_campaign=Referral_Invite&utm_medium=Referral_Program&utm_source=badge[DigitalOcean] droplets allow us to host - NUT CI farm build agents, and eventually re-house the Jenkins controller too. +| The link:https://www.digitalocean.com/?refcode=d2fbf2b9e082&utm_campaign=Referral_Invite&utm_medium=Referral_Program&utm_source=badge[DigitalOcean] + droplets allow us to host NUT CI farm Jenkins controller and the build agents + for multiple operating systems. | image:images/ci/gandi-ar21.png[alt="Gandi.Net logo",width="120",height="60",link="https://www.gandi.net/"] | link:https://www.gandi.net/[Gandi.Net] took up the costs of NUT DNS hosting. From b31fe14ccf663d30c6ae25566fff196a681ae630 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sun, 3 Mar 2024 13:12:09 +0000 Subject: [PATCH 0077/1079] docs/config-prereqs.txt: clarify that FreeBSD likely does not want to "pkg add openssl" in fact [#2275] Signed-off-by: Jim Klimov --- docs/config-prereqs.txt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/config-prereqs.txt b/docs/config-prereqs.txt index 009da51ec3..17da3f9450 100644 --- a/docs/config-prereqs.txt +++ b/docs/config-prereqs.txt @@ -717,7 +717,7 @@ below. :; pkg install \ cppunit \ - openssl nss \ + nss \ augeas \ libmodbus \ neon \ @@ -726,6 +726,15 @@ below. freeipmi \ avahi +# NOTE: At least on FreeBSD 12, system-provided crypto exists and is used +# by libnetsnmp, libneon, etc. - but is not marked as a package. Conversely, +# the openssl-1.1.1k (as of this writing) can be installed as a package into +# /usr/local/lib and then causes linking conflicts. The core system-provided +# build of openssl does include headers and is useful for NUT build "as is". +# ONLY INSTALL THIS PACKAGE IF REQUIRED (may get problems to rectify later): +:; test -e /lib/libcrypto.so -a -e /usr/lib/libssl.so || \ + pkg install openssl + :; pkg install \ lua51 From 0fbe658843f1b009fe629bbe1756393263b027a4 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sun, 3 Mar 2024 14:25:12 +0100 Subject: [PATCH 0078/1079] scripts/systemd/nut-driver-enumerator-daemon-activator.path.in: clarify the unit description (it does not strictly restart the daemon, can reload if running too) Signed-off-by: Jim Klimov --- .../systemd/nut-driver-enumerator-daemon-activator.path.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/systemd/nut-driver-enumerator-daemon-activator.path.in b/scripts/systemd/nut-driver-enumerator-daemon-activator.path.in index 615ce9fe57..02070bafba 100644 --- a/scripts/systemd/nut-driver-enumerator-daemon-activator.path.in +++ b/scripts/systemd/nut-driver-enumerator-daemon-activator.path.in @@ -1,5 +1,5 @@ # Network UPS Tools (NUT) systemd integration -# Copyright (C) 2011-2023 by NUT contirbutors +# Copyright (C) 2011-2024 by NUT contirbutors # Distributed under the terms of GPLv2+ # See https://networkupstools.org/ # and https://github.com/networkupstools/nut/ @@ -8,7 +8,7 @@ # Trigger restart of nut-driver-enumerator-daemon-activator.service # whenever ups.conf is edited, which would cause reload-or-restart # of the nut-driver-enumerator-daemon.service for actual reconfig. -Description=Network UPS Tools - Trigger restart of nut-driver-enumerator-daemon.service whenever ups.conf is edited +Description=Network UPS Tools - Trigger reload-or-restart of nut-driver-enumerator-daemon.service whenever ups.conf is edited Conflicts=nut-driver-enumerator.service nut-driver-enumerator.path After=local-fs.target Before=nut-driver.target From a7e187350ce6cb8293fc4fb775f4254e694b3eaf Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 4 Mar 2024 09:27:13 +0100 Subject: [PATCH 0079/1079] autogen.sh: in the end of successful execution, lead interactive users to running the ./configure script Signed-off-by: Jim Klimov --- autogen.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/autogen.sh b/autogen.sh index e5df373fac..ad71b5aaec 100755 --- a/autogen.sh +++ b/autogen.sh @@ -227,3 +227,5 @@ $CONFIG_SHELL -n configure 2>/dev/null >/dev/null \ } echo "The generated configure script passed shell interpreter syntax checks" +echo "Please proceed by running './configure --with-many-desired-options'" +echo "For details check './configure --help' or docs/configure.txt in NUT sources" From de79db37f62a42015a2d1e423eeb68c466492bdc Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 6 Mar 2024 16:33:41 +0100 Subject: [PATCH 0080/1079] .github/workflows/codeql.yml: extend with python Signed-off-by: Jim Klimov --- .github/workflows/codeql.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 2438bd0555..e61833bb1e 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,7 +32,7 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'cpp' ] + language: [ 'cpp', 'python' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support # TODO: Want to find Python sources to test like with LGTM, see https://github.com/networkupstools/nut/issues/1726 From e7266d25280b1aeaa7bdf34abf36d234b2a9834f Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 4 Mar 2024 21:52:12 +0100 Subject: [PATCH 0081/1079] Jenkinsfile-dynamatrix: add a TODO about "completely out-of-tree" builds Signed-off-by: Jim Klimov --- Jenkinsfile-dynamatrix | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile-dynamatrix b/Jenkinsfile-dynamatrix index 11e14f15bf..85c42d0110 100644 --- a/Jenkinsfile-dynamatrix +++ b/Jenkinsfile-dynamatrix @@ -726,7 +726,11 @@ set | sort -n """ dynamatrixAxesCommonEnv: [ ['LANG=C','LC_ALL=C','TZ=UTC', // Build in a subdirectory to check that out-of-dir - // builds are healthy too + // builds are healthy too. + // NOTE: It would be useful to also have a recipe to build + // "completely out-of-tree", in a different filesystem (to + // make sure we do not rely on hard-links, relative paths, + // etc.) 'CI_BUILDDIR=obj', 'BUILD_WARNFATAL=yes','BUILD_WARNOPT=minimal' ] From 452a2b5c51ac9b16d30c793df08adefcdaf4b8d9 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 4 Mar 2024 21:52:45 +0100 Subject: [PATCH 0082/1079] Jenkinsfile-dynamatrix: fix naming for cross-Windows builds ("Strict C" part is optional) Signed-off-by: Jim Klimov --- Jenkinsfile-dynamatrix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile-dynamatrix b/Jenkinsfile-dynamatrix index 85c42d0110..8a9c661ff7 100644 --- a/Jenkinsfile-dynamatrix +++ b/Jenkinsfile-dynamatrix @@ -1217,7 +1217,7 @@ set | sort -n """ 'bodyParStages': dynacfgPipeline.slowBuildDefaultBody_ci_build ] // one slowBuild filter configuration - ,[name: 'Strict C and GNU standard builds on cross-Windows platforms (Linux+mingw), without distcheck and docs (allowed to fail)', + ,[name: (dynacfgPipeline.disableStrictCIBuild_CrossWindows ? '' : 'Strict C and ') + 'GNU standard builds on cross-Windows platforms (Linux+mingw), without distcheck and docs (allowed to fail)', disabled: dynacfgPipeline.disableSlowBuildCIBuild, //branchRegexSource: ~/^(PR-.+|.*fightwarn.*|.*Windows.*)$/, //branchRegexTarget: ~/fightwarn|Windows-.*/, From 64b5f6804805b53a7c5a6a6588b6bab5b2dfa728 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 6 Mar 2024 16:43:45 +0100 Subject: [PATCH 0083/1079] Jenkinsfile-dynamatrix: fiddle with BUILD_WARNFATAL settings Signed-off-by: Jim Klimov --- Jenkinsfile-dynamatrix | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/Jenkinsfile-dynamatrix b/Jenkinsfile-dynamatrix index 8a9c661ff7..0dbcb21abc 100644 --- a/Jenkinsfile-dynamatrix +++ b/Jenkinsfile-dynamatrix @@ -478,8 +478,8 @@ set | sort -n """ // BUILD_TYPE=default-tgt:distcheck-light + NO_PKG_CONFIG=true ? ], dynamatrixAxesCommonEnv: [ - ['LANG=C','LC_ALL=C','TZ=UTC' - //,'BUILD_WARNFATAL=yes','BUILD_WARNOPT=hard' + ['LANG=C','LC_ALL=C','TZ=UTC','BUILD_WARNFATAL=yes' + //,'BUILD_WARNOPT=hard' ] ], allowedFailure: [ @@ -527,8 +527,8 @@ set | sort -n """ 'BUILD_TYPE': ['default-tgt:cppcheck'] ], dynamatrixAxesCommonEnv: [ - ['LANG=C','LC_ALL=C','TZ=UTC', 'DO_CLEAN_CHECK=no' - //,'BUILD_WARNFATAL=yes','BUILD_WARNOPT=hard' + ['LANG=C','LC_ALL=C','TZ=UTC', 'DO_CLEAN_CHECK=no', 'BUILD_WARNFATAL=yes' + //,'BUILD_WARNOPT=hard' ] ], allowedFailure: [ @@ -685,7 +685,8 @@ set | sort -n """ ], dynamatrixAxesCommonEnv: [ ['LANG=C','LC_ALL=C','TZ=UTC', - 'BUILD_WARNFATAL=yes','BUILD_WARNOPT=minimal' + 'BUILD_WARNFATAL=yes' + //,'BUILD_WARNOPT=medium' ] ], allowedFailure: [ @@ -732,7 +733,8 @@ set | sort -n """ // make sure we do not rely on hard-links, relative paths, // etc.) 'CI_BUILDDIR=obj', - 'BUILD_WARNFATAL=yes','BUILD_WARNOPT=minimal' + 'BUILD_WARNFATAL=yes' + //,'BUILD_WARNOPT=minimal' ] ], allowedFailure: [ @@ -771,7 +773,8 @@ set | sort -n """ ], dynamatrixAxesCommonEnv: [ ['LANG=C','LC_ALL=C','TZ=UTC', - 'BUILD_WARNFATAL=yes','BUILD_WARNOPT=minimal' + 'BUILD_WARNFATAL=yes' + //,'BUILD_WARNOPT=minimal' ] ], allowedFailure: [ From 9ddf48f89c5f51a9da590de9dd34bb8c7b51d0bc Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 6 Mar 2024 16:55:54 +0100 Subject: [PATCH 0084/1079] .github/workflows/codeql.yml, .github/codeql/codeql-config.yml: add "paths" for Python scripts Signed-off-by: Jim Klimov --- .github/codeql/codeql-config.yml | 4 ++++ .github/workflows/codeql.yml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 .github/codeql/codeql-config.yml diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml new file mode 100644 index 0000000000..28eaa5d8a1 --- /dev/null +++ b/.github/codeql/codeql-config.yml @@ -0,0 +1,4 @@ +# For interpreted languages: +paths: + - scripts/python/module + - scripts/python/app diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index e61833bb1e..de590ee96a 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -52,7 +52,7 @@ jobs: # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs # queries: security-extended,security-and-quality - + config-file: ./.github/codeql/codeql-config.yml # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). # If this step fails, then you should remove it and run the build manually (see below) From 2c48b53f9f2777691cfe14a80f724744f1acf53d Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 6 Mar 2024 17:31:45 +0100 Subject: [PATCH 0085/1079] .github/workflows/codeql.yml: non-default C/C++ "Autobuild" implementation Signed-off-by: Jim Klimov --- .github/workflows/codeql.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index de590ee96a..07a0a0c848 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -56,8 +56,16 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v3 + #- name: Autobuild + # uses: github/codeql-action/autobuild@v3 + + # https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages + - if: matrix.language == 'c-cpp' + name: NUT CI Build + run: | + ./autogen.sh + ./configure --with-all=auto --with-dev --without-docs + make -j 8 # ℹ️ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun From 6a526e43a6e917b0b5f5328a876d7add255a1d2d Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 6 Mar 2024 17:41:47 +0100 Subject: [PATCH 0086/1079] .github/workflows/codeql.yml: install prerequisite packages and ensure a "BUILD_TYPE=fightwarn-all ./ci_build.sh" loop for C/C++ "Autobuild" implementation Signed-off-by: Jim Klimov --- .github/workflows/codeql.yml | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 07a0a0c848..44fd44dc6a 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -54,18 +54,31 @@ jobs: # queries: security-extended,security-and-quality config-file: ./.github/codeql/codeql-config.yml + # https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages + - if: matrix.language == 'cpp' + name: NUT CI Prerequisite packages (Ubuntu) + run: | + sudo apt update + sudo apt install libltdl-dev libtool libtool-bin cppcheck gcc g++ clang ccache + sudo apt install libgd-dev libcppunit-dev libsystemd-dev libssl-dev libnss3-dev augeas-tools libaugeas-dev augeas-lenses libusb-dev libusb-1.0-0-dev libi2c-dev libmodbus-dev libsnmp-dev libpowerman0-dev libfreeipmi-dev libipmimonitoring-dev libavahi-common-dev libavahi-core-dev libavahi-client-dev libgpiod-dev + sudo apt install libi2c-dev i2c-tools lm-sensors || true + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). # If this step fails, then you should remove it and run the build manually (see below) #- name: Autobuild # uses: github/codeql-action/autobuild@v3 - # https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages - - if: matrix.language == 'c-cpp' - name: NUT CI Build + - if: matrix.language == 'cpp' + name: NUT CI Build (fightwarn-all) run: | - ./autogen.sh - ./configure --with-all=auto --with-dev --without-docs - make -j 8 + BUILD_TYPE=fightwarn-all ./ci_build.sh + + #- if: matrix.language == 'x-cpp' + # name: NUT CI Build + # run: | + # ./autogen.sh + # ./configure --with-all=auto --with-dev --without-docs + # make -j 8 # ℹ️ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun From 5e2f905d9acfca7156eeccd69a8c0cf55c81fb43 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 6 Mar 2024 19:02:18 +0100 Subject: [PATCH 0087/1079] .github/workflows/codeql.yml: make "ubuntu-latest" formally a part of "matrix.os" for "if" clause Signed-off-by: Jim Klimov --- .github/workflows/codeql.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 44fd44dc6a..3cee261d2a 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -23,7 +23,7 @@ on: jobs: analyze: name: Analyze - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} permissions: actions: read contents: read @@ -35,7 +35,8 @@ jobs: language: [ 'cpp', 'python' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support - # TODO: Want to find Python sources to test like with LGTM, see https://github.com/networkupstools/nut/issues/1726 + os: [ubuntu-latest] + # TOTHINK: windows-latest, macos-latest steps: - name: Checkout repository @@ -55,7 +56,7 @@ jobs: config-file: ./.github/codeql/codeql-config.yml # https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages - - if: matrix.language == 'cpp' + - if: matrix.language == 'cpp' && matrix.os == "ubuntu-latest" name: NUT CI Prerequisite packages (Ubuntu) run: | sudo apt update From 893409fcc641e90a438699259bbd6e53133b33e5 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 6 Mar 2024 22:08:07 +0100 Subject: [PATCH 0088/1079] .github/workflows/codeql.yml: fix stringification of "ubuntu-latest" Signed-off-by: Jim Klimov --- .github/workflows/codeql.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 3cee261d2a..376f9f2345 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -35,7 +35,7 @@ jobs: language: [ 'cpp', 'python' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support - os: [ubuntu-latest] + os: ['ubuntu-latest'] # TOTHINK: windows-latest, macos-latest steps: @@ -56,7 +56,7 @@ jobs: config-file: ./.github/codeql/codeql-config.yml # https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages - - if: matrix.language == 'cpp' && matrix.os == "ubuntu-latest" + - if: matrix.language == 'cpp' && matrix.os == 'ubuntu-latest' name: NUT CI Prerequisite packages (Ubuntu) run: | sudo apt update From f9adab82ea1daa175759e0509280af36e5378b73 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 6 Mar 2024 22:24:28 +0100 Subject: [PATCH 0089/1079] .github/workflows/codeql.yml: make a CodeQL matrix of compiler/NUT_SSL_VARIANTS/NUT_USB_VARIANTS instead of single fightwarn-all Signed-off-by: Jim Klimov --- .github/workflows/codeql.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 376f9f2345..0cedfc5e25 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -37,6 +37,9 @@ jobs: # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support os: ['ubuntu-latest'] # TOTHINK: windows-latest, macos-latest + compiler: ['CC=gcc CXX=g++', 'CC=clang CXX=clang++'] + NUT_SSL_VARIANTS: ['no', 'nss', 'openssl'] + NUT_USB_VARIANTS: ['no', '1.0', '0.1'] steps: - name: Checkout repository @@ -70,9 +73,14 @@ jobs: # uses: github/codeql-action/autobuild@v3 - if: matrix.language == 'cpp' - name: NUT CI Build (fightwarn-all) + name: NUT CI Build (default-all-errors matrix) run: | - BUILD_TYPE=fightwarn-all ./ci_build.sh + BUILD_TYPE=default-all-errors ${{ matrix.compiler }} NUT_SSL_VARIANTS=${{ matrix.NUT_SSL_VARIANTS }} NUT_USB_VARIANTS=${{ matrix.NUT_USB_VARIANTS }} ./ci_build.sh + + #- if: matrix.language == 'cpp' + # name: NUT CI Build (fightwarn-all) + # run: | + # BUILD_TYPE=fightwarn-all ./ci_build.sh #- if: matrix.language == 'x-cpp' # name: NUT CI Build From f5c022a7709d9fc6015cab03438b4be3cd3462ff Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 6 Mar 2024 23:40:29 +0100 Subject: [PATCH 0090/1079] .github/workflows/codeql.yml: add ./ci_build.sh options to constrain build/check scenario workload sprawl Signed-off-by: Jim Klimov --- .github/workflows/codeql.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 0cedfc5e25..e7d91e07a1 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -75,7 +75,7 @@ jobs: - if: matrix.language == 'cpp' name: NUT CI Build (default-all-errors matrix) run: | - BUILD_TYPE=default-all-errors ${{ matrix.compiler }} NUT_SSL_VARIANTS=${{ matrix.NUT_SSL_VARIANTS }} NUT_USB_VARIANTS=${{ matrix.NUT_USB_VARIANTS }} ./ci_build.sh + BUILD_TYPE=default-all-errors BUILD_SSL_ONCE=true DO_DISTCHECK=no CI_SKIP_CHECK=true CANBUILD_DOCS_ALL=no ${{ matrix.compiler }} NUT_SSL_VARIANTS=${{ matrix.NUT_SSL_VARIANTS }} NUT_USB_VARIANTS=${{ matrix.NUT_USB_VARIANTS }} ./ci_build.sh #- if: matrix.language == 'cpp' # name: NUT CI Build (fightwarn-all) From b855ff9b3566bc2f1c51ec2fcb4886501c7cf8df Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 7 Mar 2024 10:43:52 +0100 Subject: [PATCH 0091/1079] .github/workflows/codeql.yml: exile "python" analysis into one "included" matrix cell Signed-off-by: Jim Klimov --- .github/workflows/codeql.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index e7d91e07a1..9b97b02a95 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,7 +32,8 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'cpp', 'python' ] + # https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs + language: [ 'cpp' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support os: ['ubuntu-latest'] @@ -40,6 +41,13 @@ jobs: compiler: ['CC=gcc CXX=g++', 'CC=clang CXX=clang++'] NUT_SSL_VARIANTS: ['no', 'nss', 'openssl'] NUT_USB_VARIANTS: ['no', '1.0', '0.1'] + include: + # Add cell(s) to the matrix, beside the combinatorics made above + - language: 'python' + os: 'ubuntu-latest' + compiler: 'PYTHON=python3' + NUT_SSL_VARIANTS: 'no' + NUT_USB_VARIANTS: 'no' steps: - name: Checkout repository From 933c16f674fb3adc545cec89fb9f7710326c0365 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 7 Mar 2024 10:53:21 +0100 Subject: [PATCH 0092/1079] .github/workflows/codeql.yml: use C/C++ buids with "native" autogen+configure (and a single run for each config combo) Signed-off-by: Jim Klimov --- .github/workflows/codeql.yml | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 9b97b02a95..5ba1163b50 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -40,7 +40,7 @@ jobs: # TOTHINK: windows-latest, macos-latest compiler: ['CC=gcc CXX=g++', 'CC=clang CXX=clang++'] NUT_SSL_VARIANTS: ['no', 'nss', 'openssl'] - NUT_USB_VARIANTS: ['no', '1.0', '0.1'] + NUT_USB_VARIANTS: ['no', 'libusb-1.0', 'libusb-0.1'] include: # Add cell(s) to the matrix, beside the combinatorics made above - language: 'python' @@ -80,22 +80,25 @@ jobs: #- name: Autobuild # uses: github/codeql-action/autobuild@v3 - - if: matrix.language == 'cpp' - name: NUT CI Build (default-all-errors matrix) - run: | - BUILD_TYPE=default-all-errors BUILD_SSL_ONCE=true DO_DISTCHECK=no CI_SKIP_CHECK=true CANBUILD_DOCS_ALL=no ${{ matrix.compiler }} NUT_SSL_VARIANTS=${{ matrix.NUT_SSL_VARIANTS }} NUT_USB_VARIANTS=${{ matrix.NUT_USB_VARIANTS }} ./ci_build.sh + #- if: matrix.language == 'cpp' + # name: NUT CI Build (default-all-errors matrix) + # run: | + # BUILD_TYPE=default-all-errors BUILD_SSL_ONCE=true DO_DISTCHECK=no CI_SKIP_CHECK=true CANBUILD_DOCS_ALL=no ${{ matrix.compiler }} NUT_SSL_VARIANTS=${{ matrix.NUT_SSL_VARIANTS }} NUT_USB_VARIANTS=${{ matrix.NUT_USB_VARIANTS }} ./ci_build.sh #- if: matrix.language == 'cpp' # name: NUT CI Build (fightwarn-all) # run: | # BUILD_TYPE=fightwarn-all ./ci_build.sh - #- if: matrix.language == 'x-cpp' - # name: NUT CI Build - # run: | - # ./autogen.sh - # ./configure --with-all=auto --with-dev --without-docs - # make -j 8 + # TOTHINK: Can we prepare the working area once (apt, autogen => containers?) + # and then spread it out for builds and analyses? + # Can ccache be used across builds? + - if: matrix.language == 'cpp' + name: NUT CI Build + run: | + ./autogen.sh + ./configure --enable-warnings --enable-Werror --enable-Wcolor --with-all=auto --with-dev --without-docs ${{matrix.compiler}} --with-ssl=${{matrix.NUT_SSL_VARIANTS}} --with-usb=${{matrix.NUT_USB_VARIANTS}} + make -s -j 8 # ℹ️ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun From 516b30022e53e3c7725183d554064e397ce14cad Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 7 Mar 2024 11:09:29 +0100 Subject: [PATCH 0093/1079] .github/workflows/codeql.yml: revise APT preinstallation * clang or gcc/g++ depending on matrix.compiler * collapse other pkgs into one call * add libneon*-dev Signed-off-by: Jim Klimov --- .github/workflows/codeql.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 5ba1163b50..edb55bd86f 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -71,9 +71,8 @@ jobs: name: NUT CI Prerequisite packages (Ubuntu) run: | sudo apt update - sudo apt install libltdl-dev libtool libtool-bin cppcheck gcc g++ clang ccache - sudo apt install libgd-dev libcppunit-dev libsystemd-dev libssl-dev libnss3-dev augeas-tools libaugeas-dev augeas-lenses libusb-dev libusb-1.0-0-dev libi2c-dev libmodbus-dev libsnmp-dev libpowerman0-dev libfreeipmi-dev libipmimonitoring-dev libavahi-common-dev libavahi-core-dev libavahi-client-dev libgpiod-dev - sudo apt install libi2c-dev i2c-tools lm-sensors || true + case x"${{matrix.compiler}}" in x*clang*) sudo apt install clang ;; x*) sudo apt install gcc g++ ;; esac + sudo apt install libltdl-dev libtool libtool-bin cppcheck ccache libgd-dev libcppunit-dev libsystemd-dev libssl-dev libnss3-dev augeas-tools libaugeas-dev augeas-lenses libusb-dev libusb-1.0-0-dev libmodbus-dev libsnmp-dev libpowerman0-dev libfreeipmi-dev libipmimonitoring-dev libavahi-common-dev libavahi-core-dev libavahi-client-dev libgpiod-dev libneon27-dev libi2c-dev i2c-tools lm-sensors # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). # If this step fails, then you should remove it and run the build manually (see below) From 05629f0adc203906befb97a97f4c4682c213dd66 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 14 Mar 2024 09:40:16 +0000 Subject: [PATCH 0094/1079] configure.ac, *.am: wherever we export CCACHE_* envvars for convenience - avoid doing so if they were not set at configure time [#2256] Signed-off-by: Jim Klimov --- Makefile.am | 10 +++++----- clients/Makefile.am | 10 +++++----- common/Makefile.am | 10 +++++----- configure.ac | 13 +++++++++++++ drivers/Makefile.am | 10 +++++----- include/Makefile.am | 10 +++++----- lib/Makefile.am | 10 +++++----- server/Makefile.am | 10 +++++----- tests/Makefile.am | 10 +++++----- tests/NIT/Makefile.am | 10 +++++----- tools/Makefile.am | 10 +++++----- tools/nut-scanner/Makefile.am | 10 +++++----- 12 files changed, 68 insertions(+), 55 deletions(-) diff --git a/Makefile.am b/Makefile.am index e1c62d90c6..989240aa1d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,11 +3,11 @@ # Export certain values for ccache which NUT ci_build.sh can customize, # to facilitate developer iteration re-runs of "make" later. # At least GNU and BSD make implementations are okay with this syntax. -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_DIR=@CCACHE_DIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_PATH=@CCACHE_PATH@ -@NUT_AM_MAKE_CAN_EXPORT@export PATH=@PATH_DURING_CONFIGURE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_NAMESPACE@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_BASEDIR@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_DIR@export CCACHE_DIR=@CCACHE_DIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export CCACHE_PATH=@CCACHE_PATH@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export PATH=@PATH_DURING_CONFIGURE@ # include directory for aclocal ACLOCAL_AMFLAGS = -I m4 diff --git a/clients/Makefile.am b/clients/Makefile.am index b873046cc0..6c7e9b914e 100644 --- a/clients/Makefile.am +++ b/clients/Makefile.am @@ -3,11 +3,11 @@ # Export certain values for ccache which NUT ci_build.sh can customize, # to facilitate developer iteration re-runs of "make" later. # At least GNU and BSD make implementations are okay with this syntax. -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_DIR=@CCACHE_DIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_PATH=@CCACHE_PATH@ -@NUT_AM_MAKE_CAN_EXPORT@export PATH=@PATH_DURING_CONFIGURE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_NAMESPACE@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_BASEDIR@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_DIR@export CCACHE_DIR=@CCACHE_DIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export CCACHE_PATH=@CCACHE_PATH@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export PATH=@PATH_DURING_CONFIGURE@ EXTRA_DIST = diff --git a/common/Makefile.am b/common/Makefile.am index 569ad9c6ec..7957fd170f 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -3,11 +3,11 @@ # Export certain values for ccache which NUT ci_build.sh can customize, # to facilitate developer iteration re-runs of "make" later. # At least GNU and BSD make implementations are okay with this syntax. -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_DIR=@CCACHE_DIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_PATH=@CCACHE_PATH@ -@NUT_AM_MAKE_CAN_EXPORT@export PATH=@PATH_DURING_CONFIGURE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_NAMESPACE@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_BASEDIR@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_DIR@export CCACHE_DIR=@CCACHE_DIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export CCACHE_PATH=@CCACHE_PATH@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export PATH=@PATH_DURING_CONFIGURE@ AM_CFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include AM_CXXFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include diff --git a/configure.ac b/configure.ac index 88b7be472e..38d85520c3 100644 --- a/configure.ac +++ b/configure.ac @@ -4784,6 +4784,19 @@ AC_ARG_VAR(CCACHE_BASEDIR) AC_ARG_VAR(CCACHE_DIR) AC_ARG_VAR(CCACHE_PATH) +dnl Some versions of ccache take poorly to an exported empty CCACHE_DIR etc. +dnl Avoid exporting them if not set at the configure time (assuming ci_build.sh +dnl integration or user's shell profile sets them persistently) +AS_IF([test x"${CCACHE_NAMESPACE-}" = x], [NUT_AM_EXPORT_CCACHE_NAMESPACE="#"], [NUT_AM_EXPORT_CCACHE_NAMESPACE=""]) +AC_SUBST(NUT_AM_EXPORT_CCACHE_NAMESPACE) +AS_IF([test x"${CCACHE_BASEDIR-}" = x], [NUT_AM_EXPORT_CCACHE_BASEDIR="#"], [NUT_AM_EXPORT_CCACHE_BASEDIR=""]) +AC_SUBST(NUT_AM_EXPORT_CCACHE_BASEDIR) +AS_IF([test x"${CCACHE_DIR-}" = x], [NUT_AM_EXPORT_CCACHE_DIR="#"], [NUT_AM_EXPORT_CCACHE_DIR=""]) +AC_SUBST(NUT_AM_EXPORT_CCACHE_DIR) + +dnl Application of PATH_DURING_CONFIGURE is also fenced by NUT_AM_EXPORT_CCACHE_PATH: +AS_IF([test x"${CCACHE_PATH-}" = x], [NUT_AM_EXPORT_CCACHE_PATH="#"], [NUT_AM_EXPORT_CCACHE_PATH=""]) +AC_SUBST(NUT_AM_EXPORT_CCACHE_PATH) PATH_DURING_CONFIGURE="$PATH" AC_SUBST(PATH_DURING_CONFIGURE) diff --git a/drivers/Makefile.am b/drivers/Makefile.am index c7477ae512..e3a60fdf87 100644 --- a/drivers/Makefile.am +++ b/drivers/Makefile.am @@ -3,11 +3,11 @@ # Export certain values for ccache which NUT ci_build.sh can customize, # to facilitate developer iteration re-runs of "make" later. # At least GNU and BSD make implementations are okay with this syntax. -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_DIR=@CCACHE_DIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_PATH=@CCACHE_PATH@ -@NUT_AM_MAKE_CAN_EXPORT@export PATH=@PATH_DURING_CONFIGURE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_NAMESPACE@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_BASEDIR@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_DIR@export CCACHE_DIR=@CCACHE_DIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export CCACHE_PATH=@CCACHE_PATH@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export PATH=@PATH_DURING_CONFIGURE@ # Make sure out-of-dir dependencies exist (especially when dev-building parts): $(top_builddir)/common/libcommon.la \ diff --git a/include/Makefile.am b/include/Makefile.am index 90c2dbc54b..2a2109c895 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -3,11 +3,11 @@ # Export certain values for ccache which NUT ci_build.sh can customize, # to facilitate developer iteration re-runs of "make" later. # At least GNU and BSD make implementations are okay with this syntax. -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_DIR=@CCACHE_DIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_PATH=@CCACHE_PATH@ -@NUT_AM_MAKE_CAN_EXPORT@export PATH=@PATH_DURING_CONFIGURE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_NAMESPACE@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_BASEDIR@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_DIR@export CCACHE_DIR=@CCACHE_DIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export CCACHE_PATH=@CCACHE_PATH@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export PATH=@PATH_DURING_CONFIGURE@ dist_noinst_HEADERS = attribute.h common.h extstate.h proto.h \ state.h str.h timehead.h upsconf.h nut_float.h nut_stdint.h nut_platform.h \ diff --git a/lib/Makefile.am b/lib/Makefile.am index 7d272d8de6..63a0427104 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -3,11 +3,11 @@ # Export certain values for ccache which NUT ci_build.sh can customize, # to facilitate developer iteration re-runs of "make" later. # At least GNU and BSD make implementations are okay with this syntax. -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_DIR=@CCACHE_DIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_PATH=@CCACHE_PATH@ -@NUT_AM_MAKE_CAN_EXPORT@export PATH=@PATH_DURING_CONFIGURE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_NAMESPACE@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_BASEDIR@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_DIR@export CCACHE_DIR=@CCACHE_DIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export CCACHE_PATH=@CCACHE_PATH@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export PATH=@PATH_DURING_CONFIGURE@ EXTRA_DIST = README.adoc diff --git a/server/Makefile.am b/server/Makefile.am index 878f16f588..f3dcf60ac2 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -3,11 +3,11 @@ # Export certain values for ccache which NUT ci_build.sh can customize, # to facilitate developer iteration re-runs of "make" later. # At least GNU and BSD make implementations are okay with this syntax. -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_DIR=@CCACHE_DIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_PATH=@CCACHE_PATH@ -@NUT_AM_MAKE_CAN_EXPORT@export PATH=@PATH_DURING_CONFIGURE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_NAMESPACE@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_BASEDIR@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_DIR@export CCACHE_DIR=@CCACHE_DIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export CCACHE_PATH=@CCACHE_PATH@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export PATH=@PATH_DURING_CONFIGURE@ # Make sure out-of-dir dependencies exist (especially when dev-building parts): $(top_builddir)/common/libcommon.la \ diff --git a/tests/Makefile.am b/tests/Makefile.am index d7a1cd9ccc..f328d3029c 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -3,11 +3,11 @@ # Export certain values for ccache which NUT ci_build.sh can customize, # to facilitate developer iteration re-runs of "make" later. # At least GNU and BSD make implementations are okay with this syntax. -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_DIR=@CCACHE_DIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_PATH=@CCACHE_PATH@ -@NUT_AM_MAKE_CAN_EXPORT@export PATH=@PATH_DURING_CONFIGURE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_NAMESPACE@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_BASEDIR@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_DIR@export CCACHE_DIR=@CCACHE_DIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export CCACHE_PATH=@CCACHE_PATH@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export PATH=@PATH_DURING_CONFIGURE@ SUBDIRS = . NIT diff --git a/tests/NIT/Makefile.am b/tests/NIT/Makefile.am index f251fa7b1f..38206a53a3 100644 --- a/tests/NIT/Makefile.am +++ b/tests/NIT/Makefile.am @@ -3,11 +3,11 @@ # Export certain values for ccache which NUT ci_build.sh can customize, # to facilitate developer iteration re-runs of "make" later. # At least GNU and BSD make implementations are okay with this syntax. -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_DIR=@CCACHE_DIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_PATH=@CCACHE_PATH@ -@NUT_AM_MAKE_CAN_EXPORT@export PATH=@PATH_DURING_CONFIGURE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_NAMESPACE@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_BASEDIR@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_DIR@export CCACHE_DIR=@CCACHE_DIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export CCACHE_PATH=@CCACHE_PATH@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export PATH=@PATH_DURING_CONFIGURE@ EXTRA_DIST = nit.sh README.adoc diff --git a/tools/Makefile.am b/tools/Makefile.am index 97cdccf0f1..5a5f9d6840 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -3,11 +3,11 @@ # Export certain values for ccache which NUT ci_build.sh can customize, # to facilitate developer iteration re-runs of "make" later. # At least GNU and BSD make implementations are okay with this syntax. -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_DIR=@CCACHE_DIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_PATH=@CCACHE_PATH@ -@NUT_AM_MAKE_CAN_EXPORT@export PATH=@PATH_DURING_CONFIGURE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_NAMESPACE@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_BASEDIR@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_DIR@export CCACHE_DIR=@CCACHE_DIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export CCACHE_PATH=@CCACHE_PATH@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export PATH=@PATH_DURING_CONFIGURE@ # SUBDIRS are explicitly a listing of all the directories that make # must recurse into BEFORE processing the current directory. diff --git a/tools/nut-scanner/Makefile.am b/tools/nut-scanner/Makefile.am index 4ed34f7214..db2e645b09 100644 --- a/tools/nut-scanner/Makefile.am +++ b/tools/nut-scanner/Makefile.am @@ -3,11 +3,11 @@ # Export certain values for ccache which NUT ci_build.sh can customize, # to facilitate developer iteration re-runs of "make" later. # At least GNU and BSD make implementations are okay with this syntax. -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_DIR=@CCACHE_DIR@ -@NUT_AM_MAKE_CAN_EXPORT@export CCACHE_PATH=@CCACHE_PATH@ -@NUT_AM_MAKE_CAN_EXPORT@export PATH=@PATH_DURING_CONFIGURE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_NAMESPACE@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_BASEDIR@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_DIR@export CCACHE_DIR=@CCACHE_DIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export CCACHE_PATH=@CCACHE_PATH@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export PATH=@PATH_DURING_CONFIGURE@ # Generally, list headers and/or sources which are re-generated # for nut-scanner in the parent dir From 4b07e8b2f94c130c5c78775c277040e7c0f53132 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 14 Mar 2024 09:43:29 +0000 Subject: [PATCH 0095/1079] tools/nutconf/Makefile.am: apply convenience CCACHE exports like for other compiled sources [#2256] Signed-off-by: Jim Klimov --- tools/nutconf/Makefile.am | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/nutconf/Makefile.am b/tools/nutconf/Makefile.am index 53663e4a53..885ddc7c25 100644 --- a/tools/nutconf/Makefile.am +++ b/tools/nutconf/Makefile.am @@ -1,5 +1,14 @@ # Network UPS Tools: NUT configuration tool +# Export certain values for ccache which NUT ci_build.sh can customize, +# to facilitate developer iteration re-runs of "make" later. +# At least GNU and BSD make implementations are okay with this syntax. +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_NAMESPACE@export CCACHE_NAMESPACE=@CCACHE_NAMESPACE@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_BASEDIR@export CCACHE_BASEDIR=@CCACHE_BASEDIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_DIR@export CCACHE_DIR=@CCACHE_DIR@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export CCACHE_PATH=@CCACHE_PATH@ +@NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export PATH=@PATH_DURING_CONFIGURE@ + all: $(bin_PROGRAMS) bin_PROGRAMS = From b5acf59547841e061044072fbdb087ea15cfdca0 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 14 Mar 2024 10:41:32 +0000 Subject: [PATCH 0096/1079] common/nutstream.cpp: avoid pedantic warning about a const/static variable Signed-off-by: Jim Klimov --- common/nutstream.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/common/nutstream.cpp b/common/nutstream.cpp index 555cc44f15..3c8a773831 100644 --- a/common/nutstream.cpp +++ b/common/nutstream.cpp @@ -299,7 +299,23 @@ static const char* getTmpDirPath() { return "/tmp"; } +/* Pedantic builds complain about the static variable below... + * It is assumed safe to ignore since it is a std::string with + * no complex teardown at program exit. + */ +#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP) && (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_EXIT_TIME_DESTRUCTORS || defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_GLOBAL_CONSTRUCTORS) +#pragma GCC diagnostic push +# ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_GLOBAL_CONSTRUCTORS +# pragma GCC diagnostic ignored "-Wglobal-constructors" +# endif +# ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_EXIT_TIME_DESTRUCTORS +# pragma GCC diagnostic ignored "-Wexit-time-destructors" +# endif +#endif const std::string NutFile::m_tmp_dir(getTmpDirPath()); +#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP) && (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_EXIT_TIME_DESTRUCTORS || defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_GLOBAL_CONSTRUCTORS) +#pragma GCC diagnostic pop +#endif NutFile::NutFile(anonymous_t): m_name(""), From 59508c63d81e4e3822a29bad789369a09da79d0f Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 14 Mar 2024 10:26:37 +0000 Subject: [PATCH 0097/1079] Jenkinsfile-dynamatrix: add a section for direct use of autotools (once per platform) in all stable-branch builds In fallout of PR #2256 we had situations "caused" by tighter integration for NUT CI builds (and developer convenience via ./ci_build.sh) which were not seen on the NUT CI farm but could bite the common approach of `./autogen.sh && ./configure && make` on some (not all) platforms. Signed-off-by: Jim Klimov --- Jenkinsfile-dynamatrix | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/Jenkinsfile-dynamatrix b/Jenkinsfile-dynamatrix index 0dbcb21abc..9d06163fa1 100644 --- a/Jenkinsfile-dynamatrix +++ b/Jenkinsfile-dynamatrix @@ -421,6 +421,51 @@ set | sort -n """ //'bodyParStages': {} ] // one slowBuild filter configuration, autotools-Wall + ,[name: 'Default autotools driven build with default configuration, bitness and warning levels on each NUT CI farm platform (but with fatal warnings as of gnu99/gnu++11)', + disabled: dynacfgPipeline.disableSlowBuildAutotools, + branchRegexSource: ~/^(PR-.+|fightwarn.*)$/, + branchRegexTarget: dynacfgPipeline.branchStableRegex, + //branchRegexTarget: ~/fightwarn/, + appliesToChangedFilesRegex: dynacfgPipeline.appliesToChangedFilesRegex_C, + 'getParStages': { def dynamatrix, Closure body -> + return dynamatrix.generateBuild([ + //commonLabelExpr: dynacfgBase.commonLabelExpr, + //defaultDynamatrixConfig: dynacfgBase.defaultDynamatrixConfig, + requiredNodelabels: [], + excludedNodelabels: [], + + dynamatrixAxesVirtualLabelsMap: [ + //'BITS': [32, 64], + // 'CSTDVERSION': ['03', '2a'], + //'CSTDVERSION_${KEY}': [ ['c': '03', 'cxx': '03'], ['c': '99', 'cxx': '98'], ['c': '17', 'cxx': '2a'], 'ansi' ], + //'CSTDVERSION_${KEY}': [ ['c': '03', 'cxx': '03'], ['c': '99', 'cxx': '98'], ['c': '17', 'cxx': '2a'] ], + 'CSTDVERSION_${KEY}': [ ['c': '99', 'cxx': '11'] ], + 'CSTDVARIANT': ['gnu'] + ], + dynamatrixAxesCommonEnv: [ + ['LANG=C','LC_ALL=C','TZ=UTC', + // TODO: Find a way to pass space-separated tokens through withEnv() + //'CONFIG_OPTS=\"--with-all=auto\\ --with-docs=auto\\ --with-ssl=auto\\ --enable-Werror\\ --enable-warnings\\ --disable-Wcolor\\ --enable-silent-rules\"' + 'CONFIG_OPTS=--enable-Werror' + ] + ], + + mergeMode: [ 'dynamatrixAxesVirtualLabelsMap': 'replace', 'excludeCombos': 'merge' ], + allowedFailure: [ + dynacfgPipeline.axisCombos_WINDOWS, + dynacfgPipeline.axisCombos_STRICT_C + ], + runAllowedFailure: true, + //dynamatrixAxesLabels: ['OS_FAMILY', 'OS_DISTRO', '${COMPILER}VER', 'ARCH${ARCH_BITS}'], + //dynamatrixAxesLabels: [~/^OS/, '${COMPILER}VER', 'ARCH${ARCH_BITS}'], + dynamatrixAxesLabels: [~/^OS/, 'COMPILER'], + excludeCombos: dynacfgPipeline.excludeCombos_DEFAULT_STRICT_C + + [dynacfgPipeline.axisCombos_WINDOWS_CROSS] + ], body) + }, // getParStages + //'bodyParStages': {} + ] // one slowBuild filter configuration, autotools-everywhere + ,[name: 'Various non-docs distchecked target builds with main and ~newest supported C/C++ revisions (must pass on all platforms)', disabled: dynacfgPipeline.disableSlowBuildCIBuild, //branchRegexSource: ~/^(PR-.+|fightwarn.*)$/, From ec8d8811229e13d1773a7503c491dadaaa5494f9 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 14 Mar 2024 10:39:21 +0000 Subject: [PATCH 0098/1079] Jenkinsfile-dynamatrix: fix passing of (multi-token) DISTCHECK_FLAGS to autotools build/test variants Signed-off-by: Jim Klimov --- Jenkinsfile-dynamatrix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile-dynamatrix b/Jenkinsfile-dynamatrix index 9d06163fa1..faa8dbdba6 100644 --- a/Jenkinsfile-dynamatrix +++ b/Jenkinsfile-dynamatrix @@ -254,7 +254,7 @@ import org.nut.dynamatrix.*; // Imported from jenkins-dynamatrix JSL vars/autotools.groovy: // a workaround for the cases of curiously missing MAKE envvar... - dynacfgPipeline.buildPhases['distcheck'] = """( if [ x"\${MAKE-}" = x ]; then echo "WARNING: MAKE is somehow unset, defaulting!" >&2; MAKE=make; fi; eval \${CONFIG_ENVVARS} time \${MAKE} \${MAKE_OPTS} distcheck DISTCHECK_FLAGS="\${CONFIG_OPTS}" )""" + dynacfgPipeline.buildPhases['distcheck'] = """( if [ x"\${MAKE-}" = x ]; then echo "WARNING: MAKE is somehow unset, defaulting!" >&2; MAKE=make; fi; eval \${CONFIG_ENVVARS} time \${MAKE} \${MAKE_OPTS} distcheck DISTCHECK_FLAGS=\${CONFIG_OPTS:+\\"\$CONFIG_OPTS\\"} )""" // Note: shellcheck/spellcheck/... require autotools currently // or need to be redefined with respective BUILD_TYPE From bc31ba21062123632c4e09a6b28dbd4b6852a96f Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 14 Mar 2024 10:42:16 +0000 Subject: [PATCH 0099/1079] Jenkinsfile-dynamatrix: wrap unstashing of sources into their own pipeline sub-stage Signed-off-by: Jim Klimov --- Jenkinsfile-dynamatrix | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile-dynamatrix b/Jenkinsfile-dynamatrix index faa8dbdba6..b82e98bae1 100644 --- a/Jenkinsfile-dynamatrix +++ b/Jenkinsfile-dynamatrix @@ -285,7 +285,10 @@ set | sort -n """ } withEnvOptional(dynacfgPipeline.defaultTools) { - unstashCleanSrc(dynacfgPipeline.stashnameSrc) + stage('Unstash sources') { + unstashCleanSrc(dynacfgPipeline.stashnameSrc) + } + buildMatrixCellCI(dynacfgPipeline, dsbcClone, stageNameClone) //buildMatrixCellCI(dynacfgPipeline, dsbc, stageName) } @@ -315,7 +318,10 @@ set | sort -n """ } withEnvOptional(dynacfgPipeline.defaultTools) { - unstashCleanSrc(dynacfgPipeline.stashnameSrc) + stage('Unstash sources') { + unstashCleanSrc(dynacfgPipeline.stashnameSrc) + } + def dynacfgPipeline_ciBuild = dynacfgPipeline.clone() dynacfgPipeline_ciBuild.buildSystem = 'ci_build.sh' dynacfgPipeline_ciBuild.buildPhases = [:] From 44b1943f2bdbf227edc5ea538984cd8a73bbfc6f Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 18 Mar 2024 21:07:10 +0100 Subject: [PATCH 0100/1079] nutconf-related C++ sources: add new UPSMON-style notification keywords to vocabulary Signed-off-by: Jim Klimov --- common/nutconf.cpp | 13 +++++++++++++ common/nutwriter.cpp | 7 +++++++ include/nutconf.hpp | 7 +++++++ tools/nutconf/nutconf-cli.cpp | 7 +++++-- 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/common/nutconf.cpp b/common/nutconf.cpp index 33adb3c47c..86cabda19f 100644 --- a/common/nutconf.cpp +++ b/common/nutconf.cpp @@ -3,6 +3,7 @@ Copyright (C) 2012 Emilien Kia + 2024 Jim Klimov This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1075,6 +1076,18 @@ UpsmonConfiguration::NotifyType UpsmonConfiguration::NotifyTypeFromString(const return NOTIFY_NOCOMM; else if(str=="NOPARENT") return NOTIFY_NOPARENT; + else if(str=="CAL") + return NOTIFY_CAL; + else if(str=="NOTCAL") + return NOTIFY_NOTCAL; + else if(str=="OFF") + return NOTIFY_OFF; + else if(str=="NOTOFF") + return NOTIFY_NOTOFF; + else if(str=="BYPASS") + return NOTIFY_BYPASS; + else if(str=="NOTBYPASS") + return NOTIFY_NOTBYPASS; else return NOTIFY_TYPE_MAX; } diff --git a/common/nutwriter.cpp b/common/nutwriter.cpp index 8cc232bcdc..5a07478885 100644 --- a/common/nutwriter.cpp +++ b/common/nutwriter.cpp @@ -3,6 +3,7 @@ Copyright (C) 2012 Vaclav Krpec + 2024 Jim Klimov This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -240,6 +241,12 @@ const NotifyFlagsStrings::TypeStrings NotifyFlagsStrings::type_str = { "REPLBATT", // NOTIFY_REPLBATT "NOCOMM", // NOTIFY_NOCOMM "NOPARENT", // NOTIFY_NOPARENT + "CAL\t", // NOTIFY_CAL (including padding) + "NOTCAL", // NOTIFY_NOTCAL + "OFF\t", // NOTIFY_OFF (including padding) + "NOTOFF", // NOTIFY_NOTOFF + "BYPASS", // NOTIFY_BYPASS + "NOTBYPASS", // NOTIFY_NOTBYPASS }; diff --git a/include/nutconf.hpp b/include/nutconf.hpp index 086db17e23..c23101db12 100644 --- a/include/nutconf.hpp +++ b/include/nutconf.hpp @@ -3,6 +3,7 @@ Copyright (C) 2012 Emilien Kia + 2024 Jim Klimov This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -658,6 +659,12 @@ class UpsmonConfiguration : public Serialisable NOTIFY_REPLBATT, NOTIFY_NOCOMM, NOTIFY_NOPARENT, + NOTIFY_CAL, + NOTIFY_NOTCAL, + NOTIFY_OFF, + NOTIFY_NOTOFF, + NOTIFY_BYPASS, + NOTIFY_NOTBYPASS, NOTIFY_TYPE_MAX }; diff --git a/tools/nutconf/nutconf-cli.cpp b/tools/nutconf/nutconf-cli.cpp index f20a3eb724..0f27d0d6ef 100644 --- a/tools/nutconf/nutconf-cli.cpp +++ b/tools/nutconf/nutconf-cli.cpp @@ -1,5 +1,7 @@ /* - * Copyright (C) 2013 - EATON + * Copyright (C) + * 2013 - EATON + * 2024 - Jim Klimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -130,7 +132,8 @@ const char * Usage::s_text[] = { "UPS device is specified by the following sequence:", " [=]*", "Notification types:", - " ONLINE, ONBATT, LOWBATT, FSD, COMMOK, COMMBAD, SHUTDOWN, REPLBATT, NOCOMM, NOPARENT", + " ONLINE, ONBATT, LOWBATT, FSD, COMMOK, COMMBAD, SHUTDOWN, REPLBATT, NOCOMM, NOPARENT,", + " CAL, NOTCAL, OFF, NOTOFF, BYPASS, NOTBYPASS", "Notification flags:", " SYSLOG, WALL, EXEC, IGNORE", "User specification:", From 082a8b304d6cc77a5e281cb1fc70b5f44d1dcdb4 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 18 Mar 2024 21:08:43 +0100 Subject: [PATCH 0101/1079] nutconf-related C++ sources: fix typo in source var names: hotSync => hostSync Signed-off-by: Jim Klimov --- common/nutconf.cpp | 2 +- common/nutwriter.cpp | 2 +- include/nutconf.hpp | 2 +- tests/nutconf_parser_ut.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/common/nutconf.cpp b/common/nutconf.cpp index 86cabda19f..4efd831a44 100644 --- a/common/nutconf.cpp +++ b/common/nutconf.cpp @@ -1233,7 +1233,7 @@ void UpsmonConfigParser::onParseDirective(const std::string& directiveName, char { if(values.size()>0) { - _config->hotSync = StringToSettableNumber(values.front()); + _config->hostSync = StringToSettableNumber(values.front()); } } else if(directiveName == "DEADTIME") diff --git a/common/nutwriter.cpp b/common/nutwriter.cpp index 5a07478885..2e105e4b53 100644 --- a/common/nutwriter.cpp +++ b/common/nutwriter.cpp @@ -445,7 +445,7 @@ NutWriter::status_t UpsmonConfigWriter::writeConfig(const UpsmonConfiguration & UPSMON_DIRECTIVEX("MINSUPPLIES", unsigned int, config.minSupplies, false); UPSMON_DIRECTIVEX("POLLFREQ", unsigned int, config.poolFreq, false); UPSMON_DIRECTIVEX("POLLFREQALERT", unsigned int, config.poolFreqAlert, false); - UPSMON_DIRECTIVEX("HOSTSYNC", unsigned int, config.hotSync, false); + UPSMON_DIRECTIVEX("HOSTSYNC", unsigned int, config.hostSync, false); UPSMON_DIRECTIVEX("DEADTIME", unsigned int, config.deadTime, false); UPSMON_DIRECTIVEX("RBWARNTIME", unsigned int, config.rbWarnTime, false); UPSMON_DIRECTIVEX("NOCOMMWARNTIME", unsigned int, config.noCommWarnTime, false); diff --git a/include/nutconf.hpp b/include/nutconf.hpp index c23101db12..bd8eac18a0 100644 --- a/include/nutconf.hpp +++ b/include/nutconf.hpp @@ -638,7 +638,7 @@ class UpsmonConfiguration : public Serialisable void parseFromString(const std::string& str); Settable runAsUser, shutdownCmd, notifyCmd, powerDownFlag; - Settable minSupplies, poolFreq, poolFreqAlert, hotSync; + Settable minSupplies, poolFreq, poolFreqAlert, hostSync; Settable deadTime, rbWarnTime, noCommWarnTime, finalDelay; enum NotifyFlag { diff --git a/tests/nutconf_parser_ut.cpp b/tests/nutconf_parser_ut.cpp index f429b28cc9..4b182e3c16 100644 --- a/tests/nutconf_parser_ut.cpp +++ b/tests/nutconf_parser_ut.cpp @@ -278,7 +278,7 @@ void NutConfTest::testUpsmonConfigParser() CPPUNIT_ASSERT_EQUAL_MESSAGE("Cannot find POWERDOWNFLAG '/etc/killpower'", string("/etc/killpower"), *conf.powerDownFlag); CPPUNIT_ASSERT_EQUAL_MESSAGE("Cannot find POLLFREQ 30", 30u, *conf.poolFreq); CPPUNIT_ASSERT_EQUAL_MESSAGE("Cannot find POLLFREQALERT 5", 5u, *conf.poolFreqAlert); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Cannot find HOSTSYNC 15", 15u, *conf.hotSync); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Cannot find HOSTSYNC 15", 15u, *conf.hostSync); CPPUNIT_ASSERT_EQUAL_MESSAGE("Cannot find DEADTIME 15", 15u, *conf.deadTime); CPPUNIT_ASSERT_EQUAL_MESSAGE("Cannot find RBWARNTIME 43200", 43200u, *conf.rbWarnTime); CPPUNIT_ASSERT_EQUAL_MESSAGE("Cannot find NOCOMMWARNTIME 300", 300u, *conf.noCommWarnTime); From e20a8698ec627d266ef6a3cc3b08a396da93c77c Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 14 Mar 2024 11:22:56 +0000 Subject: [PATCH 0102/1079] Jenkinsfile-dynamatrix: rectify passing of CONFIG_OPTS [relies on nut/jenkins-dynamatrix#34] Signed-off-by: Jim Klimov --- Jenkinsfile-dynamatrix | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Jenkinsfile-dynamatrix b/Jenkinsfile-dynamatrix index b82e98bae1..9e82ba6e2f 100644 --- a/Jenkinsfile-dynamatrix +++ b/Jenkinsfile-dynamatrix @@ -449,10 +449,13 @@ set | sort -n """ 'CSTDVARIANT': ['gnu'] ], dynamatrixAxesCommonEnv: [ + // One set of several simultaneously exported envvars! + // CONFIG_OPTS are picked up by our dynamatrix configuration + // and substituted into shell "as is" for normal builds + // (so splitting into many tokens), or quoted as a single + // token DISTCHECK_FLAGS in its stage (split by make later). ['LANG=C','LC_ALL=C','TZ=UTC', - // TODO: Find a way to pass space-separated tokens through withEnv() - //'CONFIG_OPTS=\"--with-all=auto\\ --with-docs=auto\\ --with-ssl=auto\\ --enable-Werror\\ --enable-warnings\\ --disable-Wcolor\\ --enable-silent-rules\"' - 'CONFIG_OPTS=--enable-Werror' + 'CONFIG_OPTS=--with-all=auto --with-docs=auto --with-ssl=auto --enable-Werror --enable-warnings --disable-Wcolor --enable-silent-rules' ] ], From a760767fab7ba75248f0e0ccb0a60264f0c1695b Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 18 Mar 2024 21:17:24 +0100 Subject: [PATCH 0103/1079] nutconf-related C++ sources: deprecate certain terminology and keywords [#840] Signed-off-by: Jim Klimov --- common/nutconf.cpp | 13 +++++++------ common/nutwriter.cpp | 5 +++-- include/nutconf.hpp | 4 ++-- tests/nutconf_ut.cpp | 5 +++-- tools/nutconf/nutconf-cli.cpp | 12 ++++++------ 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/common/nutconf.cpp b/common/nutconf.cpp index 4efd831a44..19ae9afd5b 100644 --- a/common/nutconf.cpp +++ b/common/nutconf.cpp @@ -1190,7 +1190,7 @@ void UpsmonConfigParser::onParseDirective(const std::string& directiveName, char monitor.powerValue = StringToSettableNumber(*it++); monitor.username = *it++; monitor.password = *it++; - monitor.isMaster = (*it) == "master"; + monitor.isMaster = (*it) == "primary"; // master for NUT v2.7.4 and older _config->monitors.push_back(monitor); } } @@ -1583,11 +1583,11 @@ UpsdUsersConfiguration::upsmon_mode_t UpsdUsersConfiguration::getUpsmonMode() co { std::string mode_str = getStr("upsmon", "upsmon"); - if ("master" == mode_str) - return UPSMON_MASTER; + if ("primary" == mode_str || "master" == mode_str) + return UPSMON_PRIMARY; - if ("slave" == mode_str) - return UPSMON_SLAVE; + if ("secondary" == mode_str || "slave" == mode_str) + return UPSMON_SECONDARY; return UPSMON_UNDEF; } @@ -1597,7 +1597,8 @@ void UpsdUsersConfiguration::setUpsmonMode(upsmon_mode_t mode) { assert(UPSMON_UNDEF != mode); - setStr("upsmon", "upsmon", (UPSMON_MASTER == mode ? "master" : "slave")); + setStr("upsmon", "upsmon", (UPSMON_PRIMARY == mode ? "primary" : "secondary")); + /* NUT v2.7.4 and older: setStr("upsmon", "upsmon", (UPSMON_PRIMARY == mode ? "master" : "slave")); */ } diff --git a/common/nutwriter.cpp b/common/nutwriter.cpp index 2e105e4b53..a5c0c64e93 100644 --- a/common/nutwriter.cpp +++ b/common/nutwriter.cpp @@ -398,8 +398,9 @@ static std::string serializeMonitor(const UpsmonConfiguration::Monitor & monitor // Username & password directive << monitor.username << ' ' << monitor.password << ' '; - // Master/slave - directive << (monitor.isMaster ? "master" : "slave"); + // Primary/secondary (legacy master/slave) + directive << (monitor.isMaster ? "primary" : "secondary"); + /* NUT v2.7.4 and older: directive << (monitor.isMaster ? "master" : "slave");*/ return directive.str(); } diff --git a/include/nutconf.hpp b/include/nutconf.hpp index bd8eac18a0..af03a1b5e7 100644 --- a/include/nutconf.hpp +++ b/include/nutconf.hpp @@ -1084,8 +1084,8 @@ class UpsdUsersConfiguration : public GenericConfiguration /** upsmon mode */ typedef enum { UPSMON_UNDEF = 0, /**< Unknown mode */ - UPSMON_MASTER, /**< Master mode */ - UPSMON_SLAVE, /**< Slave mode */ + UPSMON_PRIMARY, /**< Primary (legacy "Master") mode */ + UPSMON_SECONDARY, /**< Secondary (legacy "Slave") mode */ } upsmon_mode_t; /** User-specific configuration attributes getters and setters \{ */ diff --git a/tests/nutconf_ut.cpp b/tests/nutconf_ut.cpp index ba8c8947d1..612a772c6a 100644 --- a/tests/nutconf_ut.cpp +++ b/tests/nutconf_ut.cpp @@ -3,6 +3,7 @@ Copyright (C) 2012 Vaclav Krpec + 2024 Jim Klimov This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -211,7 +212,7 @@ void NutConfigUnitTest::testUpsdUsersConfiguration() { load(static_cast(&config), ABS_TOP_SRCDIR "/conf/upsd.users.sample"); config.setPassword("upsmon", "ytrewq"); - config.setUpsmonMode(nut::UpsdUsersConfiguration::UPSMON_MASTER); + config.setUpsmonMode(nut::UpsdUsersConfiguration::UPSMON_PRIMARY); config.setPassword("admin", "qwerty=ui"); config.setActions("admin", nut::ConfigParamList(1, "SET")); @@ -225,7 +226,7 @@ void NutConfigUnitTest::testUpsdUsersConfiguration() { "\n" "[upsmon]\n" "\tpassword = ytrewq\n" - "\tupsmon master\n" + "\tupsmon primary\n" "\n" ); } diff --git a/tools/nutconf/nutconf-cli.cpp b/tools/nutconf/nutconf-cli.cpp index 0f27d0d6ef..8f32fe4ff8 100644 --- a/tools/nutconf/nutconf-cli.cpp +++ b/tools/nutconf/nutconf-cli.cpp @@ -128,7 +128,7 @@ const char * Usage::s_text[] = { "", "NUT modes: standalone, netserver, netclient, controlled, manual, none", "Monitor is specified by the following sequence:", - " [:] (\"master\"|\"slave\")", + " [:] (\"primary\"|\"secondary\")", "UPS device is specified by the following sequence:", " [=]*", "Notification types:", @@ -2090,7 +2090,7 @@ static nut::UpsmonConfiguration::Monitor monitor( monitor.hostname = host_port.substr(0, colon_idx); monitor.port = port; monitor.powerValue = power_value; - monitor.isMaster = "master" == mode; + monitor.isMaster = ("primary" == mode || "master" == mode); return monitor; } @@ -2594,11 +2594,11 @@ static void setUsers( nut::UpsdUsersConfiguration::upsmon_mode_t mode = nut::UpsdUsersConfiguration::UPSMON_UNDEF; - if ("master" == upsmon_user->mode) - mode = nut::UpsdUsersConfiguration::UPSMON_MASTER; + if ("primary" == upsmon_user->mode || "master" == upsmon_user->mode) + mode = nut::UpsdUsersConfiguration::UPSMON_PRIMARY; - else if ("slave" == upsmon_user->mode) - mode = nut::UpsdUsersConfiguration::UPSMON_SLAVE; + else if ("secondary" == upsmon_user->mode || "slave" == upsmon_user->mode) + mode = nut::UpsdUsersConfiguration::UPSMON_SECONDARY; else { std::cerr From 1bf62e569cf6dad0cecc5ad9f4c7aa4e53aa864b Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 18 Mar 2024 09:19:11 +0000 Subject: [PATCH 0104/1079] Makefile.am: make sure that "make all" ends up making all types of docs Signed-off-by: Jim Klimov --- Makefile.am | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Makefile.am b/Makefile.am index 989240aa1d..24e3ad7a83 100644 --- a/Makefile.am +++ b/Makefile.am @@ -9,6 +9,13 @@ @NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export CCACHE_PATH=@CCACHE_PATH@ @NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export PATH=@PATH_DURING_CONFIGURE@ +# First target defines default behavior: all +# We follow up with another pass to `make doc` because our wild recipes +# sometimes preclude generating all of them on the first pass (FIXME!) +# missing e.g. PDF and HTML which then pop up in `make check` footprint. +all: all-recursive + +@$(MAKE) $(AM_MAKEFLAGS) doc + # include directory for aclocal ACLOCAL_AMFLAGS = -I m4 From 2157cd2c639aa24bc5b1fd8c43924e6bfc25b619 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 18 Mar 2024 12:18:41 +0000 Subject: [PATCH 0105/1079] tools/gitlog2changelog.py.in: trivialize author names into plain ASCII Older asciidoc/a2x/dblatex stack fails with non-ASCII characters in section titles (date and commit author become ChangeLog sections). Inspired by: * http://aerostitch.github.io/misc/asciidoc/asciidoc-title_uft8.html * https://stackoverflow.com/questions/51710082/what-does-unicodedata-normalize-do-in-python * https://stackoverflow.com/questions/38697037/how-to-convert-python-2-unicode-function-into-correct-python-3-x-syntax Signed-off-by: Jim Klimov --- tools/gitlog2changelog.py.in | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tools/gitlog2changelog.py.in b/tools/gitlog2changelog.py.in index a5e4d78660..3bed9bfa93 100755 --- a/tools/gitlog2changelog.py.in +++ b/tools/gitlog2changelog.py.in @@ -10,6 +10,17 @@ from textwrap import TextWrapper import sys import subprocess +# Python 3 compatibility hack +try: + unicode('') +except NameError: + unicode = str + +try: + import unicodedata +except: + pass + rev_range = "HEAD" if len(sys.argv) > 1: @@ -104,6 +115,13 @@ for line in fin: try: author = authorList[1] author = author[0 : len(author) - fin_chop] + try: + if isinstance(author, str): + author = unicodedata.normalize(u'NFKD', unicode(author, "UTF=8")).encode('ascii', 'ignore').decode('utf8') + else: + author = unicodedata.normalize(u'NFKD', author).encode('ascii', 'ignore').decode('utf8') + except Exception as e: + print("Could not unicodedata.normalize() author '%s': %s" % (author, str(e))) authorFound = True except: print("Could not parse authorList = '%s'" % (line)) From 0876daefd0ce9b3a546bbd7438de750d4c7187a6 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 18 Mar 2024 12:37:16 +0000 Subject: [PATCH 0106/1079] docs/Makefile.am: hint to asciidoc/dblatex to trivialize section names into ASCII themselves Inspired by http://aerostitch.github.io/misc/asciidoc/asciidoc-title_uft8.html but did not directly help at least for Ubuntu 14.04 worker NOTE: Fallback suggestion to add --dblatex-opts="--param=latex.encoding=utf8" actually broke the PDF doc builds, not only for ChangeLog. Signed-off-by: Jim Klimov --- docs/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Makefile.am b/docs/Makefile.am index ee4560246b..e82323e757 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -244,7 +244,7 @@ $(top_builddir)/ChangeLog.adoc: $(top_builddir)/ChangeLog exit ; \ } ; \ echo " DOC-CHANGELOG-ASCIIDOC $${INPUT} => $@" \ - && printf "ifdef::txt[]\n== Very detailed Change Log\nendif::txt[]\n\n" > "$@.tmp" \ + && printf "ifdef::txt[]\n== Very detailed Change Log\n:ascii-ids:\nendif::txt[]\n\n" > "$@.tmp" \ && TABCHAR="`printf '\t'`" \ && $(SED) \ -e 's,^\([0-9a-zA-Z]\),=== \1,' \ From 1d768d41779e7faf98da825ab68e873c2c2fb73a Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 18 Mar 2024 14:35:43 +0000 Subject: [PATCH 0107/1079] configure.ac, Makefile.am, docs/Makefile.am, tools/gitlog2changelog.py.in: detect if we should mangle ChangeLog.pdf section titles with non-ASCII contributor names Signed-off-by: Jim Klimov --- Makefile.am | 8 +++++++- configure.ac | 7 +++++++ docs/Makefile.am | 8 +++++++- tools/gitlog2changelog.py.in | 23 ++++++++++++++++------- 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/Makefile.am b/Makefile.am index 24e3ad7a83..0453994435 100644 --- a/Makefile.am +++ b/Makefile.am @@ -331,11 +331,17 @@ dummy-stamp: ChangeLog: dummy-stamp +@$(MAKE) $(AM_MAKEFLAGS) $(abs_top_builddir)/ChangeLog +if WITH_PDF_NONASCII_TITLES +WITH_PDF_NONASCII_TITLES_ENVVAR = WITH_PDF_NONASCII_TITLES=yes +else +WITH_PDF_NONASCII_TITLES_ENVVAR = WITH_PDF_NONASCII_TITLES=no +endif + # Be sure to not confuse with a DIST'ed file (and so try to overwrite it): $(abs_top_builddir)/ChangeLog: tools/gitlog2changelog.py dummy-stamp @cd $(abs_top_srcdir) && \ if test -e .git ; then \ - CHANGELOG_FILE="$@" $(abs_top_builddir)/tools/gitlog2changelog.py $(GITLOG_START_POINT) || \ + CHANGELOG_FILE="$@" $(WITH_PDF_NONASCII_TITLES_ENVVAR) $(abs_top_builddir)/tools/gitlog2changelog.py $(GITLOG_START_POINT) || \ { printf "gitlog2changelog.py failed to generate the ChangeLog.\n\nNOTE: See https://github.com/networkupstools/nut/commits/master for change history.\n\n" > "$@" ; } ; \ else \ if test x"$(abs_top_srcdir)" != x"$(abs_top_builddir)" -a -s ./ChangeLog ; then \ diff --git a/configure.ac b/configure.ac index 38d85520c3..40b3ca9286 100644 --- a/configure.ac +++ b/configure.ac @@ -2722,6 +2722,7 @@ dnl not fail if we have no tools to generate it (so add to SKIP list). pdf*) AC_MSG_CHECKING([if dblatex version can build ${nut_doc_build_target_base} (minimum required ${DBLATEX_MIN_VERSION})]) can_build_doc_pdf=no + can_build_doc_pdf_nonascii_titles=no AX_COMPARE_VERSION([${DBLATEX_VERSION}], [ge], [${DBLATEX_MIN_VERSION}], [ ( cd "$DOCTESTDIR" && ${A2X} --format=pdf --destination-dir=. "${abs_srcdir}"/docs/asciidoc.txt && test -s asciidoc.pdf ) && can_build_doc_pdf=yes rm -f "${DOCTESTDIR}"/asciidoc.pdf @@ -2729,6 +2730,10 @@ dnl not fail if we have no tools to generate it (so add to SKIP list). if test "${can_build_doc_pdf}" = yes ; then AC_MSG_RESULT(yes) DOC_BUILD_LIST="${DOC_BUILD_LIST} ${nut_doc_build_target_base}" + AC_MSG_CHECKING([if dblatex can process non-ASCII section titles for PDF]) + ( cd "$DOCTESTDIR" && sed -e 's/^Intro/'"`printf '\303\215'`"'ntro/' -e 's/Works in Progress/Works '"`printf '\303\255'`"'n Progress/' < "${abs_srcdir}"/docs/asciidoc.txt > asciidoc.tmp.txt && ${A2X} --format=pdf --destination-dir=. asciidoc.tmp.txt && test -s asciidoc.tmp.pdf ) && can_build_doc_pdf_nonascii_titles=yes + rm -f "${DOCTESTDIR}"/asciidoc.tmp.pdf + AC_MSG_RESULT(${can_build_doc_pdf_nonascii_titles}) else AC_MSG_RESULT(no) if test "${nut_doc_build_target_flag}" = "yes" ; then @@ -2804,6 +2809,8 @@ no) ;; esac +AM_CONDITIONAL(WITH_PDF_NONASCII_TITLES, [test x"$can_build_doc_pdf_nonascii_titles" = xyes]) + NUT_REPORT_FEATURE([build specific documentation format(s)], [${nut_with_doc}], [${DOC_BUILD_LIST}], [WITH_DOCS], [Define to enable overall documentation generation]) diff --git a/docs/Makefile.am b/docs/Makefile.am index e82323e757..a49ec8ff57 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -233,6 +233,12 @@ $(top_builddir)/ChangeLog: # (and claims why: "Using $< in a non-suffix rule context is a GNUmake idiom"), # but it has a "$?" for "list of dependencies that are newer than the target". # For more details see https://man.freebsd.org/cgi/man.cgi +if WITH_PDF_NONASCII_TITLES +A2X_ASCII_IDS = +else !WITH_PDF_NONASCII_TITLES +A2X_ASCII_IDS = ":ascii-ids:\n" +endif !WITH_PDF_NONASCII_TITLES + $(top_builddir)/ChangeLog.adoc: $(top_builddir)/ChangeLog @INPUT="$?"; \ test -n "$${INPUT}" || INPUT="$$(top_builddir)/ChangeLog" ; \ @@ -244,7 +250,7 @@ $(top_builddir)/ChangeLog.adoc: $(top_builddir)/ChangeLog exit ; \ } ; \ echo " DOC-CHANGELOG-ASCIIDOC $${INPUT} => $@" \ - && printf "ifdef::txt[]\n== Very detailed Change Log\n:ascii-ids:\nendif::txt[]\n\n" > "$@.tmp" \ + && printf "ifdef::txt[]\n== Very detailed Change Log\n"$(A2X_ASCII_IDS)"endif::txt[]\n\n" > "$@.tmp" \ && TABCHAR="`printf '\t'`" \ && $(SED) \ -e 's,^\([0-9a-zA-Z]\),=== \1,' \ diff --git a/tools/gitlog2changelog.py.in b/tools/gitlog2changelog.py.in index 3bed9bfa93..7518f6a5a8 100755 --- a/tools/gitlog2changelog.py.in +++ b/tools/gitlog2changelog.py.in @@ -92,6 +92,14 @@ messageNL = False files = "" prevAuthorLine = "" +# Legacy default: keep as is +authorMustBeASCII = False +authorMustBeASCII_inverse_setting = str(os.environ.get("WITH_PDF_NONASCII_TITLES", "")).upper() +if authorMustBeASCII_inverse_setting in ["YES", "TRUE"]: + authorMustBeASCII = False +elif authorMustBeASCII_inverse_setting in ["NO", "FALSE"]: + authorMustBeASCII = True + # See also: https://github.com/python/cpython/blob/main/Lib/textwrap.py wrapper = TextWrapper(initial_indent="\t", subsequent_indent="\t ", break_on_hyphens=False, break_long_words=False) @@ -115,13 +123,14 @@ for line in fin: try: author = authorList[1] author = author[0 : len(author) - fin_chop] - try: - if isinstance(author, str): - author = unicodedata.normalize(u'NFKD', unicode(author, "UTF=8")).encode('ascii', 'ignore').decode('utf8') - else: - author = unicodedata.normalize(u'NFKD', author).encode('ascii', 'ignore').decode('utf8') - except Exception as e: - print("Could not unicodedata.normalize() author '%s': %s" % (author, str(e))) + if authorMustBeASCII: + try: + if isinstance(author, str): + author = unicodedata.normalize(u'NFKD', unicode(author, "UTF=8")).encode('ascii', 'ignore').decode('utf8') + else: + author = unicodedata.normalize(u'NFKD', author).encode('ascii', 'ignore').decode('utf8') + except Exception as e: + print("Could not unicodedata.normalize() author '%s': %s" % (author, str(e))) authorFound = True except: print("Could not parse authorList = '%s'" % (line)) From c2e859f55b26731c6a2f074dacdf3b82cb980161 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 18 Mar 2024 19:51:20 +0100 Subject: [PATCH 0108/1079] Jenkinsfile-dynamatrix: exclude GCC on OpenBSD 6.5 from autotools CI builds Old compiler that won't hush about warnings, pollutes CI dashboard. Equivalent builds handled by `ci_build.sh` are in quiet mode for the first compilation attempt (usually the only one, if all is OK) so these warnings are just not seen by build-log analysis parser. Signed-off-by: Jim Klimov --- Jenkinsfile-dynamatrix | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Jenkinsfile-dynamatrix b/Jenkinsfile-dynamatrix index 9e82ba6e2f..5a9f61972e 100644 --- a/Jenkinsfile-dynamatrix +++ b/Jenkinsfile-dynamatrix @@ -470,6 +470,11 @@ set | sort -n """ dynamatrixAxesLabels: [~/^OS/, 'COMPILER'], excludeCombos: dynacfgPipeline.excludeCombos_DEFAULT_STRICT_C + [dynacfgPipeline.axisCombos_WINDOWS_CROSS] + + [[~/OS_DISTRO=openbsd-6\./, ~/COMPILER=GCC/]] + // Here we picked just OSes and compilers (gcc or clang), + // so exclude systems which have e.g. gcc-4.2.1 which claims + // type range comparison warnings despite pragma fencing. + // gcc-4.8.x on CentOS 7 and Ubuntu 14.04 looks already okay. ], body) }, // getParStages //'bodyParStages': {} From 6a874f11fd05872b8f0298f57571bb8bf2440184 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 18 Mar 2024 20:45:42 +0100 Subject: [PATCH 0109/1079] Jenkinsfile-dynamatrix: for autotools-only builds, select by OS_DISTRO (avoide duplicates with OS_FAMILY) Signed-off-by: Jim Klimov --- Jenkinsfile-dynamatrix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile-dynamatrix b/Jenkinsfile-dynamatrix index 5a9f61972e..69bc55d321 100644 --- a/Jenkinsfile-dynamatrix +++ b/Jenkinsfile-dynamatrix @@ -467,7 +467,7 @@ set | sort -n """ runAllowedFailure: true, //dynamatrixAxesLabels: ['OS_FAMILY', 'OS_DISTRO', '${COMPILER}VER', 'ARCH${ARCH_BITS}'], //dynamatrixAxesLabels: [~/^OS/, '${COMPILER}VER', 'ARCH${ARCH_BITS}'], - dynamatrixAxesLabels: [~/^OS/, 'COMPILER'], + dynamatrixAxesLabels: [~/^OS_DISTRO/, 'COMPILER'], excludeCombos: dynacfgPipeline.excludeCombos_DEFAULT_STRICT_C + [dynacfgPipeline.axisCombos_WINDOWS_CROSS] + [[~/OS_DISTRO=openbsd-6\./, ~/COMPILER=GCC/]] From 056d00886fa712dd0557e579b420b577ff6d983d Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Tue, 19 Mar 2024 12:39:10 +0000 Subject: [PATCH 0110/1079] scripts/installer: avoid SCM-tracking a symlink to NUT source root Signed-off-by: Jim Klimov --- scripts/installer/Makefile.am | 8 ++++++++ scripts/installer/README.adoc | 12 ++++++------ scripts/installer/nut | 1 - 3 files changed, 14 insertions(+), 7 deletions(-) delete mode 120000 scripts/installer/nut diff --git a/scripts/installer/Makefile.am b/scripts/installer/Makefile.am index 10a67121cb..27da718516 100644 --- a/scripts/installer/Makefile.am +++ b/scripts/installer/Makefile.am @@ -32,6 +32,10 @@ EXTRA_DIST = \ SPELLCHECK_SRC = README.adoc common/README_ipp-os-shutdown.adoc +nut: + rm -f "$@" + $(LN_S) $(top_srcdir) "$@" + # NOTE: Due to portability, we do not use a GNU percent-wildcard extension. # We also have to export some variables that may be tainted by relative # paths when parsing the other makefile (e.g. MKDIR_P that may be defined @@ -54,4 +58,8 @@ spellcheck spellcheck-interactive spellcheck-sortdict: CLEANFILES = *-spellchecked +# Remove "nut" if it is a symlink to the source tree +clean-local: + if test -L nut || test -h nut ; then rm -f nut ; fi + MAINTAINERCLEANFILES = Makefile.in .dirstamp diff --git a/scripts/installer/README.adoc b/scripts/installer/README.adoc index 7c94a8be24..1cda6d7b32 100644 --- a/scripts/installer/README.adoc +++ b/scripts/installer/README.adoc @@ -8,13 +8,13 @@ of Eaton by Frederic Bohe, Vaclav Krpec, Arnaud Quette and Jim Klimov. This includes the package (tarball) creation script which relies on presence of third-party library binaries in a `$ARCH/libs` directory, -and init-scripts from NUT source tree (originally expected as a "nut" -subdirectory), as well as an interactive installer script to set up -the package on a target deployment covering package (re-)installation, -initial device discovery, password setup, etc., and helper scripts -for status overview and shutdown handling. +and init-scripts from NUT source tree (originally expected as a `nut` +subdirectory, can be a symlink to `../..`), as well as an interactive +installer script to set up the package on a target deployment covering +package (re-)installation, initial device discovery, password setup, +etc., and helper scripts for status overview and shutdown handling. -The installer relies on "nutconf" tool (emulating dummy script for +The installer relies on `nutconf` tool (emulating dummy script for tests provided here), which is part of NUT sources. Note that heavy use of `LD_LIBRARY_PATH` in these scripts may become diff --git a/scripts/installer/nut b/scripts/installer/nut deleted file mode 120000 index c25bddb6dd..0000000000 --- a/scripts/installer/nut +++ /dev/null @@ -1 +0,0 @@ -../.. \ No newline at end of file From 346071653adaad3ff5cbbd4848535773bbb5f56d Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Tue, 19 Mar 2024 13:10:16 +0000 Subject: [PATCH 0111/1079] scripts/installer/README.adoc, docs/nut.dict: update about directory layout and contents expected by make_package.sh Signed-off-by: Jim Klimov --- docs/nut.dict | 9 +++++++- scripts/installer/README.adoc | 43 ++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/docs/nut.dict b/docs/nut.dict index 9695f1816e..c79045136b 100644 --- a/docs/nut.dict +++ b/docs/nut.dict @@ -1,4 +1,4 @@ -personal_ws-1.1 en 3470 utf-8 +personal_ws-1.1 en 3478 utf-8 AAC AAS ABI @@ -1570,6 +1570,7 @@ aec af aggregator ai +aix al ala alarmcenables @@ -2198,6 +2199,7 @@ hotplug hotplugging hovercharge hpe +hpux href htaccess html @@ -2365,6 +2367,7 @@ libdir libdummy libexec libexecdir +libexpat libfreeipmi libgd libgpgme @@ -3023,6 +3026,7 @@ sitop sizeof ske skel +sl slackpkg slaveid slavesync @@ -3045,8 +3049,11 @@ socat sockdebug socketname socomec +solari solaris +solcmn solibs +solint solis somename somepass diff --git a/scripts/installer/README.adoc b/scripts/installer/README.adoc index 1cda6d7b32..e6656b736d 100644 --- a/scripts/installer/README.adoc +++ b/scripts/installer/README.adoc @@ -8,12 +8,53 @@ of Eaton by Frederic Bohe, Vaclav Krpec, Arnaud Quette and Jim Klimov. This includes the package (tarball) creation script which relies on presence of third-party library binaries in a `$ARCH/libs` directory, +pre-built package files (courtesy of NUT `make package` recipes), and init-scripts from NUT source tree (originally expected as a `nut` -subdirectory, can be a symlink to `../..`), as well as an interactive +subdirectory, can be a symlink to `../..`; currently copies stored in +the `$ARCH` subdirectories; eventually should be taken from NUT sources +during build, or from packages), as well as an interactive text-mode installer script to set up the package on a target deployment covering package (re-)installation, initial device discovery, password setup, etc., and helper scripts for status overview and shutdown handling. +Example `$ARCH` related directory layout in original posting (binary +files mentioned below are not provided into NUT Git source code base); +these are the contents `make_package.sh` script expects to work with +(you can see the names mentioned in `find ... | grep -v ...` filters): + +* `aix/` example for AIX 6 and 7 based IPSS Unix releases: + * `libs/`: `libcrypto.a`, `libcrypto.so`, etc... + * `nut-2.6.5-1.aix6.1.ppc.rpm` and `nut-client-2.6.5-1.aix6.1.ppc.rpm` + package files + * `nutconf` binary for the platform + * `aix_init` script + * `ipp-os-shutdown.conf.sample` + +* `hpux/` for PA-RISC: + * `libs/`: `libcrypto.sl`, `libexpat.sl`, `libiconv.sl`, `libintl.sl`, + `libltdl.sl`, `libneon.sl`, `libnetsnmp.sl.30`, `libssl.sl`, `libz.sl` + * Notably, `libnutscan.sl.1` (other platforms did not carry a copy) + * `nut.depot.tar.gz` package file + * `nutconf` binary for the platform + * `ipp-os-shutdown.conf.sample` + +* Solaris (SPARC and X86) spread across 3 directories: + * `solcmn/` with common platform-independent files: + * `ipp-os-shutdown.conf.sample` + * `solaris_init` script + + * `solari` with SPARC binaries: + * `libs/`: `libcrypto.so.0.9.8`, `libz.so`, etc. + * `NUT_solaris_sparc_package2.6.5.local` package file + * `nutconf` binary for the platform + + * `solint` with X86 binaries: + * `libs/`: `libcrypto.so.1.0.0`, `libgcc_s.so.1`, `libltdl.so.7`, + `libneon.so.27`, `libnetsnmp.so.15`, `libproxy.so.0`, + `libssl.so.1.0.0`, `libstdc++.so.6`, `libwrap.so.1` + * `NUT_solaris_i386_package2.6.5.local` package file + * `nutconf` binary for the platform + The installer relies on `nutconf` tool (emulating dummy script for tests provided here), which is part of NUT sources. From 9005cde004ddeb48cab30e86a4b45e8fcb6c80f2 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Tue, 19 Mar 2024 13:14:46 +0000 Subject: [PATCH 0112/1079] scripts/installer/make_package.sh: update comments Signed-off-by: Jim Klimov --- scripts/installer/make_package.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/installer/make_package.sh b/scripts/installer/make_package.sh index 2ebc08bf77..6c3aa66e81 100755 --- a/scripts/installer/make_package.sh +++ b/scripts/installer/make_package.sh @@ -12,9 +12,14 @@ rm -Rf package mkdir package -git pull --all +# NOTE: Originally this pulled installer sources (separate from NUT code base) +# If this script were to be modernized, it could be prudent to `make package` +# in NUT sources for each platform, to create the package file(s) tarballed +# below for end-user along with the interactive installer delivery. +#git pull --all # [ $? = 0 ] && git merge upstream/master || exit $? +# NOTE: See README.adoc about expected subdirectory contents with binary files NAME="ipp-solaris-$IPP_VERSION.sparc" mkdir "package/$NAME" FILE_LIST="`find . -type f -name '*' | egrep -v '.svn|.git|./nutconf-dummy|./make_package.sh|nut/|(un|)install.log|package/|aix|hpux|solint'`" From 9ef87271781beed6626126ad3e81f13dac3e0362 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 21 Mar 2024 19:21:15 +0100 Subject: [PATCH 0113/1079] m4/nut_check_libmodbus.m4: make it visible when some libmodbus is found, but does not support libusb while we want it (and will fail NUT configure later) [#2063] Signed-off-by: Jim Klimov --- m4/nut_check_libmodbus.m4 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/m4/nut_check_libmodbus.m4 b/m4/nut_check_libmodbus.m4 index dbaae4968e..c596bb1edc 100644 --- a/m4/nut_check_libmodbus.m4 +++ b/m4/nut_check_libmodbus.m4 @@ -72,7 +72,12 @@ if test -z "${nut_have_libmodbus_seen}"; then AC_CHECK_FUNCS(modbus_set_byte_timeout, [], [nut_have_libmodbus=no]) AC_CHECK_FUNCS(modbus_set_response_timeout, [], [nut_have_libmodbus=no]) - AC_CHECK_FUNCS(modbus_new_rtu_usb, [nut_have_libmodbus_usb=yes], [nut_have_libmodbus_usb=no]) + AC_CHECK_FUNCS(modbus_new_rtu_usb, [nut_have_libmodbus_usb=yes], [ + AS_IF([test x"${nut_with_usb}" = xyes && test x"${nut_with_modbus}" = xyes && test x"${nut_have_libmodbus}" = xyes ], [ + AC_MSG_WARN([Both --with-modbus and --with-usb were requested, and a libmodbus was found, but it seems to not support USB. You may require a custom build per https://github.com/networkupstools/nut/wiki/APC-UPS-with-Modbus-protocol]) + ]) + nut_have_libmodbus_usb=no + ]) dnl modbus_set_byte_timeout() and modbus_set_response_timeout() dnl in 3.0.x and 3.1.x have different args (since ~2013): the From 3e34c920b39f34ec3bed4b5782f3c610146abda2 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 21 Mar 2024 19:40:26 +0100 Subject: [PATCH 0114/1079] docs/man/apc_modbus.txt, docs/nut.dict: update manpage with instructions for USB-capable builds [#2063] Signed-off-by: Jim Klimov --- docs/man/apc_modbus.txt | 40 ++++++++++++++++++++++++++++++++++++++++ docs/nut.dict | 4 +++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/docs/man/apc_modbus.txt b/docs/man/apc_modbus.txt index 07cac400f6..4e5c98eb91 100644 --- a/docs/man/apc_modbus.txt +++ b/docs/man/apc_modbus.txt @@ -83,6 +83,46 @@ Set the Modbus slave id. The default slave id is 1. Set the Modbus response timeout. The default timeout is set by libmodbus. It can be good to set a higher timeout on TCP connections with high latency. +BUGS +---- + +This driver relies on advanced features of `libmodbus` to talk Modbus protocol +over USB specifically (Serial and TCP are part of common library codebase). +At the time of this writing, the common library project is just expecting a +merge of the pull request with this ability. + +For the time being, if your OS distribution does not ship the required feature +set, you may have to build your own `libmodbus` and subsequently (re-)build NUT +against this library, as detailed in the NUT GitHub Wiki at +https://github.com/networkupstools/nut/wiki/APC-UPS-with-Modbus-protocol + +The short sequence may be like follows: +------ +cd ~/ +git clone -b rtu_usb https://github.com/networkupstools/libmodbus +cd libmodbus +./autogen.sh +./configure --with-libusb --prefix=/path/to/prefix +make install + +cd ~/ +git clone https://github.com/networkupstools/nut +cd nut +./autogen.sh +./configure --with-drivers=apc_modbus --with-usb --with-modbus \ + --with-modbus-includes=-I/path/to/prefix/include/modbus \ + --with-modbus-libs="-L/path/to/prefix/lib -lmodbus" +make +------ + +NOTE: Other `configure` options may be needed for proper behavior, such as +`--prefix`, `--with-sysconfdir`, `--with-user` and `--with-group` to match +your packaged or otherwise preceding NUT installation. + +The `./configure --enable-inplace-runtime` may be a good start to inherit +build configuration from an existing NUT deployment, as further detailed at +https://github.com/networkupstools/nut/wiki/Building-NUT-for-in%E2%80%90place-upgrades-or-non%E2%80%90disruptive-tests + AUTHORS ------- diff --git a/docs/nut.dict b/docs/nut.dict index c79045136b..2e8118680d 100644 --- a/docs/nut.dict +++ b/docs/nut.dict @@ -1,4 +1,4 @@ -personal_ws-1.1 en 3478 utf-8 +personal_ws-1.1 en 3480 utf-8 AAC AAS ABI @@ -2431,6 +2431,7 @@ lk lldb llvm lm +lmodbus ln lnetsnmp loadPercentage @@ -2940,6 +2941,7 @@ rqt rsa rsync rts +rtu ru rubygem runlevel From 1a498d167183a1fdd5cb4aac22eafe334934103c Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Fri, 22 Mar 2024 13:24:53 +0100 Subject: [PATCH 0115/1079] tools/nut-scanner/scan_xml_http.c, tools/nut-scanner/scan_snmp.c: ignore potentially unreachable code in platforms-dependent range checks Same as 34056dd43261c92e9230e2d18ddf5e8f498d98e9 earlier. Signed-off-by: Jim Klimov --- tools/nut-scanner/scan_snmp.c | 17 +++++++++++++++++ tools/nut-scanner/scan_xml_http.c | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/tools/nut-scanner/scan_snmp.c b/tools/nut-scanner/scan_snmp.c index 89597382e3..cfe6c53c90 100644 --- a/tools/nut-scanner/scan_snmp.c +++ b/tools/nut-scanner/scan_snmp.c @@ -1033,7 +1033,24 @@ nutscan_device_t * nutscan_scan_snmp(const char * start_ip, const char * stop_ip # ifdef HAVE_SEMAPHORE if (max_threads_scantype > 0) { +#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE +#pragma GCC diagnostic push +#endif +#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE +#pragma GCC diagnostic ignored "-Wunreachable-code" +#endif +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunreachable-code" +#endif + /* Different platforms, different sizes, none fits all... */ if (SIZE_MAX > UINT_MAX && max_threads_scantype > UINT_MAX) { +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE +#pragma GCC diagnostic pop +#endif upsdebugx(1, "WARNING: %s: Limiting max_threads_scantype to range acceptable for sem_init()", __func__); diff --git a/tools/nut-scanner/scan_xml_http.c b/tools/nut-scanner/scan_xml_http.c index 490d2b9b21..0aa9ccc897 100644 --- a/tools/nut-scanner/scan_xml_http.c +++ b/tools/nut-scanner/scan_xml_http.c @@ -454,7 +454,24 @@ nutscan_device_t * nutscan_scan_xml_http_range(const char * start_ip, const char # ifdef HAVE_SEMAPHORE if (max_threads_scantype > 0) { +#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE +#pragma GCC diagnostic push +#endif +#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE +#pragma GCC diagnostic ignored "-Wunreachable-code" +#endif +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunreachable-code" +#endif + /* Different platforms, different sizes, none fits all... */ if (SIZE_MAX > UINT_MAX && max_threads_scantype > UINT_MAX) { +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE +#pragma GCC diagnostic pop +#endif upsdebugx(1, "WARNING: %s: Limiting max_threads_scantype to range acceptable for sem_init()", __func__); From 61edcb40f13b28e15ddfbc6a7b9a00821badc825 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Fri, 22 Mar 2024 13:35:13 +0100 Subject: [PATCH 0116/1079] Jenkinsfile-dynamatrix: enable "autotools driven build with default configuration ... with fatal warnings" for all branch types Earlier enabled for fightwarn and PRs against stable branches, but not for master-branch builds themselves. Signed-off-by: Jim Klimov --- Jenkinsfile-dynamatrix | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Jenkinsfile-dynamatrix b/Jenkinsfile-dynamatrix index 69bc55d321..923b5658ce 100644 --- a/Jenkinsfile-dynamatrix +++ b/Jenkinsfile-dynamatrix @@ -25,7 +25,8 @@ import org.nut.dynamatrix.*; def dynacfgPipeline = [:] // NOTE: These can be further disabled or active in different combo specs - // below based on branch names + // below based on branch names. Also note that the values are somewhat + // "inversed" -- e.g. that "disabledSomething = false" means "enable it". dynacfgPipeline.disableSlowBuildAutotools = false dynacfgPipeline.disableSlowBuildCIBuild = false dynacfgPipeline.disableSlowBuildCIBuildExperimental = false @@ -427,12 +428,12 @@ set | sort -n """ //'bodyParStages': {} ] // one slowBuild filter configuration, autotools-Wall - ,[name: 'Default autotools driven build with default configuration, bitness and warning levels on each NUT CI farm platform (but with fatal warnings as of gnu99/gnu++11)', + ,[name: 'Default autotools driven build with default configuration, bitness and warning levels on each NUT CI farm platform (but with fatal warnings as of gnu99/gnu++11, must pass where enabled)', disabled: dynacfgPipeline.disableSlowBuildAutotools, - branchRegexSource: ~/^(PR-.+|fightwarn.*)$/, - branchRegexTarget: dynacfgPipeline.branchStableRegex, + //branchRegexSource: ~/^(PR-.+|fightwarn.*)$/, + //branchRegexTarget: dynacfgPipeline.branchStableRegex, //branchRegexTarget: ~/fightwarn/, - appliesToChangedFilesRegex: dynacfgPipeline.appliesToChangedFilesRegex_C, + //appliesToChangedFilesRegex: dynacfgPipeline.appliesToChangedFilesRegex_C, 'getParStages': { def dynamatrix, Closure body -> return dynamatrix.generateBuild([ //commonLabelExpr: dynacfgBase.commonLabelExpr, From 14a3b40bf97916a29928567df1d3d5e0c593e826 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Fri, 22 Mar 2024 16:02:19 +0100 Subject: [PATCH 0117/1079] docs/man/apc_modbus.txt: update comments for libmodbus+rtu_usb builds - with a static library suggestion [#2063] Signed-off-by: Jim Klimov --- docs/man/apc_modbus.txt | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/docs/man/apc_modbus.txt b/docs/man/apc_modbus.txt index 4e5c98eb91..4deb74b4e1 100644 --- a/docs/man/apc_modbus.txt +++ b/docs/man/apc_modbus.txt @@ -104,7 +104,24 @@ cd libmodbus ./autogen.sh ./configure --with-libusb --prefix=/path/to/prefix make install +------ + +[NOTE] +====== +* you may need to `make && sudo make install` if you want to place this library + files' variant into a system path (like `--prefix=/usr/local/ups` to match + NUT defaults -- this activity would need privilege elevation via `sudo`), + and not into your home directory or some `/tmp` location. +* conversely, you may want to + `./configure --with-libusb --enable-static --disable-shared --prefix=/path/to/prefix` + and only build and install a static `libmodbus.a` (can well be installed into + `/tmp` or similarly short-lived location), so that the customized Modbus+USB + logic gets built directly into `apc_modbus` binary program and there would be + no potential run-time conflict with a dynamic library file available elsewhere + in the system. +====== +------ cd ~/ git clone https://github.com/networkupstools/nut cd nut @@ -115,9 +132,12 @@ cd nut make ------ -NOTE: Other `configure` options may be needed for proper behavior, such as +[NOTE] +====== +* Other NUT `configure` options may be needed for proper behavior, such as `--prefix`, `--with-sysconfdir`, `--with-user` and `--with-group` to match your packaged or otherwise preceding NUT installation. +====== The `./configure --enable-inplace-runtime` may be a good start to inherit build configuration from an existing NUT deployment, as further detailed at From 6641b2a761bc8cfd7522ac30c3d08663aa464cd6 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Fri, 22 Mar 2024 16:36:14 +0100 Subject: [PATCH 0118/1079] docs/man/Makefile.am: typo fix in comments Signed-off-by: Jim Klimov --- docs/man/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/man/Makefile.am b/docs/man/Makefile.am index 2f096b7889..dbd3aff360 100644 --- a/docs/man/Makefile.am +++ b/docs/man/Makefile.am @@ -950,7 +950,7 @@ CLEANFILES = *-spellchecked .prep-src-docs *-prepped SUFFIXES = .txt-prepped .txt .html .1 .3 .5 .8 -# For builds with allowed installation of prebuild man pages, check that +# For builds with allowed installation of prebuilt man pages, check that # they exist in sources (make would pull them automatically as a fallback # from failed lookup in build products). For builds that require rebuild # of man pages, abort with error if build product is missing. From 31e9979343d9435e581089de34661d87a19cf58a Mon Sep 17 00:00:00 2001 From: "James R. Parks" Date: Fri, 22 Mar 2024 22:51:54 -0700 Subject: [PATCH 0119/1079] feat: Add support for Liebert PSI5 Adding support for the Liebert PSI5 model of UPS. Signed-off-by: James R. Parks --- drivers/belkin-hid.c | 35 ++++++++++++++++++++++++++++++++++- drivers/usbhid-ups.c | 18 +++++++++++++++++- drivers/usbhid-ups.h | 1 + 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/drivers/belkin-hid.c b/drivers/belkin-hid.c index f1d4083afa..ad32335b45 100644 --- a/drivers/belkin-hid.c +++ b/drivers/belkin-hid.c @@ -31,7 +31,7 @@ #include /* for fabs() */ -#define BELKIN_HID_VERSION "Belkin/Liebert HID 0.19" +#define BELKIN_HID_VERSION "Belkin/Liebert HID 0.20" /* Belkin */ #define BELKIN_VENDORID 0x050d @@ -90,6 +90,7 @@ static const char *liebert_replacebatt_fun(double value); static const char *liebert_shutdownimm_fun(double value); static const char *liebert_config_voltage_fun(double value); static const char *liebert_line_voltage_fun(double value); +static const char *liebert_psi5_line_voltage_fun(double value); static info_lkp_t liebert_online_info[] = { { 0, NULL, liebert_online_fun, NULL } @@ -123,6 +124,10 @@ static info_lkp_t liebert_line_voltage_info[] = { { 0, NULL, liebert_line_voltage_fun, NULL }, }; +static info_lkp_t liebert_psi5_line_voltage_info[] = { + { 0, NULL, liebert_psi5_line_voltage_fun, NULL }, +}; + static double liebert_config_voltage_mult = 1.0; static double liebert_line_voltage_mult = 1.0; static char liebert_conversion_buf[10]; @@ -199,6 +204,23 @@ static const char *liebert_line_voltage_fun(double value) return liebert_conversion_buf; } +static const char *liebert_psi5_line_voltage_fun(double value) +{ + if( value < 1 ) { + if( fabs(value - 1e-3) < 1e-3 ) { + liebert_line_voltage_mult = 1e5; + upsdebugx(2, "Input/OutputVoltage = %g -> assuming correction factor = %g", + value, liebert_line_voltage_mult); + } else { + upslogx(LOG_NOTICE, "LineVoltage exponent looks wrong, but not correcting."); + } + } + + snprintf(liebert_conversion_buf, sizeof(liebert_conversion_buf), "%.1f", + value * liebert_line_voltage_mult); + return liebert_conversion_buf; +} + /* some conversion functions specific to Belkin */ /* returns statically allocated string - must not use it again before @@ -482,6 +504,17 @@ static hid_info_t belkin_hid2nut[] = { { "battery.voltage", 0, 0, "UPS.PowerSummary.Voltage", NULL, "%s", 0, liebert_line_voltage_info }, { "battery.voltage.nominal", 0, 0, "UPS.PowerSummary.ConfigVoltage", NULL, "%s", HU_FLAG_STATIC, liebert_config_voltage_info }, { "ups.load", 0, 0, "UPS.Output.PercentLoad", NULL, "%.0f", 0, NULL }, + /* Liebert PSI5 */ + { "input.voltage.nominal", 0, 0, "UPS.Flow.ConfigVoltage", NULL, "%.0f", 0, NULL }, + { "input.frequency", 0, 0, "UPS.PowerConverter.Input.Frequency", NULL, "%s", 0, divide_by_100_conversion }, + { "input.voltage", 0, 0, "UPS.PowerConverter.Input.Voltage", NULL, "%s", 0, liebert_psi5_line_voltage_info }, + { "output.voltage.nominal", 0, 0, "UPS.Flow.ConfigVoltage", NULL, "%.0f", 0, NULL }, + { "output.frequency", 0, 0, "UPS.PowerConverter.Output.Frequency", NULL, "%s", 0, divide_by_100_conversion }, + { "output.voltage", 0, 0, "UPS.PowerConverter.Output.Voltage", NULL, "%s", 0, liebert_psi5_line_voltage_info }, + { "ups.load", 0, 0, "UPS.OutletSystem.Outlet.PercentLoad", NULL, "%.0f", 0, NULL }, + { "battery.voltage", 0, 0, "UPS.BatterySystem.Battery.Voltage", NULL, "%s", 0, liebert_psi5_line_voltage_info }, + { "battery.voltage.nominal", 0, 0, "UPS.BatterySystem.Battery.ConfigVoltage", NULL, "%.0f", 0, NULL }, + { "battery.capacity", 0, 0, "UPS.Flow.ConfigApparentPower", NULL, "%.0f", 0, NULL }, /* status */ { "BOOL", 0, 0, "UPS.PowerSummary.Discharging", NULL, NULL, HU_FLAG_QUICK_POLL, liebert_discharging_info }, /* might not need to be liebert_* version */ { "BOOL", 0, 0, "UPS.PowerSummary.Charging", NULL, NULL, HU_FLAG_QUICK_POLL, liebert_charging_info }, diff --git a/drivers/usbhid-ups.c b/drivers/usbhid-ups.c index 4775d38fe8..97a66150eb 100644 --- a/drivers/usbhid-ups.c +++ b/drivers/usbhid-ups.c @@ -553,6 +553,22 @@ info_lkp_t divide_by_10_conversion[] = { { 0, NULL, divide_by_10_conversion_fun, NULL } }; +/* returns statically allocated string - must not use it again before + done with result! */ +static const char *divide_by_100_conversion_fun(double value) +{ + static char buf[20]; + + snprintf(buf, sizeof(buf), "%0.1f", value * 0.01); + + return buf; +} + +/* FIXME? Do we need an inverse "nuf()" here? */ +info_lkp_t divide_by_100_conversion[] = { + { 0, NULL, divide_by_100_conversion_fun, NULL } +}; + /* returns statically allocated string - must not use it again before done with result! */ static const char *kelvin_celsius_conversion_fun(double value) @@ -997,7 +1013,7 @@ void upsdrv_makevartable(void) addvar(VAR_VALUE, "onlinedischarge_log_throttle_hovercharge", "Set to throttle log messages about discharging while online (only if battery.charge is under this value)"); - + addvar(VAR_FLAG, "disable_fix_report_desc", "Set to disable fix-ups for broken USB encoding, etc. which we apply by default on certain vendors/products"); diff --git a/drivers/usbhid-ups.h b/drivers/usbhid-ups.h index 679ea7de7c..f6f67fea72 100644 --- a/drivers/usbhid-ups.h +++ b/drivers/usbhid-ups.h @@ -122,6 +122,7 @@ extern info_lkp_t date_conversion[]; extern info_lkp_t hex_conversion[]; extern info_lkp_t stringid_conversion[]; extern info_lkp_t divide_by_10_conversion[]; +extern info_lkp_t divide_by_100_conversion[]; extern info_lkp_t kelvin_celsius_conversion[]; /* ---------------------------------------------------------------------- */ From c3d7ee6e3c3e0084a7da920112f5f68106c0a389 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 23 Mar 2024 15:54:50 +0100 Subject: [PATCH 0120/1079] NEWS.adoc: Add Liebert PSI5 [#2369] Signed-off-by: Jim Klimov --- NEWS.adoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS.adoc b/NEWS.adoc index bb940c62ef..64e3af295a 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -180,6 +180,9 @@ https://github.com/networkupstools/nut/milestone/10 useful as an UPS driver, not just a controller developer sandbox. [#2188] * `cps-hid` subdriver now supports devices branded as Cyber Energy and built by cooperation with Cyber Power Systems. [#2312] + * `belkin-hid` subdriver now supports Liebert PSI5 devices which have a + different numeric reading scale than earlier handled models. [issue #2271, + PR #2272, PR #2369] * The `onlinedischarge` configuration flag name was too ambiguous and got deprecated (will be supported but no longer promoted by documentation), introducing `onlinedischarge_onbattery` as the meaningful alias. [#2213] From accfd812df98719cf8c9485830e55f6224f9a1c8 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Fri, 22 Mar 2024 16:33:39 +0100 Subject: [PATCH 0121/1079] Makefile.am: clarify default "all" target variants Signed-off-by: Jim Klimov --- Makefile.am | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Makefile.am b/Makefile.am index 0453994435..9484e120ce 100644 --- a/Makefile.am +++ b/Makefile.am @@ -9,11 +9,13 @@ @NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export CCACHE_PATH=@CCACHE_PATH@ @NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export PATH=@PATH_DURING_CONFIGURE@ -# First target defines default behavior: all +# First target often defines default behavior: all # We follow up with another pass to `make doc` because our wild recipes # sometimes preclude generating all of them on the first pass (FIXME!) -# missing e.g. PDF and HTML which then pop up in `make check` footprint. -all: all-recursive +# missing e.g. PDF and HTML which then pop up in `make check` footprint, +# or misses a .prep-src-docs stage needed to pattern-make man page files +# with some "make" implementations... +all all-am-local all-local: doc all-recursive +@$(MAKE) $(AM_MAKEFLAGS) doc # include directory for aclocal From c86cded4db4ca77564764086305c764bb1693843 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Fri, 22 Mar 2024 16:34:12 +0100 Subject: [PATCH 0122/1079] Makefile.am: fix typo for "docs/man" prep for spellcheck target Signed-off-by: Jim Klimov --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 9484e120ce..b99db53a16 100644 --- a/Makefile.am +++ b/Makefile.am @@ -150,7 +150,7 @@ distclean-local: spellcheck spellcheck-interactive: +@RES=0; \ (cd $(builddir)/docs && $(MAKE) $(AM_MAKEFLAGS) -s $(abs_top_builddir)/docs/.prep-src-docs) || RES=$$? ; \ - (cd $(builddir)/docs/man && $(MAKE) $(AM_MAKEFLAGS) -s $(abs_top_builddir)/docs/.prep-src-docs) || RES=$$? ; \ + (cd $(builddir)/docs/man && $(MAKE) $(AM_MAKEFLAGS) -s $(abs_top_builddir)/docs/man/.prep-src-docs) || RES=$$? ; \ (cd $(builddir)/docs && $(MAKE) $(AM_MAKEFLAGS) -s $@) || RES=$$? ; \ (cd $(builddir)/docs/man && $(MAKE) $(AM_MAKEFLAGS) -s $@) || RES=$$? ; \ (cd $(builddir)/conf && $(MAKE) $(AM_MAKEFLAGS) -s $@) || RES=$$? ; \ From c64adb30533e14a52cda8b5c26bcaabbc815d8ff Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Fri, 22 Mar 2024 16:34:46 +0100 Subject: [PATCH 0123/1079] Makefile.am: be sure to prep before the many docs-related targets Signed-off-by: Jim Klimov --- Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile.am b/Makefile.am index b99db53a16..9e66b28179 100644 --- a/Makefile.am +++ b/Makefile.am @@ -177,6 +177,8 @@ spellcheck spellcheck-interactive: doc spellcheck-sortdict \ all-docs check-docs \ man all-man man-man check-man man-html all-html: + +cd $(builddir)/docs && $(MAKE) $(AM_MAKEFLAGS) -s $(abs_top_builddir)/docs/.prep-src-docs + +cd $(builddir)/docs/man && $(MAKE) $(AM_MAKEFLAGS) -s $(abs_top_builddir)/docs/man/.prep-src-docs +cd $(builddir)/docs && $(MAKE) $(AM_MAKEFLAGS) $@ INSTALL.nut UPGRADING NEWS README: From 7de34edc4037d758d9c6937e68030914839517a4 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Fri, 22 Mar 2024 16:35:24 +0100 Subject: [PATCH 0124/1079] docs/Makefile.am, docs/man/Makefile.am: clarify default "all" target variants as requiring a prep Signed-off-by: Jim Klimov --- docs/Makefile.am | 1 + docs/man/Makefile.am | 2 ++ 2 files changed, 3 insertions(+) diff --git a/docs/Makefile.am b/docs/Makefile.am index a49ec8ff57..3442b58833 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -131,6 +131,7 @@ endif WITH_SPELLCHECK check-local: $(CHECK_LOCAL_TARGETS) # Make sure sources are there for out-of-tree builds: +all-local all-am-local \ @DOC_BUILD_LIST@ $(ASCIIDOC_PDF) $(ASCIIDOC_HTML_SINGLE) $(ASCIIDOC_HTML_CHUNKED): $(abs_top_builddir)/docs/.prep-src-docs # This list is defined by configure script choices and options: diff --git a/docs/man/Makefile.am b/docs/man/Makefile.am index dbd3aff360..49db9b036e 100644 --- a/docs/man/Makefile.am +++ b/docs/man/Makefile.am @@ -22,6 +22,8 @@ EGREP = grep -E all: +all-am-local all-local: $(abs_top_builddir)/docs/man/.prep-src-docs + # Base configuration and client manpages, always installed SRC_CONF_PAGES = \ nut.conf.txt \ From 535e0f671269d9e970f53456856911284ba14f78 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Fri, 22 Mar 2024 21:01:20 +0100 Subject: [PATCH 0125/1079] Makefile.am, docs/Makefile.am: use abs_top_builddir for wrapper rules Signed-off-by: Jim Klimov --- Makefile.am | 8 ++++---- docs/Makefile.am | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Makefile.am b/Makefile.am index 9e66b28179..08de3eb46a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -177,12 +177,12 @@ spellcheck spellcheck-interactive: doc spellcheck-sortdict \ all-docs check-docs \ man all-man man-man check-man man-html all-html: - +cd $(builddir)/docs && $(MAKE) $(AM_MAKEFLAGS) -s $(abs_top_builddir)/docs/.prep-src-docs - +cd $(builddir)/docs/man && $(MAKE) $(AM_MAKEFLAGS) -s $(abs_top_builddir)/docs/man/.prep-src-docs - +cd $(builddir)/docs && $(MAKE) $(AM_MAKEFLAGS) $@ + +cd $(abs_top_builddir)/docs && $(MAKE) $(AM_MAKEFLAGS) -s $(abs_top_builddir)/docs/.prep-src-docs + +cd $(abs_top_builddir)/docs/man && $(MAKE) $(AM_MAKEFLAGS) -s $(abs_top_builddir)/docs/man/.prep-src-docs + +cd $(abs_top_builddir)/docs && $(MAKE) $(AM_MAKEFLAGS) $@ INSTALL.nut UPGRADING NEWS README: - +cd $(builddir)/docs && $(MAKE) $(AM_MAKEFLAGS) ../$(@F).adoc-parsed && cp -f ../$(@F).adoc-parsed ../$(@F) + +cd $(abs_top_builddir)/docs && $(MAKE) $(AM_MAKEFLAGS) ../$(@F).adoc-parsed && cp -f ../$(@F).adoc-parsed ../$(@F) # Workarounds for https://github.com/github/markup/issues/1095 # require direct definition of our attributes in each source diff --git a/docs/Makefile.am b/docs/Makefile.am index 3442b58833..36f1dbb34d 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -186,10 +186,10 @@ check-html-chunked: $(ASCIIDOC_HTML_CHUNKED) # chosen during configure script execution. The "all-man" and "all-html" # rules build everything documented. check-man all-man man-man all-html html-man: - +cd $(top_builddir)/docs/man/ && $(MAKE) $(AM_MAKEFLAGS) -f Makefile $@ + +cd $(abs_top_builddir)/docs/man/ && $(MAKE) $(AM_MAKEFLAGS) -f Makefile $@ man: - +cd $(top_builddir)/docs/man/ && $(MAKE) $(AM_MAKEFLAGS) -f Makefile all + +cd $(abs_top_builddir)/docs/man/ && $(MAKE) $(AM_MAKEFLAGS) -f Makefile all CLEANFILES = *.xml *.html *.pdf *-spellchecked docbook-xsl.css docinfo.xml.in.tmp CLEANFILES += $(top_builddir)/INSTALL.nut $(top_builddir)/UPGRADING $(top_builddir)/NEWS $(top_builddir)/ChangeLog.adoc $(top_builddir)/README From 0b38251f50ae9e3511e4be274fdb49830985b039 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 23 Mar 2024 18:15:31 +0100 Subject: [PATCH 0126/1079] tools/gitlog2changelog.py.in: trace absence of "unicode" type in some python bundles Signed-off-by: Jim Klimov --- tools/gitlog2changelog.py.in | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tools/gitlog2changelog.py.in b/tools/gitlog2changelog.py.in index 7518f6a5a8..2f4468dbf4 100755 --- a/tools/gitlog2changelog.py.in +++ b/tools/gitlog2changelog.py.in @@ -12,8 +12,15 @@ import subprocess # Python 3 compatibility hack try: + try: + import unicode + except: + # Maybe built-in? + pass unicode('') -except NameError: +except NameError as ex: + #DEBUG# sys.stderr.write("Using 'str' as 'unicode': %s\n" % str(ex)) + #DEBUG# sys.stderr.flush() unicode = str try: From 7dc1020c5321b15b4f62f094f5ab3a5d6f1c638d Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 23 Mar 2024 18:16:39 +0100 Subject: [PATCH 0127/1079] tools/gitlog2changelog.py.in: when authorMustBeASCII, only parse str via unicode() if we did not shortcut it earlier, and fix a typo in encoding value Signed-off-by: Jim Klimov --- tools/gitlog2changelog.py.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/gitlog2changelog.py.in b/tools/gitlog2changelog.py.in index 2f4468dbf4..889bf3793e 100755 --- a/tools/gitlog2changelog.py.in +++ b/tools/gitlog2changelog.py.in @@ -132,8 +132,8 @@ for line in fin: author = author[0 : len(author) - fin_chop] if authorMustBeASCII: try: - if isinstance(author, str): - author = unicodedata.normalize(u'NFKD', unicode(author, "UTF=8")).encode('ascii', 'ignore').decode('utf8') + if isinstance(author, str) and unicode != str: + author = unicodedata.normalize(u'NFKD', unicode(author, "utf-8")).encode('ascii', 'ignore').decode('utf8') else: author = unicodedata.normalize(u'NFKD', author).encode('ascii', 'ignore').decode('utf8') except Exception as e: From 69e7faef5efb9b6ed925ad5e0516ac17a3d58fa0 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 23 Mar 2024 18:29:12 +0100 Subject: [PATCH 0128/1079] UPGRADING.adoc, NEWS.adoc: mention changes in tools/gitlog2changelog.py.in [#2360, #2366] Signed-off-by: Jim Klimov --- NEWS.adoc | 6 ++++++ UPGRADING.adoc | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/NEWS.adoc b/NEWS.adoc index bb940c62ef..c96914f6b0 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -221,6 +221,12 @@ https://github.com/networkupstools/nut/milestone/10 known deficiencies in Windows platform support, as well as some un-awareness about configuration key words which appeared in NUT since 2013. [#2290] + - The `tools/gitlog2changelog.py.in` script was revised, in particular to + convert section titles (with contributor names coming from Git metadata) + into plain ASCII character set, for `dblatex` versions which do not allow + diacritics and other kinds of non-trivial characters in sections. This can + cause successful builds of `ChangeLog.pdf` file on more platforms, but at + expense of a semi-cosmetic difference in those names. [PR #2360, PR #2366] Release notes for NUT 2.8.1 - what's new since 2.8.0 ---------------------------------------------------- diff --git a/UPGRADING.adoc b/UPGRADING.adoc index cb89c907dd..fbbac8b3df 100644 --- a/UPGRADING.adoc +++ b/UPGRADING.adoc @@ -44,6 +44,13 @@ Changes from 2.8.1 to 2.8.2 appear as comments, or enabled by specifying the `-U` command-line option several times. [#2221] +- The `tools/gitlog2changelog.py.in` script was revised, in particular to + convert section titles (with contributor names) into plain ASCII character + set, for `dblatex` versions which do not allow diacritics and other kinds + of non-trivial characters in sections. A number of other projects seem to + use the NUT version of the script, and are encouraged to look at related + changes in `configure.ac` and `Makefile.am` recipes. [PR #2360, PR #2366] + Changes from 2.8.0 to 2.8.1 --------------------------- From a75a1d5f9e508e43f2941e62498c8e7c1a104537 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sun, 24 Mar 2024 14:37:22 +0100 Subject: [PATCH 0129/1079] drivers/riello_usb.c: comment the meaning of logical blocks changed by PR #1692 Signed-off-by: Jim Klimov --- drivers/riello_usb.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/riello_usb.c b/drivers/riello_usb.c index 58b995724e..3551c916fc 100644 --- a/drivers/riello_usb.c +++ b/drivers/riello_usb.c @@ -1107,6 +1107,9 @@ void upsdrv_updateinfo(void) dstate_setinfo("output.frequency", "%.2f", DevData.Fout/10.0); dstate_setinfo("battery.voltage", "%.1f", DevData.Ubat/10.0); if (localcalculation) { + /* NOTE: at this time "localcalculation" is a configuration toggle. + * Maybe later it can be replaced by a common "runtimecal" setting. */ + /* Considered "Ubat" physical range here is 10.7V to 12.9V: */ battcharge = ((DevData.Ubat <= 129) && (DevData.Ubat >=107)) ? (((DevData.Ubat-107)*100)/22) : ((DevData.Ubat < 107) ? 0 : 100); battruntime = (DevData.NomBatCap * DevData.NomUbat * 3600.0/DevData.NomPowerKW) * (battcharge/100.0); upsloadfactor = (DevData.Pout1 > 0) ? (DevData.Pout1/100.0) : 1; @@ -1123,12 +1126,18 @@ void upsdrv_updateinfo(void) localcalculation_logged = 1; } if ((DevData.BatCap < 0xFFFF) && (DevData.BatTime < 0xFFFF)) { + /* Use values reported by the driver unless they are marked + * invalid/unknown by HW/FW (all bits in the word are set). + */ dstate_setinfo("battery.charge", "%u", DevData.BatCap); dstate_setinfo("battery.runtime", "%u", DevData.BatTime*60); } } if (DevData.Tsystem == 255) { + /* Use values reported by the driver unless they are marked + * invalid/unknown by HW/FW (all bits in the word are set). + */ /*dstate_setinfo("ups.temperature", "%u", 0);*/ upsdebugx(4, "Reported temperature value is 0xFF, " "probably meaning \"-1\" for error or " From 0d84d795c0d5cc55bf5ba0e463e5a7bfbba6578f Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sun, 24 Mar 2024 14:49:15 +0100 Subject: [PATCH 0130/1079] drivers/riello_usb.c: bump (C) and DRIVER_VERSION for "localcalculation" related support [#1692] Signed-off-by: Jim Klimov --- drivers/riello_usb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/riello_usb.c b/drivers/riello_usb.c index 3551c916fc..cb81a6477e 100644 --- a/drivers/riello_usb.c +++ b/drivers/riello_usb.c @@ -8,6 +8,8 @@ * * Copyright (C) 2012 - Elio Parisi * Copyright (C) 2016 Eaton + * Copyright (C) 2022-2024 "amikot" + * Copyright (C) 2022-2024 Jim Klimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,7 +36,7 @@ #include "riello.h" #define DRIVER_NAME "Riello USB driver" -#define DRIVER_VERSION "0.11" +#define DRIVER_VERSION "0.12" #define DEFAULT_OFFDELAY 5 /*!< seconds (max 0xFF) */ #define DEFAULT_BOOTDELAY 5 /*!< seconds (max 0xFF) */ From 648010c213c689a06acdd3af83e5ea54766f21c2 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sun, 24 Mar 2024 15:13:34 +0100 Subject: [PATCH 0131/1079] drivers/riello_usb.c, docs/man/riello_usb.txt: allow configurable battery.voltage.low/.high for localcalculation guesstimates [#1692] Signed-off-by: Jim Klimov --- docs/man/riello_usb.txt | 21 +++++++++++++-------- drivers/riello_usb.c | 41 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/docs/man/riello_usb.txt b/docs/man/riello_usb.txt index 71bfb95ed3..5bd2f30309 100644 --- a/docs/man/riello_usb.txt +++ b/docs/man/riello_usb.txt @@ -32,17 +32,22 @@ include::nut_usb_addvars.txt[] EXTRA ARGUMENTS --------------- -You may need to tweak some settings, depending on the make and model of your UPS -(see linkman:ups.conf[5]): +You may need to tweak some settings, depending on the make and model of your +UPS (see linkman:ups.conf[5]): *localcalculation*:: -When enabled, driver will calculate values of `battery.runtime` and `battery.charge` -locally. This is for some Riello models (iPlug and iDialog series) that provide -incorrect values. Local calculation is done according to nominal battery capacity, -nominal battery voltage, actual battery charge, maximum and actual UPS load. +When enabled, driver will calculate values of `battery.runtime` and +`battery.charge` "locally" in the driver. This is for some Riello models +(iPlug and iDialog series) which provide incorrect values in hardware readings. +This "local calculation" is done according to nominal battery capacity, nominal +battery voltage, actual battery charge, maximum and actual UPS load. + -Lead battery charge graph is not linear, so guesstimated charge value may not be -perfectly accurate. However it should be good enough to determine battery +You may want to also configure 'default.battery.voltage.low' and +'default.battery.voltage.high' in case the built-in default range +(from 10.7V to 12.9V) does not match your hardware. ++ +NOTE: Lead (PbAc) battery charge graph is not linear, so guesstimated charge value may +not be perfectly accurate. However it should be good enough to determine battery actual status and roughly estimate the time it can power the system. + WARNING: This keyword may be deprecated in future releases of the driver, in favor of diff --git a/drivers/riello_usb.c b/drivers/riello_usb.c index cb81a6477e..528d251158 100644 --- a/drivers/riello_usb.c +++ b/drivers/riello_usb.c @@ -73,6 +73,8 @@ static USBDeviceMatcher_t *regex_matcher = NULL; /* Flag for estimation of battery.runtime and battery.charge */ static int localcalculation = 0; static int localcalculation_logged = 0; +static double batt_volt_low = 10.7; +static double batt_volt_high = 12.9; static int (*subdriver_command)(uint8_t *cmd, uint8_t *buf, uint16_t length, uint16_t buflen) = NULL; @@ -961,7 +963,9 @@ void upsdrv_initinfo(void) if (testvar("localcalculation")) { localcalculation = 1; upsdebugx(1, "Will guesstimate battery charge and runtime " - "instead of trusting device readings (if any)"); + "instead of trusting device readings (if any); " + "consider also setting default.battery.voltage.low " + "and default.battery.voltage.high for this device"); } dstate_setinfo("driver.parameter.localcalculation", "%d", localcalculation); @@ -1074,6 +1078,7 @@ void upsdrv_updateinfo(void) int battcharge; float battruntime; float upsloadfactor; + const char *val = NULL; upsdebugx(1, "countlost %d",countlost); @@ -1108,11 +1113,39 @@ void upsdrv_updateinfo(void) dstate_setinfo("input.bypass.frequency", "%.2f", DevData.Fbypass/10.0); dstate_setinfo("output.frequency", "%.2f", DevData.Fout/10.0); dstate_setinfo("battery.voltage", "%.1f", DevData.Ubat/10.0); + + /* Can be set via default.* or override.* driver options + * if not served by the device HW/FW */ + val = dstate_getinfo("battery.voltage.low"); + if (val) { + batt_volt_low = strtod(val, NULL); + } + + val = dstate_getinfo("battery.voltage.high"); + if (val) { + batt_volt_high = strtod(val, NULL); + } + if (localcalculation) { /* NOTE: at this time "localcalculation" is a configuration toggle. - * Maybe later it can be replaced by a common "runtimecal" setting. */ - /* Considered "Ubat" physical range here is 10.7V to 12.9V: */ - battcharge = ((DevData.Ubat <= 129) && (DevData.Ubat >=107)) ? (((DevData.Ubat-107)*100)/22) : ((DevData.Ubat < 107) ? 0 : 100); + * Maybe later it can be replaced by a common "runtimecal" setting. */ + /* Considered "Ubat" physical range here is e.g. 10.7V to 12.9V + * seen as "107" or "129" integers in the DevData properties: */ + uint16_t Ubat_low = batt_volt_low * 10; /* e.g. 107 */ + uint16_t Ubat_high = batt_volt_high * 10; /* e.g. 129 */ + static int batt_volt_logged = 0; + + if (!batt_volt_logged) { + upsdebugx(0, "\nUsing battery.voltage.low=%.1f and " + "battery.voltage.high=%.1f for \"localcalculation\" " + "guesstimates of battery.charge and battery.runtime", + batt_volt_low, batt_volt_high); + batt_volt_logged = 1; + } + + battcharge = ((DevData.Ubat <= Ubat_high) && (DevData.Ubat >= Ubat_low)) + ? (((DevData.Ubat - Ubat_low)*100) / (Ubat_high - Ubat_low)) + : ((DevData.Ubat < Ubat_low) ? 0 : 100); battruntime = (DevData.NomBatCap * DevData.NomUbat * 3600.0/DevData.NomPowerKW) * (battcharge/100.0); upsloadfactor = (DevData.Pout1 > 0) ? (DevData.Pout1/100.0) : 1; From 68e4c83240601bc517e8b25b570abcf6a1bda861 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sun, 24 Mar 2024 16:08:20 +0100 Subject: [PATCH 0132/1079] drivers/riello_usb.c, docs/man/riello_usb.txt: pick battery low/high range via known or configured battery.voltage.nominal [#1692] Signed-off-by: Jim Klimov --- docs/man/riello_usb.txt | 4 +- drivers/riello_usb.c | 84 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 85 insertions(+), 3 deletions(-) diff --git a/docs/man/riello_usb.txt b/docs/man/riello_usb.txt index 5bd2f30309..8e6e282c24 100644 --- a/docs/man/riello_usb.txt +++ b/docs/man/riello_usb.txt @@ -44,7 +44,9 @@ battery voltage, actual battery charge, maximum and actual UPS load. + You may want to also configure 'default.battery.voltage.low' and 'default.battery.voltage.high' in case the built-in default range -(from 10.7V to 12.9V) does not match your hardware. +(from 10.7V to 12.9V) does not match your hardware, or give a shot +to 'default.battery.voltage.nominal' (e.g. '24') if your device does +not serve that either. + NOTE: Lead (PbAc) battery charge graph is not linear, so guesstimated charge value may not be perfectly accurate. However it should be good enough to determine battery diff --git a/drivers/riello_usb.c b/drivers/riello_usb.c index 528d251158..a30075ec25 100644 --- a/drivers/riello_usb.c +++ b/drivers/riello_usb.c @@ -73,6 +73,9 @@ static USBDeviceMatcher_t *regex_matcher = NULL; /* Flag for estimation of battery.runtime and battery.charge */ static int localcalculation = 0; static int localcalculation_logged = 0; +/* NOTE: Do not change these default, they refer to battery.voltage.nominal=12.0 + * and used in related maths later */ +static double batt_volt_nom = 12.0; static double batt_volt_low = 10.7; static double batt_volt_high = 12.9; @@ -950,6 +953,7 @@ void upsdrv_initups(void) void upsdrv_initinfo(void) { int ret; + const char *valN = NULL, *valL = NULL, *valH = NULL; ret = start_ups_comm(); @@ -997,15 +1001,87 @@ void upsdrv_initinfo(void) dstate_setinfo("ups.serial", "%s", (unsigned char*) DevData.Identification); dstate_setinfo("ups.firmware", "%s", (unsigned char*) DevData.Version); + /* Is it set by user default/override configuration? + * NOTE: "valN" is also used for a check just below. + */ + valN = dstate_getinfo("battery.voltage.nominal"); + if (valN) { + batt_volt_nom = strtod(valN, NULL); + upsdebugx(1, "Using battery.voltage.nominal=%.1f " + "likely coming from user configuration", + batt_volt_nom); + } + if (get_ups_nominal() == 0) { dstate_setinfo("ups.realpower.nominal", "%u", DevData.NomPowerKW); dstate_setinfo("ups.power.nominal", "%u", DevData.NomPowerKVA); dstate_setinfo("output.voltage.nominal", "%u", DevData.NominalUout); dstate_setinfo("output.frequency.nominal", "%.1f", DevData.NomFout/10.0); - dstate_setinfo("battery.voltage.nominal", "%u", DevData.NomUbat); + + /* Is it set by user default/override configuration (see just above)? */ + if (valN) { + upsdebugx(1, "...instead of battery.voltage.nominal=%u " + "reported by the device", DevData.NomUbat); + } else { + dstate_setinfo("battery.voltage.nominal", "%u", DevData.NomUbat); + batt_volt_nom = (double)DevData.NomUbat; + } + dstate_setinfo("battery.capacity", "%u", DevData.NomBatCap); + } else { + /* TOTHINK: Check the momentary reading of battery.voltage + * or would it be too confusing (especially if it is above + * 12V and might correspond to a discharged UPS when the + * driver starts up after an outage?) + * NOTE: DevData.Ubat would be scaled by 10! + */ + if (!valN) { + /* The nominal was not already set by user configuration... */ + upsdebugx(1, "Using built-in default battery.voltage.nominal=%.1f", + batt_volt_nom); + dstate_setinfo("battery.voltage.nominal", "%.1f", batt_volt_nom); + } } + /* We have a nominal voltage by now - either from user configuration + * or from the device itself (or initial defaults for 12V). Do we have + * any low/high range from HW/FW or defaults from ups.conf? */ + valL = dstate_getinfo("battery.voltage.low"); + valH = dstate_getinfo("battery.voltage.high"); + + if (!valL && !valH) { + /* Both not set (NULL) => pick by nominal (X times 12V). + * Pick a suitable low/high range (or keep built-in default). + */ + int times12 = batt_volt_nom / 12; + if (times12 > 1) { + /* Scale up the range for 24V (X=2) etc. */ + upsdebugx(1, "Using %i times the voltage range of 12V PbAc battery", times12); + batt_volt_low *= times12; + batt_volt_high *= times12; + } + } else { + /* If just one of those is set, then what? */ + if (valL || valH) { + upsdebugx(1, "WARNING: Only one of battery.voltage.low=%.1f " + "or battery.voltage.high=%.1f is set via " + "driver configuration; keeping the other " + "at built-in default value (and not aligning " + "with battery.voltage.nominal=%.1f)", + batt_volt_low, batt_volt_high, batt_volt_nom); + } else { + upsdebugx(1, "Both of battery.voltage.low=%.1f " + "or battery.voltage.high=%.1f are set via " + "driver configuration; not aligning " + "with battery.voltage.nominal=%.1f", + batt_volt_low, batt_volt_high, batt_volt_nom); + } + } + + /* Whatever the origin, make the values known via dstate */ + dstate_setinfo("battery.voltage.low", "%.1f", batt_volt_low); + dstate_setinfo("battery.voltage.high", "%.1f", batt_volt_high); + /* commands ----------------------------------------------- */ dstate_addcmd("load.off"); dstate_addcmd("load.on"); @@ -1078,7 +1154,9 @@ void upsdrv_updateinfo(void) int battcharge; float battruntime; float upsloadfactor; +#ifdef RIELLO_DYNAMIC_BATTVOLT_INFO const char *val = NULL; +#endif upsdebugx(1, "countlost %d",countlost); @@ -1114,6 +1192,7 @@ void upsdrv_updateinfo(void) dstate_setinfo("output.frequency", "%.2f", DevData.Fout/10.0); dstate_setinfo("battery.voltage", "%.1f", DevData.Ubat/10.0); +#ifdef RIELLO_DYNAMIC_BATTVOLT_INFO /* Can be set via default.* or override.* driver options * if not served by the device HW/FW */ val = dstate_getinfo("battery.voltage.low"); @@ -1125,11 +1204,12 @@ void upsdrv_updateinfo(void) if (val) { batt_volt_high = strtod(val, NULL); } +#endif if (localcalculation) { /* NOTE: at this time "localcalculation" is a configuration toggle. * Maybe later it can be replaced by a common "runtimecal" setting. */ - /* Considered "Ubat" physical range here is e.g. 10.7V to 12.9V + /* Considered "Ubat" physical range here (e.g. 10.7V to 12.9V) is * seen as "107" or "129" integers in the DevData properties: */ uint16_t Ubat_low = batt_volt_low * 10; /* e.g. 107 */ uint16_t Ubat_high = batt_volt_high * 10; /* e.g. 129 */ From 9bb7a0c6cb0309768ad1a965b261bcbf88aeb3f6 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sun, 24 Mar 2024 16:12:48 +0100 Subject: [PATCH 0133/1079] drivers/riello_usb.c: extend built-in default battery low/high range to match nutdrv_qx data for PbAc batteries [#1692] Signed-off-by: Jim Klimov --- drivers/riello_usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/riello_usb.c b/drivers/riello_usb.c index a30075ec25..4d321d0d28 100644 --- a/drivers/riello_usb.c +++ b/drivers/riello_usb.c @@ -76,8 +76,8 @@ static int localcalculation_logged = 0; /* NOTE: Do not change these default, they refer to battery.voltage.nominal=12.0 * and used in related maths later */ static double batt_volt_nom = 12.0; -static double batt_volt_low = 10.7; -static double batt_volt_high = 12.9; +static double batt_volt_low = 10.4; +static double batt_volt_high = 13.0; static int (*subdriver_command)(uint8_t *cmd, uint8_t *buf, uint16_t length, uint16_t buflen) = NULL; From d6f69345bf8832a5b255c0f1abf5d5beb818a30f Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 25 Mar 2024 14:00:04 +0100 Subject: [PATCH 0134/1079] drivers/belkin-hid.c: update (C) heading [#2369 follow-up] Signed-off-by: Jim Klimov --- drivers/belkin-hid.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/belkin-hid.c b/drivers/belkin-hid.c index ad32335b45..5da14d896d 100644 --- a/drivers/belkin-hid.c +++ b/drivers/belkin-hid.c @@ -3,7 +3,8 @@ * Copyright (C) * 2003 - 2008 Arnaud Quette * 2005 Peter Selinger - * 2011, 2014 Charles Lepple + * 2011, 2014 Charles Lepple + * 2024 James R. Parks * * Sponsored by MGE UPS SYSTEMS * From a2d112d46e3cfea82288aa2acbab72c715d97f27 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 25 Mar 2024 14:04:25 +0100 Subject: [PATCH 0135/1079] drivers/belkin-hid.c: whitespace fix Signed-off-by: Jim Klimov --- drivers/belkin-hid.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/belkin-hid.c b/drivers/belkin-hid.c index 5da14d896d..7c45bab95f 100644 --- a/drivers/belkin-hid.c +++ b/drivers/belkin-hid.c @@ -98,23 +98,23 @@ static info_lkp_t liebert_online_info[] = { }; static info_lkp_t liebert_discharging_info[] = { - { 0, NULL, liebert_discharging_fun, NULL } + { 0, NULL, liebert_discharging_fun, NULL } }; static info_lkp_t liebert_charging_info[] = { - { 0, NULL, liebert_charging_fun, NULL } + { 0, NULL, liebert_charging_fun, NULL } }; static info_lkp_t liebert_lowbatt_info[] = { - { 0, NULL, liebert_lowbatt_fun, NULL } + { 0, NULL, liebert_lowbatt_fun, NULL } }; static info_lkp_t liebert_replacebatt_info[] = { - { 0, NULL, liebert_replacebatt_fun, NULL } + { 0, NULL, liebert_replacebatt_fun, NULL } }; static info_lkp_t liebert_shutdownimm_info[] = { - { 0, NULL, liebert_shutdownimm_fun, NULL } + { 0, NULL, liebert_shutdownimm_fun, NULL } }; static info_lkp_t liebert_config_voltage_info[] = { From c0d0bdf0ca40067a796ac30f47f5a4770fce9c82 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 25 Mar 2024 11:56:00 +0100 Subject: [PATCH 0136/1079] Add unit tests for belkin-hid liebert_line_voltage_fun() and related methods [#2370] Signed-off-by: Jim Klimov --- drivers/belkin-hid.c | 32 ++++--- tests/.gitignore | 4 + tests/Makefile.am | 22 ++++- tests/driver-stub-usb.c | 67 +++++++++++++ tests/getexponenttest.c | 207 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 315 insertions(+), 17 deletions(-) create mode 100644 tests/driver-stub-usb.c create mode 100644 tests/getexponenttest.c diff --git a/drivers/belkin-hid.c b/drivers/belkin-hid.c index 7c45bab95f..857cf58c1f 100644 --- a/drivers/belkin-hid.c +++ b/drivers/belkin-hid.c @@ -5,6 +5,7 @@ * 2005 Peter Selinger * 2011, 2014 Charles Lepple * 2024 James R. Parks + * 2024 Jim Klimov * * Sponsored by MGE UPS SYSTEMS * @@ -32,7 +33,7 @@ #include /* for fabs() */ -#define BELKIN_HID_VERSION "Belkin/Liebert HID 0.20" +#define BELKIN_HID_VERSION "Belkin/Liebert HID 0.21" /* Belkin */ #define BELKIN_VENDORID 0x050d @@ -89,9 +90,19 @@ static const char *liebert_charging_fun(double value); static const char *liebert_lowbatt_fun(double value); static const char *liebert_replacebatt_fun(double value); static const char *liebert_shutdownimm_fun(double value); -static const char *liebert_config_voltage_fun(double value); -static const char *liebert_line_voltage_fun(double value); -static const char *liebert_psi5_line_voltage_fun(double value); + +/* These lookup functions also cover the 1e-7 factor which seems to + * be due to a broken report descriptor in certain Liebert units. + * Exposed for unit testing - not "static" */ +const char *liebert_config_voltage_fun(double value); +const char *liebert_line_voltage_fun(double value); +const char *liebert_psi5_line_voltage_fun(double value); + +extern double liebert_config_voltage_mult, liebert_line_voltage_mult; +double liebert_config_voltage_mult = 1.0; +double liebert_line_voltage_mult = 1.0; +static char liebert_conversion_buf[10]; + static info_lkp_t liebert_online_info[] = { { 0, NULL, liebert_online_fun, NULL } @@ -129,13 +140,6 @@ static info_lkp_t liebert_psi5_line_voltage_info[] = { { 0, NULL, liebert_psi5_line_voltage_fun, NULL }, }; -static double liebert_config_voltage_mult = 1.0; -static double liebert_line_voltage_mult = 1.0; -static char liebert_conversion_buf[10]; - -/* These lookup functions also cover the 1e-7 factor which seems to be due to a - * broken report descriptor in certain Liebert units. - */ static const char *liebert_online_fun(double value) { return value ? "online" : "!online"; @@ -170,7 +174,7 @@ static const char *liebert_shutdownimm_fun(double value) * Logic is weird since the ConfigVoltage item comes after InputVoltage and * OutputVoltage. */ -static const char *liebert_config_voltage_fun(double value) +const char *liebert_config_voltage_fun(double value) { if( value < 1 ) { if( fabs(value - 1e-7) < 1e-9 ) { @@ -188,7 +192,7 @@ static const char *liebert_config_voltage_fun(double value) return liebert_conversion_buf; } -static const char *liebert_line_voltage_fun(double value) +const char *liebert_line_voltage_fun(double value) { if( value < 1 ) { if( fabs(value - 1e-7) < 1e-9 ) { @@ -205,7 +209,7 @@ static const char *liebert_line_voltage_fun(double value) return liebert_conversion_buf; } -static const char *liebert_psi5_line_voltage_fun(double value) +const char *liebert_psi5_line_voltage_fun(double value) { if( value < 1 ) { if( fabs(value - 1e-3) < 1e-3 ) { diff --git a/tests/.gitignore b/tests/.gitignore index 876e375e29..1036cac317 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -16,6 +16,10 @@ /nuttimetest /nuttimetest.log /nuttimetest.trs +/getexponenttest +/getexponenttest.log +/getexponenttest.trs +/belkin-hid.c /getvaluetest /getvaluetest.log /getvaluetest.trs diff --git a/tests/Makefile.am b/tests/Makefile.am index f328d3029c..94588ce202 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -16,6 +16,7 @@ all: $(TESTS) EXTRA_DIST = nut-driver-enumerator-test.sh nut-driver-enumerator-test--ups.conf TESTS = +noinst_LTLIBRARIES = CLEANFILES = *.trs *.log AM_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/drivers @@ -57,15 +58,29 @@ nuttimetest_SOURCES = nuttimetest.c nuttimetest_LDADD = $(top_builddir)/common/libcommon.la # Separate the .deps of other dirs from this one -LINKED_SOURCE_FILES = hidparser.c +LINKED_SOURCE_FILES = hidparser.c belkin-hid.c # NOTE: Not using "$<" due to a legacy Sun/illumos dmake bug with resolver # of dynamic vars, see e.g. https://man.omnios.org/man1/make#BUGS hidparser.c: $(top_srcdir)/drivers/hidparser.c test -s "$@" || ln -s -f "$(top_srcdir)/drivers/hidparser.c" "$@" +belkin-hid.c: $(top_srcdir)/drivers/belkin-hid.c + test -s "$@" || ln -s -f "$(top_srcdir)/drivers/belkin-hid.c" "$@" + if WITH_USB -TESTS += getvaluetest +TESTS += getvaluetest getexponenttest + +# We only need to call a few methods, not use the whole source - so +# not linking it as a getvaluetest_SOURCE file (has too many deps): +noinst_LTLIBRARIES += libbelkin.la +nodist_libbelkin_la_SOURCES = belkin-hid.c driver-stub-usb.c +libbelkin_la_CFLAGS = $(AM_CFLAGS) $(LIBUSB_CFLAGS) +libbelkin_la_LIBADD = $(top_builddir)/common/libcommon.la + +getexponenttest_SOURCES = getexponenttest.c +#getexponenttest_CFLAGS = $(AM_CFLAGS) $(LIBUSB_CFLAGS) +getexponenttest_LDADD = $(top_builddir)/common/libcommon.la libbelkin.la getvaluetest_SOURCES = getvaluetest.c nodist_getvaluetest_SOURCES = hidparser.c @@ -73,7 +88,7 @@ nodist_getvaluetest_SOURCES = hidparser.c getvaluetest_CFLAGS = $(AM_CFLAGS) $(LIBUSB_CFLAGS) getvaluetest_LDADD = $(top_builddir)/common/libcommon.la else !WITH_USB -EXTRA_DIST += getvaluetest.c hidparser.c +EXTRA_DIST += getvaluetest.c hidparser.c belkin-hid.c endif !WITH_USB if WITH_GPIO @@ -101,6 +116,7 @@ EXTRA_DIST += generic_gpio_utest.h generic_gpio_test.txt # Make sure out-of-dir dependencies exist (especially when dev-building parts): $(top_builddir)/drivers/libdummy_mockdrv.la \ $(top_builddir)/common/libnutconf.la \ +$(top_builddir)/common/libcommonclient.la \ $(top_builddir)/common/libcommon.la: dummy +@cd $(@D) && $(MAKE) $(AM_MAKEFLAGS) $(@F) diff --git a/tests/driver-stub-usb.c b/tests/driver-stub-usb.c new file mode 100644 index 0000000000..e483eea41d --- /dev/null +++ b/tests/driver-stub-usb.c @@ -0,0 +1,67 @@ +/* placeholder method implementations to just link the libbelkin stub + * and eventually similar code by directly using driver source code + * for almost-in-vivo testing (and minimal intrusion to that codebase). + * See also: getexponenttest.c + * + * Copyright (C) + * 2024 Jim Klimov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "common.h" + +#include "usb-common.h" +int is_usb_device_supported(usb_device_id_t *usb_device_id_list, USBDevice_t *device) { + NUT_UNUSED_VARIABLE(usb_device_id_list); + NUT_UNUSED_VARIABLE(device); + return -1; +} + +#include "usbhid-ups.h" +hid_dev_handle_t udev = HID_DEV_HANDLE_CLOSED; +info_lkp_t beeper_info[] = { { 0, NULL, NULL, NULL } }; +info_lkp_t date_conversion[] = { { 0, NULL, NULL, NULL } }; +info_lkp_t stringid_conversion[] = { { 0, NULL, NULL, NULL } }; +info_lkp_t divide_by_10_conversion[] = { { 0, NULL, NULL, NULL } }; +info_lkp_t divide_by_100_conversion[] = { { 0, NULL, NULL, NULL } }; + +void possibly_supported(const char *mfr, HIDDevice_t *hd) { + NUT_UNUSED_VARIABLE(mfr); + NUT_UNUSED_VARIABLE(hd); +} + +int fix_report_desc(HIDDevice_t *arg_pDev, HIDDesc_t *arg_pDesc) { + NUT_UNUSED_VARIABLE(arg_pDev); + NUT_UNUSED_VARIABLE(arg_pDesc); + return -1; +} + +#include "libhid.h" +usage_lkp_t hid_usage_lkp[] = { {NULL, 0} }; +char *HIDGetItemString(hid_dev_handle_t arg_udev, const char *hidpath, char *buf, size_t buflen, usage_tables_t *utab) { + NUT_UNUSED_VARIABLE(arg_udev); + NUT_UNUSED_VARIABLE(hidpath); + NUT_UNUSED_VARIABLE(buf); + NUT_UNUSED_VARIABLE(buflen); + NUT_UNUSED_VARIABLE(utab); + return NULL; +} + +#include "main.h" +char *getval(const char *var) { + NUT_UNUSED_VARIABLE(var); + return NULL; +} diff --git a/tests/getexponenttest.c b/tests/getexponenttest.c new file mode 100644 index 0000000000..94d082ac31 --- /dev/null +++ b/tests/getexponenttest.c @@ -0,0 +1,207 @@ +/* getexponenttest - check detection of correct multiplication exponent value + * for miniscule readings from USB HID (as used in e.g. drivers/belkin-hid.c + * subdriver). Eventually may be extended to similar tests for other driver + * methods. + * + * See also: + * https://github.com/networkupstools/nut/issues/2370 + * + * Copyright (C) + * 2024 Jim Klimov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include "nut_stdint.h" +#include +#include +#include +#include "common.h" + +/* from drivers/belkin-hid.c: */ +extern double liebert_config_voltage_mult, liebert_line_voltage_mult; +const char *liebert_config_voltage_fun(double value); +const char *liebert_line_voltage_fun(double value); +const char *liebert_psi5_line_voltage_fun(double value); + +static void Usage(char *name) { +/* + printf("%s {-c | -l | -p } \n", name); + printf("\n"); + printf("%s -c 12\n", name); + printf("%s -p 0.001212\n", name); + printf("%s -l 1.39e-06\n", name); +*/ + printf("%s\nIf no arguments are given a builtin set of tests are run.\n", name); +} + +static int RunBuiltInTests(char *argv[]) { + int exitStatus = 0; + size_t i; + + double rawValue, value, mult; + const char *valueStr; + + static char* methodName[3] = { + "liebert_config_voltage_mult() ", + "liebert_line_voltage_mult() ", + "liebert_psi5_line_voltage_mult()" + }; + + static struct { + char *buf; /* raw voltage as a string (from CLI input, e.g. NUT driver log trace) */ + double expectedRawValue; /* parsed raw voltage (as seen in USB HID reports) */ + char type; /* 1 = config, 2 = line, 3 = PSI5 line */ + double expectedMult; /* expected liebert_config_voltage_mult or liebert_line_voltage_mult */ + double expectedValue; /* the expected result of decoding the value in the buffer */ + } testData[] = { + {.buf = "0.000273", .expectedRawValue = 0.000273, .type = 3, .expectedMult = 1e5, .expectedValue = 27.3 }, + {.buf = "0.001212", .expectedRawValue = 0.001212, .type = 3, .expectedMult = 1e5, .expectedValue = 121.2 }, + + {.buf = "1.39e-06", .expectedRawValue = 0.00000139, .type = 2, .expectedMult = 1e7, .expectedValue = 13.9 }, + {.buf = "2.201e-05", .expectedRawValue = 0.00002201, .type = 2, .expectedMult = 1e7, .expectedValue = 220.1 }, + + /* Edge cases - what should not be converted (good enough already) */ + {.buf = "12", .expectedRawValue = 12.0, .type = 3, .expectedMult = 1, .expectedValue = 12.0 }, + {.buf = "12.3", .expectedRawValue = 12.3, .type = 3, .expectedMult = 1, .expectedValue = 12.3 }, + {.buf = "232.1", .expectedRawValue = 232.1, .type = 3, .expectedMult = 1, .expectedValue = 232.1 }, + {.buf = "240", .expectedRawValue = 240.0, .type = 3, .expectedMult = 1, .expectedValue = 240.0 }, + + {.buf = "12", .expectedRawValue = 12.0, .type = 2, .expectedMult = 1, .expectedValue = 12.0 }, + {.buf = "12.3", .expectedRawValue = 12.3, .type = 2, .expectedMult = 1, .expectedValue = 12.3 }, + {.buf = "232.1", .expectedRawValue = 232.1, .type = 2, .expectedMult = 1, .expectedValue = 232.1 }, + {.buf = "240", .expectedRawValue = 240.0, .type = 2, .expectedMult = 1, .expectedValue = 240.0 }, + + /* Config values (nominal battery/input/... voltage) are often integers: */ + {.buf = "24", .expectedRawValue = 24.0, .type = 1, .expectedMult = 1, .expectedValue = 24.0 }, + {.buf = "120", .expectedRawValue = 120.0, .type = 1, .expectedMult = 1, .expectedValue = 120.0 } + }; + + NUT_UNUSED_VARIABLE(argv); + + for (i = 0; i < SIZEOF_ARRAY(testData); i++) { + liebert_line_voltage_mult = 1.0; + liebert_config_voltage_mult = 1.0; + + rawValue = strtod(testData[i].buf, NULL); + if (rawValue != testData[i].expectedRawValue) { + printf(" value '%s' parsing FAIL: got %g expected %g\n", + testData[i].buf, rawValue, testData[i].expectedRawValue); + /* Fix testData definition! */ + exitStatus = 1; + } + + switch (testData[i].type) { + case 1: + valueStr = liebert_config_voltage_fun(rawValue); + mult = liebert_config_voltage_mult; + /* NOTE: The method does also set a default + * liebert_line_voltage_mult if config voltage + * is miniscule and not a plain integer */ + break; + + case 2: + valueStr = liebert_line_voltage_fun(rawValue); + mult = liebert_line_voltage_mult; + break; + + case 3: + valueStr = liebert_psi5_line_voltage_fun(rawValue); + mult = liebert_line_voltage_mult; + break; + + default: + printf(" invalid entry\n"); + continue; + } + + printf("Test #%" PRIiSIZE " \t", i + 1); + value = strtod(valueStr, NULL); + if (value == testData[i].expectedValue && mult == testData[i].expectedMult) { + printf("%s\tGOT value %9g\tmult %6g PASS\n", + (testData[i].type < 1 || testData[i].type > 3 ? "" : methodName[testData[i].type - 1]), + value, mult); + } else { + printf("%s\tGOT value %9g\tmult %6g FAIL" + "\tEXPECTED v=%7g\tm=%7g" + "\tORIGINAL (string)'%s'\t=> (double)%g\n", + (testData[i].type < 1 || testData[i].type > 3 ? "" : methodName[testData[i].type - 1]), + value, mult, + testData[i].expectedValue, + testData[i].expectedMult, + testData[i].buf, rawValue); + exitStatus = 1; + } + } + + return (exitStatus); +} + +/* +static int RunCommandLineTest(char *argv[]) { + uint8_t reportBuf[64]; + size_t bufSize; + char *start, *end; + HIDData_t data; + long value, expectedValue; + + start = argv[1]; + end = NULL; + for (bufSize = 0; *start != 0; bufSize++) { + reportBuf[bufSize] = (uint8_t) strtol(start, (char **)&end, 16); + if (start == end) break; + start = end; + } + memset((void *)&data, 0, sizeof(data)); + data.Offset = (uint8_t) atoi(argv[2]); + data.Size = (uint8_t) atoi(argv[3]); + data.LogMin = strtol(argv[4], 0, 0); + data.LogMax = strtol(argv[5], 0, 0); + expectedValue = strtol(argv[6], 0, 0); + + GetValue(reportBuf, &data, &value); + + printf("Test #0 "); + PrintBufAndData(reportBuf, bufSize, &data); + if (value == expectedValue) { + printf(" value %ld PASS\n", value); + return (0); + } else { + printf(" value %ld FAIL expected %ld\n", value, expectedValue); + return (1); + } +} +*/ + +int main (int argc, char *argv[]) { + int status; + + switch (argc) { + case 1: + status = RunBuiltInTests(argv); + break; +/* + case 7: + status = RunCommandLineTest(argv); + break; +*/ + default: + Usage(argv[0]); + status = 2; + } + return(status); +} From 6fc102468f162c85a92e7cb450817ed4bb3be631 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 25 Mar 2024 17:18:27 +0100 Subject: [PATCH 0137/1079] drivers/belkin-hid.c: Revert modifications for unit-testing, arrange its build differently [#2371] Signed-off-by: Jim Klimov --- drivers/belkin-hid.c | 20 +++++++++----------- tests/Makefile.am | 13 +++++++------ tests/driver-stub-usb.c | 4 ++-- tests/getexponenttest.c | 4 +++- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/drivers/belkin-hid.c b/drivers/belkin-hid.c index 857cf58c1f..552ad400a2 100644 --- a/drivers/belkin-hid.c +++ b/drivers/belkin-hid.c @@ -33,7 +33,7 @@ #include /* for fabs() */ -#define BELKIN_HID_VERSION "Belkin/Liebert HID 0.21" +#define BELKIN_HID_VERSION "Belkin/Liebert HID 0.20" /* Belkin */ #define BELKIN_VENDORID 0x050d @@ -94,16 +94,14 @@ static const char *liebert_shutdownimm_fun(double value); /* These lookup functions also cover the 1e-7 factor which seems to * be due to a broken report descriptor in certain Liebert units. * Exposed for unit testing - not "static" */ -const char *liebert_config_voltage_fun(double value); -const char *liebert_line_voltage_fun(double value); -const char *liebert_psi5_line_voltage_fun(double value); +static const char *liebert_config_voltage_fun(double value); +static const char *liebert_line_voltage_fun(double value); +static const char *liebert_psi5_line_voltage_fun(double value); -extern double liebert_config_voltage_mult, liebert_line_voltage_mult; -double liebert_config_voltage_mult = 1.0; -double liebert_line_voltage_mult = 1.0; +static double liebert_config_voltage_mult = 1.0; +static double liebert_line_voltage_mult = 1.0; static char liebert_conversion_buf[10]; - static info_lkp_t liebert_online_info[] = { { 0, NULL, liebert_online_fun, NULL } }; @@ -174,7 +172,7 @@ static const char *liebert_shutdownimm_fun(double value) * Logic is weird since the ConfigVoltage item comes after InputVoltage and * OutputVoltage. */ -const char *liebert_config_voltage_fun(double value) +static const char *liebert_config_voltage_fun(double value) { if( value < 1 ) { if( fabs(value - 1e-7) < 1e-9 ) { @@ -192,7 +190,7 @@ const char *liebert_config_voltage_fun(double value) return liebert_conversion_buf; } -const char *liebert_line_voltage_fun(double value) +static const char *liebert_line_voltage_fun(double value) { if( value < 1 ) { if( fabs(value - 1e-7) < 1e-9 ) { @@ -209,7 +207,7 @@ const char *liebert_line_voltage_fun(double value) return liebert_conversion_buf; } -const char *liebert_psi5_line_voltage_fun(double value) +static const char *liebert_psi5_line_voltage_fun(double value) { if( value < 1 ) { if( fabs(value - 1e-3) < 1e-3 ) { diff --git a/tests/Makefile.am b/tests/Makefile.am index 94588ce202..d5f6ab0be6 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -73,14 +73,15 @@ TESTS += getvaluetest getexponenttest # We only need to call a few methods, not use the whole source - so # not linking it as a getvaluetest_SOURCE file (has too many deps): -noinst_LTLIBRARIES += libbelkin.la -nodist_libbelkin_la_SOURCES = belkin-hid.c driver-stub-usb.c -libbelkin_la_CFLAGS = $(AM_CFLAGS) $(LIBUSB_CFLAGS) -libbelkin_la_LIBADD = $(top_builddir)/common/libcommon.la +noinst_LTLIBRARIES += libdriverstubusb.la +nodist_libdriverstubusb_la_SOURCES = driver-stub-usb.c +libdriverstubusb_la_CFLAGS = $(AM_CFLAGS) $(LIBUSB_CFLAGS) +#libdriverstubusb_la_LIBADD = $(top_builddir)/common/libcommon.la +getexponenttest.c: belkin-hid.c getexponenttest_SOURCES = getexponenttest.c -#getexponenttest_CFLAGS = $(AM_CFLAGS) $(LIBUSB_CFLAGS) -getexponenttest_LDADD = $(top_builddir)/common/libcommon.la libbelkin.la +getexponenttest_CFLAGS = $(AM_CFLAGS) $(LIBUSB_CFLAGS) +getexponenttest_LDADD = $(top_builddir)/common/libcommon.la libdriverstubusb.la getvaluetest_SOURCES = getvaluetest.c nodist_getvaluetest_SOURCES = hidparser.c diff --git a/tests/driver-stub-usb.c b/tests/driver-stub-usb.c index e483eea41d..0ddedbd91f 100644 --- a/tests/driver-stub-usb.c +++ b/tests/driver-stub-usb.c @@ -1,5 +1,5 @@ -/* placeholder method implementations to just link the libbelkin stub - * and eventually similar code by directly using driver source code +/* placeholder/mock method implementations to just directly use driver + * source code as done for belkin-hid.c (and eventually similar code) * for almost-in-vivo testing (and minimal intrusion to that codebase). * See also: getexponenttest.c * diff --git a/tests/getexponenttest.c b/tests/getexponenttest.c index 94d082ac31..df3bd21ed4 100644 --- a/tests/getexponenttest.c +++ b/tests/getexponenttest.c @@ -32,11 +32,13 @@ #include #include "common.h" -/* from drivers/belkin-hid.c: */ +#include "belkin-hid.c" +/* from drivers/belkin-hid.c we test: extern double liebert_config_voltage_mult, liebert_line_voltage_mult; const char *liebert_config_voltage_fun(double value); const char *liebert_line_voltage_fun(double value); const char *liebert_psi5_line_voltage_fun(double value); + */ static void Usage(char *name) { /* From 7a31f1dafb02ede9aa6c2efb18aab3db1965b463 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 25 Mar 2024 17:24:50 +0100 Subject: [PATCH 0138/1079] tests/getexponenttest.c: use our macros to avoid "comparing floating point with == or != is unsafe [-Werror,-Wfloat-equal]" [#2371] Signed-off-by: Jim Klimov --- tests/getexponenttest.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/getexponenttest.c b/tests/getexponenttest.c index df3bd21ed4..b5d5c5b669 100644 --- a/tests/getexponenttest.c +++ b/tests/getexponenttest.c @@ -27,6 +27,7 @@ #include "config.h" #include "nut_stdint.h" +#include "nut_float.h" #include #include #include @@ -100,7 +101,7 @@ static int RunBuiltInTests(char *argv[]) { liebert_config_voltage_mult = 1.0; rawValue = strtod(testData[i].buf, NULL); - if (rawValue != testData[i].expectedRawValue) { + if (!d_equal(rawValue, testData[i].expectedRawValue)) { printf(" value '%s' parsing FAIL: got %g expected %g\n", testData[i].buf, rawValue, testData[i].expectedRawValue); /* Fix testData definition! */ @@ -133,7 +134,7 @@ static int RunBuiltInTests(char *argv[]) { printf("Test #%" PRIiSIZE " \t", i + 1); value = strtod(valueStr, NULL); - if (value == testData[i].expectedValue && mult == testData[i].expectedMult) { + if (d_equal(value, testData[i].expectedValue) && d_equal(mult, testData[i].expectedMult)) { printf("%s\tGOT value %9g\tmult %6g PASS\n", (testData[i].type < 1 || testData[i].type > 3 ? "" : methodName[testData[i].type - 1]), value, mult); From 2a0f33ac858a32cdf73a7e2d0cb8f7931d32339c Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 25 Mar 2024 17:30:24 +0100 Subject: [PATCH 0139/1079] tests: rename getexponenttest => getexponenttest-belkin-hid since it became quite specific to that subdriver source Still, can serve as an example/blueprint for other drivers' tests. Signed-off-by: Jim Klimov --- tests/.gitignore | 6 +++--- tests/Makefile.am | 10 +++++----- tests/driver-stub-usb.c | 2 +- ...{getexponenttest.c => getexponenttest-belkin-hid.c} | 9 +++++---- 4 files changed, 14 insertions(+), 13 deletions(-) rename tests/{getexponenttest.c => getexponenttest-belkin-hid.c} (95%) diff --git a/tests/.gitignore b/tests/.gitignore index 1036cac317..1648d7c1de 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -16,9 +16,9 @@ /nuttimetest /nuttimetest.log /nuttimetest.trs -/getexponenttest -/getexponenttest.log -/getexponenttest.trs +/getexponenttest-belkin-hid +/getexponenttest-belkin-hid.log +/getexponenttest-belkin-hid.trs /belkin-hid.c /getvaluetest /getvaluetest.log diff --git a/tests/Makefile.am b/tests/Makefile.am index d5f6ab0be6..bc0f231e28 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -69,7 +69,7 @@ belkin-hid.c: $(top_srcdir)/drivers/belkin-hid.c test -s "$@" || ln -s -f "$(top_srcdir)/drivers/belkin-hid.c" "$@" if WITH_USB -TESTS += getvaluetest getexponenttest +TESTS += getvaluetest getexponenttest-belkin-hid # We only need to call a few methods, not use the whole source - so # not linking it as a getvaluetest_SOURCE file (has too many deps): @@ -78,10 +78,10 @@ nodist_libdriverstubusb_la_SOURCES = driver-stub-usb.c libdriverstubusb_la_CFLAGS = $(AM_CFLAGS) $(LIBUSB_CFLAGS) #libdriverstubusb_la_LIBADD = $(top_builddir)/common/libcommon.la -getexponenttest.c: belkin-hid.c -getexponenttest_SOURCES = getexponenttest.c -getexponenttest_CFLAGS = $(AM_CFLAGS) $(LIBUSB_CFLAGS) -getexponenttest_LDADD = $(top_builddir)/common/libcommon.la libdriverstubusb.la +getexponenttest-belkin-hid.c: belkin-hid.c +getexponenttest_belkin_hid_SOURCES = getexponenttest-belkin-hid.c +getexponenttest_belkin_hid_CFLAGS = $(AM_CFLAGS) $(LIBUSB_CFLAGS) +getexponenttest_belkin_hid_LDADD = $(top_builddir)/common/libcommon.la libdriverstubusb.la getvaluetest_SOURCES = getvaluetest.c nodist_getvaluetest_SOURCES = hidparser.c diff --git a/tests/driver-stub-usb.c b/tests/driver-stub-usb.c index 0ddedbd91f..6cb557a75c 100644 --- a/tests/driver-stub-usb.c +++ b/tests/driver-stub-usb.c @@ -1,7 +1,7 @@ /* placeholder/mock method implementations to just directly use driver * source code as done for belkin-hid.c (and eventually similar code) * for almost-in-vivo testing (and minimal intrusion to that codebase). - * See also: getexponenttest.c + * See also: getexponenttest-belkin-hid.c * * Copyright (C) * 2024 Jim Klimov diff --git a/tests/getexponenttest.c b/tests/getexponenttest-belkin-hid.c similarity index 95% rename from tests/getexponenttest.c rename to tests/getexponenttest-belkin-hid.c index b5d5c5b669..21256ebb5a 100644 --- a/tests/getexponenttest.c +++ b/tests/getexponenttest-belkin-hid.c @@ -1,7 +1,8 @@ -/* getexponenttest - check detection of correct multiplication exponent value - * for miniscule readings from USB HID (as used in e.g. drivers/belkin-hid.c - * subdriver). Eventually may be extended to similar tests for other driver - * methods. +/* getexponenttest-belkin-hid - check detection of correct multiplication + * exponent value for miniscule readings from USB HID (as used in the + * drivers/belkin-hid.c subdriver of usbhid-ups). + * Eventually may be extended to similar tests for other drivers' methods, + * or more likely cloned to #include them in similar fashion. * * See also: * https://github.com/networkupstools/nut/issues/2370 From 2d71eb9a8276b26fccc6335d4fec8215fe6a63dd Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 25 Mar 2024 17:40:41 +0100 Subject: [PATCH 0140/1079] tests: no longer need a replica of belkin-hid.c in tests/ to build getexponenttest-belkin-hid Suffices that we #include it in the test source, and drivers/ are among include dirs Signed-off-by: Jim Klimov --- tests/.gitignore | 1 - tests/Makefile.am | 9 +++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/tests/.gitignore b/tests/.gitignore index 1648d7c1de..97af77e45d 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -19,7 +19,6 @@ /getexponenttest-belkin-hid /getexponenttest-belkin-hid.log /getexponenttest-belkin-hid.trs -/belkin-hid.c /getvaluetest /getvaluetest.log /getvaluetest.trs diff --git a/tests/Makefile.am b/tests/Makefile.am index bc0f231e28..036948359f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -58,16 +58,13 @@ nuttimetest_SOURCES = nuttimetest.c nuttimetest_LDADD = $(top_builddir)/common/libcommon.la # Separate the .deps of other dirs from this one -LINKED_SOURCE_FILES = hidparser.c belkin-hid.c +LINKED_SOURCE_FILES = hidparser.c # NOTE: Not using "$<" due to a legacy Sun/illumos dmake bug with resolver # of dynamic vars, see e.g. https://man.omnios.org/man1/make#BUGS hidparser.c: $(top_srcdir)/drivers/hidparser.c test -s "$@" || ln -s -f "$(top_srcdir)/drivers/hidparser.c" "$@" -belkin-hid.c: $(top_srcdir)/drivers/belkin-hid.c - test -s "$@" || ln -s -f "$(top_srcdir)/drivers/belkin-hid.c" "$@" - if WITH_USB TESTS += getvaluetest getexponenttest-belkin-hid @@ -78,7 +75,7 @@ nodist_libdriverstubusb_la_SOURCES = driver-stub-usb.c libdriverstubusb_la_CFLAGS = $(AM_CFLAGS) $(LIBUSB_CFLAGS) #libdriverstubusb_la_LIBADD = $(top_builddir)/common/libcommon.la -getexponenttest-belkin-hid.c: belkin-hid.c +getexponenttest-belkin-hid.c: $(top_srcdir)/drivers/belkin-hid.c getexponenttest_belkin_hid_SOURCES = getexponenttest-belkin-hid.c getexponenttest_belkin_hid_CFLAGS = $(AM_CFLAGS) $(LIBUSB_CFLAGS) getexponenttest_belkin_hid_LDADD = $(top_builddir)/common/libcommon.la libdriverstubusb.la @@ -89,7 +86,7 @@ nodist_getvaluetest_SOURCES = hidparser.c getvaluetest_CFLAGS = $(AM_CFLAGS) $(LIBUSB_CFLAGS) getvaluetest_LDADD = $(top_builddir)/common/libcommon.la else !WITH_USB -EXTRA_DIST += getvaluetest.c hidparser.c belkin-hid.c +EXTRA_DIST += getvaluetest.c hidparser.c endif !WITH_USB if WITH_GPIO From 5356387d96bebe5732b357d5101373705bbf27d5 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 25 Mar 2024 17:49:57 +0100 Subject: [PATCH 0141/1079] drivers/belkin-hid.c: comment expectations for liebert_line_voltage_fun() and friends Signed-off-by: Jim Klimov --- drivers/belkin-hid.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/drivers/belkin-hid.c b/drivers/belkin-hid.c index 552ad400a2..b14d36d18e 100644 --- a/drivers/belkin-hid.c +++ b/drivers/belkin-hid.c @@ -174,8 +174,13 @@ static const char *liebert_shutdownimm_fun(double value) */ static const char *liebert_config_voltage_fun(double value) { - if( value < 1 ) { - if( fabs(value - 1e-7) < 1e-9 ) { + /* Does not fire with devices seen diring investigation for + * https://github.com/networkupstools/nut/issues/2370 + * as the ones seen serve nominal "config" values as integers + * (e.g. "230" for line and "24" for battery). + */ + if (value < 1) { + if (fabs(value - 1e-7) < 1e-9) { liebert_config_voltage_mult = 1e8; liebert_line_voltage_mult = 1e7; /* stomp this in case input voltage was low */ upsdebugx(2, "ConfigVoltage = %g -> assuming correction factor = %g", @@ -192,8 +197,17 @@ static const char *liebert_config_voltage_fun(double value) static const char *liebert_line_voltage_fun(double value) { - if( value < 1 ) { - if( fabs(value - 1e-7) < 1e-9 ) { + /* Keep large readings like "230" or "24" as is */ + if (value < 1) { + /* Practical use-case for mult=1e7: + * 1.39e-06 => 13.9 + * 2.201e-05 => 220.1 + * NOTE: The clause below is in fact broken for this use-case, + * but was present in sources for ages (worked wrongly with an + * integer-oriented abs() so collapsed into "if (0 < 1e-9) {")! + * if (fabs(value - 1e-7) < 1e-9) { + */ + if (fabs(value - 1e-7) < 1e-9) { liebert_line_voltage_mult = 1e7; upsdebugx(2, "Input/OutputVoltage = %g -> assuming correction factor = %g", value, liebert_line_voltage_mult); @@ -209,8 +223,12 @@ static const char *liebert_line_voltage_fun(double value) static const char *liebert_psi5_line_voltage_fun(double value) { - if( value < 1 ) { - if( fabs(value - 1e-3) < 1e-3 ) { + if (value < 1) { + /* Practical use-case for mult=1e5: + * 0.000273 => 27.3 + * 0.001212 => 121.2 + */ + if (fabs(value - 1e-3) < 1e-3) { liebert_line_voltage_mult = 1e5; upsdebugx(2, "Input/OutputVoltage = %g -> assuming correction factor = %g", value, liebert_line_voltage_mult); From 630de574db645271d604a715351a26bb76d26233 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 25 Mar 2024 18:17:00 +0100 Subject: [PATCH 0142/1079] tests/getexponenttest-belkin-hid.c: add tests for larger value ranges (over 200V) Signed-off-by: Jim Klimov --- tests/getexponenttest-belkin-hid.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/getexponenttest-belkin-hid.c b/tests/getexponenttest-belkin-hid.c index 21256ebb5a..084e22abf2 100644 --- a/tests/getexponenttest-belkin-hid.c +++ b/tests/getexponenttest-belkin-hid.c @@ -75,9 +75,14 @@ static int RunBuiltInTests(char *argv[]) { } testData[] = { {.buf = "0.000273", .expectedRawValue = 0.000273, .type = 3, .expectedMult = 1e5, .expectedValue = 27.3 }, {.buf = "0.001212", .expectedRawValue = 0.001212, .type = 3, .expectedMult = 1e5, .expectedValue = 121.2 }, + {.buf = "0.002456", .expectedRawValue = 0.002456, .type = 3, .expectedMult = 1e5, .expectedValue = 245.6 }, + {.buf = "0.003801", .expectedRawValue = 0.003801, .type = 3, .expectedMult = 1e5, .expectedValue = 380.1 }, + {.buf = "0.004151", .expectedRawValue = 0.004151, .type = 3, .expectedMult = 1e5, .expectedValue = 415.1 }, {.buf = "1.39e-06", .expectedRawValue = 0.00000139, .type = 2, .expectedMult = 1e7, .expectedValue = 13.9 }, + {.buf = "1.273e-05", .expectedRawValue = 0.00001273, .type = 2, .expectedMult = 1e7, .expectedValue = 127.3 }, {.buf = "2.201e-05", .expectedRawValue = 0.00002201, .type = 2, .expectedMult = 1e7, .expectedValue = 220.1 }, + {.buf = "4.201e-05", .expectedRawValue = 0.00004201, .type = 2, .expectedMult = 1e7, .expectedValue = 420.1 }, /* Edge cases - what should not be converted (good enough already) */ {.buf = "12", .expectedRawValue = 12.0, .type = 3, .expectedMult = 1, .expectedValue = 12.0 }, From c0b0c040d3d942bfe1203ea1ac413176033d1b13 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 25 Mar 2024 18:20:11 +0100 Subject: [PATCH 0143/1079] drivers/belkin-hid.c: fix liebert_line_voltage_fun() and friends for 0..500V range (cover 3-pole while we are at it) Not touching liebert_config_voltage_fun() at the moment as have no non-integer examples under hand to test against. Signed-off-by: Jim Klimov --- drivers/belkin-hid.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/belkin-hid.c b/drivers/belkin-hid.c index b14d36d18e..23561d9bf0 100644 --- a/drivers/belkin-hid.c +++ b/drivers/belkin-hid.c @@ -33,7 +33,7 @@ #include /* for fabs() */ -#define BELKIN_HID_VERSION "Belkin/Liebert HID 0.20" +#define BELKIN_HID_VERSION "Belkin/Liebert HID 0.21" /* Belkin */ #define BELKIN_VENDORID 0x050d @@ -207,7 +207,7 @@ static const char *liebert_line_voltage_fun(double value) * integer-oriented abs() so collapsed into "if (0 < 1e-9) {")! * if (fabs(value - 1e-7) < 1e-9) { */ - if (fabs(value - 1e-7) < 1e-9) { + if (fabs(value - 1e-5) < 4*1e-5) { liebert_line_voltage_mult = 1e7; upsdebugx(2, "Input/OutputVoltage = %g -> assuming correction factor = %g", value, liebert_line_voltage_mult); @@ -228,7 +228,7 @@ static const char *liebert_psi5_line_voltage_fun(double value) * 0.000273 => 27.3 * 0.001212 => 121.2 */ - if (fabs(value - 1e-3) < 1e-3) { + if (fabs(value - 1e-3) < 4*1e-3) { liebert_line_voltage_mult = 1e5; upsdebugx(2, "Input/OutputVoltage = %g -> assuming correction factor = %g", value, liebert_line_voltage_mult); From 490fa8bb047afb47a78469e414ac4dc05a18c49a Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Tue, 26 Mar 2024 02:05:40 +0100 Subject: [PATCH 0144/1079] tests/getexponenttest-belkin-hid.c, drivers/belkin-hid.c: absorb liebert_psi5_line_voltage_fun() into common liebert_line_voltage_fun() Hopefully should help more devices than those which serve this or that HID subtree only. Follows up from PR #2369 Signed-off-by: Jim Klimov --- drivers/belkin-hid.c | 35 ++++++++++-------------------- tests/getexponenttest-belkin-hid.c | 34 ++++++++++------------------- 2 files changed, 23 insertions(+), 46 deletions(-) diff --git a/drivers/belkin-hid.c b/drivers/belkin-hid.c index 23561d9bf0..1baed8f00d 100644 --- a/drivers/belkin-hid.c +++ b/drivers/belkin-hid.c @@ -96,7 +96,6 @@ static const char *liebert_shutdownimm_fun(double value); * Exposed for unit testing - not "static" */ static const char *liebert_config_voltage_fun(double value); static const char *liebert_line_voltage_fun(double value); -static const char *liebert_psi5_line_voltage_fun(double value); static double liebert_config_voltage_mult = 1.0; static double liebert_line_voltage_mult = 1.0; @@ -134,10 +133,6 @@ static info_lkp_t liebert_line_voltage_info[] = { { 0, NULL, liebert_line_voltage_fun, NULL }, }; -static info_lkp_t liebert_psi5_line_voltage_info[] = { - { 0, NULL, liebert_psi5_line_voltage_fun, NULL }, -}; - static const char *liebert_online_fun(double value) { return value ? "online" : "!online"; @@ -199,6 +194,9 @@ static const char *liebert_line_voltage_fun(double value) { /* Keep large readings like "230" or "24" as is */ if (value < 1) { + int picked_scale = 0; + /* NOTE: Start with tiniest scale first */ + /* Practical use-case for mult=1e7: * 1.39e-06 => 13.9 * 2.201e-05 => 220.1 @@ -209,27 +207,18 @@ static const char *liebert_line_voltage_fun(double value) */ if (fabs(value - 1e-5) < 4*1e-5) { liebert_line_voltage_mult = 1e7; - upsdebugx(2, "Input/OutputVoltage = %g -> assuming correction factor = %g", - value, liebert_line_voltage_mult); - } else { - upslogx(LOG_NOTICE, "LineVoltage exponent looks wrong, but not correcting."); - } - } - - snprintf(liebert_conversion_buf, sizeof(liebert_conversion_buf), "%.1f", - value * liebert_line_voltage_mult); - return liebert_conversion_buf; -} - -static const char *liebert_psi5_line_voltage_fun(double value) -{ - if (value < 1) { + picked_scale = 1; + } else /* Practical use-case for mult=1e5: * 0.000273 => 27.3 * 0.001212 => 121.2 */ if (fabs(value - 1e-3) < 4*1e-3) { liebert_line_voltage_mult = 1e5; + picked_scale = 1; + } + + if (picked_scale) { upsdebugx(2, "Input/OutputVoltage = %g -> assuming correction factor = %g", value, liebert_line_voltage_mult); } else { @@ -528,12 +517,12 @@ static hid_info_t belkin_hid2nut[] = { /* Liebert PSI5 */ { "input.voltage.nominal", 0, 0, "UPS.Flow.ConfigVoltage", NULL, "%.0f", 0, NULL }, { "input.frequency", 0, 0, "UPS.PowerConverter.Input.Frequency", NULL, "%s", 0, divide_by_100_conversion }, - { "input.voltage", 0, 0, "UPS.PowerConverter.Input.Voltage", NULL, "%s", 0, liebert_psi5_line_voltage_info }, + { "input.voltage", 0, 0, "UPS.PowerConverter.Input.Voltage", NULL, "%s", 0, liebert_line_voltage_info }, { "output.voltage.nominal", 0, 0, "UPS.Flow.ConfigVoltage", NULL, "%.0f", 0, NULL }, { "output.frequency", 0, 0, "UPS.PowerConverter.Output.Frequency", NULL, "%s", 0, divide_by_100_conversion }, - { "output.voltage", 0, 0, "UPS.PowerConverter.Output.Voltage", NULL, "%s", 0, liebert_psi5_line_voltage_info }, + { "output.voltage", 0, 0, "UPS.PowerConverter.Output.Voltage", NULL, "%s", 0, liebert_line_voltage_info }, { "ups.load", 0, 0, "UPS.OutletSystem.Outlet.PercentLoad", NULL, "%.0f", 0, NULL }, - { "battery.voltage", 0, 0, "UPS.BatterySystem.Battery.Voltage", NULL, "%s", 0, liebert_psi5_line_voltage_info }, + { "battery.voltage", 0, 0, "UPS.BatterySystem.Battery.Voltage", NULL, "%s", 0, liebert_line_voltage_info }, { "battery.voltage.nominal", 0, 0, "UPS.BatterySystem.Battery.ConfigVoltage", NULL, "%.0f", 0, NULL }, { "battery.capacity", 0, 0, "UPS.Flow.ConfigApparentPower", NULL, "%.0f", 0, NULL }, /* status */ diff --git a/tests/getexponenttest-belkin-hid.c b/tests/getexponenttest-belkin-hid.c index 084e22abf2..5cb872b02b 100644 --- a/tests/getexponenttest-belkin-hid.c +++ b/tests/getexponenttest-belkin-hid.c @@ -39,15 +39,14 @@ extern double liebert_config_voltage_mult, liebert_line_voltage_mult; const char *liebert_config_voltage_fun(double value); const char *liebert_line_voltage_fun(double value); -const char *liebert_psi5_line_voltage_fun(double value); */ static void Usage(char *name) { /* - printf("%s {-c | -l | -p } \n", name); + printf("%s {-c | -l } \n", name); printf("\n"); printf("%s -c 12\n", name); - printf("%s -p 0.001212\n", name); + printf("%s -l 0.001212\n", name); printf("%s -l 1.39e-06\n", name); */ printf("%s\nIf no arguments are given a builtin set of tests are run.\n", name); @@ -60,24 +59,23 @@ static int RunBuiltInTests(char *argv[]) { double rawValue, value, mult; const char *valueStr; - static char* methodName[3] = { + static char* methodName[2] = { "liebert_config_voltage_mult() ", - "liebert_line_voltage_mult() ", - "liebert_psi5_line_voltage_mult()" + "liebert_line_voltage_mult() " }; static struct { char *buf; /* raw voltage as a string (from CLI input, e.g. NUT driver log trace) */ double expectedRawValue; /* parsed raw voltage (as seen in USB HID reports) */ - char type; /* 1 = config, 2 = line, 3 = PSI5 line */ + char type; /* 1 = config, 2 = line */ double expectedMult; /* expected liebert_config_voltage_mult or liebert_line_voltage_mult */ double expectedValue; /* the expected result of decoding the value in the buffer */ } testData[] = { - {.buf = "0.000273", .expectedRawValue = 0.000273, .type = 3, .expectedMult = 1e5, .expectedValue = 27.3 }, - {.buf = "0.001212", .expectedRawValue = 0.001212, .type = 3, .expectedMult = 1e5, .expectedValue = 121.2 }, - {.buf = "0.002456", .expectedRawValue = 0.002456, .type = 3, .expectedMult = 1e5, .expectedValue = 245.6 }, - {.buf = "0.003801", .expectedRawValue = 0.003801, .type = 3, .expectedMult = 1e5, .expectedValue = 380.1 }, - {.buf = "0.004151", .expectedRawValue = 0.004151, .type = 3, .expectedMult = 1e5, .expectedValue = 415.1 }, + {.buf = "0.000273", .expectedRawValue = 0.000273, .type = 2, .expectedMult = 1e5, .expectedValue = 27.3 }, + {.buf = "0.001212", .expectedRawValue = 0.001212, .type = 2, .expectedMult = 1e5, .expectedValue = 121.2 }, + {.buf = "0.002456", .expectedRawValue = 0.002456, .type = 2, .expectedMult = 1e5, .expectedValue = 245.6 }, + {.buf = "0.003801", .expectedRawValue = 0.003801, .type = 2, .expectedMult = 1e5, .expectedValue = 380.1 }, + {.buf = "0.004151", .expectedRawValue = 0.004151, .type = 2, .expectedMult = 1e5, .expectedValue = 415.1 }, {.buf = "1.39e-06", .expectedRawValue = 0.00000139, .type = 2, .expectedMult = 1e7, .expectedValue = 13.9 }, {.buf = "1.273e-05", .expectedRawValue = 0.00001273, .type = 2, .expectedMult = 1e7, .expectedValue = 127.3 }, @@ -85,11 +83,6 @@ static int RunBuiltInTests(char *argv[]) { {.buf = "4.201e-05", .expectedRawValue = 0.00004201, .type = 2, .expectedMult = 1e7, .expectedValue = 420.1 }, /* Edge cases - what should not be converted (good enough already) */ - {.buf = "12", .expectedRawValue = 12.0, .type = 3, .expectedMult = 1, .expectedValue = 12.0 }, - {.buf = "12.3", .expectedRawValue = 12.3, .type = 3, .expectedMult = 1, .expectedValue = 12.3 }, - {.buf = "232.1", .expectedRawValue = 232.1, .type = 3, .expectedMult = 1, .expectedValue = 232.1 }, - {.buf = "240", .expectedRawValue = 240.0, .type = 3, .expectedMult = 1, .expectedValue = 240.0 }, - {.buf = "12", .expectedRawValue = 12.0, .type = 2, .expectedMult = 1, .expectedValue = 12.0 }, {.buf = "12.3", .expectedRawValue = 12.3, .type = 2, .expectedMult = 1, .expectedValue = 12.3 }, {.buf = "232.1", .expectedRawValue = 232.1, .type = 2, .expectedMult = 1, .expectedValue = 232.1 }, @@ -128,11 +121,6 @@ static int RunBuiltInTests(char *argv[]) { mult = liebert_line_voltage_mult; break; - case 3: - valueStr = liebert_psi5_line_voltage_fun(rawValue); - mult = liebert_line_voltage_mult; - break; - default: printf(" invalid entry\n"); continue; @@ -148,7 +136,7 @@ static int RunBuiltInTests(char *argv[]) { printf("%s\tGOT value %9g\tmult %6g FAIL" "\tEXPECTED v=%7g\tm=%7g" "\tORIGINAL (string)'%s'\t=> (double)%g\n", - (testData[i].type < 1 || testData[i].type > 3 ? "" : methodName[testData[i].type - 1]), + (testData[i].type < 1 || testData[i].type > 2 ? "" : methodName[testData[i].type - 1]), value, mult, testData[i].expectedValue, testData[i].expectedMult, From 43f4b996056f265025cb80fa6133451c36470878 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Tue, 26 Mar 2024 02:37:04 +0100 Subject: [PATCH 0145/1079] NEWS.adoc: document fixes for Belkin/Liebert readings Signed-off-by: Jim Klimov --- NEWS.adoc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/NEWS.adoc b/NEWS.adoc index ba5eb36150..4cd6964b3c 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -182,7 +182,9 @@ https://github.com/networkupstools/nut/milestone/10 by cooperation with Cyber Power Systems. [#2312] * `belkin-hid` subdriver now supports Liebert PSI5 devices which have a different numeric reading scale than earlier handled models. [issue #2271, - PR #2272, PR #2369] + PR #2272, PR #2369] Generally the wrong-scale processing was addressed, + including a regression in NUT v2.8.0 which led to zero values + in voltage data points which NUT v2.7.4 reported well [#2371] * The `onlinedischarge` configuration flag name was too ambiguous and got deprecated (will be supported but no longer promoted by documentation), introducing `onlinedischarge_onbattery` as the meaningful alias. [#2213] From 229f91f7ee2c5732a73a4803ab50b69803d8aeb1 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Tue, 26 Mar 2024 12:08:15 +0100 Subject: [PATCH 0146/1079] tests/Makefile.am: EXTRA_DIST the test mock "program" source Signed-off-by: Jim Klimov --- tests/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Makefile.am b/tests/Makefile.am index 036948359f..b6633707a4 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -88,6 +88,7 @@ getvaluetest_LDADD = $(top_builddir)/common/libcommon.la else !WITH_USB EXTRA_DIST += getvaluetest.c hidparser.c endif !WITH_USB +EXTRA_DIST += driver-stub-usb.c if WITH_GPIO TESTS += gpiotest From e89e6cae8e9afca3b96ff3a378c14e5220b4f80a Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sun, 31 Mar 2024 01:29:41 +0100 Subject: [PATCH 0147/1079] drivers/riello_usb.c: upsdrv_initinfo(): set batt_volt_* limit vars from settings or initial reading [#1692] Signed-off-by: Jim Klimov --- drivers/riello_usb.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/riello_usb.c b/drivers/riello_usb.c index 4d321d0d28..baf8d8858e 100644 --- a/drivers/riello_usb.c +++ b/drivers/riello_usb.c @@ -1061,6 +1061,12 @@ void upsdrv_initinfo(void) batt_volt_high *= times12; } } else { + if (valL) + batt_volt_low = strtod(valL, NULL); + + if (valH) + batt_volt_high = strtod(valH, NULL); + /* If just one of those is set, then what? */ if (valL || valH) { upsdebugx(1, "WARNING: Only one of battery.voltage.low=%.1f " From 0e14eebfaad138dc8eeb527b759a33a73a5ba813 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sun, 31 Mar 2024 03:08:17 +0200 Subject: [PATCH 0148/1079] drivers/riello_usb.c: upsdrv_initinfo(): set batt_volt_* limit vars from nominal voltage alignment, then apply from settings or initial reading [#1692] Signed-off-by: Jim Klimov --- drivers/riello_usb.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/drivers/riello_usb.c b/drivers/riello_usb.c index baf8d8858e..32a46b5618 100644 --- a/drivers/riello_usb.c +++ b/drivers/riello_usb.c @@ -1049,30 +1049,47 @@ void upsdrv_initinfo(void) valL = dstate_getinfo("battery.voltage.low"); valH = dstate_getinfo("battery.voltage.high"); - if (!valL && !valH) { - /* Both not set (NULL) => pick by nominal (X times 12V). - * Pick a suitable low/high range (or keep built-in default). + { /* scoping */ + /* Pick a suitable low/high range (or keep built-in default). + * The factor may be a count of battery packs in the UPS. */ int times12 = batt_volt_nom / 12; if (times12 > 1) { /* Scale up the range for 24V (X=2) etc. */ - upsdebugx(1, "Using %i times the voltage range of 12V PbAc battery", times12); + upsdebugx(3, "%s: Using %i times the voltage range of 12V PbAc battery", + __func__, times12); batt_volt_low *= times12; batt_volt_high *= times12; } + } + + if (!valL && !valH) { + /* Both not set (NULL) => pick by nominal (X times 12V above). */ + upsdebugx(3, "Neither battery.voltage.low=%.1f " + "nor battery.voltage.high=%.1f is set via " + "driver configuration or by device; keeping " + "at built-in default value (aligned " + "with battery.voltage.nominal=%.1f)", + batt_volt_low, batt_volt_high, batt_volt_nom); } else { - if (valL) + if (valL) { batt_volt_low = strtod(valL, NULL); + upsdebugx(2, "%s: Using battery.voltage.low=%.1f from device or settings", + __func__, batt_volt_low); + } - if (valH) + if (valH) { batt_volt_high = strtod(valH, NULL); + upsdebugx(2, "%s: Using battery.voltage.high=%.1f from device or settings", + __func__, batt_volt_high); + } /* If just one of those is set, then what? */ if (valL || valH) { upsdebugx(1, "WARNING: Only one of battery.voltage.low=%.1f " "or battery.voltage.high=%.1f is set via " "driver configuration; keeping the other " - "at built-in default value (and not aligning " + "at built-in default value (aligned " "with battery.voltage.nominal=%.1f)", batt_volt_low, batt_volt_high, batt_volt_nom); } else { From 3bdb12ff4c339629c38e9cbf351538b9dec6f79b Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sun, 31 Mar 2024 22:45:35 +0200 Subject: [PATCH 0149/1079] NEWS.adoc: mention belkin-hid fix as also a regression fix [#2371] Signed-off-by: Jim Klimov --- NEWS.adoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS.adoc b/NEWS.adoc index 4cd6964b3c..c08a8d9d4d 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -87,6 +87,10 @@ https://github.com/networkupstools/nut/milestone/10 `configure` script option `--with-debuginfo`. Note that default autoconf behavior usually embeds moderate optimizations and debug information on its own. [PR #2310] + * A fix applied among clean-ups between NUT v2.7.4 and v2.8.0 releases + backfired for `usbhid-ups` subdriver `belkin-hid` which in practice + relied on the broken older behavior; more details in its entry below. + [PR #2371] - nut-usbinfo.pl, nut-scanner and libnutscan: * Library API version for `libnutscan` was bumped from 2.2.0 to 2.5.0 From 3abb88f4d70934b9ffd38e93fd23bcbd02406937 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 1 Apr 2024 09:59:14 +0200 Subject: [PATCH 0150/1079] docs/maintainer-guide.txt: update release instructions, fix typos Signed-off-by: Jim Klimov --- docs/maintainer-guide.txt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/maintainer-guide.txt b/docs/maintainer-guide.txt index 51c7561ab4..7b0014f5ce 100644 --- a/docs/maintainer-guide.txt +++ b/docs/maintainer-guide.txt @@ -88,7 +88,7 @@ MAINTAINER SANDBOX (to be completed and pushed) * clean up "in-development" bits from files, e.g.: ** TODO etc. referring planned future in the `NEWS.adoc` and `UPDATING.adoc` - files + files - except for the upcoming release ** comment away the top-most (auto-resolved) NUT version and build date in `docs/docinfo.xml.in` -- DO NOT add (or at least commit) an entry for the actual fixed release version and date just yet @@ -104,9 +104,11 @@ MAINTAINER SANDBOX (to be completed and pushed) any recent changes to drivers (including `main.c` and other major impact from common code) and sub-drivers (`*-hid.c` for `usbhid-ups`, `*-mib.c` for `snmp-ups`, `nutdrv_qx_*` etc.) have been reflected in bumps to their - `DRIVER_VERSION` or equivalen macros + `DRIVER_VERSION` or equivalent macros ** ideally maintained during development, as features are getting merged for community testing and future development baseline in the master branch +** this is the good time to remove the `PLANNED` status from the upcoming + release info section title * NOTE that the `ChangeLog` file is currently not tracked in SCM * update this document: `docs/maintainer-guide.txt` as it inevitably requires * commit these finishing touches @@ -158,7 +160,8 @@ MAINTAINER SANDBOX (to be completed and pushed) * post-release update of the "in-development" codebase: ** maybe update nut/configure.ac version to .1 (ex: 2.8.0.1) ** `git revert` the commit which cleaned up "in-development" bits above -** Possibly resolve relevant merge conflicts for the changed context +** Possibly resolve relevant merge conflicts for the changed context, + e.g. the changed "PLANNED" status of the now-issued release info * push commits and tag From 4c9396e0221022950e211d960372a241634788be Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 1 Apr 2024 10:06:17 +0200 Subject: [PATCH 0151/1079] docs/maintainer-guide.txt: top note about (not-)spellchecking this doc Signed-off-by: Jim Klimov --- docs/maintainer-guide.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/maintainer-guide.txt b/docs/maintainer-guide.txt index 7b0014f5ce..6f10f9cb1f 100644 --- a/docs/maintainer-guide.txt +++ b/docs/maintainer-guide.txt @@ -6,6 +6,10 @@ ____________________ Introduction ============ +////////////////////////////////////////////////////////////////////////////// +NOTE: This file is currently not delivered in tarballs nor spellchecked. +////////////////////////////////////////////////////////////////////////////// + ... Mailing lists administration From fc9d6211b46955ce7961536cac53a2e10e248584 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 1 Apr 2024 10:10:03 +0200 Subject: [PATCH 0152/1079] NEWS.adoc, UPGRADING.adoc, docs/docinfo.xml.in: finalize text before NUT v2.8.2 release Signed-off-by: Jim Klimov --- NEWS.adoc | 27 --------------------------- UPGRADING.adoc | 6 ------ docs/docinfo.xml.in | 2 ++ 3 files changed, 2 insertions(+), 33 deletions(-) diff --git a/NEWS.adoc b/NEWS.adoc index cddd558d64..e852491806 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -13,33 +13,6 @@ ChangeLog file (generated for release archives), or to the Git version control history for "live" codebase. -PLANNED: Release notes for NUT 2.8.4 - what's new since 2.8.3 -------------------------------------------------------------- - -https://github.com/networkupstools/nut/milestone/9 - - - (expected) Dynamic Mapping Files (DMF) feature supported, to allow - the driver binaries to be built once and data mappings to be loaded - and modernized on the fly [Ported from 42ITy project] - - -PLANNED: Release notes for NUT 2.8.3 - what's new since 2.8.2 -------------------------------------------------------------- - -https://github.com/networkupstools/nut/milestone/11 - - - (expected) clean-up of libusb API variants support [#300 and follow-ups] - - - (expected) CI automation for coding style - - - (expected) CI automation for use of data points in drivers that conform - to patterns defined in link:docs/nut-names.txt[] - - - (expected) Porting of performance and bug fixes from 42ITy project - - - (expected) Bug fixes for fallout possible due to "fightwarn" effort in 2.8.0 - - PLANNED: Release notes for NUT 2.8.2 - what's new since 2.8.1 ------------------------------------------------------------- diff --git a/UPGRADING.adoc b/UPGRADING.adoc index fbbac8b3df..522727b426 100644 --- a/UPGRADING.adoc +++ b/UPGRADING.adoc @@ -21,12 +21,6 @@ be beneficial to add `--enable-option-checking=fatal` to the `./configure` command line, in order to quickly pick up any other removed option flags. ====== -Changes from 2.8.2 to 2.8.3 ---------------------------- - -- PLANNED: Keep track of any further API clean-up? - - Changes from 2.8.1 to 2.8.2 --------------------------- diff --git a/docs/docinfo.xml.in b/docs/docinfo.xml.in index 20284705e6..0ad2acf5da 100644 --- a/docs/docinfo.xml.in +++ b/docs/docinfo.xml.in @@ -1,6 +1,7 @@ + + + 2.8.2 + 2024-04-01 + JK + + Some changes to docs and recipes, libnutscan API and functionality. + Added nutconf (library and tool). Fixed some regressions and added + improvements for certain new device series. + + + 2.8.1 2023-10-31 diff --git a/scripts/Windows/build-mingw-nut.sh b/scripts/Windows/build-mingw-nut.sh index bafccc0ab4..a213f2bbb2 100755 --- a/scripts/Windows/build-mingw-nut.sh +++ b/scripts/Windows/build-mingw-nut.sh @@ -24,7 +24,7 @@ DLLLDD_SOURCED=true . "${SCRIPTDIR}/dllldd.sh" # This should match the tarball and directory name, # if a stable version is used: -[ -n "$VER_OPT" ] || VER_OPT=2.8.1 +[ -n "$VER_OPT" ] || VER_OPT=2.8.2 DEBUG=true # default to 32bits build From f53a2354c5700a1ebafbaa425caf115c4b1cec49 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 1 Apr 2024 14:10:04 +0200 Subject: [PATCH 0155/1079] docs/maintainer-guide.txt: example command fix Signed-off-by: Jim Klimov --- docs/maintainer-guide.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/maintainer-guide.txt b/docs/maintainer-guide.txt index 6f10f9cb1f..51219fd66d 100644 --- a/docs/maintainer-guide.txt +++ b/docs/maintainer-guide.txt @@ -148,7 +148,7 @@ MAINTAINER SANDBOX (to be completed and pushed) ---- * create a GPG-signed tag v (ex: v2.8.0): ---- -:; git tag -sm 'Release NUT v2.8.0' +:; git tag -sm 'Release NUT v2.8.0' v2.8.0 ---- ** try to avoid adding signed tags later (ex. v2.8.0-signed) to avoid the mess in GitHub release URLs (or do amend that post-factum), for more From 350271b35ba8513ceba5618afa471c9c6a632642 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 1 Apr 2024 14:11:19 +0200 Subject: [PATCH 0156/1079] docs/maintainer-guide.txt: example command for tag remake Signed-off-by: Jim Klimov --- docs/maintainer-guide.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/maintainer-guide.txt b/docs/maintainer-guide.txt index 51219fd66d..37777e929d 100644 --- a/docs/maintainer-guide.txt +++ b/docs/maintainer-guide.txt @@ -150,6 +150,7 @@ MAINTAINER SANDBOX (to be completed and pushed) ---- :; git tag -sm 'Release NUT v2.8.0' v2.8.0 ---- +** in case of second thoughts, `git tag -d v2.8.0` and retry later ** try to avoid adding signed tags later (ex. v2.8.0-signed) to avoid the mess in GitHub release URLs (or do amend that post-factum), for more details see e.g. https://github.com/networkupstools/nut/issues/1971 From f2458d310b41bd98a76065fb477e78c7eb86adea Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 1 Apr 2024 19:29:34 +0000 Subject: [PATCH 0157/1079] Makefile.am: avoid parallelizing "doc" and "all-recursive" just in case (only follow up by "make doc") Maybe this is behind duplicate man page builds which tend to step on each other's toes. Signed-off-by: Jim Klimov --- Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 08de3eb46a..7153c9e558 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,7 +15,8 @@ # missing e.g. PDF and HTML which then pop up in `make check` footprint, # or misses a .prep-src-docs stage needed to pattern-make man page files # with some "make" implementations... -all all-am-local all-local: doc all-recursive +all all-am-local all-local: all-recursive + +@$(MAKE) $(AM_MAKEFLAGS) doc +@$(MAKE) $(AM_MAKEFLAGS) doc # include directory for aclocal From 8486a450d05e925e8fa597aaee8f5b66227744a2 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 1 Apr 2024 22:06:31 +0200 Subject: [PATCH 0158/1079] docs/maintainer-guide.txt: update instruction Signed-off-by: Jim Klimov --- docs/maintainer-guide.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/maintainer-guide.txt b/docs/maintainer-guide.txt index 37777e929d..dddd09baf6 100644 --- a/docs/maintainer-guide.txt +++ b/docs/maintainer-guide.txt @@ -123,7 +123,7 @@ MAINTAINER SANDBOX (to be completed and pushed) ** revise `.github/workflows/PyNUTClient.yml` for fallback `TAG_NAME` naming ** revise `appveyor.yml` for branch naming ** revise `scripts/Windows/build-mingw-nut.sh` for fallback value of `VER_OPT` -** update version to (ex: 2.8.0) in `configure.ac` +** update version to (ex: 2.8.0) in `configure.ac` ** commit with a relevant release message, e.g.: ---- :; git commit -sm 'Update versions for release of NUT v2.8.0' From 440ca2348e665abf3787c30bdcd9373b479f4efc Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 1 Apr 2024 22:07:23 +0200 Subject: [PATCH 0159/1079] configure.ac: mark exact NUT v2.8.2 release Happy Fools' Day! Signed-off-by: Jim Klimov --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index ed24101cb0..cffd288da8 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ dnl +------------------------------------------------------------------+ dnl NUT version number is defined here, with a Git suffixed macro like dnl NUT_VERSION_MACRO "2.7.4-2838-gdfc3ac08" dnl in include/nut_version.h (generated by make) -AC_INIT([nut],[2.8.2.1],[https://github.com/networkupstools/nut/issues]) +AC_INIT([nut],[2.8.2],[https://github.com/networkupstools/nut/issues]) dnl See docs/maintainer-guide.txt about releases - updating the version dnl above is a small part of the consistent ritual! From 09367182860150e3d287abeea0d300237685f9d5 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Mon, 1 Apr 2024 22:45:08 +0200 Subject: [PATCH 0160/1079] Revert "NEWS.adoc, UPGRADING.adoc, docs/docinfo.xml.in: finalize text before NUT v2.8.2 release" This reverts commit fc9d6211b46955ce7961536cac53a2e10e248584. Signed-off-by: Jim Klimov --- NEWS.adoc | 27 +++++++++++++++++++++++++++ UPGRADING.adoc | 6 ++++++ docs/docinfo.xml.in | 2 -- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/NEWS.adoc b/NEWS.adoc index b46a18411a..44779d61ad 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -13,6 +13,33 @@ ChangeLog file (generated for release archives), or to the Git version control history for "live" codebase. +PLANNED: Release notes for NUT 2.8.4 - what's new since 2.8.3 +------------------------------------------------------------- + +https://github.com/networkupstools/nut/milestone/9 + + - (expected) Dynamic Mapping Files (DMF) feature supported, to allow + the driver binaries to be built once and data mappings to be loaded + and modernized on the fly [Ported from 42ITy project] + + +PLANNED: Release notes for NUT 2.8.3 - what's new since 2.8.2 +------------------------------------------------------------- + +https://github.com/networkupstools/nut/milestone/11 + + - (expected) clean-up of libusb API variants support [#300 and follow-ups] + + - (expected) CI automation for coding style + + - (expected) CI automation for use of data points in drivers that conform + to patterns defined in link:docs/nut-names.txt[] + + - (expected) Porting of performance and bug fixes from 42ITy project + + - (expected) Bug fixes for fallout possible due to "fightwarn" effort in 2.8.0 + + Release notes for NUT 2.8.2 - what's new since 2.8.1 ---------------------------------------------------- diff --git a/UPGRADING.adoc b/UPGRADING.adoc index 522727b426..fbbac8b3df 100644 --- a/UPGRADING.adoc +++ b/UPGRADING.adoc @@ -21,6 +21,12 @@ be beneficial to add `--enable-option-checking=fatal` to the `./configure` command line, in order to quickly pick up any other removed option flags. ====== +Changes from 2.8.2 to 2.8.3 +--------------------------- + +- PLANNED: Keep track of any further API clean-up? + + Changes from 2.8.1 to 2.8.2 --------------------------- diff --git a/docs/docinfo.xml.in b/docs/docinfo.xml.in index 2b5bd63724..ea0c5fcee0 100644 --- a/docs/docinfo.xml.in +++ b/docs/docinfo.xml.in @@ -1,7 +1,6 @@ - - +