gattlib: Introduce 'gattlib_register_on_disconnect()'

pull/95/head
Olivier Martin 2019-05-03 09:47:58 +02:00
parent bcac05a811
commit 98ac9e5d2b
3 changed files with 42 additions and 10 deletions

View File

@ -220,7 +220,8 @@ gboolean on_handle_device_property_change(
const gchar *const *arg_invalidated_properties,
gpointer user_data)
{
GMainLoop *loop = user_data;
gatt_connection_t* connection = user_data;
gattlib_context_t* conn_context = connection->context;
// Retrieve 'Value' from 'arg_changed_properties'
if (g_variant_n_children (arg_changed_properties) > 0) {
@ -231,8 +232,16 @@ gboolean on_handle_device_property_change(
g_variant_get (arg_changed_properties, "a{sv}", &iter);
while (g_variant_iter_loop (iter, "{&sv}", &key, &value)) {
if (strcmp(key, "UUIDs") == 0) {
g_main_loop_quit(loop);
// When UUIDs properties appear, we are connected to the device
g_main_loop_quit(conn_context->connection_loop);
break;
} else if (strcmp(key, "Connected") == 0) {
if (!g_variant_get_boolean(value)) {
// Disconnection case
if (connection->disconnection_handler) {
connection->disconnection_handler(connection->disconnection_user_data);
}
}
}
}
}
@ -316,17 +325,19 @@ gatt_connection_t *gattlib_connect(const char *src, const char *dst,
// Wait for the property 'UUIDs' to be changed. We assume 'org.bluez.GattService1
// and 'org.bluez.GattCharacteristic1' to be advertised at that moment.
GMainLoop *loop = g_main_loop_new(NULL, 0);
conn_context->connection_loop = g_main_loop_new(NULL, 0);
// Register a handle for notification
g_signal_connect(device,
"g-properties-changed",
G_CALLBACK (on_handle_device_property_change),
loop);
connection);
g_timeout_add_seconds (CONNECT_TIMEOUT, stop_scan_func, loop);
g_main_loop_run(loop);
g_main_loop_unref(loop);
g_timeout_add_seconds (CONNECT_TIMEOUT, stop_scan_func, conn_context->connection_loop);
g_main_loop_run(conn_context->connection_loop);
g_main_loop_unref(conn_context->connection_loop);
// Set the attribute to NULL even if not required
conn_context->connection_loop = NULL;
return connection;
@ -364,6 +375,11 @@ int gattlib_disconnect(gatt_connection_t* connection) {
return 0;
}
void gattlib_register_on_disconnect(gatt_connection_t *connection, gattlib_disconnection_handler_t handler, void* user_data) {
connection->disconnection_handler = handler;
connection->disconnection_user_data = user_data;
}
// Bluez was using org.bluez.Device1.GattServices until 5.37 to expose the list of available GATT Services
#if BLUEZ_VERSION < BLUEZ_VERSIONS(5, 38)
int gattlib_discover_primary(gatt_connection_t* connection, gattlib_primary_service_t** services, int* services_count) {

View File

@ -41,6 +41,10 @@
typedef struct {
char* device_object_path;
OrgBluezDevice1* device;
// This attribute is only used during the connection stage. By placing the attribute here, we can pass
// `gatt_connection_t` to
GMainLoop *connection_loop;
} gattlib_context_t;
#endif

View File

@ -69,6 +69,14 @@ typedef struct _GAttrib GAttrib;
typedef void (*gattlib_event_handler_t)(const uuid_t* uuid, const uint8_t* data, size_t data_length, void* user_data);
/**
* @brief Handler called on disconnection
*
* @param connection Connection that is disconnecting
* @param user_data Data defined when calling `gattlib_register_on_disconnect()`
*/
typedef void (*gattlib_disconnection_handler_t)(void* user_data);
typedef struct _gatt_connection_t {
void* context;
@ -77,17 +85,19 @@ typedef struct _gatt_connection_t {
gattlib_event_handler_t indication_handler;
void* indication_user_data;
gattlib_disconnection_handler_t disconnection_handler;
void* disconnection_user_data;
} gatt_connection_t;
typedef void (*gattlib_discovered_device_t)(const char* addr, const char* name);
typedef void (*gatt_connect_cb_t)(gatt_connection_t* connection, void* user_data);
typedef void* (*gatt_read_cb_t)(const void* buffer, size_t buffer_len);
/**
* Open Bluetooth adapter
* @brief Open Bluetooth adapter
*
* @adapter_name With value NULL, the default adapter will be selected.
* @param adapter_name With value NULL, the default adapter will be selected.
*/
int gattlib_adapter_open(const char* adapter_name, void** adapter);
int gattlib_adapter_scan_enable(void* adapter, gattlib_discovered_device_t discovered_device_cb, int timeout);
@ -111,6 +121,8 @@ gatt_connection_t *gattlib_connect_async(const char *src, const char *dst,
int gattlib_disconnect(gatt_connection_t* connection);
void gattlib_register_on_disconnect(gatt_connection_t *connection, gattlib_disconnection_handler_t handler, void* user_data);
typedef struct {
uint16_t attr_handle_start;
uint16_t attr_handle_end;