[Nut-upsdev] Device argument for USB matching
Edgar Fuß
ef at math.uni-bonn.de
Thu Feb 4 18:05:16 GMT 2021
I needed a "device" argument for USB matching in order to indepedently match two identical UPSen attached to the same bus.
I'll attach a patch. Is that the preferred way of proposing such a change?
The changes to usb-common.[hc] and libusb.c are straightforward (sans the DEBUG_EXACT_MATCH_DEVICE, which I modeled after DEBUG_EXACT_MATCH_BUS, whatever that is used for).
The changes to the various USB drivers are mechanical. Maybe some #define for the regex array size (or even seven more #defines for the magical index values) would be useful.
The line numbers in nutdrv.qx.c will not match yours; I've a much larger change (new driver) in there.
No changes to documentation yet.
-------------- next part --------------
diff -ru /tmp/nut-2.7.4/drivers/usb-common.h ./usb-common.h
--- /tmp/nut-2.7.4/drivers/usb-common.h 2015-12-29 13:08:34.000000000 +0100
+++ ./usb-common.h 2021-01-29 15:41:13.000000000 +0100
@@ -30,7 +30,7 @@
/*!
* USBDevice_t: Describe a USB device. This structure contains exactly
- * the 5 pieces of information by which a USB device identifies
+ * the pieces of information by which a USB device identifies
* itself, so it serves as a kind of "fingerprint" of the device. This
* information must be matched exactly when reopening a device, and
* therefore must not be "improved" or updated by a client
@@ -44,6 +44,7 @@
char *Product; /*!< Device's Product Name */
char *Serial; /*!< Product serial number */
char *Bus; /*!< Bus name, e.g. "003" */
+ char *Device; /*!< Device name, e.g. "001" */
uint16_t bcdDevice; /*!< Device release number */
} USBDevice_t;
diff -ru /tmp/nut-2.7.4/drivers/usb-common.c ./usb-common.c
--- /tmp/nut-2.7.4/drivers/usb-common.c 2015-12-29 09:42:34.000000000 +0100
+++ ./usb-common.c 2021-01-29 15:40:26.000000000 +0100
@@ -103,6 +103,11 @@
return 0;
}
#endif
+#ifdef DEBUG_EXACT_MATCH_DEVICE
+ if (strcmp_null(hd->Device, data->Device) != 0) {
+ return 0;
+ }
+#endif
return 1;
}
@@ -138,6 +143,9 @@
#ifdef DEBUG_EXACT_MATCH_BUS
data->Bus = hd->Bus ? strdup(hd->Bus) : NULL;
#endif
+#ifdef DEBUG_EXACT_MATCH_DEVICE
+ data->Device = hd->Device ? strdup(hd->Device) : NULL;
+#endif
*matcher = m;
return 0;
@@ -160,6 +168,9 @@
#ifdef DEBUG_EXACT_MATCH_BUS
free(data->Bus);
#endif
+#ifdef DEBUG_EXACT_MATCH_DEVICE
+ free(data->Device);
+#endif
free(data);
free(matcher);
}
@@ -271,7 +282,7 @@
/* private data type: hold a set of compiled regular expressions. */
typedef struct regex_matcher_data_s {
- regex_t *regex[6];
+ regex_t *regex[7];
} regex_matcher_data_t;
/* private callback function for regex matches */
@@ -309,18 +320,23 @@
if (r != 1) {
return r;
}
+
+ r = match_regex(data->regex[6], hd->Device);
+ if (r != 1) {
+ return r;
+ }
return 1;
}
/* constructor: create a regular expression matcher. This matcher is
- * based on six regular expression strings in regex_array[0..5],
+ * based on seven regular expression strings in regex_array[0..6],
* corresponding to: vendorid, productid, vendor, product, serial,
- * bus. Any of these strings can be NULL, which matches
+ * bus, device. Any of these strings can be NULL, which matches
* everything. Cflags are as in regcomp(3). Typical values for cflags
* are REG_ICASE (case insensitive matching) and REG_EXTENDED (use
* extended regular expressions). On success, return 0 and store the
* matcher in *matcher. On error, return -1 with errno set, or return
- * i=1--6 to indicate that the regular expression regex_array[i-1] was
+ * i=1--7 to indicate that the regular expression regex_array[i-1] was
* ill-formed (an error message can then be retrieved with
* regerror(3)).
*/
@@ -345,7 +361,7 @@
m->privdata = (void *)data;
m->next = NULL;
- for (i=0; i<6; i++) {
+ for (i=0; i<7; i++) {
r = compile_regex(&data->regex[i], regex[i], cflags);
if (r == -2) {
r = i+1;
@@ -372,7 +388,7 @@
data = (regex_matcher_data_t *)matcher->privdata;
- for (i = 0; i < 6; i++) {
+ for (i = 0; i < 7; i++) {
if (!data->regex[i]) {
continue;
}
diff -ru /tmp/nut-2.7.4/drivers/libusb.c ./libusb.c
--- /tmp/nut-2.7.4/drivers/libusb.c 2015-12-29 13:08:34.000000000 +0100
+++ ./libusb.c 2021-01-29 15:31:33.000000000 +0100
@@ -63,6 +63,7 @@
addvar(VAR_VALUE, "productid", "Regular expression to match UPS Product numerical ID (4 digits hexadecimal)");
addvar(VAR_VALUE, "bus", "Regular expression to match USB bus name");
+ addvar(VAR_VALUE, "device", "Regular expression to match USB device name");
addvar(VAR_VALUE, "usb_set_altinterface", "Force redundant call to usb_set_altinterface() (value=bAlternateSetting; default=0)");
}
@@ -198,11 +199,13 @@
free(curDevice->Product);
free(curDevice->Serial);
free(curDevice->Bus);
+ free(curDevice->Device);
memset(curDevice, '\0', sizeof(*curDevice));
curDevice->VendorID = dev->descriptor.idVendor;
curDevice->ProductID = dev->descriptor.idProduct;
curDevice->Bus = strdup(bus->dirname);
+ curDevice->Device = strdup(dev->filename);
curDevice->bcdDevice = dev->descriptor.bcdDevice;
if (dev->descriptor.iManufacturer) {
@@ -235,6 +238,7 @@
upsdebugx(2, "- Product: %s", curDevice->Product ? curDevice->Product : "unknown");
upsdebugx(2, "- Serial Number: %s", curDevice->Serial ? curDevice->Serial : "unknown");
upsdebugx(2, "- Bus: %s", curDevice->Bus ? curDevice->Bus : "unknown");
+ upsdebugx(2, "- Device: %s", curDevice->Device ? curDevice->Device : "unknown");
upsdebugx(2, "- Device release number: %04x", curDevice->bcdDevice);
if ((curDevice->VendorID == 0x463) && (curDevice->bcdDevice == 0x0202)) {
diff -ru /tmp/nut-2.7.4/drivers/blazer_usb.c ./blazer_usb.c
--- /tmp/nut-2.7.4/drivers/blazer_usb.c 2015-12-29 13:08:34.000000000 +0100
+++ ./blazer_usb.c 2021-01-29 15:20:42.000000000 +0100
@@ -522,7 +522,7 @@
int ret, langid;
char tbuf[255]; /* Some devices choke on size > 255 */
- char *regex_array[6];
+ char *regex_array[7];
char *subdrv = getval("subdriver");
@@ -532,6 +532,7 @@
regex_array[3] = getval("product");
regex_array[4] = getval("serial");
regex_array[5] = getval("bus");
+ regex_array[6] = getval("device");
/* check for language ID workaround (#1) */
if (getval("langid_fix")) {
diff -ru /tmp/nut-2.7.4/drivers/nutdrv_qx.c ./nutdrv_qx.c
--- /tmp/nut-2.7.4/drivers/nutdrv_qx.c 2016-03-08 13:01:11.000000000 +0100
+++ ./nutdrv_qx.c 2021-02-01 14:58:02.000000000 +0100
@@ -1930,7 +2006,7 @@
int ret, langid;
char tbuf[255]; /* Some devices choke on size > 255 */
- char *regex_array[6];
+ char *regex_array[7];
char *subdrv = getval("subdriver");
@@ -1940,6 +2016,7 @@
regex_array[3] = getval("product");
regex_array[4] = getval("serial");
regex_array[5] = getval("bus");
+ regex_array[6] = getval("device");
/* Check for language ID workaround (#1) */
if (getval("langid_fix")) {
diff -ru /tmp/nut-2.7.4/drivers/riello_usb.c ./riello_usb.c
--- /tmp/nut-2.7.4/drivers/riello_usb.c 2015-12-29 13:08:34.000000000 +0100
+++ ./riello_usb.c 2021-01-29 15:21:07.000000000 +0100
@@ -793,7 +793,7 @@
};
int ret;
- char *regex_array[6];
+ char *regex_array[7];
char *subdrv = getval("subdriver");
@@ -803,6 +803,7 @@
regex_array[3] = getval("product");
regex_array[4] = getval("serial");
regex_array[5] = getval("bus");
+ regex_array[6] = getval("device");
/* pick up the subdriver name if set explicitly */
if (subdrv) {
diff -ru /tmp/nut-2.7.4/drivers/tripplite_usb.c ./tripplite_usb.c
--- /tmp/nut-2.7.4/drivers/tripplite_usb.c 2015-12-29 13:08:34.000000000 +0100
+++ ./tripplite_usb.c 2021-01-29 15:21:26.000000000 +0100
@@ -1429,7 +1429,7 @@
*/
void upsdrv_initups(void)
{
- char *regex_array[6];
+ char *regex_array[7];
char *value;
int r;
@@ -1440,6 +1440,7 @@
regex_array[3] = getval("product"); /* product string */
regex_array[4] = getval("serial"); /* probably won't see this */
regex_array[5] = getval("bus");
+ regex_array[6] = getval("device");
r = USBNewRegexMatcher(®ex_matcher, regex_array, REG_ICASE | REG_EXTENDED);
if (r==-1) {
diff -ru /tmp/nut-2.7.4/drivers/usbhid-ups.c ./usbhid-ups.c
--- /tmp/nut-2.7.4/drivers/usbhid-ups.c 2015-12-29 13:08:34.000000000 +0100
+++ ./usbhid-ups.c 2021-01-29 15:21:44.000000000 +0100
@@ -920,7 +920,7 @@
subdriver_matcher = device_path;
#else
- char *regex_array[6];
+ char *regex_array[7];
upsdebugx(1, "upsdrv_initups...");
@@ -943,6 +943,7 @@
regex_array[3] = getval("product");
regex_array[4] = getval("serial");
regex_array[5] = getval("bus");
+ regex_array[6] = getval("device");
ret = USBNewRegexMatcher(®ex_matcher, regex_array, REG_ICASE | REG_EXTENDED);
switch(ret)
More information about the Nut-upsdev
mailing list