File fix-usbhid-ups-commands.patch of Package nut
From 534a343a21c2d99c2c158b57c26b00745a6c670b Mon Sep 17 00:00:00 2001
From: Jim Klimov <jimklimov+nut@gmail.com>
Date: Tue, 13 May 2025 16:44:20 +0200
Subject: [PATCH 1/5] drivers/usbhid-ups.h: revise comment markup
Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
---
drivers/usbhid-ups.h | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/drivers/usbhid-ups.h b/drivers/usbhid-ups.h
index a73e1ee353..b34854a91f 100644
--- a/drivers/usbhid-ups.h
+++ b/drivers/usbhid-ups.h
@@ -174,16 +174,16 @@ typedef enum {
typedef struct {
const char *info_type; /* NUT variable name */
- int info_flags; /* NUT flags (to set in addinfo) */
- int info_len; /* if ST_FLAG_STRING: length of the string */
- /* if HU_TYPE_CMD: command value */
+ int info_flags; /* NUT flags (to set in addinfo) */
+ int info_len; /* if ST_FLAG_STRING: length of the string */
+ /* if HU_TYPE_CMD: command value */
const char *hidpath; /* Full HID Object path (or NULL for server side vars) */
- HIDData_t *hiddata; /* Full HID Object data (for caching purpose, filled at runtime) */
+ HIDData_t *hiddata; /* Full HID Object data (for caching purpose, filled at runtime) */
const char *dfl; /* if HU_FLAG_ABSENT: default value ; format otherwise */
- unsigned long hidflags; /* driver's own flags */
- info_lkp_t *hid2info; /* lookup table between HID and NUT values */
- /* if HU_FLAG_ENUM is set, hid2info is also used
- * as enumerated values (dstate_addenum()) */
+ unsigned long hidflags; /* driver's own flags */
+ info_lkp_t *hid2info; /* lookup table between HID and NUT values */
+ /* if HU_FLAG_ENUM is set, hid2info is also used
+ * as enumerated values (dstate_addenum()) */
/* char *info_HID_format; *//* FFE: HID format for complex values */
/* interpreter interpret; *//* FFE: interpreter fct, NULL if not needed */
@@ -192,15 +192,16 @@ typedef struct {
/* TODO: rework flags */
#define HU_FLAG_STATIC 2 /* retrieve info only once. */
-#define HU_FLAG_SEMI_STATIC 4 /* retrieve info smartly */
+#define HU_FLAG_SEMI_STATIC 4 /* retrieve info smartly. */
#define HU_FLAG_ABSENT 8 /* data is absent in the device, */
- /* use default value. */
-#define HU_FLAG_QUICK_POLL 16 /* Mandatory vars */
+ /* so we use default value. */
+#define HU_FLAG_QUICK_POLL 16 /* Mandatory vars. */
#define HU_FLAG_STALE 32 /* data stale, don't try too often. */
-#define HU_FLAG_ENUM 128 /* enum values exist */
+/* see 64 below */
+#define HU_FLAG_ENUM 128 /* enum values exist. */
/* hints for su_ups_set, applicable only to rw vars */
-#define HU_TYPE_CMD 64 /* instant command */
+#define HU_TYPE_CMD 64 /* instant command */
#define HU_CMD_MASK 0x2000
From 71bf4ccbff7d1edd6198a388bb465330830233e6 Mon Sep 17 00:00:00 2001
From: Jim Klimov <jimklimov+nut@gmail.com>
Date: Tue, 13 May 2025 16:45:19 +0200
Subject: [PATCH 2/5] drivers/usbhid-ups.h: bump (C)
Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
---
drivers/usbhid-ups.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/usbhid-ups.h b/drivers/usbhid-ups.h
index b34854a91f..96aad8d776 100644
--- a/drivers/usbhid-ups.h
+++ b/drivers/usbhid-ups.h
@@ -4,6 +4,7 @@
* 2003-2009 Arnaud Quette <http://arnaud.quette.free.fr/contact.html>
* 2005-2006 Peter Selinger <selinger@users.sourceforge.net>
* 2007-2009 Arjen de Korte <adkorte-guest@alioth.debian.org>
+ * 2017-2025 Jim Klimov <jimklimov+nut@gmail.com>
*
* This program was sponsored by MGE UPS SYSTEMS, and now Eaton
*
From 8f3557074a9074306163e331d9a2356eb8fc173d Mon Sep 17 00:00:00 2001
From: Jim Klimov <jimklimov+nut@gmail.com>
Date: Tue, 13 May 2025 17:15:16 +0200
Subject: [PATCH 3/5] drivers/usbhid-ups.c: drop EOL from single-line
upsdebugx() reports
Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
---
drivers/usbhid-ups.c | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/drivers/usbhid-ups.c b/drivers/usbhid-ups.c
index db8aab21f3..577382e0ef 100644
--- a/drivers/usbhid-ups.c
+++ b/drivers/usbhid-ups.c
@@ -900,7 +900,7 @@ int instcmd(const char *cmdname, const char *extradata)
return instcmd("load.off.delay", dstate_getinfo("ups.delay.shutdown"));
}
- upsdebugx(2, "instcmd: info element unavailable %s\n", cmdname);
+ upsdebugx(2, "instcmd: info element unavailable %s", cmdname);
return STAT_INSTCMD_INVALID;
}
@@ -911,14 +911,14 @@ int instcmd(const char *cmdname, const char *extradata)
/* Check if the item is an instant command */
if (!(hidups_item->hidflags & HU_TYPE_CMD)) {
- upsdebugx(2, "instcmd: %s is not an instant command\n", cmdname);
+ upsdebugx(2, "instcmd: %s is not an instant command", cmdname);
return STAT_INSTCMD_INVALID;
}
/* If extradata is empty, use the default value from the HID-to-NUT table */
val = extradata ? extradata : hidups_item->dfl;
if (!val) {
- upsdebugx(2, "instcmd: %s requires an explicit parameter\n", cmdname);
+ upsdebugx(2, "instcmd: %s requires an explicit parameter", cmdname);
return STAT_INSTCMD_CONVERSION_FAILED;
}
@@ -931,13 +931,13 @@ int instcmd(const char *cmdname, const char *extradata)
/* Actual variable setting */
if (HIDSetDataValue(udev, hidups_item->hiddata, value) == 1) {
- upsdebugx(3, "instcmd: SUCCEED\n");
+ upsdebugx(3, "instcmd: SUCCEED");
/* Set the status so that SEMI_STATIC vars are polled */
data_has_changed = TRUE;
return STAT_INSTCMD_HANDLED;
}
- upsdebugx(3, "instcmd: FAILED\n"); /* TODO: HANDLED but FAILED, not UNKNOWN! */
+ upsdebugx(3, "instcmd: FAILED"); /* TODO: HANDLED but FAILED, not UNKNOWN! */
return STAT_INSTCMD_FAILED;
}
@@ -953,26 +953,26 @@ int setvar(const char *varname, const char *val)
hidups_item = find_nut_info(varname);
if (hidups_item == NULL) {
- upsdebugx(2, "setvar: info element unavailable %s\n", varname);
+ upsdebugx(2, "setvar: info element unavailable %s", varname);
return STAT_SET_UNKNOWN;
}
/* Checking item writability and HID Path */
if (!(hidups_item->info_flags & ST_FLAG_RW)) {
- upsdebugx(2, "setvar: not writable %s\n", varname);
+ upsdebugx(2, "setvar: not writable %s", varname);
return STAT_SET_UNKNOWN;
}
/* handle server side variable */
if (hidups_item->hidflags & HU_FLAG_ABSENT) {
- upsdebugx(2, "setvar: setting server side variable %s\n", varname);
+ upsdebugx(2, "setvar: setting server side variable %s", varname);
dstate_setinfo(hidups_item->info_type, "%s", val);
return STAT_SET_HANDLED;
}
/* HU_FLAG_ABSENT is the only case of HID Path == NULL */
if (hidups_item->hidpath == NULL) {
- upsdebugx(2, "setvar: ID Path is NULL for %s\n", varname);
+ upsdebugx(2, "setvar: ID Path is NULL for %s", varname);
return STAT_SET_UNKNOWN;
}
@@ -985,13 +985,13 @@ int setvar(const char *varname, const char *val)
/* Actual variable setting */
if (HIDSetDataValue(udev, hidups_item->hiddata, value) == 1) {
- upsdebugx(5, "setvar: SUCCEED\n");
+ upsdebugx(5, "setvar: SUCCEED");
/* Set the status so that SEMI_STATIC vars are polled */
data_has_changed = TRUE;
return STAT_SET_HANDLED;
}
- upsdebugx(3, "setvar: FAILED\n"); /* FIXME: HANDLED but FAILED, not UNKNOWN! */
+ upsdebugx(3, "setvar: FAILED"); /* FIXME: HANDLED but FAILED, not UNKNOWN! */
return STAT_SET_UNKNOWN;
}
@@ -1253,7 +1253,7 @@ void upsdrv_updateinfo(void)
ups_infoval_set(item, value);
}
#ifdef DEBUG
- upsdebugx(1, "took %.3f seconds handling interrupt reports...\n",
+ upsdebugx(1, "took %.3f seconds handling interrupt reports...",
interval());
#endif
/* clear status buffer before beginning */
@@ -1289,7 +1289,7 @@ void upsdrv_updateinfo(void)
dstate_dataok();
#ifdef DEBUG
- upsdebugx(1, "took %.3f seconds handling feature reports...\n",
+ upsdebugx(1, "took %.3f seconds handling feature reports...",
interval());
#endif
}
From 6c65b4926e625af4309576ba6bac173a76937c27 Mon Sep 17 00:00:00 2001
From: Jim Klimov <jimklimov+nut@gmail.com>
Date: Tue, 13 May 2025 16:50:20 +0200
Subject: [PATCH 4/5] drivers/usbhid-ups.h, drivers/usbhid-ups.c, NEWS.adoc,
docs/nut.dict: introduce HU_FLAG_CMD_PARAM_REQUIRED and a
HU_TYPE_CMD_PARAM_REQUIRED shortcut for setting in the mapping tables
Complete the feature started in commit 7991e4592e042f16f5e0757083f0fd58503e8a5e
which became a regression of NUT v2.8.3 [#2860].
Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
---
docs/nut.dict | 3 ++-
drivers/usbhid-ups.c | 17 ++++++++++++++---
drivers/usbhid-ups.h | 4 ++++
4 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/docs/nut.dict b/docs/nut.dict
index 0eb9d8bfe0..73c1619e0b 100644
--- a/docs/nut.dict
+++ b/docs/nut.dict
@@ -1,4 +1,4 @@
-personal_ws-1.1 en 3462 utf-8
+personal_ws-1.1 en 3463 utf-8
AAC
AAS
ABI
@@ -488,6 +488,7 @@ HOWTO
HPE
HPUX
HREF
+HU
HUPCL
HUZKVEIkHnC
HV
diff --git a/drivers/usbhid-ups.c b/drivers/usbhid-ups.c
index 577382e0ef..ae9a5ef2f6 100644
--- a/drivers/usbhid-ups.c
+++ b/drivers/usbhid-ups.c
@@ -29,7 +29,7 @@
*/
#define DRIVER_NAME "Generic HID driver"
-#define DRIVER_VERSION "0.62"
+#define DRIVER_VERSION "0.64"
#define HU_VAR_WAITBEFORERECONNECT "waitbeforereconnect"
@@ -918,8 +918,19 @@ int instcmd(const char *cmdname, const char *extradata)
/* If extradata is empty, use the default value from the HID-to-NUT table */
val = extradata ? extradata : hidups_item->dfl;
if (!val) {
- upsdebugx(2, "instcmd: %s requires an explicit parameter", cmdname);
- return STAT_INSTCMD_CONVERSION_FAILED;
+ if (hidups_item->hidflags & HU_FLAG_CMD_PARAM_REQUIRED) {
+ upsdebugx(2, "instcmd: %s requires an explicit or default parameter", cmdname);
+ return STAT_INSTCMD_CONVERSION_FAILED;
+ }
+
+ /* If we end up with atol() below, it should return 0 on error
+ * anyway (on platforms where it would not crash due to NULL),
+ * so we make it portably explicit here as a string "0" to be
+ * handled below.
+ */
+ upsdebugx(4, "instcmd: %s got no explicit nor default parameter, "
+ "but does not require one: falling back to \"0\"", cmdname);
+ val = "0";
}
/* Lookup the new value if needed */
diff --git a/drivers/usbhid-ups.h b/drivers/usbhid-ups.h
index 96aad8d776..c65227d882 100644
--- a/drivers/usbhid-ups.h
+++ b/drivers/usbhid-ups.h
@@ -200,9 +200,13 @@ typedef struct {
#define HU_FLAG_STALE 32 /* data stale, don't try too often. */
/* see 64 below */
#define HU_FLAG_ENUM 128 /* enum values exist. */
+#define HU_FLAG_CMD_PARAM_REQUIRED 256 /* if also HU_TYPE_CMD, require during
+ * instcmd() that a non-trivial command
+ * parameter is passed. */
/* hints for su_ups_set, applicable only to rw vars */
#define HU_TYPE_CMD 64 /* instant command */
+#define HU_TYPE_CMD_PARAM_REQUIRED (HU_TYPE_CMD | HU_FLAG_CMD_PARAM_REQUIRED) /* Shortcut for setting in the mapping tables */
#define HU_CMD_MASK 0x2000
From 82cb7bee4a6bf732b5d61fc4dbac057c2c2eac45 Mon Sep 17 00:00:00 2001
From: Jim Klimov <jimklimov+nut@gmail.com>
Date: Wed, 14 May 2025 01:17:50 +0200
Subject: [PATCH 5/5] drivers/usbhid-ups.{c,h}, NEWS.adoc: rename
HU_FLAG_CMD_PARAM_REQUIRED => HU_FLAG_PARAM_REQUIRED and extend to setvar()
too [#2955, #2860]
---
drivers/usbhid-ups.c | 58 ++++++++++++++++++++++++++++++++------------
drivers/usbhid-ups.h | 8 +++---
3 files changed, 53 insertions(+), 25 deletions(-)
diff --git a/drivers/usbhid-ups.c b/drivers/usbhid-ups.c
index ae9a5ef2f6..abbf3a166d 100644
--- a/drivers/usbhid-ups.c
+++ b/drivers/usbhid-ups.c
@@ -917,27 +917,32 @@ int instcmd(const char *cmdname, const char *extradata)
/* If extradata is empty, use the default value from the HID-to-NUT table */
val = extradata ? extradata : hidups_item->dfl;
- if (!val) {
- if (hidups_item->hidflags & HU_FLAG_CMD_PARAM_REQUIRED) {
- upsdebugx(2, "instcmd: %s requires an explicit or default parameter", cmdname);
- return STAT_INSTCMD_CONVERSION_FAILED;
- }
-
- /* If we end up with atol() below, it should return 0 on error
- * anyway (on platforms where it would not crash due to NULL),
- * so we make it portably explicit here as a string "0" to be
- * handled below.
- */
- upsdebugx(4, "instcmd: %s got no explicit nor default parameter, "
- "but does not require one: falling back to \"0\"", cmdname);
- val = "0";
+ if (!val && hidups_item->hidflags & HU_FLAG_PARAM_REQUIRED) {
+ upsdebugx(2, "instcmd: %s requires an explicit or default parameter", cmdname);
+ return STAT_INSTCMD_CONVERSION_FAILED;
}
/* Lookup the new value if needed */
if (hidups_item->hid2info != NULL) {
+ /* item->nuf() is expected to handle NULL if it must */
value = hu_find_valinfo(hidups_item->hid2info, val);
} else {
- value = atol(val);
+ if (!val) {
+ /* If we end up with atol(NULL) below, it should return
+ * 0 on error anyway (on platforms where it would not
+ * crash instead due to the NULL), so we make it portably
+ * explicit here.
+ */
+ /* FIXME: Look up data points (maybe via override.* or
+ * default.* settings) for delay/etc. when handling
+ * commands like shutdown.* or load.* ?
+ */
+ upsdebugx(4, "instcmd: %s got no explicit nor default parameter, "
+ "but does not require one: falling back to 0", cmdname);
+ value = 0;
+ } else {
+ value = atol(val);
+ }
}
/* Actual variable setting */
@@ -987,11 +992,32 @@ int setvar(const char *varname, const char *val)
return STAT_SET_UNKNOWN;
}
+ /* FIXME: This code did not use "dfl"; should it start to?
+ * If val is empty, use the default value from the HID-to-NUT table */
+ /* if (!val) val = hidups_item->dfl; */
+
+ if (!val && hidups_item->hidflags & HU_FLAG_PARAM_REQUIRED) {
+ upsdebugx(2, "setvar: %s requires an explicit or default parameter", varname);
+ return STAT_SET_CONVERSION_FAILED;
+ }
+
/* Lookup the new value if needed */
if (hidups_item->hid2info != NULL) {
+ /* item->nuf() is expected to handle NULL if it must */
value = hu_find_valinfo(hidups_item->hid2info, val);
} else {
- value = atol(val);
+ if (!val) {
+ /* If we end up with atol(NULL) below, it should return
+ * 0 on error anyway (on platforms where it would not
+ * crash instead due to the NULL), so we make it portably
+ * explicit here.
+ */
+ upsdebugx(4, "setvar: %s got no explicit nor default parameter, "
+ "but does not require one: falling back to 0", varname);
+ value = 0;
+ } else {
+ value = atol(val);
+ }
}
/* Actual variable setting */
diff --git a/drivers/usbhid-ups.h b/drivers/usbhid-ups.h
index c65227d882..8fe3e815d1 100644
--- a/drivers/usbhid-ups.h
+++ b/drivers/usbhid-ups.h
@@ -200,13 +200,13 @@ typedef struct {
#define HU_FLAG_STALE 32 /* data stale, don't try too often. */
/* see 64 below */
#define HU_FLAG_ENUM 128 /* enum values exist. */
-#define HU_FLAG_CMD_PARAM_REQUIRED 256 /* if also HU_TYPE_CMD, require during
- * instcmd() that a non-trivial command
- * parameter is passed. */
+#define HU_FLAG_PARAM_REQUIRED 256 /* require during setvar() or
+ * instcmd() that a non-trivial
+ * value parameter is passed. */
/* hints for su_ups_set, applicable only to rw vars */
#define HU_TYPE_CMD 64 /* instant command */
-#define HU_TYPE_CMD_PARAM_REQUIRED (HU_TYPE_CMD | HU_FLAG_CMD_PARAM_REQUIRED) /* Shortcut for setting in the mapping tables */
+#define HU_TYPE_CMD_PARAM_REQUIRED (HU_TYPE_CMD | HU_FLAG_PARAM_REQUIRED) /* Shortcut for setting in the mapping tables */
#define HU_CMD_MASK 0x2000