diff options
| author | Nick Brassel <nick@tzarc.org> | 2024-10-06 21:44:36 +1300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-10-06 21:44:36 +1300 |
| commit | 305e7baa71ccecf8c126863a7f439361dd9cc750 (patch) | |
| tree | ee3cd9148d8545bfa2daa523c93cb959fd396a6f | |
| parent | 65b5dc7e0f73ffb9983ab1ad3f2e2494a6c090d4 (diff) | |
Allow for `get_hardware_id()` to be used for serial number. (#24053)
* Allow for `get_hardware_id()` to be used for serial number.
* Length checks.
* Explain length.
* Cleanup.
* Preprocessor magic.
* Use the force, Batman.
* Swap logic; if SERIAL_NUMBER is defined use that, otherwise derive it.
* Cleanup.
* Cleanup.
| -rw-r--r-- | platforms/chibios/config.h | 4 | ||||
| -rw-r--r-- | tmk_core/protocol/usb_descriptor.c | 91 |
2 files changed, 82 insertions, 13 deletions
diff --git a/platforms/chibios/config.h b/platforms/chibios/config.h index 006415a5dc..a58479bb97 100644 --- a/platforms/chibios/config.h +++ b/platforms/chibios/config.h | |||
| @@ -5,3 +5,7 @@ | |||
| 5 | #ifndef CORTEX_ENABLE_WFI_IDLE | 5 | #ifndef CORTEX_ENABLE_WFI_IDLE |
| 6 | # define CORTEX_ENABLE_WFI_IDLE TRUE | 6 | # define CORTEX_ENABLE_WFI_IDLE TRUE |
| 7 | #endif // CORTEX_ENABLE_WFI_IDLE | 7 | #endif // CORTEX_ENABLE_WFI_IDLE |
| 8 | |||
| 9 | #ifndef SERIAL_NUMBER_USE_HARDWARE_ID | ||
| 10 | # define SERIAL_NUMBER_USE_HARDWARE_ID TRUE | ||
| 11 | #endif // SERIAL_NUMBER_USE_HARDWARE_ID | ||
diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c index 7efd085ea3..7454c9a7c4 100644 --- a/tmk_core/protocol/usb_descriptor.c +++ b/tmk_core/protocol/usb_descriptor.c | |||
| @@ -49,6 +49,16 @@ | |||
| 49 | # include "os_detection.h" | 49 | # include "os_detection.h" |
| 50 | #endif | 50 | #endif |
| 51 | 51 | ||
| 52 | #if defined(SERIAL_NUMBER) || (defined(SERIAL_NUMBER_USE_HARDWARE_ID) && SERIAL_NUMBER_USE_HARDWARE_ID == TRUE) | ||
| 53 | |||
| 54 | # define HAS_SERIAL_NUMBER | ||
| 55 | |||
| 56 | # if defined(SERIAL_NUMBER_USE_HARDWARE_ID) && SERIAL_NUMBER_USE_HARDWARE_ID == TRUE | ||
| 57 | # include "hardware_id.h" | ||
| 58 | # endif | ||
| 59 | |||
| 60 | #endif // defined(SERIAL_NUMBER) || (defined(SERIAL_NUMBER_USE_HARDWARE_ID) && SERIAL_NUMBER_USE_HARDWARE_ID == TRUE) | ||
| 61 | |||
| 52 | // clang-format off | 62 | // clang-format off |
| 53 | 63 | ||
| 54 | /* | 64 | /* |
| @@ -451,11 +461,11 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = { | |||
| 451 | .ReleaseNumber = DEVICE_VER, | 461 | .ReleaseNumber = DEVICE_VER, |
| 452 | .ManufacturerStrIndex = 0x01, | 462 | .ManufacturerStrIndex = 0x01, |
| 453 | .ProductStrIndex = 0x02, | 463 | .ProductStrIndex = 0x02, |
| 454 | #if defined(SERIAL_NUMBER) | 464 | #ifdef HAS_SERIAL_NUMBER |
| 455 | .SerialNumStrIndex = 0x03, | 465 | .SerialNumStrIndex = 0x03, |
| 456 | #else | 466 | #else // HAS_SERIAL_NUMBER |
| 457 | .SerialNumStrIndex = 0x00, | 467 | .SerialNumStrIndex = 0x00, |
| 458 | #endif | 468 | #endif // HAS_SERIAL_NUMBER |
| 459 | .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS | 469 | .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS |
| 460 | }; | 470 | }; |
| 461 | 471 | ||
| @@ -1037,9 +1047,13 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = { | |||
| 1037 | /* | 1047 | /* |
| 1038 | * String descriptors | 1048 | * String descriptors |
| 1039 | */ | 1049 | */ |
| 1050 | |||
| 1051 | #define USB_DESCRIPTOR_SIZE_LITERAL_U16STRING(str) \ | ||
| 1052 | (sizeof(USB_Descriptor_Header_t) + sizeof(str) - sizeof(wchar_t)) // include header, don't count null terminator | ||
| 1053 | |||
| 1040 | const USB_Descriptor_String_t PROGMEM LanguageString = { | 1054 | const USB_Descriptor_String_t PROGMEM LanguageString = { |
| 1041 | .Header = { | 1055 | .Header = { |
| 1042 | .Size = 4, | 1056 | .Size = sizeof(USB_Descriptor_Header_t) + sizeof(uint16_t), |
| 1043 | .Type = DTYPE_String | 1057 | .Type = DTYPE_String |
| 1044 | }, | 1058 | }, |
| 1045 | .UnicodeString = {LANGUAGE_ID_ENG} | 1059 | .UnicodeString = {LANGUAGE_ID_ENG} |
| @@ -1047,7 +1061,7 @@ const USB_Descriptor_String_t PROGMEM LanguageString = { | |||
| 1047 | 1061 | ||
| 1048 | const USB_Descriptor_String_t PROGMEM ManufacturerString = { | 1062 | const USB_Descriptor_String_t PROGMEM ManufacturerString = { |
| 1049 | .Header = { | 1063 | .Header = { |
| 1050 | .Size = sizeof(USBSTR(MANUFACTURER)), | 1064 | .Size = USB_DESCRIPTOR_SIZE_LITERAL_U16STRING(USBSTR(MANUFACTURER)), |
| 1051 | .Type = DTYPE_String | 1065 | .Type = DTYPE_String |
| 1052 | }, | 1066 | }, |
| 1053 | .UnicodeString = USBSTR(MANUFACTURER) | 1067 | .UnicodeString = USBSTR(MANUFACTURER) |
| @@ -1055,24 +1069,70 @@ const USB_Descriptor_String_t PROGMEM ManufacturerString = { | |||
| 1055 | 1069 | ||
| 1056 | const USB_Descriptor_String_t PROGMEM ProductString = { | 1070 | const USB_Descriptor_String_t PROGMEM ProductString = { |
| 1057 | .Header = { | 1071 | .Header = { |
| 1058 | .Size = sizeof(USBSTR(PRODUCT)), | 1072 | .Size = USB_DESCRIPTOR_SIZE_LITERAL_U16STRING(USBSTR(PRODUCT)), |
| 1059 | .Type = DTYPE_String | 1073 | .Type = DTYPE_String |
| 1060 | }, | 1074 | }, |
| 1061 | .UnicodeString = USBSTR(PRODUCT) | 1075 | .UnicodeString = USBSTR(PRODUCT) |
| 1062 | }; | 1076 | }; |
| 1063 | 1077 | ||
| 1078 | // clang-format on | ||
| 1079 | |||
| 1064 | #if defined(SERIAL_NUMBER) | 1080 | #if defined(SERIAL_NUMBER) |
| 1081 | // clang-format off | ||
| 1065 | const USB_Descriptor_String_t PROGMEM SerialNumberString = { | 1082 | const USB_Descriptor_String_t PROGMEM SerialNumberString = { |
| 1066 | .Header = { | 1083 | .Header = { |
| 1067 | .Size = sizeof(USBSTR(SERIAL_NUMBER)), | 1084 | .Size = USB_DESCRIPTOR_SIZE_LITERAL_U16STRING(USBSTR(SERIAL_NUMBER)), |
| 1068 | .Type = DTYPE_String | 1085 | .Type = DTYPE_String |
| 1069 | }, | 1086 | }, |
| 1070 | .UnicodeString = USBSTR(SERIAL_NUMBER) | 1087 | .UnicodeString = USBSTR(SERIAL_NUMBER) |
| 1071 | }; | 1088 | }; |
| 1072 | #endif | ||
| 1073 | |||
| 1074 | // clang-format on | 1089 | // clang-format on |
| 1075 | 1090 | ||
| 1091 | #else // defined(SERIAL_NUMBER) | ||
| 1092 | |||
| 1093 | # if defined(SERIAL_NUMBER_USE_HARDWARE_ID) && SERIAL_NUMBER_USE_HARDWARE_ID == TRUE | ||
| 1094 | |||
| 1095 | # if defined(__AVR__) | ||
| 1096 | # error Dynamically setting the serial number on AVR is unsupported as LUFA requires the string to be in PROGMEM. | ||
| 1097 | # endif // defined(__AVR__) | ||
| 1098 | |||
| 1099 | # ifndef SERIAL_NUMBER_LENGTH | ||
| 1100 | # define SERIAL_NUMBER_LENGTH (sizeof(hardware_id_t) * 2) | ||
| 1101 | # endif | ||
| 1102 | |||
| 1103 | # define SERIAL_NUMBER_DESCRIPTOR_SIZE \ | ||
| 1104 | (sizeof(USB_Descriptor_Header_t) /* Descriptor header */ \ | ||
| 1105 | + (((SERIAL_NUMBER_LENGTH) + 1) * sizeof(wchar_t))) /* Length of serial number, with potential extra character as we're converting 2 nibbles at a time */ | ||
| 1106 | |||
| 1107 | uint8_t SerialNumberString[SERIAL_NUMBER_DESCRIPTOR_SIZE] = {0}; | ||
| 1108 | |||
| 1109 | void set_serial_number_descriptor(void) { | ||
| 1110 | static bool is_set = false; | ||
| 1111 | if (is_set) { | ||
| 1112 | return; | ||
| 1113 | } | ||
| 1114 | is_set = true; | ||
| 1115 | |||
| 1116 | static const char hex_str[] = "0123456789ABCDEF"; | ||
| 1117 | hardware_id_t id = get_hardware_id(); | ||
| 1118 | USB_Descriptor_String_t* desc = (USB_Descriptor_String_t*)SerialNumberString; | ||
| 1119 | |||
| 1120 | // Copy across nibbles from the hardware ID as unicode hex characters | ||
| 1121 | int length = MIN(sizeof(id) * 2, SERIAL_NUMBER_LENGTH); | ||
| 1122 | uint8_t* p = (uint8_t*)&id; | ||
| 1123 | for (int i = 0; i < length; i += 2) { | ||
| 1124 | desc->UnicodeString[i + 0] = hex_str[p[i / 2] >> 4]; | ||
| 1125 | desc->UnicodeString[i + 1] = hex_str[p[i / 2] & 0xF]; | ||
| 1126 | } | ||
| 1127 | |||
| 1128 | desc->Header.Size = sizeof(USB_Descriptor_Header_t) + (length * sizeof(wchar_t)); // includes header, don't count null terminator | ||
| 1129 | desc->Header.Type = DTYPE_String; | ||
| 1130 | } | ||
| 1131 | |||
| 1132 | # endif // defined(SERIAL_NUMBER_USE_HARDWARE_ID) && SERIAL_NUMBER_USE_HARDWARE_ID == TRUE | ||
| 1133 | |||
| 1134 | #endif // defined(SERIAL_NUMBER) | ||
| 1135 | |||
| 1076 | /** | 1136 | /** |
| 1077 | * This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" | 1137 | * This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" |
| 1078 | * documentation) by the application code so that the address and size of a requested descriptor can be given | 1138 | * documentation) by the application code so that the address and size of a requested descriptor can be given |
| @@ -1114,13 +1174,18 @@ uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const | |||
| 1114 | Size = pgm_read_byte(&ProductString.Header.Size); | 1174 | Size = pgm_read_byte(&ProductString.Header.Size); |
| 1115 | 1175 | ||
| 1116 | break; | 1176 | break; |
| 1117 | #if defined(SERIAL_NUMBER) | 1177 | #ifdef HAS_SERIAL_NUMBER |
| 1118 | case 0x03: | 1178 | case 0x03: |
| 1119 | Address = &SerialNumberString; | 1179 | Address = (const USB_Descriptor_String_t*)&SerialNumberString; |
| 1120 | Size = pgm_read_byte(&SerialNumberString.Header.Size); | 1180 | # if defined(SERIAL_NUMBER) |
| 1181 | Size = pgm_read_byte(&SerialNumberString.Header.Size); | ||
| 1182 | # else | ||
| 1183 | set_serial_number_descriptor(); | ||
| 1184 | Size = ((const USB_Descriptor_String_t*)SerialNumberString)->Header.Size; | ||
| 1185 | # endif | ||
| 1121 | 1186 | ||
| 1122 | break; | 1187 | break; |
| 1123 | #endif | 1188 | #endif // HAS_SERIAL_NUMBER |
| 1124 | } | 1189 | } |
| 1125 | #ifdef OS_DETECTION_ENABLE | 1190 | #ifdef OS_DETECTION_ENABLE |
| 1126 | process_wlength(wLength); | 1191 | process_wlength(wLength); |
