Update USB Serial Number from SPI flash's uniqueID

Also allow flash to be separately enabled via PLATFORM_EXTRAS.

NOTE: this does *NOT* enable the serial number
in the bootrom.  Still investigating options there.
This commit is contained in:
Henry Gabryjelski 2023-02-17 15:42:46 -08:00
commit 5784c8de77
6 changed files with 71 additions and 5 deletions

View file

@ -5,6 +5,8 @@ PLATFORM=PM3RDV4
#PLATFORM=PM3GENERIC
# If you want more than one PLATFORM_EXTRAS option, separate them by spaces:
#PLATFORM_EXTRAS=BTADDON
#PLATFORM_EXTRAS=FLASH
#PLATFORM_EXTRAS=BTADDON FLASH
#STANDALONE=LF_SAMYRUN
# Uncomment the lines below in order to make a 256KB image

View file

@ -2471,8 +2471,11 @@ static void PacketReceived(PacketCommandNG *packet) {
LED_B_OFF();
break;
}
if (page < 3)
if (page < 3) {
isok = Flash_WipeMemoryPage(page);
// let spiffs check and update its info post flash erase
rdv40_spiffs_check();
}
reply_mix(CMD_ACK, isok, 0, 0, 0, 0);
LED_B_OFF();
@ -2677,6 +2680,17 @@ void __attribute__((noreturn)) AppMain(void) {
I2C_init(false);
#endif
#ifdef WITH_FLASH
if (FlashInit()) {
uint64_t flash_uniqueID = 0;
if (!Flash_CheckBusy(BUSY_TIMEOUT)) { // OK because firmware was built for devices with flash
Flash_UniqueID((uint8_t*)&(flash_uniqueID));
}
FlashStop();
usb_update_serial(flash_uniqueID);
}
#endif
#ifdef WITH_FPC_USART
usart_init(USART_BAUD_RATE, USART_PARITY);
#endif

View file

@ -22,7 +22,7 @@
#include "ticks.h"
#include "dbprint.h"
#include "string.h"
#include "spiffs.h"
#include "usb_cdc.h"
/* here: use NCPS2 @ PA10: */
#define SPI_CSR_NUM 2
@ -436,7 +436,9 @@ out:
return len;
}
// WARNING -- if callers are using a file system (such as SPIFFS),
// they should inform the file system of this change
// e.g., rdv40_spiffs_check()
bool Flash_WipeMemoryPage(uint8_t page) {
if (!FlashInit()) {
if (g_dbglevel > 3) Dbprintf("Flash_WriteData init fail");
@ -451,8 +453,6 @@ bool Flash_WipeMemoryPage(uint8_t page) {
FlashStop();
// let spiffs check and update its info post flash erase
rdv40_spiffs_check();
return true;
}
// Wipes flash memory completely, fills with 0xFF

View file

@ -114,6 +114,10 @@ endif
# parsing additional PLATFORM_EXTRAS tokens
PLATFORM_EXTRAS_TMP:=$(PLATFORM_EXTRAS)
ifneq (,$(findstring FLASH,$(PLATFORM_EXTRAS_TMP)))
PLATFORM_DEFS += -DWITH_FLASH
PLATFORM_EXTRAS_TMP := $(strip $(filter-out FLASH,$(PLATFORM_EXTRAS_TMP)))
endif
ifneq (,$(findstring BTADDON,$(PLATFORM_EXTRAS_TMP)))
PLATFORM_DEFS += -DWITH_FPC_USART_HOST
PLATFORM_EXTRAS_TMP := $(strip $(filter-out BTADDON,$(PLATFORM_EXTRAS_TMP)))

View file

@ -366,11 +366,56 @@ static const char StrProduct[] = {
'p', 0, 'r', 0, 'o', 0, 'x', 0, 'm', 0, 'a', 0, 'r', 0, 'k', 0, '3', 0
};
#ifndef WITH_FLASH
static const char StrSerialNumber[] = {
14, // Length
0x03, // Type is string
'i', 0, 'c', 0, 'e', 0, 'm', 0, 'a', 0, 'n', 0
};
#else // WITH_FLASH is defined
// Manually calculated size of descriptor with unique ID:
// offset 0, lengt h 1: total length field
// offset 1, length 1: descriptor type field
// offset 2, length 12: 6x unicode chars (original string)
// offset 14, length 4: 2x unicode chars (underscores) [[ to avoid descriptor being (size % 8) == 0, OS bug workaround ]]
// offset 18, length 32: 16x unicode chars (8-byte serial as hex characters)
// ============================
// total: 50 bytes
#define USB_STRING_DESCRIPTOR_SERIAL_NUMBER_LENGTH 50
char StrSerialNumber[] = {
14, // Length is initially identical to non-unique version ... The length updated at boot, if unique serial is available
0x03, // Type is string
'i', 0, 'c', 0, 'e', 0, 'm', 0, 'a', 0, 'n', 0,
'_', 0, '_', 0,
'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0,
'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0,
};
void usb_update_serial(uint64_t newSerialNumber) {
static bool configured = false; // TODO: enable by setting to false here...
if (configured) {
return;
}
// run this only once per boot... even if it fails to find serial number
configured = true;
if ((newSerialNumber == 0x0000000000000000) || (newSerialNumber == 0xFFFFFFFFFFFFFFFF)) {
return;
}
// Descriptor is, effectively, initially identical to non-unique serial
// number because it reports the shorter length in the first byte.
// Convert uniqueID's eight bytes to 16 unicode characters in the
// descriptor and, finally, update the descriptor's length, which
// causes the serial number to become visible.
for (uint8_t i = 0; i < 16; i++) {
uint8_t nibble = (uint8_t)((newSerialNumber >> (60 - (4*i))) & 0xFu);
char c = nibble < 10 ? '0' + nibble : 'A' + (nibble-10);
StrSerialNumber[18+(2*i)] = c; // [ 18, 20, 22, .., 46, 48 ]
}
StrSerialNumber[0] = USB_STRING_DESCRIPTOR_SERIAL_NUMBER_LENGTH;
}
#endif
// size includes their own field.
static const char StrMS_OSDescriptor[] = {

View file

@ -31,6 +31,7 @@ bool usb_poll_validate_length(void);
uint32_t usb_read(uint8_t *data, size_t len);
int usb_write(const uint8_t *data, const size_t len);
uint32_t usb_read_ng(uint8_t *data, size_t len);
void usb_update_serial(uint64_t newSerialNumber);
void SetUSBreconnect(int value);
int GetUSBreconnect(void);