usb: device_next: allow to limit number or digits in serial number

Add Kconfig option to limit the length requested from HWINFO to a
meaningful number of digits. Also, check the length returned by the
HWINFO driver and rename the variables to a more suitable name.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
This commit is contained in:
Johann Fischer 2025-06-17 10:20:46 +02:00 committed by Benjamin Cabé
commit 76579d21ab
2 changed files with 23 additions and 12 deletions

View file

@ -96,6 +96,16 @@ config USBD_MSG_WORK_DELAY
Message work may need to be delayed because the device stack is not
yet ready to publish the message. The delay unit is milliseconds.
config USBD_HWINFO_DEVID_LENGTH
int "The length of the device ID requested from HWINFO in bytes"
depends on HWINFO
range 8 128
default 16
help
Each byte represents two digits in the serial number string
descriptor. This option can be used to limit the length requested
from HWINFO to a meaningful number of digits.
rsource "class/Kconfig"
rsource "app/Kconfig.cdc_acm_serial"

View file

@ -533,13 +533,13 @@ static int sreq_get_desc_cfg(struct usbd_context *const uds_ctx,
return 0;
}
#define USBD_HWID_SN_MAX 32U
#define USBD_SN_ASCII7_LENGTH (CONFIG_USBD_HWINFO_DEVID_LENGTH * 2)
/* Generate valid USB device serial number from hwid */
static ssize_t get_sn_from_hwid(uint8_t sn[static USBD_HWID_SN_MAX])
static ssize_t get_sn_from_hwid(uint8_t sn[static USBD_SN_ASCII7_LENGTH])
{
static const char hex[] = "0123456789ABCDEF";
uint8_t hwid[USBD_HWID_SN_MAX / 2U];
uint8_t hwid[USBD_SN_ASCII7_LENGTH / 2U];
ssize_t hwid_len = -ENOSYS;
if (IS_ENABLED(CONFIG_HWINFO)) {
@ -554,36 +554,37 @@ static ssize_t get_sn_from_hwid(uint8_t sn[static USBD_HWID_SN_MAX])
return hwid_len;
}
for (ssize_t i = 0; i < hwid_len; i++) {
for (ssize_t i = 0; i < MIN(hwid_len, sizeof(hwid)); i++) {
sn[i * 2] = hex[hwid[i] >> 4];
sn[i * 2 + 1] = hex[hwid[i] & 0xF];
}
return hwid_len * 2;
return MIN(hwid_len, sizeof(hwid)) * 2;
}
/* Copy and convert ASCII-7 string descriptor to UTF16-LE */
static void string_ascii7_to_utf16le(struct usbd_desc_node *const dn,
struct net_buf *const buf, const uint16_t wLength)
{
uint8_t hwid_sn[USBD_HWID_SN_MAX];
uint8_t sn_ascii7_str[USBD_SN_ASCII7_LENGTH];
struct usb_desc_header head = {
.bDescriptorType = dn->bDescriptorType,
};
uint8_t *ascii7_str;
const uint8_t *ascii7_str;
size_t len;
size_t i;
if (dn->str.utype == USBD_DUT_STRING_SERIAL_NUMBER && dn->str.use_hwinfo) {
ssize_t hwid_len = get_sn_from_hwid(hwid_sn);
if (IS_ENABLED(CONFIG_HWINFO) &&
dn->str.utype == USBD_DUT_STRING_SERIAL_NUMBER && dn->str.use_hwinfo) {
ssize_t sn_ascii7_str_len = get_sn_from_hwid(sn_ascii7_str);
if (hwid_len < 0) {
if (sn_ascii7_str_len < 0) {
errno = -ENOTSUP;
return;
}
head.bLength = sizeof(head) + hwid_len * 2;
ascii7_str = hwid_sn;
head.bLength = sizeof(head) + sn_ascii7_str_len * 2;
ascii7_str = sn_ascii7_str;
} else {
head.bLength = dn->bLength;
ascii7_str = (uint8_t *)dn->ptr;