diff options
author | Elvis Pfützenreuter <epx@signove.com> | 2011-03-14 15:53:56 -0300 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2011-03-15 10:42:50 +0200 |
commit | bb096e674c6a143db73fb636aa611a392cdb92f8 (patch) | |
tree | bf960dd50051a7c2802a8b04553b075415f0a003 /lib/uuid.c | |
parent | 3ed993262f2e172971fabb13aea9cf5d28bd9ed3 (diff) | |
download | bluez-bb096e674c6a143db73fb636aa611a392cdb92f8.tar.gz |
Add more functions for new UUID handling
This patch adds more functions that are necessary to handle the new
bt_uuid_t type, and moves basic things like byte-swapping functions and
uint128_t type to bluetooth.h.
Diffstat (limited to 'lib/uuid.c')
-rw-r--r-- | lib/uuid.c | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/lib/uuid.c b/lib/uuid.c index d6ca480fa..325016aab 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -27,6 +27,8 @@ #endif #include <string.h> +#include <stdlib.h> +#include <errno.h> #include "uuid.h" @@ -126,3 +128,146 @@ int bt_uuid_cmp(const bt_uuid_t *uuid1, const bt_uuid_t *uuid2) return bt_uuid128_cmp(&u1, &u2); } + +/* + * convert the UUID to string, copying a maximum of n characters. + */ +int bt_uuid_to_string(const bt_uuid_t *uuid, char *str, size_t n) +{ + if (!uuid) { + snprintf(str, n, "NULL"); + return -EINVAL; + } + + switch (uuid->type) { + case BT_UUID16: + snprintf(str, n, "%.4x", uuid->value.u16); + break; + case BT_UUID32: + snprintf(str, n, "%.8x", uuid->value.u32); + break; + case BT_UUID128: { + unsigned int data0; + unsigned short data1; + unsigned short data2; + unsigned short data3; + unsigned int data4; + unsigned short data5; + + uint128_t nvalue; + const uint8_t *data = (uint8_t *) &nvalue; + + hton128(&uuid->value.u128, &nvalue); + + memcpy(&data0, &data[0], 4); + memcpy(&data1, &data[4], 2); + memcpy(&data2, &data[6], 2); + memcpy(&data3, &data[8], 2); + memcpy(&data4, &data[10], 4); + memcpy(&data5, &data[14], 2); + + snprintf(str, n, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x", + ntohl(data0), ntohs(data1), + ntohs(data2), ntohs(data3), + ntohl(data4), ntohs(data5)); + } + break; + default: + snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type); + return -EINVAL; /* Enum type of UUID not set */ + } + + return 0; +} + +static inline int is_uuid128(const char *string) +{ + return (strlen(string) == 36 && + string[8] == '-' && + string[13] == '-' && + string[18] == '-' && + string[23] == '-'); +} + +static inline int is_uuid32(const char *string) +{ + return (strlen(string) == 8 || strlen(string) == 10); +} + +static inline int is_uuid16(const char *string) +{ + return (strlen(string) == 4 || strlen(string) == 6); +} + +static int bt_string_to_uuid16(bt_uuid_t *uuid, const char *string) +{ + uint16_t u16; + char *endptr = NULL; + + u16 = strtol(string, &endptr, 16); + if (endptr && *endptr == '\0') { + bt_uuid16_create(uuid, u16); + return 0; + } + + return -EINVAL; +} + +static int bt_string_to_uuid32(bt_uuid_t *uuid, const char *string) +{ + uint32_t u32; + char *endptr = NULL; + + u32 = strtol(string, &endptr, 16); + if (endptr && *endptr == '\0') { + bt_uuid32_create(uuid, u32); + return 0; + } + + return -EINVAL; +} + +static int bt_string_to_uuid128(bt_uuid_t *uuid, const char *string) +{ + uint32_t data0, data4; + uint16_t data1, data2, data3, data5; + uint128_t n128, u128; + uint8_t *val = (uint8_t *) &n128; + + if (sscanf(string, "%08x-%04hx-%04hx-%04hx-%08x%04hx", + &data0, &data1, &data2, + &data3, &data4, &data5) != 6) + return -EINVAL; + + data0 = htonl(data0); + data1 = htons(data1); + data2 = htons(data2); + data3 = htons(data3); + data4 = htonl(data4); + data5 = htons(data5); + + memcpy(&val[0], &data0, 4); + memcpy(&val[4], &data1, 2); + memcpy(&val[6], &data2, 2); + memcpy(&val[8], &data3, 2); + memcpy(&val[10], &data4, 4); + memcpy(&val[14], &data5, 2); + + ntoh128(&n128, &u128); + + bt_uuid128_create(uuid, u128); + + return 0; +} + +int bt_string_to_uuid(bt_uuid_t *uuid, const char *string) +{ + if (is_uuid128(string)) + return bt_string_to_uuid128(uuid, string); + else if (is_uuid32(string)) + return bt_string_to_uuid32(uuid, string); + else if (is_uuid16(string)) + return bt_string_to_uuid16(uuid, string); + + return -EINVAL; +} |