diff --git a/bluez/CMakeLists.txt b/bluez/CMakeLists.txt index 4d02933..4d056fa 100644 --- a/bluez/CMakeLists.txt +++ b/bluez/CMakeLists.txt @@ -73,7 +73,8 @@ set(bluez5_SRCS ${bluez5_DIR}/attrib/att.c set(gattlib_SRCS gattlib_adapter.c gattlib_connect.c gattlib_discover.c - gattlib_read_write.c) + gattlib_read_write.c + ../gattlib_common.c) # Added Glib support pkg_search_module(GLIB REQUIRED glib-2.0) diff --git a/bluez/gattlib_connect.c b/bluez/gattlib_connect.c index f6d43a1..2624622 100644 --- a/bluez/gattlib_connect.c +++ b/bluez/gattlib_connect.c @@ -418,70 +418,3 @@ void gattlib_register_indication(gatt_connection_t* connection, gattlib_event_ha connection->indication_handler = indication_handler; connection->indication_user_data = user_data; } - -int gattlib_uuid_to_string(const uuid_t *uuid, char *str, size_t n) { - if (uuid->type == SDP_UUID16) { - snprintf(str, n, "0x%.4x", uuid->value.uuid16); - } else if (uuid->type == SDP_UUID32) { - snprintf(str, n, "0x%.8x", uuid->value.uuid32); - } else if (uuid->type == SDP_UUID128) { - unsigned int data0; - unsigned short data1; - unsigned short data2; - unsigned short data3; - unsigned int data4; - unsigned short data5; - - memcpy(&data0, &uuid->value.uuid128.data[0], 4); - memcpy(&data1, &uuid->value.uuid128.data[4], 2); - memcpy(&data2, &uuid->value.uuid128.data[6], 2); - memcpy(&data3, &uuid->value.uuid128.data[8], 2); - memcpy(&data4, &uuid->value.uuid128.data[10], 4); - memcpy(&data5, &uuid->value.uuid128.data[14], 2); - - snprintf(str, n, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x", - ntohl(data0), ntohs(data1), ntohs(data2), - ntohs(data3), ntohl(data4), ntohs(data5)); - } else { - snprintf(str, n, "Unsupported type:%d", uuid->type); - return -1; - } - return 0; -} - -int gattlib_string_to_uuid(const char *str, size_t n, uuid_t *uuid) { - bt_uuid_t bt_uuid; - - int ret = bt_string_to_uuid(&bt_uuid, str); - if (ret == 0) { - bt_uuid_to_uuid(&bt_uuid, uuid); - } - - return ret; -} - -int gattlib_uuid_cmp(const uuid_t *uuid1, const uuid_t *uuid2) { - if (uuid1->type != uuid2->type) { - return 1; - } else if (uuid1->type == SDP_UUID16) { - if (uuid1->value.uuid16 == uuid2->value.uuid16) { - return 0; - } else { - return 2; - } - } else if (uuid1->type == SDP_UUID32) { - if (uuid1->value.uuid32 == uuid2->value.uuid32) { - return 0; - } else { - return 2; - } - } else if (uuid1->type == SDP_UUID128) { - if (memcmp(&uuid1->value.uuid128, &uuid2->value.uuid128, sizeof(uuid1->value.uuid128)) == 0) { - return 0; - } else { - return 2; - } - } else { - return 3; - } -} diff --git a/bluez/gattlib_read_write.c b/bluez/gattlib_read_write.c index c490f3d..6694735 100644 --- a/bluez/gattlib_read_write.c +++ b/bluez/gattlib_read_write.c @@ -94,19 +94,6 @@ void uuid_to_bt_uuid(uuid_t* uuid, bt_uuid_t* bt_uuid) { } } -void bt_uuid_to_uuid(bt_uuid_t* bt_uuid, uuid_t* uuid) { - memcpy(&uuid->value, &bt_uuid->value, sizeof(uuid->value)); - if (bt_uuid->type == BT_UUID16) { - uuid->type = SDP_UUID16; - } else if (bt_uuid->type == BT_UUID32) { - uuid->type = SDP_UUID32; - } else if (bt_uuid->type == BT_UUID128) { - uuid->type = SDP_UUID128; - } else { - uuid->type = SDP_UUID_UNSPEC; - } -} - int gattlib_read_char_by_uuid(gatt_connection_t* connection, uuid_t* uuid, void* buffer, size_t buffer_len) { diff --git a/dbus/bluez5/lib/uuid.c b/dbus/bluez5/lib/uuid.c new file mode 100644 index 0000000..3ab7fc8 --- /dev/null +++ b/dbus/bluez5/lib/uuid.c @@ -0,0 +1,312 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2011 Nokia Corporation + * Copyright (C) 2011 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include "uuid.h" + +static uint128_t bluetooth_base_uuid = { + .data = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB } +}; + +#define BASE_UUID16_OFFSET 2 +#define BASE_UUID32_OFFSET 0 + +static void bt_uuid16_to_uuid128(const bt_uuid_t *src, bt_uuid_t *dst) +{ + uint16_t be16; + + dst->value.u128 = bluetooth_base_uuid; + dst->type = BT_UUID128; + + /* + * No matter the system: 128-bit UUIDs should be stored + * as big-endian. 16-bit UUIDs are stored on host order. + */ + + be16 = htons(src->value.u16); + memcpy(&dst->value.u128.data[BASE_UUID16_OFFSET], &be16, sizeof(be16)); +} + +static void bt_uuid32_to_uuid128(const bt_uuid_t *src, bt_uuid_t *dst) +{ + uint32_t be32; + + dst->value.u128 = bluetooth_base_uuid; + dst->type = BT_UUID128; + + /* + * No matter the system: 128-bit UUIDs should be stored + * as big-endian. 32-bit UUIDs are stored on host order. + */ + + be32 = htonl(src->value.u32); + memcpy(&dst->value.u128.data[BASE_UUID32_OFFSET], &be32, sizeof(be32)); +} + +void bt_uuid_to_uuid128(const bt_uuid_t *src, bt_uuid_t *dst) +{ + switch (src->type) { + case BT_UUID128: + *dst = *src; + break; + case BT_UUID32: + bt_uuid32_to_uuid128(src, dst); + break; + case BT_UUID16: + bt_uuid16_to_uuid128(src, dst); + break; + case BT_UUID_UNSPEC: + default: + break; + } +} + +static int bt_uuid128_cmp(const bt_uuid_t *u1, const bt_uuid_t *u2) +{ + return memcmp(&u1->value.u128, &u2->value.u128, sizeof(uint128_t)); +} + +int bt_uuid16_create(bt_uuid_t *btuuid, uint16_t value) +{ + memset(btuuid, 0, sizeof(bt_uuid_t)); + btuuid->type = BT_UUID16; + btuuid->value.u16 = value; + + return 0; +} + +int bt_uuid32_create(bt_uuid_t *btuuid, uint32_t value) +{ + memset(btuuid, 0, sizeof(bt_uuid_t)); + btuuid->type = BT_UUID32; + btuuid->value.u32 = value; + + return 0; +} + +int bt_uuid128_create(bt_uuid_t *btuuid, uint128_t value) +{ + memset(btuuid, 0, sizeof(bt_uuid_t)); + btuuid->type = BT_UUID128; + btuuid->value.u128 = value; + + return 0; +} + +int bt_uuid_cmp(const bt_uuid_t *uuid1, const bt_uuid_t *uuid2) +{ + bt_uuid_t u1, u2; + + bt_uuid_to_uuid128(uuid1, &u1); + bt_uuid_to_uuid128(uuid2, &u2); + + 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) +{ + bt_uuid_t tmp; + unsigned int data0; + unsigned short data1; + unsigned short data2; + unsigned short data3; + unsigned int data4; + unsigned short data5; + const uint8_t *data; + + if (!uuid || uuid->type == BT_UUID_UNSPEC) { + snprintf(str, n, "NULL"); + return -EINVAL; + } + + /* Convert to 128 Bit format */ + bt_uuid_to_uuid128(uuid, &tmp); + data = (uint8_t *) &tmp.value.u128; + + 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)); + + 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_base_uuid128(const char *string) +{ + uint16_t uuid; + char dummy[2]; + + if (!is_uuid128(string)) + return 0; + + return sscanf(string, + "0000%04hx-0000-1000-8000-00805%1[fF]9%1[bB]34%1[fF]%1[bB]", + &uuid, dummy, dummy, dummy, dummy) == 5; +} + +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' || *endptr == '-')) { + 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 u128; + uint8_t *val = (uint8_t *) &u128; + + 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); + + bt_uuid128_create(uuid, u128); + + return 0; +} + +int bt_string_to_uuid(bt_uuid_t *uuid, const char *string) +{ + if (is_base_uuid128(string)) + return bt_string_to_uuid16(uuid, string + 4); + else 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; +} + +int bt_uuid_strcmp(const void *a, const void *b) +{ + bt_uuid_t u1, u2; + + if (bt_string_to_uuid(&u1, a) < 0) + return -EINVAL; + + if (bt_string_to_uuid(&u2, b) < 0) + return -EINVAL; + + return bt_uuid_cmp(&u1, &u2); +} + +int bt_uuid_to_le(const bt_uuid_t *src, void *dst) +{ + bt_uuid_t uuid; + + switch (src->type) { + case BT_UUID16: + bt_put_le16(src->value.u16, dst); + return 0; + case BT_UUID32: + bt_uuid32_to_uuid128(src, &uuid); + src = &uuid; + /* Fallthrough */ + case BT_UUID128: + /* Convert from 128-bit BE to LE */ + bswap_128(&src->value.u128, dst); + return 0; + case BT_UUID_UNSPEC: + default: + return -EINVAL; + } +} diff --git a/dbus/bluez5/lib/uuid.h b/dbus/bluez5/lib/uuid.h new file mode 100644 index 0000000..2dcfe9e --- /dev/null +++ b/dbus/bluez5/lib/uuid.h @@ -0,0 +1,181 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2011 Nokia Corporation + * Copyright (C) 2011 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __BLUETOOTH_UUID_H +#define __BLUETOOTH_UUID_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define GENERIC_AUDIO_UUID "00001203-0000-1000-8000-00805f9b34fb" + +#define HSP_HS_UUID "00001108-0000-1000-8000-00805f9b34fb" +#define HSP_AG_UUID "00001112-0000-1000-8000-00805f9b34fb" + +#define HFP_HS_UUID "0000111e-0000-1000-8000-00805f9b34fb" +#define HFP_AG_UUID "0000111f-0000-1000-8000-00805f9b34fb" + +#define ADVANCED_AUDIO_UUID "0000110d-0000-1000-8000-00805f9b34fb" + +#define A2DP_SOURCE_UUID "0000110a-0000-1000-8000-00805f9b34fb" +#define A2DP_SINK_UUID "0000110b-0000-1000-8000-00805f9b34fb" + +#define AVRCP_REMOTE_UUID "0000110e-0000-1000-8000-00805f9b34fb" +#define AVRCP_TARGET_UUID "0000110c-0000-1000-8000-00805f9b34fb" + +#define PANU_UUID "00001115-0000-1000-8000-00805f9b34fb" +#define NAP_UUID "00001116-0000-1000-8000-00805f9b34fb" +#define GN_UUID "00001117-0000-1000-8000-00805f9b34fb" +#define BNEP_SVC_UUID "0000000f-0000-1000-8000-00805f9b34fb" + +#define PNPID_UUID "00002a50-0000-1000-8000-00805f9b34fb" +#define DEVICE_INFORMATION_UUID "0000180a-0000-1000-8000-00805f9b34fb" + +#define GATT_UUID "00001801-0000-1000-8000-00805f9b34fb" +#define IMMEDIATE_ALERT_UUID "00001802-0000-1000-8000-00805f9b34fb" +#define LINK_LOSS_UUID "00001803-0000-1000-8000-00805f9b34fb" +#define TX_POWER_UUID "00001804-0000-1000-8000-00805f9b34fb" +#define BATTERY_UUID "0000180f-0000-1000-8000-00805f9b34fb" +#define SCAN_PARAMETERS_UUID "00001813-0000-1000-8000-00805f9b34fb" + +#define SAP_UUID "0000112D-0000-1000-8000-00805f9b34fb" + +#define HEART_RATE_UUID "0000180d-0000-1000-8000-00805f9b34fb" +#define HEART_RATE_MEASUREMENT_UUID "00002a37-0000-1000-8000-00805f9b34fb" +#define BODY_SENSOR_LOCATION_UUID "00002a38-0000-1000-8000-00805f9b34fb" +#define HEART_RATE_CONTROL_POINT_UUID "00002a39-0000-1000-8000-00805f9b34fb" + +#define HEALTH_THERMOMETER_UUID "00001809-0000-1000-8000-00805f9b34fb" +#define TEMPERATURE_MEASUREMENT_UUID "00002a1c-0000-1000-8000-00805f9b34fb" +#define TEMPERATURE_TYPE_UUID "00002a1d-0000-1000-8000-00805f9b34fb" +#define INTERMEDIATE_TEMPERATURE_UUID "00002a1e-0000-1000-8000-00805f9b34fb" +#define MEASUREMENT_INTERVAL_UUID "00002a21-0000-1000-8000-00805f9b34fb" + +#define CYCLING_SC_UUID "00001816-0000-1000-8000-00805f9b34fb" +#define CSC_MEASUREMENT_UUID "00002a5b-0000-1000-8000-00805f9b34fb" +#define CSC_FEATURE_UUID "00002a5c-0000-1000-8000-00805f9b34fb" +#define SENSOR_LOCATION_UUID "00002a5d-0000-1000-8000-00805f9b34fb" +#define SC_CONTROL_POINT_UUID "00002a55-0000-1000-8000-00805f9b34fb" + +#define RFCOMM_UUID_STR "00000003-0000-1000-8000-00805f9b34fb" + +#define HDP_UUID "00001400-0000-1000-8000-00805f9b34fb" +#define HDP_SOURCE_UUID "00001401-0000-1000-8000-00805f9b34fb" +#define HDP_SINK_UUID "00001402-0000-1000-8000-00805f9b34fb" + +#define HID_UUID "00001124-0000-1000-8000-00805f9b34fb" + +#define DUN_GW_UUID "00001103-0000-1000-8000-00805f9b34fb" + +#define GAP_UUID "00001800-0000-1000-8000-00805f9b34fb" +#define PNP_UUID "00001200-0000-1000-8000-00805f9b34fb" + +#define SPP_UUID "00001101-0000-1000-8000-00805f9b34fb" + +#define OBEX_SYNC_UUID "00001104-0000-1000-8000-00805f9b34fb" +#define OBEX_OPP_UUID "00001105-0000-1000-8000-00805f9b34fb" +#define OBEX_FTP_UUID "00001106-0000-1000-8000-00805f9b34fb" +#define OBEX_PCE_UUID "0000112e-0000-1000-8000-00805f9b34fb" +#define OBEX_PSE_UUID "0000112f-0000-1000-8000-00805f9b34fb" +#define OBEX_PBAP_UUID "00001130-0000-1000-8000-00805f9b34fb" +#define OBEX_MAS_UUID "00001132-0000-1000-8000-00805f9b34fb" +#define OBEX_MNS_UUID "00001133-0000-1000-8000-00805f9b34fb" +#define OBEX_MAP_UUID "00001134-0000-1000-8000-00805f9b34fb" + +/* GATT UUIDs section */ +#define GATT_PRIM_SVC_UUID 0x2800 +#define GATT_SND_SVC_UUID 0x2801 +#define GATT_INCLUDE_UUID 0x2802 +#define GATT_CHARAC_UUID 0x2803 + +/* GATT Characteristic Types */ +#define GATT_CHARAC_DEVICE_NAME 0x2A00 +#define GATT_CHARAC_APPEARANCE 0x2A01 +#define GATT_CHARAC_PERIPHERAL_PRIV_FLAG 0x2A02 +#define GATT_CHARAC_RECONNECTION_ADDRESS 0x2A03 +#define GATT_CHARAC_PERIPHERAL_PREF_CONN 0x2A04 +#define GATT_CHARAC_SERVICE_CHANGED 0x2A05 +#define GATT_CHARAC_SYSTEM_ID 0x2A23 +#define GATT_CHARAC_MODEL_NUMBER_STRING 0x2A24 +#define GATT_CHARAC_SERIAL_NUMBER_STRING 0x2A25 +#define GATT_CHARAC_FIRMWARE_REVISION_STRING 0x2A26 +#define GATT_CHARAC_HARDWARE_REVISION_STRING 0x2A27 +#define GATT_CHARAC_SOFTWARE_REVISION_STRING 0x2A28 +#define GATT_CHARAC_MANUFACTURER_NAME_STRING 0x2A29 +#define GATT_CHARAC_PNP_ID 0x2A50 + +/* GATT Characteristic Descriptors */ +#define GATT_CHARAC_EXT_PROPER_UUID 0x2900 +#define GATT_CHARAC_USER_DESC_UUID 0x2901 +#define GATT_CLIENT_CHARAC_CFG_UUID 0x2902 +#define GATT_SERVER_CHARAC_CFG_UUID 0x2903 +#define GATT_CHARAC_FMT_UUID 0x2904 +#define GATT_CHARAC_AGREG_FMT_UUID 0x2905 +#define GATT_CHARAC_VALID_RANGE_UUID 0x2906 +#define GATT_EXTERNAL_REPORT_REFERENCE 0x2907 +#define GATT_REPORT_REFERENCE 0x2908 + +typedef struct { + enum { + BT_UUID_UNSPEC = 0, + BT_UUID16 = 16, + BT_UUID32 = 32, + BT_UUID128 = 128, + } type; + union { + uint16_t u16; + uint32_t u32; + uint128_t u128; + } value; +} bt_uuid_t; + +int bt_uuid_strcmp(const void *a, const void *b); + +int bt_uuid16_create(bt_uuid_t *btuuid, uint16_t value); +int bt_uuid32_create(bt_uuid_t *btuuid, uint32_t value); +int bt_uuid128_create(bt_uuid_t *btuuid, uint128_t value); + +int bt_uuid_cmp(const bt_uuid_t *uuid1, const bt_uuid_t *uuid2); +void bt_uuid_to_uuid128(const bt_uuid_t *src, bt_uuid_t *dst); + +#define MAX_LEN_UUID_STR 37 + +int bt_uuid_to_string(const bt_uuid_t *uuid, char *str, size_t n); +int bt_string_to_uuid(bt_uuid_t *uuid, const char *string); + +int bt_uuid_to_le(const bt_uuid_t *uuid, void *dst); + +static inline int bt_uuid_len(const bt_uuid_t *uuid) +{ + return uuid->type / 8; +} + +#ifdef __cplusplus +} +#endif + +#endif /* __BLUETOOTH_UUID_H */ diff --git a/gattlib_common.c b/gattlib_common.c new file mode 100644 index 0000000..0b38bb8 --- /dev/null +++ b/gattlib_common.c @@ -0,0 +1,81 @@ +#include "gattlib_internal.h" + +void bt_uuid_to_uuid(bt_uuid_t* bt_uuid, uuid_t* uuid) { + memcpy(&uuid->value, &bt_uuid->value, sizeof(uuid->value)); + if (bt_uuid->type == BT_UUID16) { + uuid->type = SDP_UUID16; + } else if (bt_uuid->type == BT_UUID32) { + uuid->type = SDP_UUID32; + } else if (bt_uuid->type == BT_UUID128) { + uuid->type = SDP_UUID128; + } else { + uuid->type = SDP_UUID_UNSPEC; + } +} + +int gattlib_uuid_to_string(const uuid_t *uuid, char *str, size_t n) { + if (uuid->type == SDP_UUID16) { + snprintf(str, n, "0x%.4x", uuid->value.uuid16); + } else if (uuid->type == SDP_UUID32) { + snprintf(str, n, "0x%.8x", uuid->value.uuid32); + } else if (uuid->type == SDP_UUID128) { + unsigned int data0; + unsigned short data1; + unsigned short data2; + unsigned short data3; + unsigned int data4; + unsigned short data5; + + memcpy(&data0, &uuid->value.uuid128.data[0], 4); + memcpy(&data1, &uuid->value.uuid128.data[4], 2); + memcpy(&data2, &uuid->value.uuid128.data[6], 2); + memcpy(&data3, &uuid->value.uuid128.data[8], 2); + memcpy(&data4, &uuid->value.uuid128.data[10], 4); + memcpy(&data5, &uuid->value.uuid128.data[14], 2); + + snprintf(str, n, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x", + ntohl(data0), ntohs(data1), ntohs(data2), + ntohs(data3), ntohl(data4), ntohs(data5)); + } else { + snprintf(str, n, "Unsupported type:%d", uuid->type); + return -1; + } + return 0; +} + +int gattlib_string_to_uuid(const char *str, size_t n, uuid_t *uuid) { + bt_uuid_t bt_uuid; + + int ret = bt_string_to_uuid(&bt_uuid, str); + if (ret == 0) { + bt_uuid_to_uuid(&bt_uuid, uuid); + } + + return ret; +} + +int gattlib_uuid_cmp(const uuid_t *uuid1, const uuid_t *uuid2) { + if (uuid1->type != uuid2->type) { + return 1; + } else if (uuid1->type == SDP_UUID16) { + if (uuid1->value.uuid16 == uuid2->value.uuid16) { + return 0; + } else { + return 2; + } + } else if (uuid1->type == SDP_UUID32) { + if (uuid1->value.uuid32 == uuid2->value.uuid32) { + return 0; + } else { + return 2; + } + } else if (uuid1->type == SDP_UUID128) { + if (memcmp(&uuid1->value.uuid128, &uuid2->value.uuid128, sizeof(uuid1->value.uuid128)) == 0) { + return 0; + } else { + return 2; + } + } else { + return 3; + } +}