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
					
				
					 2 changed files with 82 additions and 13 deletions
				
			
		| 
						 | 
				
			
			@ -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;
 | 
			
		||||
                    Size    = pgm_read_byte(&SerialNumberString.Header.Size);
 | 
			
		||||
                    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…
	
	Add table
		Add a link
		
	
		Reference in a new issue