diff --git a/examples/ble_scan/ble_scan.c b/examples/ble_scan/ble_scan.c index ae7bd15..b69967e 100644 --- a/examples/ble_scan/ble_scan.c +++ b/examples/ble_scan/ble_scan.c @@ -213,9 +213,9 @@ static void *ble_connect_device(void *arg) { printf("------------START %s ---------------\n", addr); - gatt_connection = gattlib_connect(NULL, addr, BDADDR_LE_PUBLIC, BT_IO_SEC_LOW, 0, 0); + gatt_connection = gattlib_connect(NULL, addr, BDADDR_LE_PUBLIC, BT_SEC_LOW, 0, 0); if (gatt_connection == NULL) { - gatt_connection = gattlib_connect(NULL, addr, BDADDR_LE_RANDOM, BT_IO_SEC_LOW, 0, 0); + gatt_connection = gattlib_connect(NULL, addr, BDADDR_LE_RANDOM, BT_SEC_LOW, 0, 0); if (gatt_connection == NULL) { fprintf(stderr, "Fail to connect to the bluetooth device.\n"); //gattlib_disconnect(connection); diff --git a/examples/discover/discover.c b/examples/discover/discover.c index 6b8b109..a08e01b 100644 --- a/examples/discover/discover.c +++ b/examples/discover/discover.c @@ -40,7 +40,7 @@ int main(int argc, char *argv[]) return 1; } - connection = gattlib_connect(NULL, argv[1], BDADDR_LE_PUBLIC, BT_IO_SEC_LOW, 0, 0); + connection = gattlib_connect(NULL, argv[1], BDADDR_LE_PUBLIC, BT_SEC_LOW, 0, 0); if (connection == NULL) { fprintf(stderr, "Fail to connect to the bluetooth device.\n"); return 1; diff --git a/examples/gatttool/gatttool.c b/examples/gatttool/gatttool.c index edf6e05..261df84 100644 --- a/examples/gatttool/gatttool.c +++ b/examples/gatttool/gatttool.c @@ -222,6 +222,19 @@ done: g_main_loop_quit(event_loop); } +static 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; + } +} + static gboolean characteristics_read(gpointer user_data) { gatt_connection_t* connection = (gatt_connection_t*)user_data; @@ -229,8 +242,11 @@ static gboolean characteristics_read(gpointer user_data) if (opt_uuid != NULL) { uint8_t buffer[0x100]; + uuid_t uuid; - int len = gattlib_read_char_by_uuid(connection, opt_uuid, buffer, sizeof(buffer)); + bt_uuid_to_uuid(opt_uuid, &uuid); + + int len = gattlib_read_char_by_uuid(connection, &uuid, buffer, sizeof(buffer)); if (len == 0) { return FALSE; } else { @@ -368,7 +384,10 @@ static gboolean characteristics_desc(gpointer user_data) return FALSE; } else { for (int i = 0; i < descriptor_count; i++) { - g_print("handle = 0x%04x, uuid = %s\n", descriptors[i].handle, descriptors[i].uuid); + char uuid_str[MAX_LEN_UUID_STR + 1]; + + gattlib_uuid_to_string(&descriptors[i].uuid, uuid_str, MAX_LEN_UUID_STR + 1); + g_print("handle = 0x%04x, uuid = %s\n", descriptors[i].handle, uuid_str); } free(descriptors); return TRUE; diff --git a/examples/gatttool/interactive.c b/examples/gatttool/interactive.c index 7e6f2f3..c5a521a 100644 --- a/examples/gatttool/interactive.c +++ b/examples/gatttool/interactive.c @@ -451,7 +451,10 @@ static void cmd_char_desc(int argcp, char **argvp) int ret = gattlib_discover_desc_range(g_connection, start, end, &descriptors, &descriptor_count); if (ret == 0) { for (int i = 0; i < descriptor_count; i++) { - printf("handle: 0x%04x, uuid: %s\n", descriptors[i].handle, descriptors[i].uuid); + char uuid_str[MAX_LEN_UUID_STR + 1]; + + gattlib_uuid_to_string(&descriptors[i].uuid, uuid_str, MAX_LEN_UUID_STR + 1); + printf("handle: 0x%04x, uuid: %s\n", descriptors[i].handle, uuid_str); } free(descriptors); } diff --git a/examples/read_write/read_write.c b/examples/read_write/read_write.c index 0468aed..e9491c9 100644 --- a/examples/read_write/read_write.c +++ b/examples/read_write/read_write.c @@ -30,7 +30,7 @@ typedef enum { READ, WRITE} operation_t; operation_t g_operation; -static bt_uuid_t g_uuid; +static uuid_t g_uuid; long int value_data; static void usage(char *argv[]) { @@ -63,12 +63,12 @@ int main(int argc, char *argv[]) { return 1; } - if (bt_string_to_uuid(&g_uuid, argv[3]) < 0) { + if (gattlib_string_to_uuid(argv[3], strlen(argv[3]) + 1, &g_uuid) < 0) { usage(argv); return 1; } - connection = gattlib_connect(NULL, argv[1], BDADDR_LE_PUBLIC, BT_IO_SEC_LOW, 0, 0); + connection = gattlib_connect(NULL, argv[1], BDADDR_LE_PUBLIC, BT_SEC_LOW, 0, 0); if (connection == NULL) { fprintf(stderr, "Fail to connect to the bluetooth device.\n"); return 1; diff --git a/include/gattlib.h b/include/gattlib.h index cdaa398..9e8f3f0 100644 --- a/include/gattlib.h +++ b/include/gattlib.h @@ -29,8 +29,7 @@ #include #include -#include "uuid.h" -#include "btio.h" +#include #ifndef BDADDR_BREDR /* GattLib note: BD Address have only been introduced into Bluez v4.100. */ @@ -46,14 +45,12 @@ #define ATT_MAX_MTU ATT_MAX_VALUE_LEN #endif -#if BLUEZ_VERSION_MAJOR == 4 typedef enum { - BT_IO_SEC_SDP = 0, - BT_IO_SEC_LOW, - BT_IO_SEC_MEDIUM, - BT_IO_SEC_HIGH, -} BtIOSecLevel; -#endif + BT_SEC_SDP = 0, + BT_SEC_LOW, + BT_SEC_MEDIUM, + BT_SEC_HIGH, +} gattlib_bt_sec_level_t; typedef struct _GAttrib GAttrib; @@ -83,10 +80,10 @@ typedef void* (*gatt_read_cb_t)(void* buffer, size_t buffer_len); * @param mtu Specify the MTU size */ gatt_connection_t *gattlib_connect(const gchar *src, const gchar *dst, - uint8_t dest_type, BtIOSecLevel sec_level, int psm, int mtu); + uint8_t dest_type, gattlib_bt_sec_level_t sec_level, int psm, int mtu); gatt_connection_t *gattlib_connect_async(const gchar *src, const gchar *dst, - uint8_t dest_type, BtIOSecLevel sec_level, int psm, int mtu, + uint8_t dest_type, gattlib_bt_sec_level_t sec_level, int psm, int mtu, gatt_connect_cb_t connect_cb); int gattlib_disconnect(gatt_connection_t* connection); @@ -94,20 +91,20 @@ int gattlib_disconnect(gatt_connection_t* connection); typedef struct { uint16_t attr_handle_start; uint16_t attr_handle_end; - bt_uuid_t uuid; + uuid_t uuid; } gattlib_primary_service_t; typedef struct { uint16_t handle; uint8_t properties; uint16_t value_handle; - bt_uuid_t uuid; + uuid_t uuid; } gattlib_characteristic_t; typedef struct { - char uuid[MAX_LEN_UUID_STR + 1]; uint16_t handle; uint16_t uuid16; + uuid_t uuid; } gattlib_descriptor_t; int gattlib_discover_primary(gatt_connection_t* connection, gattlib_primary_service_t** services, int* services_count); @@ -116,15 +113,15 @@ int gattlib_discover_char(gatt_connection_t* connection, gattlib_characteristic_ int gattlib_discover_desc_range(gatt_connection_t* connection, int start, int end, gattlib_descriptor_t** descriptors, int* descriptor_count); int gattlib_discover_desc(gatt_connection_t* connection, gattlib_descriptor_t** descriptors, int* descriptor_count); -int gattlib_read_char_by_uuid(gatt_connection_t* connection, bt_uuid_t* uuid, void* buffer, size_t buffer_len); -int gattlib_read_char_by_uuid_async(gatt_connection_t* connection, bt_uuid_t* uuid, gatt_read_cb_t gatt_read_cb); +int gattlib_read_char_by_uuid(gatt_connection_t* connection, uuid_t* uuid, void* buffer, size_t buffer_len); +int gattlib_read_char_by_uuid_async(gatt_connection_t* connection, uuid_t* uuid, gatt_read_cb_t gatt_read_cb); int gattlib_write_char_by_handle(gatt_connection_t* connection, uint16_t handle, void* buffer, size_t buffer_len); void gattlib_register_notification(gatt_connection_t* connection, gattlib_event_handler_t notification_handler, void* user_data); void gattlib_register_indication(gatt_connection_t* connection, gattlib_event_handler_t indication_handler, void* user_data); -int gattlib_uuid_to_string(const bt_uuid_t *uuid, char *str, size_t n); -int gattlib_string_to_uuid(bt_uuid_t *uuid, const char *str); +int gattlib_uuid_to_string(const uuid_t *uuid, char *str, size_t n); +int gattlib_string_to_uuid(const char *str, size_t n, uuid_t *uuid); #endif diff --git a/include/gattlib_internal.h b/include/gattlib_internal.h index 3fdc8b3..acbccf9 100644 --- a/include/gattlib_internal.h +++ b/include/gattlib_internal.h @@ -29,6 +29,8 @@ #include "gattlib.h" +#include "uuid.h" + #if BLUEZ_VERSION_MAJOR == 5 #include "src/shared/att-types.h" #include "src/shared/util.h" @@ -50,4 +52,7 @@ GSource* gattlib_watch_connection_full(GIOChannel* io, GIOCondition condition, GIOFunc func, gpointer user_data, GDestroyNotify notify); GSource* gattlib_timeout_add_seconds(guint interval, GSourceFunc function, gpointer data); +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); + #endif diff --git a/src/gattlib_connect.c b/src/gattlib_connect.c index 1295215..e8a8615 100644 --- a/src/gattlib_connect.c +++ b/src/gattlib_connect.c @@ -27,7 +27,6 @@ #include #include -#include "uuid.h" #include "gattlib_internal.h" @@ -268,13 +267,29 @@ static gatt_connection_t *initialize_gattlib_connection(const gchar *src, const } } +static BtIOSecLevel get_bt_io_sec_level(gattlib_bt_sec_level_t sec_level) { + switch(sec_level) { + case BT_SEC_SDP: + return BT_IO_SEC_SDP; + case BT_SEC_LOW: + return BT_IO_SEC_LOW; + case BT_SEC_MEDIUM: + return BT_IO_SEC_MEDIUM; + case BT_SEC_HIGH: + return BT_IO_SEC_HIGH; + default: + return BT_IO_SEC_SDP; + } +} + gatt_connection_t *gattlib_connect_async(const gchar *src, const gchar *dst, - uint8_t dest_type, BtIOSecLevel sec_level, int psm, int mtu, + uint8_t dest_type, gattlib_bt_sec_level_t sec_level, int psm, int mtu, gatt_connect_cb_t connect_cb) { io_connect_arg_t* io_connect_arg = malloc(sizeof(io_connect_arg_t)); + BtIOSecLevel bt_io_sec_level = get_bt_io_sec_level(sec_level); - return initialize_gattlib_connection(src, dst, dest_type, sec_level, + return initialize_gattlib_connection(src, dst, dest_type, bt_io_sec_level, psm, mtu, connect_cb, io_connect_arg); } @@ -295,12 +310,13 @@ static gboolean connection_timeout(gpointer user_data) { * @param mtu Specify the MTU size */ gatt_connection_t *gattlib_connect(const gchar *src, const gchar *dst, - uint8_t dest_type, BtIOSecLevel sec_level, int psm, int mtu) + uint8_t dest_type, gattlib_bt_sec_level_t sec_level, int psm, int mtu) { + BtIOSecLevel bt_io_sec_level = get_bt_io_sec_level(sec_level); io_connect_arg_t io_connect_arg; GSource* timeout; - gatt_connection_t *conn = initialize_gattlib_connection(src, dst, dest_type, sec_level, + gatt_connection_t *conn = initialize_gattlib_connection(src, dst, dest_type, bt_io_sec_level, psm, mtu, NULL, &io_connect_arg); if (conn == NULL) { if (io_connect_arg.error) { @@ -401,10 +417,43 @@ void gattlib_register_indication(gatt_connection_t* connection, gattlib_event_ha connection->indication_user_data = user_data; } -int gattlib_uuid_to_string(const bt_uuid_t *uuid, char *str, size_t n) { - return bt_uuid_to_string(uuid, str, n); +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, "0x%.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(bt_uuid_t *uuid, const char *str) { - return bt_string_to_uuid(uuid, str); +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; } diff --git a/src/gattlib_discover.c b/src/gattlib_discover.c index 92a2e93..d1a093b 100644 --- a/src/gattlib_discover.c +++ b/src/gattlib_discover.c @@ -23,9 +23,11 @@ #include #include +#include #include "gattlib_internal.h" +#include "uuid.h" #include "att.h" #include "gattrib.h" #include "gatt.h" @@ -59,7 +61,7 @@ static void primary_all_cb(uint8_t status, GSList *services, void *user_data) { data->services[i].attr_handle_start = prim->range.start; data->services[i].attr_handle_end = prim->range.end; - bt_string_to_uuid(&data->services[i].uuid, prim->uuid); + gattlib_string_to_uuid(prim->uuid, MAX_LEN_UUID_STR + 1, &data->services[i].uuid); assert(i < data->services_count); } @@ -122,7 +124,7 @@ static void characteristic_cb(uint8_t status, GSList *characteristics, void *use data->characteristics[i].handle = chars->handle; data->characteristics[i].properties = chars->properties; data->characteristics[i].value_handle = chars->value_handle; - bt_string_to_uuid(&data->characteristics[i].uuid, chars->uuid); + gattlib_string_to_uuid(chars->uuid, MAX_LEN_UUID_STR + 1, &data->characteristics[i].uuid); assert(i < data->characteristics_count); } @@ -232,7 +234,7 @@ static void char_desc_cb(uint8_t status, GSList *descriptors, void *user_data) data->descriptors[i].handle = desc->handle; data->descriptors[i].uuid16 = desc->uuid16; - strncpy(data->descriptors[i].uuid, desc->uuid, MAX_LEN_UUID_STR); + gattlib_string_to_uuid(desc->uuid, MAX_LEN_UUID_STR + 1, &data->descriptors[i].uuid); assert(i < data->descriptors_count); } diff --git a/src/gattlib_read_write.c b/src/gattlib_read_write.c index 6e2d0d7..4af1de1 100644 --- a/src/gattlib_read_write.c +++ b/src/gattlib_read_write.c @@ -25,6 +25,7 @@ #include "gattlib_internal.h" +#include "uuid.h" #include "att.h" #include "gattrib.h" #include "gatt.h" @@ -81,10 +82,37 @@ done: } } -int gattlib_read_char_by_uuid(gatt_connection_t* connection, bt_uuid_t* uuid, +void uuid_to_bt_uuid(uuid_t* uuid, bt_uuid_t* bt_uuid) { + memcpy(&bt_uuid->value, &uuid->value, sizeof(bt_uuid->value)); + if (uuid->type == SDP_UUID16) { + bt_uuid->type = BT_UUID16; + } else if (uuid->type == SDP_UUID32) { + bt_uuid->type = BT_UUID32; + } else if (uuid->type == SDP_UUID128) { + bt_uuid->type = BT_UUID128; + } else { + bt_uuid->type = BT_UUID_UNSPEC; + } +} + +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) { struct gattlib_result_read_uuid_t* gattlib_result; + bt_uuid_t bt_uuid; const int start = 0x0001; const int end = 0xffff; int len; @@ -99,7 +127,9 @@ int gattlib_read_char_by_uuid(gatt_connection_t* connection, bt_uuid_t* uuid, gattlib_result->callback = NULL; gattlib_result->completed = FALSE; - gatt_read_char_by_uuid(connection->attrib, start, end, uuid, + uuid_to_bt_uuid(uuid, &bt_uuid); + + gatt_read_char_by_uuid(connection->attrib, start, end, &bt_uuid, gattlib_result_read_uuid_cb, gattlib_result); // Wait for completion of the event @@ -113,12 +143,13 @@ int gattlib_read_char_by_uuid(gatt_connection_t* connection, bt_uuid_t* uuid, return len; } -int gattlib_read_char_by_uuid_async(gatt_connection_t* connection, bt_uuid_t* uuid, +int gattlib_read_char_by_uuid_async(gatt_connection_t* connection, uuid_t* uuid, gatt_read_cb_t gatt_read_cb) { struct gattlib_result_read_uuid_t* gattlib_result; const int start = 0x0001; const int end = 0xffff; + bt_uuid_t bt_uuid; int i; gattlib_result = malloc(sizeof(struct gattlib_result_read_uuid_t)); @@ -131,7 +162,9 @@ int gattlib_read_char_by_uuid_async(gatt_connection_t* connection, bt_uuid_t* uu gattlib_result->callback = gatt_read_cb; gattlib_result->completed = FALSE; - return gatt_read_char_by_uuid(connection->attrib, start, end, uuid, + uuid_to_bt_uuid(uuid, &bt_uuid); + + return gatt_read_char_by_uuid(connection->attrib, start, end, &bt_uuid, gattlib_result_read_uuid_cb, gattlib_result); }