tlv_eeprom: add support for UUID values
authorHugo Villeneuve <hvilleneuve@dimonoff.com>
Fri, 14 Nov 2025 18:43:46 +0000 (13:43 -0500)
committerHugo Villeneuve <hvilleneuve@dimonoff.com>
Mon, 17 Nov 2025 15:50:01 +0000 (10:50 -0500)
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
configure.ac
src/Makefile.am
src/options.c
src/options.h
src/tlv_eeprom.c

index c8b9adb..54ee89d 100644 (file)
@@ -45,6 +45,13 @@ else
     AC_MSG_ERROR([Please install zlib and zlib-devel packages])
 fi
 
+AC_CHECK_HEADERS(uuid/uuid.h,,[AC_MSG_ERROR([You need the uuid library.])])
+
+saved_LIBS=$LIBS
+AC_CHECK_LIB(uuid, uuid_parse, ,[AC_MSG_ERROR([You need the uuid library.])])
+AC_SUBST(UUID_LIBS, $LIBS)
+LIBS=$saved_LIBS
+
 AC_SUBST(WARNINGCFLAGS)
 AC_SUBST(ac_aux_dir)
 
index a6d7523..c9fcbc4 100644 (file)
@@ -4,7 +4,8 @@ AM_CPPFLAGS = \
     $(WARNINGCFLAGS)
 
 LDADD = \
-    @ZLIB_LIBS@
+    @ZLIB_LIBS@ \
+    @UUID_LIBS@
 
 bin_PROGRAMS = mtlv
 
index 9345401..bf8a3c9 100644 (file)
@@ -63,6 +63,7 @@ static struct argp_option argp_options[] = {
        {0,        0,  0,      0, ARGP_CMD_STR, 0 },
        {"dev",   'd', "path", 0, "EEPROM device path (if not using I2C bus/addr)", 0},
        {"key",   'k', "key",  0, "TLV key", 0},
+       {"uuid",  'u', 0,      0, "force key value to UUID format", 0},
        {"value", 'v', "val",  0, "TLV value (string)", 0},
        {"help",  'h', 0,  0, "Give this help list", -1},
        {"usage", USAGE_KEY, 0,    0, "Give a short usage message", -1},
@@ -152,6 +153,9 @@ parse_opt(int key, char *arg, struct argp_state *state)
        case 'k':
                decode_int(arg, state, &options.tlv_key);
                break;
+       case 'u':
+               options.uuid = true;
+               break;
        case 'v':
                options.tlv_value = arg;
                break;
@@ -182,6 +186,7 @@ int parse_command_line_options(int argc, char *argv[])
        options.tlv_cmd = TLV_CMD_NONE;
        options.tlv_key = -1;
        options.tlv_value = NULL;
+       options.uuid = false;
 
        /* Parse our arguments. */
        rc = argp_parse(&argp, argc, argv, ARGP_NO_HELP, 0, NULL);
index f07f6de..8b6ac8e 100644 (file)
@@ -30,6 +30,7 @@ struct options_t {
        enum tlv_cmd_t tlv_cmd;
        int tlv_key;
        char * tlv_value;
+       int uuid;
 };
 
 int parse_command_line_options(int argc, char *argv[]);
index 25786fd..133df10 100644 (file)
 #include <string.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <uuid/uuid.h>
 #include <zlib.h> /* For crc32 routine */
 
 #include "linux-compat.h"
 #include "tlv_eeprom.h"
+#include "options.h"
 
 /* File scope function prototypes */
 static bool is_checksum_valid(u8 *eeprom);
@@ -35,6 +37,8 @@ static int set_bytes(char *buf, const char *string, int *converted_accum);
 #define HDR_SIZE sizeof(struct tlvinfo_header)
 #define ENT_SIZE sizeof(struct tlvinfo_tlv)
 
+extern struct options_t options;
+
 static inline bool is_digit(char c)
 {
        return (c >= '0' && c <= '9');
@@ -267,6 +271,45 @@ static inline const char *tlv_type2name(u8 type)
        return name;
 }
 
+/**
+ *  set_uuid
+ *
+ *  Converts a 16 bits UUID-formatted string into a binary buffer.
+ *
+ *  This function takes a pointer to a 16 bits (8-4-4-4-12) UUID-formatted
+ *  string (i.e."XYXYXYXY-XYXY-XYXY-XYXY-XYXYXYXYXYXY", where "XY" is a
+ *  two-digit hex number).
+ *  The string format is verified and then converted to binary and stored in a
+ *  buffer.
+ */
+static int set_uuid(char *buf, const char *string)
+{
+       int   err = 0;
+       uuid_t uu;
+
+       if (!string) {
+               printf("ERROR: NULL uuid string passed in\n");
+               return -1;
+       }
+
+       err = uuid_parse(string, uu);
+       if (err)
+               goto bad_format;
+
+       memcpy(buf, uu, sizeof(uu));
+
+       return 0;
+
+bad_format:
+       printf("ERROR: Bad UUID string format: %s\n", string);
+       return -1;
+}
+
+static void get_uuid(const u8 *buf, char *out)
+{
+       uuid_unparse(buf, out);
+}
+
 /*
  *  decode_tlv
  *
@@ -334,17 +377,21 @@ static void decode_tlv_value(struct tlvinfo_tlv *tlv, char *value, int value_len
                break;
        case TLV_CODE_VENDOR_EXT:
        default:
-               value[0] = 0;
-               for (i = 0; (i < (DECODE_VALUE_MAX / 5)) && (i < tlv->length);
-                               i++) {
-                       char dec_val[DECODE_VALUE_MAX];
+               if (options.uuid) {
+                       get_uuid(tlv->value, value);
+               } else {
+                       value[0] = 0;
+                       for (i = 0; (i < (DECODE_VALUE_MAX / 5)) && (i < tlv->length);
+                            i++) {
+                               char dec_val[DECODE_VALUE_MAX];
 
-                       sprintf(dec_val, "0x%02X", tlv->value[i]);
+                               sprintf(dec_val, "0x%02X", tlv->value[i]);
 
-                       if (i != 0)
-                               strcat(value, " ");
+                               if (i != 0)
+                                       strcat(value, " ");
 
-                       strcat(value, dec_val);
+                               strcat(value, dec_val);
+                       }
                }
                break;
        }
@@ -616,7 +663,11 @@ bool tlvinfo_add_tlv(u8 *eeprom, int tcode, char *strval)
                return false;
        case TLV_CODE_VENDOR_EXT:
        default:
-               if (set_bytes(data, strval, &new_tlv_len) != 0)
+               if (options.uuid) {
+                       if (set_uuid(data, strval) != 0)
+                               return false;
+                       new_tlv_len = sizeof(uuid_t);
+               } else if (set_bytes(data, strval, &new_tlv_len) != 0)
                        return false;
                break;
        }