diff --git a/CMakeLists.txt b/CMakeLists.txt index 9718dd86..6c840074 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,7 +59,7 @@ list(GET BLUEZ_VERSIONS 0 BLUEZ_VERSION_MAJOR) list(GET BLUEZ_VERSIONS 1 BLUEZ_VERSION_MINOR) add_definitions(-DBLUEZ_VERSION_MAJOR=${BLUEZ_VERSION_MAJOR} -DBLUEZ_VERSION_MINOR=${BLUEZ_VERSION_MINOR}) -set(GATTLIB_FORCE_DBUS OFF CACHE BOOLEAN "Build gattlib with D-Bus support on Bluez version < v5.42") +set(GATTLIB_FORCE_DBUS OFF CACHE BOOL "Build gattlib with D-Bus support on Bluez version < v5.42") if (BLUEZ_VERSION_MAJOR LESS 5) set(GATTLIB_DBUS FALSE) diff --git a/bluez/gattlib_read_write.c b/bluez/gattlib_read_write.c index f6705297..3df666ab 100644 --- a/bluez/gattlib_read_write.c +++ b/bluez/gattlib_read_write.c @@ -35,6 +35,14 @@ struct gattlib_result_read_uuid_t { size_t* buffer_len; gatt_read_cb_t callback; int completed; + void* user_data; +}; + +struct gattlib_result_write_uuid_t { + const void* buffer; + size_t buffer_len; + gatt_write_cb_t callback; + void* user_data; }; static void gattlib_result_read_uuid_cb(guint8 status, const guint8 *pdu, guint16 len, gpointer user_data) { @@ -64,7 +72,7 @@ static void gattlib_result_read_uuid_cb(guint8 status, const guint8 *pdu, guint1 value += 2; if (gattlib_result->callback) { - gattlib_result->callback(value, buffer_len); + gattlib_result->callback(value, buffer_len, gattlib_result->user_data); } else { void* buffer = malloc(buffer_len); if (buffer == NULL) { @@ -135,7 +143,7 @@ int gattlib_read_char_by_uuid(gatt_connection_t* connection, uuid_t* uuid, } int gattlib_read_char_by_uuid_async(gatt_connection_t* connection, uuid_t* uuid, - gatt_read_cb_t gatt_read_cb) + gatt_read_cb_t gatt_read_cb, void* user_data) { gattlib_context_t* conn_context = connection->context; struct gattlib_result_read_uuid_t* gattlib_result; @@ -151,6 +159,7 @@ int gattlib_read_char_by_uuid_async(gatt_connection_t* connection, uuid_t* uuid, gattlib_result->buffer_len = 0; gattlib_result->callback = gatt_read_cb; gattlib_result->completed = FALSE; + gattlib_result->user_data = user_data; uuid_to_bt_uuid(uuid, &bt_uuid); @@ -187,6 +196,48 @@ int gattlib_write_char_by_handle(gatt_connection_t* connection, uint16_t handle, return 0; } +void gattlib_write_result_cb_async(guint8 status, const guint8 *pdu, guint16 len, gpointer user_data) { + struct gattlib_result_write_uuid_t* gattlib_result = (struct gattlib_result_write_uuid_t*)user_data; + + if(gattlib_result->callback) { + gattlib_result->callback(status, gattlib_result->buffer, gattlib_result->buffer_len, gattlib_result->user_data); + } +} + +int gattlib_write_char_by_handle_async(gatt_connection_t* connection, uint16_t handle, const void* buffer, size_t buffer_len, gatt_write_cb_t gatt_write_cb, void* user_data) { + gattlib_context_t* conn_context = connection->context; + + struct gattlib_result_write_uuid_t* gattlib_result = malloc(sizeof(struct gattlib_result_write_uuid_t)); + if (gattlib_result == NULL) { + return GATTLIB_OUT_OF_MEMORY; + } + gattlib_result->callback = gatt_write_cb; + gattlib_result->buffer = buffer; + gattlib_result->buffer_len = buffer_len; + gattlib_result->user_data = user_data; + + guint ret = gatt_write_char(conn_context->attrib, handle, (void*)buffer, buffer_len, + gattlib_write_result_cb_async, gattlib_result); + if (ret == 0) { + return 1; + } + + return 0; +} + +int gattlib_write_char_by_uuid_async(gatt_connection_t* connection, uuid_t* uuid, const void* buffer, size_t buffer_len, gatt_write_cb_t gatt_write_cb, void* user_data) { + uint16_t handle = 0; + int ret; + + ret = get_handle_from_uuid(connection, uuid, &handle); + if (ret) { + fprintf(stderr, "Fail to find handle for UUID.\n"); + return ret; + } + + return gattlib_write_char_by_handle_async(connection, handle, buffer, buffer_len, gatt_write_cb, user_data); +} + int gattlib_write_char_by_uuid(gatt_connection_t* connection, uuid_t* uuid, const void* buffer, size_t buffer_len) { uint16_t handle = 0; int ret; diff --git a/dbus/gattlib_char.c b/dbus/gattlib_char.c index 0b7064dc..201dae37 100644 --- a/dbus/gattlib_char.c +++ b/dbus/gattlib_char.c @@ -290,7 +290,7 @@ int gattlib_read_char_by_uuid(gatt_connection_t* connection, uuid_t* uuid, void } } -int gattlib_read_char_by_uuid_async(gatt_connection_t* connection, uuid_t* uuid, gatt_read_cb_t gatt_read_cb) { +int gattlib_read_char_by_uuid_async(gatt_connection_t* connection, uuid_t* uuid, gatt_read_cb_t gatt_read_cb, void *user_data) { int ret = GATTLIB_SUCCESS; struct dbus_characteristic dbus_characteristic = get_characteristic_from_uuid(connection, uuid); @@ -304,7 +304,7 @@ int gattlib_read_char_by_uuid_async(gatt_connection_t* connection, uuid_t* uuid, percentage = org_bluez_battery1_get_percentage(dbus_characteristic.battery); - gatt_read_cb((const void*)&percentage, sizeof(percentage)); + gatt_read_cb((const void*)&percentage, sizeof(percentage), user_data); return GATTLIB_SUCCESS; } else { @@ -334,7 +334,7 @@ int gattlib_read_char_by_uuid_async(gatt_connection_t* connection, uuid_t* uuid, gsize n_elements; gconstpointer const_buffer = g_variant_get_fixed_array(out_value, &n_elements, sizeof(guchar)); if (const_buffer) { - gatt_read_cb(const_buffer, n_elements); + gatt_read_cb(const_buffer, n_elements, user_data); } g_object_unref(dbus_characteristic.gatt); @@ -396,6 +396,14 @@ int gattlib_write_char_by_uuid(gatt_connection_t* connection, uuid_t* uuid, cons return ret; } +int gattlib_write_char_by_uuid_async(gatt_connection_t* connection, uuid_t* uuid, const void* buffer, size_t buffer_len, gatt_write_cb_t gatt_write_cb, void* user_data) { + int ret = gattlib_write_char_by_uuid(connection, uuid, buffer, buffer_len); + if(gatt_write_cb) { + gatt_write_cb(ret, buffer, buffer_len, user_data); + } + return ret; +} + int gattlib_write_char_by_handle(gatt_connection_t* connection, uint16_t handle, const void* buffer, size_t buffer_len) { int ret; @@ -411,6 +419,15 @@ int gattlib_write_char_by_handle(gatt_connection_t* connection, uint16_t handle, return ret; } +int gattlib_write_char_by_handle_async(gatt_connection_t* connection, uint16_t handle, const void* buffer, size_t buffer_len, gatt_write_cb_t gatt_write_cb, void* user_data) { + int ret = gattlib_write_char_by_handle(connection, handle, buffer, buffer_len); + if(gatt_write_cb) { + gatt_write_cb(ret, buffer, buffer_len, user_data); + } + return ret; +} + + int gattlib_write_without_response_char_by_uuid(gatt_connection_t* connection, uuid_t* uuid, const void* buffer, size_t buffer_len) { int ret; diff --git a/include/gattlib.h b/include/gattlib.h index 17cec7e1..12b2cb62 100644 --- a/include/gattlib.h +++ b/include/gattlib.h @@ -201,7 +201,16 @@ typedef void (*gatt_connect_cb_t)(gatt_connection_t* connection, void* user_data * @param buffer_len Length of the read data * */ -typedef void* (*gatt_read_cb_t)(const void *buffer, size_t buffer_len); +typedef void* (*gatt_read_cb_t)(const void *buffer, size_t buffer_len, void* user_data); + +/** + * @brief Callback called when GATT characteristic write value has been sent + * + * @param buffer contains the value written. + * @param buffer_len Length of the write data + * + */ +typedef void* (*gatt_write_cb_t)(int status, const void *buffer, size_t buffer_len, void* user_data); /** @@ -447,10 +456,11 @@ int gattlib_read_char_by_uuid(gatt_connection_t* connection, uuid_t* uuid, void* * @param connection Active GATT connection * @param uuid UUID of the GATT characteristic to read * @param gatt_read_cb is the callback to read when the GATT characteristic is available + * @param user_data is the user specific data to pass to the callback * * @return GATTLIB_SUCCESS on success or GATTLIB_* error code */ -int gattlib_read_char_by_uuid_async(gatt_connection_t* connection, uuid_t* uuid, gatt_read_cb_t gatt_read_cb); +int gattlib_read_char_by_uuid_async(gatt_connection_t* connection, uuid_t* uuid, gatt_read_cb_t gatt_read_cb, void* user_data); /** * @brief Function to write to the GATT characteristic UUID @@ -464,6 +474,21 @@ int gattlib_read_char_by_uuid_async(gatt_connection_t* connection, uuid_t* uuid, */ int gattlib_write_char_by_uuid(gatt_connection_t* connection, uuid_t* uuid, const void* buffer, size_t buffer_len); + +/** + * @brief Function to write to the GATT characteristic UUID + * + * @param connection Active GATT connection + * @param uuid UUID of the GATT characteristic to read + * @param buffer contains the values to write to the GATT characteristic + * @param buffer_len is the length of the buffer to write + * @param gatt_write_cb is the function to call at the end of the write + * @param user_data user data for the callback + * + * @return GATTLIB_SUCCESS on success or GATTLIB_* error code + */ +int gattlib_write_char_by_uuid_async(gatt_connection_t* connection, uuid_t* uuid, const void* buffer, size_t buffer_len, gatt_write_cb_t gatt_write_cb, void* user_data); + /** * @brief Function to write to the GATT characteristic handle * @@ -476,6 +501,20 @@ int gattlib_write_char_by_uuid(gatt_connection_t* connection, uuid_t* uuid, cons */ int gattlib_write_char_by_handle(gatt_connection_t* connection, uint16_t handle, const void* buffer, size_t buffer_len); +/** + * @brief Function to write to the GATT characteristic handle + * + * @param connection Active GATT connection + * @param handle is the handle of the GATT characteristic + * @param buffer contains the values to write to the GATT characteristic + * @param buffer_len is the length of the buffer to write + * @param gatt_write_cb is the function to call at the end of the write + * @param user_data user data for the callback + * + * @return GATTLIB_SUCCESS on success or GATTLIB_* error code + */ +int gattlib_write_char_by_handle_async(gatt_connection_t* connection, uint16_t handle, const void* buffer, size_t buffer_len, gatt_write_cb_t gatt_write_cb, void* user_data); + /** * @brief Function to write without response to the GATT characteristic UUID *