diff --git a/shared-module/usb_audio/__init__.c b/shared-module/usb_audio/__init__.c index 16f5952bc6a..3b1171e90d9 100644 --- a/shared-module/usb_audio/__init__.c +++ b/shared-module/usb_audio/__init__.c @@ -329,7 +329,7 @@ size_t usb_audio_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *de const uint8_t ep_out = forced_iso_ep ? iso_ep_num : descriptor_counts->current_endpoint; const uint8_t ep_in = forced_iso_ep ? iso_ep_num : (descriptor_counts->current_endpoint + 1); - usb_add_interface_string(*current_interface_string, "CircuitPython Headset"); + usb_add_interface_name(*current_interface_string, NULL, "Headset"); const uint8_t usb_audio_descriptor[] = { USB_AUDIO_HEADSET_DESCRIPTOR( @@ -365,7 +365,7 @@ size_t usb_audio_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *de } if (usb_audio_direction_is_output()) { - usb_add_interface_string(*current_interface_string, "CircuitPython Speaker"); + usb_add_interface_name(*current_interface_string, NULL, "Speaker"); // The AudioStreaming interface follows the AudioControl interface. usb_audio_spk_as_itf = descriptor_counts->current_interface + 1; @@ -394,7 +394,7 @@ size_t usb_audio_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *de return sizeof(usb_audio_descriptor); } - usb_add_interface_string(*current_interface_string, "CircuitPython Microphone"); + usb_add_interface_name(*current_interface_string, NULL, "Microphone"); // The AudioStreaming interface follows the AudioControl interface. usb_audio_mic_as_itf = descriptor_counts->current_interface + 1; diff --git a/shared-module/usb_cdc/__init__.c b/shared-module/usb_cdc/__init__.c index dd15905e116..deb41c9abfc 100644 --- a/shared-module/usb_cdc/__init__.c +++ b/shared-module/usb_cdc/__init__.c @@ -126,10 +126,10 @@ static const uint8_t usb_cdc_descriptor_template[] = { 0x00, // 65 bInterval 0 (unit depends on device speed) }; -static const char console_cdc_comm_interface_name[] = USB_INTERFACE_NAME " CDC control"; -static const char data_cdc_comm_interface_name[] = USB_INTERFACE_NAME " CDC2 control"; -static const char console_cdc_data_interface_name[] = USB_INTERFACE_NAME " CDC data"; -static const char data_cdc_data_interface_name[] = USB_INTERFACE_NAME " CDC2 data"; +static const char console_cdc_comm_interface_name[] = "CDC control"; +static const char data_cdc_comm_interface_name[] = "CDC2 control"; +static const char console_cdc_data_interface_name[] = "CDC data"; +static const char data_cdc_data_interface_name[] = "CDC2 data"; // .idx is set later. @@ -205,41 +205,24 @@ size_t usb_cdc_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *desc descriptor_counts->current_endpoint++; #if CIRCUITPY_FULL_BUILD - const char *control_interface_name = - console ? console_cdc_comm_interface_name : data_cdc_comm_interface_name; - const char *data_interface_name = - console ? console_cdc_data_interface_name : data_cdc_data_interface_name; - - char *custom_control_interface_name = + const char *custom_control_interface_name = console ? custom_usb_cdc_console_control_interface_name : custom_usb_cdc_data_control_interface_name; - char *custom_data_interface_name = + const char *custom_data_interface_name = console ? custom_usb_cdc_console_data_interface_name : custom_usb_cdc_data_data_interface_name; - - if (custom_control_interface_name != NULL) { - control_interface_name = custom_control_interface_name; - } - if (custom_data_interface_name != NULL) { - data_interface_name = custom_data_interface_name; - } - - usb_add_interface_string(*current_interface_string, control_interface_name); - descriptor_buf[CDC_COMM_INTERFACE_STRING_INDEX] = *current_interface_string; - (*current_interface_string)++; - - usb_add_interface_string(*current_interface_string, data_interface_name); - descriptor_buf[CDC_DATA_INTERFACE_STRING_INDEX] = *current_interface_string; - (*current_interface_string)++; #else - usb_add_interface_string(*current_interface_string, + const char *custom_control_interface_name = NULL; + const char *custom_data_interface_name = NULL; + #endif + + usb_add_interface_name(*current_interface_string, custom_control_interface_name, console ? console_cdc_comm_interface_name : data_cdc_comm_interface_name); descriptor_buf[CDC_COMM_INTERFACE_STRING_INDEX] = *current_interface_string; (*current_interface_string)++; - usb_add_interface_string(*current_interface_string, + usb_add_interface_name(*current_interface_string, custom_data_interface_name, console ? console_cdc_data_interface_name : data_cdc_data_interface_name); descriptor_buf[CDC_DATA_INTERFACE_STRING_INDEX] = *current_interface_string; (*current_interface_string)++; - #endif return sizeof(usb_cdc_descriptor_template); } @@ -370,7 +353,7 @@ static const uint8_t usb_vendor_descriptor_template[] = { 0x0 // 22 bInterval 0 }; -static const char vendor_interface_name[] = USB_INTERFACE_NAME " WebUSB"; +static const char vendor_interface_name[] = "WebUSB"; bool usb_vendor_enabled(void) { @@ -413,7 +396,7 @@ size_t usb_vendor_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *d descriptor_counts->num_out_endpoints++; descriptor_counts->current_endpoint++; - usb_add_interface_string(*current_interface_string, vendor_interface_name); + usb_add_interface_name(*current_interface_string, NULL, vendor_interface_name); descriptor_buf[VENDOR_INTERFACE_STRING_INDEX] = *current_interface_string; (*current_interface_string)++; diff --git a/shared-module/usb_hid/__init__.c b/shared-module/usb_hid/__init__.c index 4d0d5fc2e3d..26ca5108743 100644 --- a/shared-module/usb_hid/__init__.c +++ b/shared-module/usb_hid/__init__.c @@ -145,8 +145,6 @@ size_t usb_hid_descriptor_length(void) { // This is the interface descriptor, not the report descriptor. size_t usb_hid_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string, uint16_t report_descriptor_length, uint8_t boot_device) { - const char *usb_hid_interface_name; - memcpy(descriptor_buf, usb_hid_descriptor_template, sizeof(usb_hid_descriptor_template)); descriptor_buf[HID_DESCRIPTOR_INTERFACE_INDEX] = descriptor_counts->current_interface; @@ -157,12 +155,7 @@ size_t usb_hid_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *desc descriptor_buf[HID_DESCRIPTOR_INTERFACE_PROTOCOL_INDEX] = boot_device; // 1: keyboard, 2: mouse } - if (custom_usb_hid_interface_name == NULL) { - usb_hid_interface_name = USB_INTERFACE_NAME " HID"; - } else { - usb_hid_interface_name = custom_usb_hid_interface_name; - } - usb_add_interface_string(*current_interface_string, usb_hid_interface_name); + usb_add_interface_name(*current_interface_string, custom_usb_hid_interface_name, "HID"); descriptor_buf[HID_DESCRIPTOR_INTERFACE_STRING_INDEX] = *current_interface_string; (*current_interface_string)++; diff --git a/shared-module/usb_midi/__init__.c b/shared-module/usb_midi/__init__.c index 1722911536f..ae8d6a601cb 100644 --- a/shared-module/usb_midi/__init__.c +++ b/shared-module/usb_midi/__init__.c @@ -163,11 +163,6 @@ char *custom_usb_midi_in_jack_name = NULL; char *custom_usb_midi_out_jack_name = NULL; size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string) { - const char *midi_streaming_interface_name; - const char *midi_audio_control_interface_name; - const char *midi_in_jack_name; - const char *midi_out_jack_name; - memcpy(descriptor_buf, usb_midi_descriptor_template, sizeof(usb_midi_descriptor_template)); descriptor_buf[MIDI_AUDIO_CONTROL_INTERFACE_NUMBER_INDEX] = descriptor_counts->current_interface; @@ -191,43 +186,19 @@ size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *des descriptor_buf[MIDI_STREAMING_INTERFACE_NUMBER_INDEX_2] = descriptor_counts->current_interface; descriptor_counts->current_interface++; - if (custom_usb_midi_streaming_interface_name == NULL) { - midi_streaming_interface_name = USB_INTERFACE_NAME " MIDI"; - } else { - midi_streaming_interface_name = custom_usb_midi_streaming_interface_name; - } - - usb_add_interface_string(*current_interface_string, midi_streaming_interface_name); + usb_add_interface_name(*current_interface_string, custom_usb_midi_streaming_interface_name, "MIDI"); descriptor_buf[MIDI_STREAMING_INTERFACE_STRING_INDEX] = *current_interface_string; (*current_interface_string)++; - if (custom_usb_midi_audio_control_interface_name == NULL) { - midi_audio_control_interface_name = USB_INTERFACE_NAME " Audio"; - } else { - midi_audio_control_interface_name = custom_usb_midi_audio_control_interface_name; - } - - usb_add_interface_string(*current_interface_string, midi_audio_control_interface_name); + usb_add_interface_name(*current_interface_string, custom_usb_midi_audio_control_interface_name, "Audio"); descriptor_buf[MIDI_AUDIO_CONTROL_INTERFACE_STRING_INDEX] = *current_interface_string; (*current_interface_string)++; - if (custom_usb_midi_in_jack_name == NULL) { - midi_in_jack_name = USB_INTERFACE_NAME " usb_midi.ports[0]"; - } else { - midi_in_jack_name = custom_usb_midi_in_jack_name; - } - - usb_add_interface_string(*current_interface_string, midi_in_jack_name); + usb_add_interface_name(*current_interface_string, custom_usb_midi_in_jack_name, "usb_midi.ports[0]"); descriptor_buf[MIDI_IN_JACK_STRING_INDEX] = *current_interface_string; (*current_interface_string)++; - if (custom_usb_midi_out_jack_name == NULL) { - midi_out_jack_name = USB_INTERFACE_NAME " usb_midi.ports[0]"; - } else { - midi_out_jack_name = custom_usb_midi_out_jack_name; - } - - usb_add_interface_string(*current_interface_string, midi_out_jack_name); + usb_add_interface_name(*current_interface_string, custom_usb_midi_out_jack_name, "usb_midi.ports[0]"); descriptor_buf[MIDI_OUT_JACK_STRING_INDEX] = *current_interface_string; (*current_interface_string)++; diff --git a/shared-module/usb_video/__init__.c b/shared-module/usb_video/__init__.c index 241c9d768f8..3558afaa613 100644 --- a/shared-module/usb_video/__init__.c +++ b/shared-module/usb_video/__init__.c @@ -121,7 +121,7 @@ void shared_module_usb_video_swapbuffers(void) { } size_t usb_video_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string) { - usb_add_interface_string(*current_interface_string, "CircuitPython UVC"); + usb_add_interface_name(*current_interface_string, NULL, "UVC"); const uint8_t usb_video_descriptor[] = { #if CFG_TUD_VIDEO_STREAMING_BULK TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(*current_interface_string, descriptor_counts->current_endpoint | 0x80, usb_video_frame_width, usb_video_frame_height, DEFAULT_FRAME_RATE, 64, descriptor_counts->current_interface, descriptor_counts->current_interface + 1) diff --git a/supervisor/shared/usb/usb_desc.c b/supervisor/shared/usb/usb_desc.c index 7a0bc4686bb..56a4dd6af40 100644 --- a/supervisor/shared/usb/usb_desc.c +++ b/supervisor/shared/usb/usb_desc.c @@ -49,6 +49,8 @@ typedef union { } interface_string_t; static interface_string_t collected_interface_strings[MAX_INTERFACE_STRINGS]; +// Bit n set: string n is a suffix to put after USB_INTERFACE_NAME and a space. +static uint32_t prefixed_interface_strings; static size_t collected_interface_strings_length; static uint8_t current_interface_string; @@ -289,20 +291,37 @@ static bool usb_build_configuration_descriptor(void) { } // str must not be on the heap. -void usb_add_interface_string(uint8_t interface_string_index, const char str[]) { +void usb_add_interface_name(uint8_t interface_string_index, const char *custom_name, const char *default_suffix) { if (interface_string_index > MAX_INTERFACE_STRINGS) { reset_into_safe_mode(SAFE_MODE_USB_TOO_MANY_INTERFACE_NAMES); } + const char *str = custom_name; + if (str == NULL) { + str = default_suffix; + prefixed_interface_strings |= 1u << interface_string_index; + collected_interface_strings_length += sizeof(USB_INTERFACE_NAME " ") - 1; + } collected_interface_strings[interface_string_index].char_str = str; collected_interface_strings_length += strlen(str); } +void usb_add_interface_string(uint8_t interface_string_index, const char str[]) { + usb_add_interface_name(interface_string_index, str, NULL); +} + static const uint16_t language_id[] = { 0x0304, 0x0409, }; +static uint16_t *ascii_to_le16(uint16_t *dest, const char *str) { + while (*str) { + *dest++ = *str++; + } + return dest; +} + static bool usb_build_interface_string_table(void) { // Allocate space for the le16 String descriptors. // Space needed is 2 bytes for String Descriptor header, then 2 bytes for each character @@ -322,22 +341,20 @@ static bool usb_build_interface_string_table(void) { // Start at 1 to skip the Language ID. for (uint8_t string_index = 1; string_index < current_interface_string; string_index++) { const char *str = collected_interface_strings[string_index].char_str; - const size_t str_len = strlen(str); - // 1 word for descriptor type and length, 1 word for each character. - const uint8_t descriptor_size_words = 1 + str_len; - const uint8_t descriptor_size_bytes = descriptor_size_words * 2; - string_descriptor[0] = 0x0300 | descriptor_size_bytes; - - // Convert to le16. - for (size_t i = 0; i < str_len; i++) { - string_descriptor[i + 1] = str[i]; + // Convert to le16 after 1 word for descriptor type and length. + uint16_t *end = string_descriptor + 1; + if (prefixed_interface_strings & (1u << string_index)) { + end = ascii_to_le16(end, USB_INTERFACE_NAME " "); } + end = ascii_to_le16(end, str); + const uint8_t descriptor_size_bytes = (end - string_descriptor) * 2; + string_descriptor[0] = 0x0300 | descriptor_size_bytes; // Save ptr to string descriptor with le16 str. collected_interface_strings[string_index].descriptor = string_descriptor; // Move to next descriptor slot. - string_descriptor += descriptor_size_words; + string_descriptor = end; } return true; } @@ -358,6 +375,7 @@ bool usb_build_descriptors(const usb_identification_t *identification) { serial_number_hex_string[sizeof(serial_number_hex_string) - 1] = '\0'; current_interface_string = 1; + prefixed_interface_strings = 0; collected_interface_strings_length = 0; return usb_build_device_descriptor(identification) && diff --git a/supervisor/shared/usb/usb_msc_flash.c b/supervisor/shared/usb/usb_msc_flash.c index f3398c66e04..01b0eae2e10 100644 --- a/supervisor/shared/usb/usb_msc_flash.c +++ b/supervisor/shared/usb/usb_msc_flash.c @@ -107,7 +107,7 @@ size_t usb_msc_descriptor_length(void) { return sizeof(usb_msc_descriptor_template); } -static const char storage_interface_name[] = USB_INTERFACE_NAME " Mass Storage"; +static const char storage_interface_name[] = "Mass Storage"; size_t usb_msc_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string) { memcpy(descriptor_buf, usb_msc_descriptor_template, sizeof(usb_msc_descriptor_template)); @@ -127,7 +127,7 @@ size_t usb_msc_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *desc descriptor_counts->num_out_endpoints++; descriptor_counts->current_endpoint++; - usb_add_interface_string(*current_interface_string, storage_interface_name); + usb_add_interface_name(*current_interface_string, NULL, storage_interface_name); descriptor_buf[MSC_INTERFACE_STRING_INDEX] = *current_interface_string; (*current_interface_string)++; diff --git a/supervisor/usb.h b/supervisor/usb.h index 09718babf51..9c667c6f217 100644 --- a/supervisor/usb.h +++ b/supervisor/usb.h @@ -47,6 +47,8 @@ typedef struct { // Shared implementation. bool usb_enabled(void); void usb_add_interface_string(uint8_t interface_string_index, const char str[]); +// Add custom_name, or if it is NULL, USB_INTERFACE_NAME, a space, and default_suffix. +void usb_add_interface_name(uint8_t interface_string_index, const char *custom_name, const char *default_suffix); bool usb_build_descriptors(const usb_identification_t *identification); bool usb_connected(void); void usb_disconnect(void);