From ad83b70bbd3a0f6eff64d6b8dbfc14621d3cba97 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 31 Jul 2024 18:49:45 +0200 Subject: [PATCH] drivers/libusb0.c: libusb_open(): try to re-fetch curDevice->Vendor, Product, Serial if NULL, after claiming it by other criteria [#2562] Signed-off-by: Jim Klimov --- drivers/libusb0.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/drivers/libusb0.c b/drivers/libusb0.c index 64dc70c093..c201d3d96f 100644 --- a/drivers/libusb0.c +++ b/drivers/libusb0.c @@ -542,6 +542,58 @@ static int libusb_open(usb_dev_handle **udevp, nut_usb_set_altinterface(udev); + /* If libusb failed to identify the device strings earlier, + * can we do that after claiming the interface? Just try... + * Note that we succeeded so far, meaning these strings were + * not among matching criteria. But they can be important for + * our drivers (e.g. per-model tweaks) and pretty reporting + * of certain `device.*` and/or `ups.*` data points. + */ + if (!curDevice->Vendor) { + retries = MAX_RETRY; + while (retries > 0) { + ret = usb_get_string_simple(udev, dev->descriptor.iManufacturer, + string, sizeof(string)); + if (ret > 0) { + curDevice->Vendor = xstrdup(string); + break; + } + retries--; + upsdebugx(1, "%s get iManufacturer failed, retrying...", __func__); + } + upsdebugx(2, "- Manufacturer: %s", curDevice->Vendor ? curDevice->Vendor : "unknown"); + } + + if (!curDevice->Product) { + retries = MAX_RETRY; + while (retries > 0) { + ret = usb_get_string_simple(udev, dev->descriptor.iProduct, + string, sizeof(string)); + if (ret > 0) { + curDevice->Product = xstrdup(string); + break; + } + retries--; + upsdebugx(1, "%s get iProduct failed, retrying...", __func__); + } + upsdebugx(2, "- Product: %s", curDevice->Product ? curDevice->Product : "unknown"); + } + + if (!curDevice->Serial) { + retries = MAX_RETRY; + while (retries > 0) { + ret = usb_get_string_simple(udev, dev->descriptor.iSerialNumber, + string, sizeof(string)); + if (ret > 0) { + curDevice->Serial = xstrdup(string); + break; + } + retries--; + upsdebugx(1, "%s get iSerialNumber failed, retrying...", __func__); + } + upsdebugx(2, "- Serial Number: %s", curDevice->Serial ? curDevice->Serial : "unknown"); + } + /* Did the driver provide a callback method for any further * device acceptance checks (e.g. when same ID is supported * by several sub-drivers, differing by vendor/model strings)?