From 24e4e71e769674fbd0b3c53cc949bdebe271f629 Mon Sep 17 00:00:00 2001 From: kapouchima <8651984+kapouchima@users.noreply.github.com> Date: Tue, 8 Sep 2026 13:31:47 +0200 Subject: [PATCH] stm32/otg: report the full bLength in generated string descriptors The string generators wrote tp->total, the transfer size clamped to wLength, into bLength. A host that probes the 2-byte header first (macOS, Windows) therefore read bLength = 2 and recorded empty manufacturer, product and serial strings: the device showed up as "Generic CDC" with no serial, and WebUSB permissions keyed on the serial did not carry over from the ST ROM DFU device to the app. Linux asks for 255 bytes up front and was unaffected. String 0 was also fed through the UTF-16 widening generator and came out as 06 03 09 00 04 00 instead of the 4-byte LANGID list 04 03 09 04. Carry the full length in tx_ptr_t and serve string 0 as raw bytes. Verified on an STM32H725 (PMD mock): 2-byte probes return the real bLength, langid 0x0409 requests return the strings, and macOS records vendor, product and the ROM-identical serial at enumeration. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01ExwkpjVKyyM5HBhzois9fr --- src/platform/stm32/stm32_otg.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/platform/stm32/stm32_otg.c b/src/platform/stm32/stm32_otg.c index ad8868db..9c4246a9 100644 --- a/src/platform/stm32/stm32_otg.c +++ b/src/platform/stm32/stm32_otg.c @@ -78,6 +78,7 @@ typedef struct tx_ptr { uint16_t offset; uint16_t total; uint8_t zlp; + uint8_t blength; // full descriptor length when generated on the fly } tx_ptr_t; @@ -205,7 +206,7 @@ read_string_as_desc(void *opaque) switch(tp->offset) { case 0: - r = tp->total; + r = tp->blength; break; case 1: r = USB_DESC_TYPE_STRING; @@ -234,7 +235,7 @@ read_bin2hex_as_desc(void *opaque) switch(tp->offset) { case 0: - r = tp->total; + r = tp->blength; break; case 1: r = USB_DESC_TYPE_STRING; @@ -379,12 +380,15 @@ handle_get_descriptor(usb_ctrl_t *uc) case USB_DESC_TYPE_STRING: + // String 0 is the raw LANGID list, not a UTF-16 string + if(index == 0) { + desc = "\x04\x03\x09\x04"; + desclen = 4; + break; + } + getch = read_string_as_desc; switch(index) { - case 0: - desc = "\x09\x04"; - desclen = 2; - break; case 1: desc = uc->uc_manufacturer; desclen = strlen(desc); @@ -419,6 +423,7 @@ handle_get_descriptor(usb_ctrl_t *uc) tp->getch = getch; tp->offset = 0; tp->total = MIN(reqlen, desclen); + tp->blength = desclen; tp->zlp = 0; // If the descriptor is shorter then asked for and is a multiple of 8