mirror of
				https://github.com/mfulz/qmk_firmware.git
				synced 2025-10-30 21:02:32 +01:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									65b5dc7e0f
								
							
						
					
					
						commit
						305e7baa71
					
				| @ -5,3 +5,7 @@ | ||||
| #ifndef CORTEX_ENABLE_WFI_IDLE | ||||
| #    define CORTEX_ENABLE_WFI_IDLE TRUE | ||||
| #endif // CORTEX_ENABLE_WFI_IDLE
 | ||||
| 
 | ||||
| #ifndef SERIAL_NUMBER_USE_HARDWARE_ID | ||||
| #    define SERIAL_NUMBER_USE_HARDWARE_ID TRUE | ||||
| #endif // SERIAL_NUMBER_USE_HARDWARE_ID
 | ||||
|  | ||||
| @ -49,6 +49,16 @@ | ||||
| #    include "os_detection.h" | ||||
| #endif | ||||
| 
 | ||||
| #if defined(SERIAL_NUMBER) || (defined(SERIAL_NUMBER_USE_HARDWARE_ID) && SERIAL_NUMBER_USE_HARDWARE_ID == TRUE) | ||||
| 
 | ||||
| #    define HAS_SERIAL_NUMBER | ||||
| 
 | ||||
| #    if defined(SERIAL_NUMBER_USE_HARDWARE_ID) && SERIAL_NUMBER_USE_HARDWARE_ID == TRUE | ||||
| #        include "hardware_id.h" | ||||
| #    endif | ||||
| 
 | ||||
| #endif // defined(SERIAL_NUMBER) || (defined(SERIAL_NUMBER_USE_HARDWARE_ID) && SERIAL_NUMBER_USE_HARDWARE_ID == TRUE)
 | ||||
| 
 | ||||
| // clang-format off
 | ||||
| 
 | ||||
| /*
 | ||||
| @ -451,11 +461,11 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = { | ||||
|     .ReleaseNumber              = DEVICE_VER, | ||||
|     .ManufacturerStrIndex       = 0x01, | ||||
|     .ProductStrIndex            = 0x02, | ||||
| #if defined(SERIAL_NUMBER) | ||||
| #ifdef HAS_SERIAL_NUMBER | ||||
|     .SerialNumStrIndex          = 0x03, | ||||
| #else | ||||
| #else // HAS_SERIAL_NUMBER
 | ||||
|     .SerialNumStrIndex          = 0x00, | ||||
| #endif | ||||
| #endif // HAS_SERIAL_NUMBER
 | ||||
|     .NumberOfConfigurations     = FIXED_NUM_CONFIGURATIONS | ||||
| }; | ||||
| 
 | ||||
| @ -1037,9 +1047,13 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = { | ||||
| /*
 | ||||
|  * String descriptors | ||||
|  */ | ||||
| 
 | ||||
| #define USB_DESCRIPTOR_SIZE_LITERAL_U16STRING(str) \ | ||||
|     (sizeof(USB_Descriptor_Header_t) + sizeof(str) - sizeof(wchar_t)) // include header, don't count null terminator
 | ||||
| 
 | ||||
| const USB_Descriptor_String_t PROGMEM LanguageString = { | ||||
|     .Header = { | ||||
|         .Size                   = 4, | ||||
|         .Size                   = sizeof(USB_Descriptor_Header_t) + sizeof(uint16_t), | ||||
|         .Type                   = DTYPE_String | ||||
|     }, | ||||
|     .UnicodeString              = {LANGUAGE_ID_ENG} | ||||
| @ -1047,7 +1061,7 @@ const USB_Descriptor_String_t PROGMEM LanguageString = { | ||||
| 
 | ||||
| const USB_Descriptor_String_t PROGMEM ManufacturerString = { | ||||
|     .Header = { | ||||
|         .Size                   = sizeof(USBSTR(MANUFACTURER)), | ||||
|         .Size                   = USB_DESCRIPTOR_SIZE_LITERAL_U16STRING(USBSTR(MANUFACTURER)), | ||||
|         .Type                   = DTYPE_String | ||||
|     }, | ||||
|     .UnicodeString              = USBSTR(MANUFACTURER) | ||||
| @ -1055,24 +1069,70 @@ const USB_Descriptor_String_t PROGMEM ManufacturerString = { | ||||
| 
 | ||||
| const USB_Descriptor_String_t PROGMEM ProductString = { | ||||
|     .Header = { | ||||
|         .Size                   = sizeof(USBSTR(PRODUCT)), | ||||
|         .Size                   = USB_DESCRIPTOR_SIZE_LITERAL_U16STRING(USBSTR(PRODUCT)), | ||||
|         .Type                   = DTYPE_String | ||||
|     }, | ||||
|     .UnicodeString              = USBSTR(PRODUCT) | ||||
| }; | ||||
| 
 | ||||
| // clang-format on
 | ||||
| 
 | ||||
| #if defined(SERIAL_NUMBER) | ||||
| // clang-format off
 | ||||
| const USB_Descriptor_String_t PROGMEM SerialNumberString = { | ||||
|     .Header = { | ||||
|         .Size                   = sizeof(USBSTR(SERIAL_NUMBER)), | ||||
|         .Size                   = USB_DESCRIPTOR_SIZE_LITERAL_U16STRING(USBSTR(SERIAL_NUMBER)), | ||||
|         .Type                   = DTYPE_String | ||||
|     }, | ||||
|     .UnicodeString              = USBSTR(SERIAL_NUMBER) | ||||
| }; | ||||
| #endif | ||||
| 
 | ||||
| // clang-format on
 | ||||
| 
 | ||||
| #else // defined(SERIAL_NUMBER)
 | ||||
| 
 | ||||
| #    if defined(SERIAL_NUMBER_USE_HARDWARE_ID) && SERIAL_NUMBER_USE_HARDWARE_ID == TRUE | ||||
| 
 | ||||
| #        if defined(__AVR__) | ||||
| #            error Dynamically setting the serial number on AVR is unsupported as LUFA requires the string to be in PROGMEM. | ||||
| #        endif // defined(__AVR__)
 | ||||
| 
 | ||||
| #        ifndef SERIAL_NUMBER_LENGTH | ||||
| #            define SERIAL_NUMBER_LENGTH (sizeof(hardware_id_t) * 2) | ||||
| #        endif | ||||
| 
 | ||||
| #        define SERIAL_NUMBER_DESCRIPTOR_SIZE                                            \ | ||||
|             (sizeof(USB_Descriptor_Header_t)                     /* Descriptor header */ \ | ||||
|              + (((SERIAL_NUMBER_LENGTH) + 1) * sizeof(wchar_t))) /* Length of serial number, with potential extra character as we're converting 2 nibbles at a time */ | ||||
| 
 | ||||
| uint8_t SerialNumberString[SERIAL_NUMBER_DESCRIPTOR_SIZE] = {0}; | ||||
| 
 | ||||
| void set_serial_number_descriptor(void) { | ||||
|     static bool is_set = false; | ||||
|     if (is_set) { | ||||
|         return; | ||||
|     } | ||||
|     is_set = true; | ||||
| 
 | ||||
|     static const char        hex_str[] = "0123456789ABCDEF"; | ||||
|     hardware_id_t            id        = get_hardware_id(); | ||||
|     USB_Descriptor_String_t* desc      = (USB_Descriptor_String_t*)SerialNumberString; | ||||
| 
 | ||||
|     // Copy across nibbles from the hardware ID as unicode hex characters
 | ||||
|     int      length = MIN(sizeof(id) * 2, SERIAL_NUMBER_LENGTH); | ||||
|     uint8_t* p      = (uint8_t*)&id; | ||||
|     for (int i = 0; i < length; i += 2) { | ||||
|         desc->UnicodeString[i + 0] = hex_str[p[i / 2] >> 4]; | ||||
|         desc->UnicodeString[i + 1] = hex_str[p[i / 2] & 0xF]; | ||||
|     } | ||||
| 
 | ||||
|     desc->Header.Size = sizeof(USB_Descriptor_Header_t) + (length * sizeof(wchar_t)); // includes header, don't count null terminator
 | ||||
|     desc->Header.Type = DTYPE_String; | ||||
| } | ||||
| 
 | ||||
| #    endif // defined(SERIAL_NUMBER_USE_HARDWARE_ID) && SERIAL_NUMBER_USE_HARDWARE_ID == TRUE
 | ||||
| 
 | ||||
| #endif // defined(SERIAL_NUMBER)
 | ||||
| 
 | ||||
| /**
 | ||||
|  * This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" | ||||
|  * 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 | ||||
|                     Size    = pgm_read_byte(&ProductString.Header.Size); | ||||
| 
 | ||||
|                     break; | ||||
| #if defined(SERIAL_NUMBER) | ||||
| #ifdef HAS_SERIAL_NUMBER | ||||
|                 case 0x03: | ||||
|                     Address = &SerialNumberString; | ||||
|                     Address = (const USB_Descriptor_String_t*)&SerialNumberString; | ||||
| #    if defined(SERIAL_NUMBER) | ||||
|                     Size = pgm_read_byte(&SerialNumberString.Header.Size); | ||||
| #    else | ||||
|                     set_serial_number_descriptor(); | ||||
|                     Size = ((const USB_Descriptor_String_t*)SerialNumberString)->Header.Size; | ||||
| #    endif | ||||
| 
 | ||||
|                     break; | ||||
| #endif | ||||
| #endif // HAS_SERIAL_NUMBER
 | ||||
|             } | ||||
| #ifdef OS_DETECTION_ENABLE | ||||
|             process_wlength(wLength); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Nick Brassel
						Nick Brassel