diff --git a/Makefile.dep b/Makefile.dep index 5cbbf1db90aa41bf4d542e949978d4fffa598335..fec1eac1250fb1697133fa0b545c8fb1cb391b16 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -780,6 +780,7 @@ endif ifneq (,$(filter uuid,$(USEMODULE))) USEMODULE += hashes USEMODULE += random + USEMODULE += fmt endif # Enable periph_gpio when periph_gpio_irq is enabled diff --git a/sys/include/uuid.h b/sys/include/uuid.h index 2616ebd3b4beab5f77afa2c10b61dd442a64dfd5..1c8acb41a90f17139ed5c9a40b215ed4fc1f0cbb 100644 --- a/sys/include/uuid.h +++ b/sys/include/uuid.h @@ -38,6 +38,8 @@ extern "C" { #define UUID_NODE_LEN (6U) /**< Size of the node identifier in bytes */ +#define UUID_STR_LEN (36U) /**< Size of a string UUID without null character */ + /** * @name UUID version identifiers * @{ @@ -140,6 +142,14 @@ static inline bool uuid_equal(uuid_t *uuid1, uuid_t *uuid2) return (memcmp(uuid1, uuid2, sizeof(uuid_t)) == 0); } +/** + * @brief Generate an UUID string from an UUID structure + * + * @param[in] uuid UUID + * @param[out] str null-terminated UUID string, must be at least UUID_STR_LEN + 1 bytes + */ +void uuid_to_string(const uuid_t *uuid, char *str); + #ifdef __cplusplus } #endif diff --git a/sys/uuid/uuid.c b/sys/uuid/uuid.c index a7c9c95e4073c5413c414c627d25328bc881dba3..aeb94e28b44b2655c6fb206048152511b45e2a37 100644 --- a/sys/uuid/uuid.c +++ b/sys/uuid/uuid.c @@ -23,6 +23,7 @@ #include "hashes/sha1.h" #include "random.h" #include "uuid.h" +#include "fmt.h" const uuid_t uuid_namespace_dns = { /* 6ba7b810-9dad-11d1-80b4-00c04fd430c8 */ .time_low.u8 = { 0x6b, 0xa7, 0xb8, 0x10 }, @@ -110,3 +111,20 @@ void uuid_v5(uuid_t *uuid, const uuid_t *ns, const uint8_t *name, size_t len) _set_version(uuid, UUID_V5); _set_reserved(uuid); } + +void uuid_to_string(const uuid_t *uuid, char *str) +{ + char *p = str; + p += fmt_u32_hex(p, byteorder_ntohl(uuid->time_low)); + p += fmt_char(p, '-'); + p += fmt_u16_hex(p, byteorder_ntohs(uuid->time_mid)); + p += fmt_char(p, '-'); + p += fmt_u16_hex(p, byteorder_ntohs(uuid->time_hi)); + p += fmt_char(p, '-'); + p += fmt_byte_hex(p, uuid->clk_seq_hi_res); + p += fmt_byte_hex(p, uuid->clk_seq_low); + p += fmt_char(p, '-'); + p += fmt_bytes_hex(p, uuid->node, UUID_NODE_LEN); + *p = '\0'; + fmt_to_lower(str, str); +} diff --git a/tests/unittests/tests-uuid/tests-uuid.c b/tests/unittests/tests-uuid/tests-uuid.c index 0552d24ae877ed175d31f26f21bcfedde12539da..aceadf39827aa00f92da7a55a7407cca9eac1665 100644 --- a/tests/unittests/tests-uuid/tests-uuid.c +++ b/tests/unittests/tests-uuid/tests-uuid.c @@ -95,12 +95,33 @@ void test_uuid_v5(void) TEST_ASSERT_EQUAL_INT(uuid_version(&uuid_next), UUID_V5); } +void test_uuid_str(void) +{ + char str[40]; + const char dns[] = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"; + uuid_to_string(&uuid_namespace_dns, str); + TEST_ASSERT_EQUAL_INT(0, memcmp(dns, str, sizeof(dns))); + + const char url[] = "6ba7b811-9dad-11d1-80b4-00c04fd430c8"; + uuid_to_string(&uuid_namespace_url, str); + TEST_ASSERT_EQUAL_INT(0, memcmp(url, str, sizeof(dns))); + + const char iso[] = "6ba7b812-9dad-11d1-80b4-00c04fd430c8"; + uuid_to_string(&uuid_namespace_iso, str); + TEST_ASSERT_EQUAL_INT(0, memcmp(iso, str, sizeof(dns))); + + const char x500[] = "6ba7b814-9dad-11d1-80b4-00c04fd430c8"; + uuid_to_string(&uuid_namespace_x500, str); + TEST_ASSERT_EQUAL_INT(0, memcmp(x500, str, sizeof(dns))); +} + Test *tests_uuid_all(void) { EMB_UNIT_TESTFIXTURES(fixtures) { new_TestFixture(test_uuid_v3), new_TestFixture(test_uuid_v4), new_TestFixture(test_uuid_v5), + new_TestFixture(test_uuid_str), }; EMB_UNIT_TESTCALLER(uuid_tests, NULL, NULL, fixtures);