libftdi Archives

Subject: [PATCH 3/4] ftdi_eeprom: add UUID auto-generation for serial numbers

From: Vincent Jardin <vjardin@xxxxxxx>
To: libftdi@xxxxxxxxxxxxxxxxxxxxxxx
Cc: thomas.jarosch@xxxxxxxxxxxxx, Vincent Jardin <vjardin@xxxxxxx>
Date: Sat, 7 Mar 2026 00:15:48 +0100
When serial="%UUID%" is set in the config file, ftdi_eeprom generates
a random UUID v4 at flash time and uses it as the device serial number.
This provides unique-per-device identification without manual tracking.

    $ cat device.conf
    serial="%UUID%"
    use_serial=true

    $ ftdi_eeprom --flash-eeprom device.conf
    Generated UUID serial: A3F7B21C-E8F4-404D-86FA-07870EED3582

Uses libuuid (optional dependency, auto-detected by cmake). When libuuid
is not available, using %UUID% prints a clear error and exits.
---
 ftdi_eeprom/CMakeLists.txt | 15 +++++++++++++++
 ftdi_eeprom/example.conf   |  3 ++-
 ftdi_eeprom/main.c         | 23 ++++++++++++++++++++++-
 3 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/ftdi_eeprom/CMakeLists.txt b/ftdi_eeprom/CMakeLists.txt
index 38147b5..30c9f3f 100644
--- a/ftdi_eeprom/CMakeLists.txt
+++ b/ftdi_eeprom/CMakeLists.txt
@@ -1,6 +1,12 @@
 find_package(Confuse REQUIRED)
 find_package(Libintl)
 
+find_path(UUID_INCLUDE_DIR uuid/uuid.h)
+find_library(UUID_LIBRARY NAMES uuid)
+if (UUID_INCLUDE_DIR AND UUID_LIBRARY)
+    set(UUID_FOUND TRUE)
+endif ()
+
 # determine docdir
 include(GNUInstallDirs)
 if (NOT CMAKE_INSTALL_DOCDIR)
@@ -16,6 +22,12 @@ message(STATUS "Building ftdi_eeprom")
 include_directories(${CONFUSE_INCLUDE_DIRS})
 list(APPEND libs ${CONFUSE_LIBRARIES})
 
+if (UUID_FOUND)
+    include_directories(${UUID_INCLUDE_DIR})
+    list(APPEND libs ${UUID_LIBRARY})
+    add_definitions(-DHAVE_UUID)
+endif ()
+
 if (LIBINTL_FOUND)
     include_directories(${LIBINTL_INCLUDE_DIR})
     list(APPEND libs ${LIBINTL_LIBRARIES})
@@ -45,6 +57,9 @@ target_link_libraries(ftdi_eeprom ${CONFUSE_LIBRARIES})
 if (LIBINTL_FOUND)
     target_link_libraries(ftdi_eeprom ${LIBINTL_LIBRARIES})
 endif ()
+if (UUID_FOUND)
+    target_link_libraries(ftdi_eeprom ${UUID_LIBRARY})
+endif ()
 if (NOT SHAREDLIBS AND STATICLIBS)
     target_link_libraries(ftdi_eeprom ${LIBUSB_LIBRARIES})
 endif ()
diff --git a/ftdi_eeprom/example.conf b/ftdi_eeprom/example.conf
index 545703e..a397dd1 100644
--- a/ftdi_eeprom/example.conf
+++ b/ftdi_eeprom/example.conf
@@ -24,7 +24,8 @@ product_id="0x6001"                                           
                        # Integer: Product ID. FT245R factory default 0x
 ##############################
 manufacturer="ACME Inc"                                                        
# String: Manufacturer. FT245R factory default FTDI
 product="USB Serial Converter"                                                 
        # String: Product. FT245R factory default FT245R USB FIFO
-serial="08-15"                                                                 
                # String: Serial"number". FT245R factory default (sample chip) 
A9082P2B
+serial="08-15"                                                                 
                # String: Serial number. FT245R factory default (sample chip) 
A9082P2B
+                                                                               
                # Use "%UUID%" to auto-generate a UUID v4 at flash time 
(requires libuuid)
 use_serial=true                                                                
                # Boolean: Use the serial number string
 
 ############
diff --git a/ftdi_eeprom/main.c b/ftdi_eeprom/main.c
index 566d9e6..20ec4b2 100644
--- a/ftdi_eeprom/main.c
+++ b/ftdi_eeprom/main.c
@@ -38,6 +38,9 @@
 #include <string.h>
 #include <errno.h>
 #include <sys/stat.h>
+#ifdef HAVE_UUID
+#include <uuid/uuid.h>
+#endif
 
 #include <confuse.h>
 #include <libusb.h>
@@ -454,9 +457,27 @@ int main(int argc, char *argv[])
             }
         }
     }
+    const char *cfg_serial = cfg_getstr(cfg, "serial");
+    char uuid_serial[37]; /* "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\0" */
+
+    if (strcmp(cfg_serial, "%UUID%") == 0)
+    {
+#ifdef HAVE_UUID
+        uuid_t uuid;
+
+        uuid_generate(uuid);
+        uuid_unparse_upper(uuid, uuid_serial);
+        cfg_serial = uuid_serial;
+        printf("Generated UUID serial: %s\n", cfg_serial);
+#else
+        fprintf(stderr, "Error: serial=%%UUID%% requires libuuid support (not 
compiled in)\n");
+        exit(-1);
+#endif
+    }
+
     ftdi_eeprom_initdefaults (ftdi, cfg_getstr(cfg, "manufacturer"),
                               cfg_getstr(cfg, "product"),
-                              cfg_getstr(cfg, "serial"));
+                              cfg_serial);
 
     printf("FTDI read eeprom: %d\n", ftdi_read_eeprom(ftdi));
     eeprom_get_value(ftdi, CHIP_SIZE, &my_eeprom_size);
-- 
2.51.0


--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx   

Current Thread