[Nut-upsdev] nutdrv_qx langid problem (Issue #3040)

David Woodhouse dwmw2 at infradead.org
Thu Aug 7 10:48:12 BST 2025


In https://github.com/networkupstools/nut/issues/3040 I bought a new
'Vida Armour' UPS and sniffed USB communication of the Windows drivers.

If I understand correctly, the 'protocol' in nutdev_qx describes how we
parse the strings we get back from the UPS, while the 'subdriver'
describes what we do in order to *elicit* those strings.

This UPS looks very close to the megatec protocol and fabula subdriver.
I get these strings from the following string descriptors:

 • 0x03: (242.0 000.0 243.0 000 50.0 54.0 28.0 00001001\r
 • 0x0d: #230.0  10 48.00 50.0\r
 • 0xf3: BL100\r
 • 0x0c: #                           V4.20     \r

Supporting this variant probably shouldn't be hard, but I'm failing at
the first hurdle. The driver fails to start up because the UPS doesn't
return any valid langids from descriptor zero, and the explicit
noscanlangid and langid= options to the driver don't seem to make any
difference.

I run:

LIBUSB_DEBUG=9 nutdrv_qx -a armour -DDDD -x vendorid=0001 -xproductid=0000   -x subdriver=fabula -x protocol=megatec -x noscanlangid -x langid_fix=0x409 -x novendor -x norating

It says it's going to try to read string descriptor 0x03 and failing...

   0.043142	[D3] send: Q1
   0.043144	[D4] command index: 0x03
[ 0.040293] [0028990f] libusb: debug [libusb_submit_transfer] transfer 0x557487783d20
[ 0.040294] [0028990f] libusb: debug [add_to_flying_list] arm timer for timeout in 1000ms (first in line)
[ 0.040304] [0028990f] libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
[ 0.040306] [0028990f] libusb: debug [usbi_wait_for_events] poll() 3 fds with timeout in 60000ms
[ 0.044198] [0028990f] libusb: debug [usbi_wait_for_events] poll() returned 1
[ 0.044205] [0028990f] libusb: debug [reap_for_handle] urb type=2 status=0 transferred=0
[ 0.044208] [0028990f] libusb: debug [handle_control_completion] handling completion status 0
[ 0.044212] [0028990f] libusb: debug [arm_timer_for_next_timeout] no timeouts, disarming timer
[ 0.044215] [0028990f] libusb: debug [usbi_handle_transfer_completion] transfer 0x557487783d20 has callback 0x7fd2f6818c20
[ 0.044217] [0028990f] libusb: debug [sync_transfer_cb] actual_length=0
[ 0.044221] [0028990f] libusb: debug [libusb_free_transfer] transfer 0x557487783d20
   0.047081	[D3] read: Input/Output Error (-1)
[ 0.044230] [0028990f] libusb: debug [libusb_close]  


But wireshark/usbmon says it actually tried to read descriptor #0:

Setup Data
    bmRequestType: 0x80
        1... .... = Direction: Device-to-host
        .00. .... = Type: Standard (0x0)
        ...0 0000 = Recipient: Device (0x00)
    bRequest: GET DESCRIPTOR (6)
    Descriptor Index: 0x00
    bDescriptorType: STRING (0x03)
    Language Id: no language specified (0x0000)
    wLength: 4

.. and got a zero-length reply?

USB URB
    [Source: 3.12.0]
    [Destination: host]
    URB id: 0xffff8eb71392ac00
    URB type: URB_COMPLETE ('C')
    URB transfer type: URB_CONTROL (0x02)
    Endpoint: 0x80, Direction: IN
        1... .... = Direction: IN (1)
        .... 0000 = Endpoint number: 0
    Device: 12
    URB bus id: 3
    Device setup request: not relevant ('-')
    Data: present ('\0')
    URB sec: 1754559469
    URB usec: 970070
    URB status: Success (0)
    URB length [bytes]: 0
    Data length [bytes]: 0

Why did it do that? I asked it not to! And even if I hadn't explicitly
asked it not to... couldn't it have proceeded with en_US anyway rather
than completely aborting?

This is nut-2.8.3 (on Fedora 41) with libusb 1.0.28.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5069 bytes
Desc: not available
URL: <http://alioth-lists.debian.net/pipermail/nut-upsdev/attachments/20250807/e687c50a/attachment.p7s>


More information about the Nut-upsdev mailing list