usb: device_next: allow reuse of string descriptor nodes
If we try to reuse a string descriptor node, the content will
be corrupted because the device stack assumes it is still ASCII7
encoded. Add a flag to indicate that a descriptor node contains
UTF16LE encoded content.
And while we are at it, add a flag to indicate that the SN string
should not be obtained from the hwinfo API.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
diff --git a/include/zephyr/usb/usbd.h b/include/zephyr/usb/usbd.h
index 34b1c64..410fdf9 100644
--- a/include/zephyr/usb/usbd.h
+++ b/include/zephyr/usb/usbd.h
@@ -58,13 +58,17 @@
* Descriptor node
*
* Descriptor node is used to manage descriptors that are not
- * directly part of a structure string, and bos descriptors.
+ * directly part of a structure, such as string or bos descriptors.
*/
struct usbd_desc_node {
/** slist node struct */
sys_snode_t node;
- /** Optional descriptor index, required for string descriptors */
- uint32_t idx;
+ /** Descriptor index, required for string descriptors */
+ unsigned int idx : 8;
+ /** If not set, string descriptor must be converted to UTF16LE */
+ unsigned int utf16le : 1;
+ /** If not set, device stack obtains SN using the hwinfo API */
+ unsigned int custom_sn : 1;
/** Pointer to a descriptor */
void *desc;
};
diff --git a/subsys/usb/device_next/usbd_desc.c b/subsys/usb/device_next/usbd_desc.c
index 89a1a1a..bea3b05 100644
--- a/subsys/usb/device_next/usbd_desc.c
+++ b/subsys/usb/device_next/usbd_desc.c
@@ -61,6 +61,8 @@
buf[i] = 0U;
buf[i - 1] = buf[ascii_idx_max--];
}
+
+ dn->utf16le = true;
}
/**
@@ -163,16 +165,18 @@
dev_desc->iProduct = desc_nd->idx;
break;
case USBD_DESC_SERIAL_NUMBER_IDX:
- /* FIXME, should we force the use of hwid here? */
- ret = usbd_get_sn_from_hwid(desc_nd);
+ if (!desc_nd->custom_sn) {
+ ret = usbd_get_sn_from_hwid(desc_nd);
+ desc_nd->utf16le = false;
+ }
+
dev_desc->iSerialNumber = desc_nd->idx;
break;
default:
break;
}
- if (desc_nd->idx) {
- /* FIXME, should we force ascii7 -> utf16le? */
+ if (desc_nd->idx && !desc_nd->utf16le) {
usbd_ascii7_to_utf16le(desc_nd);
}
}