summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Brassel <nick@tzarc.org>2024-10-06 21:44:36 +1300
committerGitHub <noreply@github.com>2024-10-06 21:44:36 +1300
commit305e7baa71ccecf8c126863a7f439361dd9cc750 (patch)
treeee3cd9148d8545bfa2daa523c93cb959fd396a6f
parent65b5dc7e0f73ffb9983ab1ad3f2e2494a6c090d4 (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.h4
-rw-r--r--tmk_core/protocol/usb_descriptor.c91
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
1040const USB_Descriptor_String_t PROGMEM LanguageString = { 1054const 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
1048const USB_Descriptor_String_t PROGMEM ManufacturerString = { 1062const 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
1056const USB_Descriptor_String_t PROGMEM ProductString = { 1070const 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
1065const USB_Descriptor_String_t PROGMEM SerialNumberString = { 1082const 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
1107uint8_t SerialNumberString[SERIAL_NUMBER_DESCRIPTOR_SIZE] = {0};
1108
1109void 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);