mirror of https://github.com/labapart/gattlib
Consolidate handlers
parent
5ca46ad208
commit
a85dd83015
|
@ -51,9 +51,18 @@ static gpointer _gattlib_connected_device_thread(gpointer data) {
|
|||
gattlib_context_t* conn_context = connection->context;
|
||||
const gchar *device_mac_address = org_bluez_device1_get_address(conn_context->device);
|
||||
|
||||
g_rec_mutex_lock(&connection->on_connection.mutex);
|
||||
|
||||
if (!gattlib_has_valid_handler(&connection->on_connection)) {
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
connection->on_connection.callback.connection_handler(
|
||||
conn_context->adapter, device_mac_address, connection, 0 /* no error */,
|
||||
connection->on_connection.user_data);
|
||||
|
||||
EXIT:
|
||||
g_rec_mutex_unlock(&connection->on_connection.mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,22 +31,22 @@ void gattlib_disconnected_device_python_callback(gatt_connection_t* connection,
|
|||
#endif
|
||||
|
||||
void gattlib_on_disconnected_device(gatt_connection_t* connection) {
|
||||
if (connection->on_disconnection.callback.callback == NULL) {
|
||||
// We do not have (anymore) a callback, nothing to do
|
||||
GATTLIB_LOG(GATTLIB_DEBUG, "No callback for GATT disconnection.");
|
||||
return;
|
||||
}
|
||||
if (gattlib_has_valid_handler(&connection->on_disconnection)) {
|
||||
g_rec_mutex_lock(&connection->on_disconnection.mutex);
|
||||
|
||||
#if defined(WITH_PYTHON)
|
||||
// Check if we are using the Python callback, in case of Python argument we keep track of the argument to free them
|
||||
// once we are done with the handler.
|
||||
if ((gattlib_disconnection_handler_t)connection->on_disconnection.callback.callback == gattlib_disconnected_device_python_callback) {
|
||||
connection->on_disconnection.python_args = connection->on_disconnection.user_data;
|
||||
}
|
||||
// Check if we are using the Python callback, in case of Python argument we keep track of the argument to free them
|
||||
// once we are done with the handler.
|
||||
if ((gattlib_disconnection_handler_t)connection->on_disconnection.callback.callback == gattlib_disconnected_device_python_callback) {
|
||||
connection->on_disconnection.python_args = connection->on_disconnection.user_data;
|
||||
}
|
||||
#endif
|
||||
|
||||
// For GATT disconnection we do not use thread to ensure the callback is synchronous.
|
||||
connection->on_disconnection.callback.disconnection_handler(connection, connection->on_disconnection.user_data);
|
||||
// For GATT disconnection we do not use thread to ensure the callback is synchronous.
|
||||
connection->on_disconnection.callback.disconnection_handler(connection, connection->on_disconnection.user_data);
|
||||
|
||||
g_rec_mutex_unlock(&connection->on_disconnection.mutex);
|
||||
}
|
||||
|
||||
// Clean GATTLIB connection on disconnection
|
||||
gattlib_connection_free(connection);
|
||||
|
|
|
@ -55,12 +55,21 @@ struct gattlib_discovered_device_thread_args {
|
|||
static gpointer _gattlib_discovered_device_thread(gpointer data) {
|
||||
struct gattlib_discovered_device_thread_args* args = data;
|
||||
|
||||
g_rec_mutex_lock(&args->gattlib_adapter->ble_scan.discovered_device_callback.mutex);
|
||||
|
||||
if (!gattlib_has_valid_handler(&args->gattlib_adapter->ble_scan.discovered_device_callback)) {
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
args->gattlib_adapter->ble_scan.discovered_device_callback.callback.discovered_device(
|
||||
args->gattlib_adapter,
|
||||
args->mac_address, args->name,
|
||||
args->gattlib_adapter->ble_scan.discovered_device_callback.user_data
|
||||
);
|
||||
|
||||
EXIT:
|
||||
g_rec_mutex_unlock(&args->gattlib_adapter->ble_scan.discovered_device_callback.mutex);
|
||||
|
||||
free(args->mac_address);
|
||||
if (args->name != NULL) {
|
||||
free(args->name);
|
||||
|
|
|
@ -56,11 +56,15 @@ void gattlib_notification_device_thread(gpointer data, gpointer user_data) {
|
|||
struct gattlib_notification_device_thread_args* args = data;
|
||||
struct gattlib_handler* handler = user_data;
|
||||
|
||||
g_rec_mutex_lock(&handler->mutex);
|
||||
|
||||
handler->callback.notification_handler(
|
||||
args->uuid, args->data, args->data_length,
|
||||
handler->user_data
|
||||
);
|
||||
|
||||
g_rec_mutex_unlock(&handler->mutex);
|
||||
|
||||
if (args->uuid != NULL) {
|
||||
free(args->uuid);
|
||||
args->uuid = NULL;
|
||||
|
|
|
@ -144,6 +144,12 @@ int gattlib_uuid_cmp(const uuid_t *uuid1, const uuid_t *uuid2) {
|
|||
}
|
||||
|
||||
void gattlib_handler_free(struct gattlib_handler* handler) {
|
||||
g_rec_mutex_lock(&handler->mutex);
|
||||
|
||||
if (!gattlib_has_valid_handler(handler)) {
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
// Reset callback to stop calling it after we stopped
|
||||
handler->callback.callback = NULL;
|
||||
|
||||
|
@ -162,17 +168,20 @@ void gattlib_handler_free(struct gattlib_handler* handler) {
|
|||
g_thread_pool_free(handler->thread_pool, FALSE /* immediate */, TRUE /* wait */);
|
||||
handler->thread_pool = NULL;
|
||||
}
|
||||
|
||||
EXIT:
|
||||
g_rec_mutex_unlock(&handler->mutex);
|
||||
}
|
||||
|
||||
bool gattlib_has_valid_handler(struct gattlib_handler* handler) {
|
||||
return (handler->callback.callback != NULL);
|
||||
return (handler != NULL) && (handler->callback.callback != NULL);
|
||||
}
|
||||
|
||||
void gattlib_handler_dispatch_to_thread(struct gattlib_handler* handler, void (*python_callback)(),
|
||||
GThreadFunc thread_func, const char* thread_name, void* (*thread_args_allocator)(va_list args), ...) {
|
||||
GError *error = NULL;
|
||||
|
||||
if (handler->callback.callback == NULL) {
|
||||
if (!gattlib_has_valid_handler(handler)) {
|
||||
// We do not have (anymore) a callback, nothing to do
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,11 @@ struct gattlib_handler {
|
|||
void* user_data;
|
||||
// We create a thread to ensure the callback is not blocking the mainloop
|
||||
GThread *thread;
|
||||
// The mutex ensures the callbacks is not being freed while being called
|
||||
// We use a recursive mutex to be able to disable BLE scan from 'on_discovered_device'
|
||||
// when we want to connect to the discovered device.
|
||||
// Note: The risk is that we are actually realising the handle from the one we are executing
|
||||
GRecMutex mutex;
|
||||
// Thread pool
|
||||
GThreadPool *thread_pool;
|
||||
#if defined(WITH_PYTHON)
|
||||
|
@ -49,7 +54,6 @@ struct _gatt_connection_t {
|
|||
GMutex connection_mutex;
|
||||
|
||||
struct gattlib_handler on_connection;
|
||||
struct gattlib_handler on_connection_error;
|
||||
struct gattlib_handler notification;
|
||||
struct gattlib_handler indication;
|
||||
struct gattlib_handler on_disconnection;
|
||||
|
|
|
@ -176,6 +176,11 @@ int gattlib_connect(void *adapter, const char *dst,
|
|||
return GATTLIB_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (connect_cb == NULL) {
|
||||
GATTLIB_LOG(GATTLIB_DEBUG, "gattlib_connect: Missing connection callback");
|
||||
return GATTLIB_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
get_device_path_from_mac(adapter_name, dst, object_path, sizeof(object_path));
|
||||
|
||||
gattlib_context_t* conn_context = calloc(sizeof(gattlib_context_t), 1);
|
||||
|
@ -303,6 +308,12 @@ void gattlib_connection_free(gatt_connection_t* connection) {
|
|||
|
||||
disconnect_all_notifications(conn_context);
|
||||
|
||||
// Free all handler
|
||||
gattlib_handler_free(&connection->on_connection);
|
||||
gattlib_handler_free(&connection->on_disconnection);
|
||||
gattlib_handler_free(&connection->indication);
|
||||
gattlib_handler_free(&connection->notification);
|
||||
|
||||
// Note: We do not free adapter as it might still be used by other devices
|
||||
|
||||
free(connection->context);
|
||||
|
|
Loading…
Reference in New Issue