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.
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(&regex_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(&regex_matcher, regex_array, REG_ICASE | 
REG_EXTENDED);
        switch(ret)
_______________________________________________
Nut-upsdev mailing list
[email protected]
https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsdev

Reply via email to