Skip to content

Commit b91b9eb

Browse files
authored
Merge 49b8524 into 2617706
2 parents 2617706 + 49b8524 commit b91b9eb

2 files changed

Lines changed: 50 additions & 5 deletions

File tree

‎NEWS.adoc‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ https://github.com/networkupstools/nut/milestone/13
6565
* Added `modbus_retries` option to configure the number of read retry
6666
attempts on timeout errors, simplifying error recovery. [PR #3414]
6767
* Increased default TCP response timeout to 2000 ms. [PR #3418]
68+
* It should now properly handle mismatches of criteria passed to the
69+
regular expression matcher (e.g. serial number) allowing several USB
70+
devices to be monitored without conflict. [#2609]
6871

6972
- `dummy-ups` driver updates:
7073
* Added `authconf` driver parameter for repeater mode to control
@@ -1803,7 +1806,6 @@ This requirement compromises usability of `make distcheck` on platforms without
18031806
to have fixed a Segmentation Fault seen in earlier NUT releases with
18041807
some of the devices supported by this driver. [#2427]
18051808
1806-
18071809
- `upsd` updates:
18081810
* `upsd_cleanup()` is now traced, to more easily see that the daemon is
18091811
exiting (and/or start-up has aborted due to configuration or run-time

‎drivers/apc_modbus.c‎

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
#endif
4444

4545
#define DRIVER_NAME "NUT APC Modbus driver " DRIVER_NAME_NUT_MODBUS_HAS_USB_WITH_STR " USB support (libmodbus link type: " NUT_MODBUS_LINKTYPE_STR ")"
46-
#define DRIVER_VERSION "0.21"
46+
#define DRIVER_VERSION "0.22"
4747

4848
#if defined NUT_MODBUS_HAS_USB
4949

@@ -939,6 +939,18 @@ static void _apc_modbus_create_reopen_matcher(void)
939939
int r;
940940

941941
if (reopen_matcher != NULL) {
942+
USBDeviceMatcher_t *curr, *prev = NULL;
943+
for (curr = best_matcher; curr != NULL; curr = curr->next) {
944+
if (curr == reopen_matcher) {
945+
if (prev) {
946+
prev->next = curr->next;
947+
} else {
948+
best_matcher = curr->next;
949+
}
950+
} else {
951+
prev = curr;
952+
}
953+
}
942954
USBFreeExactMatcher(reopen_matcher);
943955
reopen_matcher = NULL;
944956
}
@@ -965,8 +977,9 @@ static int _apc_modbus_reopen(void)
965977

966978
#if defined NUT_MODBUS_HAS_USB
967979
/* We might have matched a new device in the modbus_connect callback.
968-
* Because of this we want a new exact matcher. */
969-
best_matcher = best_matcher->next;
980+
* Because of this we want a new exact matcher. The method will drop
981+
* the old reopen_matcher from our list starting at best_matcher, and
982+
* from memory. */
970983
_apc_modbus_create_reopen_matcher();
971984
#endif /* defined NUT_MODBUS_HAS_USB */
972985

@@ -1928,10 +1941,37 @@ static int _apc_modbus_usb_callback(const modbus_usb_device_t *device)
19281941

19291942
_apc_modbus_usb_lib_to_nut(device, &usbdevice);
19301943

1944+
upsdebugx(2, "- VendorID: %04x", usbdevice.VendorID);
1945+
upsdebugx(2, "- ProductID: %04x", usbdevice.ProductID);
1946+
upsdebugx(2, "- Manufacturer: %s", usbdevice.Vendor ? usbdevice.Vendor : "unknown");
1947+
upsdebugx(2, "- Product: %s", usbdevice.Product ? usbdevice.Product : "unknown");
1948+
upsdebugx(2, "- Serial Number: %s", usbdevice.Serial ? usbdevice.Serial : "unknown");
1949+
upsdebugx(2, "- Bus: %s", usbdevice.Bus ? usbdevice.Bus : "unknown");
1950+
#if (defined WITH_USB_BUSPORT) && (WITH_USB_BUSPORT)
1951+
upsdebugx(2, "- Bus Port: %s", usbdevice.BusPort ? usbdevice.BusPort : "unknown");
1952+
#endif
1953+
upsdebugx(2, "- Device: %s", usbdevice.Device ? usbdevice.Device : "unknown");
1954+
upsdebugx(2, "- Device release number: %04x", usbdevice.bcdDevice);
1955+
1956+
upsdebugx(2, "Trying to match device");
19311957
current_matcher = best_matcher;
1958+
upsdebugx(5, "%s: current_matcher=%p", __func__, (void*)current_matcher);
19321959
while (current_matcher != NULL) {
1933-
if (current_matcher->match_function(&usbdevice, current_matcher->privdata) == 1) {
1960+
int ret = current_matcher->match_function(&usbdevice, current_matcher->privdata);
1961+
upsdebugx(5, "%s: Tried matcher %p returned %d", __func__, (void*)current_matcher, ret);
1962+
if (ret == 1) {
1963+
/* known good hit */
19341964
break;
1965+
} else if (ret == 0) {
1966+
/* known active rejection */
1967+
upsdebugx(2, "%s: Device does not match - skipping", __func__);
1968+
/* go to next device that libmodbus would suggest and use this callback again */
1969+
return -1;
1970+
} else if (ret == -1) {
1971+
fatal_with_errno(EXIT_FAILURE, "%s: matcher", __func__);
1972+
} else if (ret == -2) {
1973+
upsdebugx(2, "%s: matcher: unspecified error", __func__);
1974+
return -1;
19351975
}
19361976

19371977
current_matcher = current_matcher->next;
@@ -2229,7 +2269,10 @@ void upsdrv_cleanup(void)
22292269

22302270
#if defined NUT_MODBUS_HAS_USB
22312271
USBFreeExactMatcher(reopen_matcher);
2272+
reopen_matcher = NULL;
2273+
22322274
USBFreeExactMatcher(regex_matcher);
2275+
regex_matcher = NULL;
22332276

22342277
if (usbdevice.Vendor)
22352278
free(usbdevice.Vendor);

0 commit comments

Comments
 (0)