From db04a0eb5c3503aeb07a6dc5eaad57e3b59956db Mon Sep 17 00:00:00 2001 From: Olivier Martin Date: Mon, 8 Apr 2024 22:00:36 +0200 Subject: [PATCH] Introduce gattlib_connection_is_valid() to not access 'connection->device' --- common/gattlib_callback_connected_device.c | 2 +- common/gattlib_callback_disconnected_device.c | 2 +- common/gattlib_common.c | 6 +-- common/gattlib_common_adapter.c | 39 ++++++++++++++++++- common/gattlib_internal.h | 7 ++++ dbus/gattlib.c | 14 +++---- dbus/gattlib_advertisement.c | 2 +- 7 files changed, 57 insertions(+), 15 deletions(-) diff --git a/common/gattlib_callback_connected_device.c b/common/gattlib_callback_connected_device.c index 42ffbaf..e564090 100644 --- a/common/gattlib_callback_connected_device.c +++ b/common/gattlib_callback_connected_device.c @@ -87,7 +87,7 @@ static void* _connected_device_thread_args_allocator(va_list args) { } void gattlib_on_connected_device(gattlib_connection_t* connection) { - if (!gattlib_device_is_valid(connection->device)) { + if (!gattlib_connection_is_valid(connection)) { GATTLIB_LOG(GATTLIB_ERROR, "gattlib_on_connected_device: Device is not valid"); return; } diff --git a/common/gattlib_callback_disconnected_device.c b/common/gattlib_callback_disconnected_device.c index 1cf90a8..dc59067 100644 --- a/common/gattlib_callback_disconnected_device.c +++ b/common/gattlib_callback_disconnected_device.c @@ -33,7 +33,7 @@ void gattlib_disconnected_device_python_callback(gattlib_connection_t* connectio void gattlib_on_disconnected_device(gattlib_connection_t* connection) { g_rec_mutex_lock(&m_gattlib_mutex); - if (!gattlib_device_is_valid(connection->device)) { + if (!gattlib_connection_is_valid(connection)) { GATTLIB_LOG(GATTLIB_ERROR, "gattlib_on_disconnected_device: Device not valid"); g_rec_mutex_unlock(&m_gattlib_mutex); return; diff --git a/common/gattlib_common.c b/common/gattlib_common.c index 127c07c..20e1181 100644 --- a/common/gattlib_common.c +++ b/common/gattlib_common.c @@ -20,7 +20,7 @@ int gattlib_register_notification(gattlib_connection_t* connection, gattlib_even goto EXIT; } - if (!gattlib_device_is_valid(connection->device)) { + if (!gattlib_connection_is_valid(connection)) { GATTLIB_LOG(GATTLIB_ERROR, "gattlib_register_notification: Device not valid"); ret = GATTLIB_DEVICE_DISCONNECTED; goto EXIT; @@ -58,7 +58,7 @@ int gattlib_register_indication(gattlib_connection_t* connection, gattlib_event_ goto EXIT; } - if (!gattlib_device_is_valid(connection->device)) { + if (!gattlib_connection_is_valid(connection)) { GATTLIB_LOG(GATTLIB_ERROR, "gattlib_register_indication: Device not valid"); ret = GATTLIB_DEVICE_DISCONNECTED; goto EXIT; @@ -93,7 +93,7 @@ int gattlib_register_on_disconnect(gattlib_connection_t *connection, gattlib_dis goto EXIT; } - if (!gattlib_device_is_valid(connection->device)) { + if (!gattlib_connection_is_valid(connection)) { GATTLIB_LOG(GATTLIB_ERROR, "gattlib_register_on_disconnect: Device not valid"); ret = GATTLIB_DEVICE_DISCONNECTED; goto EXIT; diff --git a/common/gattlib_common_adapter.c b/common/gattlib_common_adapter.c index 6f11269..d56ed5b 100644 --- a/common/gattlib_common_adapter.c +++ b/common/gattlib_common_adapter.c @@ -103,9 +103,9 @@ bool gattlib_device_is_valid(gattlib_device_t* device) { return device_is_valid.found; } -struct _connection_is_connected { +struct _connection_is_valid { gattlib_connection_t* connection; - bool is_connected; + bool is_valid; }; static gint _is_device_connection(gconstpointer a, gconstpointer b) { @@ -113,6 +113,41 @@ static gint _is_device_connection(gconstpointer a, gconstpointer b) { return (&device->connection == b) ? 0 : -1; // We need to return 0 when it matches } +static void _gattlib_connection_is_valid(gpointer data, gpointer user_data) { + gattlib_adapter_t* adapter = data; + struct _connection_is_valid* connection_is_valid = user_data; + + //printf("_gattlib_connection_is_connected: Check device in adapter:%s\n", adapter->id); + + GSList *device_entry = g_slist_find_custom(adapter->devices, connection_is_valid->connection, _is_device_connection); + if (device_entry == NULL) { + //printf("_gattlib_connection_is_connected: Did not find device %s\n", connection_is_connected->connection->device->device_id); + return; + } + + connection_is_valid->is_valid = true; +} + +bool gattlib_connection_is_valid(gattlib_connection_t* connection) { + struct _connection_is_valid connection_is_valid = { + .connection = connection, + .is_valid = false + }; + + g_rec_mutex_lock(&m_gattlib_mutex); + //printf("gattlib_connection_is_connected A"); + g_slist_foreach(m_adapter_list, _gattlib_connection_is_valid, &connection_is_valid); + //printf("gattlib_connection_is_connected B"); + g_rec_mutex_unlock(&m_gattlib_mutex); + + return connection_is_valid.is_valid; +} + +struct _connection_is_connected { + gattlib_connection_t* connection; + bool is_connected; +}; + static void _gattlib_connection_is_connected(gpointer data, gpointer user_data) { gattlib_adapter_t* adapter = data; struct _connection_is_connected* connection_is_connected = user_data; diff --git a/common/gattlib_internal.h b/common/gattlib_internal.h index d834006..d23ea69 100644 --- a/common/gattlib_internal.h +++ b/common/gattlib_internal.h @@ -133,6 +133,13 @@ int gattlib_adapter_unref(gattlib_adapter_t* adapter); bool gattlib_device_is_valid(gattlib_device_t* device); int gattlib_device_ref(gattlib_device_t* device); int gattlib_device_unref(gattlib_device_t* device); +/** + * This function is similar to 'gattlib_device_is_valid()' except we check if + * the connection (connected or not) still belongs to a valid device. + * + * It is to avoid to use 'connection->device' when the device has been freed + */ +bool gattlib_connection_is_valid(gattlib_connection_t* connection); bool gattlib_connection_is_connected(gattlib_connection_t* connection); void gattlib_handler_dispatch_to_thread(struct gattlib_handler* handler, void (*python_callback)(), diff --git a/dbus/gattlib.c b/dbus/gattlib.c index 2074464..08545de 100644 --- a/dbus/gattlib.c +++ b/dbus/gattlib.c @@ -21,7 +21,7 @@ static void _on_device_connect(gattlib_connection_t* connection) { g_rec_mutex_lock(&m_gattlib_mutex); - if (!gattlib_device_is_valid(connection->device)) { + if (!gattlib_connection_is_valid(connection)) { GATTLIB_LOG(GATTLIB_ERROR, "_on_device_connect: Device not valid"); goto EXIT; } @@ -142,7 +142,7 @@ static gboolean _stop_connect_func(gpointer data) { g_rec_mutex_lock(&m_gattlib_mutex); - if (!gattlib_device_is_valid(connection->device)) { + if (!gattlib_connection_is_valid(connection)) { GATTLIB_LOG(GATTLIB_ERROR, "_stop_connect_func: Device not valid"); goto EXIT; } @@ -424,7 +424,7 @@ int gattlib_discover_primary(gattlib_connection_t* connection, gattlib_primary_s return GATTLIB_INVALID_PARAMETER; } - if (!gattlib_device_is_valid(connection->device)) { + if (!gattlib_connection_is_valid(connection)) { GATTLIB_LOG(GATTLIB_ERROR, "gattlib_discover_primary: Device not valid"); g_rec_mutex_unlock(&m_gattlib_mutex); return GATTLIB_DEVICE_DISCONNECTED; @@ -517,7 +517,7 @@ int gattlib_discover_primary(gattlib_connection_t* connection, gattlib_primary_s goto EXIT; } - if (!gattlib_device_is_valid(connection->device)) { + if (!gattlib_connection_is_valid(connection)) { GATTLIB_LOG(GATTLIB_ERROR, "gattlib_discover_primary: Device not valid"); ret = GATTLIB_DEVICE_DISCONNECTED; goto EXIT; @@ -679,7 +679,7 @@ int gattlib_discover_char_range(gattlib_connection_t* connection, uint16_t start // Increase bluez_device object reference counter to avoid to keep locking the mutex g_rec_mutex_lock(&m_gattlib_mutex); - if (!gattlib_device_is_valid(connection->device)) { + if (!gattlib_connection_is_valid(connection)) { GATTLIB_LOG(GATTLIB_ERROR, "gattlib_discover_char_range: Device not valid"); g_rec_mutex_unlock(&m_gattlib_mutex); return GATTLIB_DEVICE_DISCONNECTED; @@ -939,7 +939,7 @@ int gattlib_discover_char_range(gattlib_connection_t* connection, uint16_t start g_rec_mutex_lock(&m_gattlib_mutex); - if (!gattlib_device_is_valid(connection->device)) { + if (!gattlib_connection_is_valid(connection)) { GATTLIB_LOG(GATTLIB_ERROR, "gattlib_discover_char_range: Device not valid"); ret = GATTLIB_DEVICE_DISCONNECTED; goto EXIT; @@ -1119,7 +1119,7 @@ int gattlib_get_rssi(gattlib_connection_t *connection, int16_t *rssi) return GATTLIB_INVALID_PARAMETER; } - if (!gattlib_device_is_valid(connection->device)) { + if (!gattlib_connection_is_valid(connection)) { GATTLIB_LOG(GATTLIB_ERROR, "gattlib_get_rssi: Device not valid"); g_rec_mutex_unlock(&m_gattlib_mutex); return GATTLIB_DEVICE_DISCONNECTED; diff --git a/dbus/gattlib_advertisement.c b/dbus/gattlib_advertisement.c index 55e5dbf..9aaa640 100644 --- a/dbus/gattlib_advertisement.c +++ b/dbus/gattlib_advertisement.c @@ -125,7 +125,7 @@ int gattlib_get_advertisement_data(gattlib_connection_t *connection, return GATTLIB_INVALID_PARAMETER; } - if (!gattlib_device_is_valid(connection->device)) { + if (!gattlib_connection_is_valid(connection)) { g_rec_mutex_unlock(&m_gattlib_mutex); return GATTLIB_DEVICE_DISCONNECTED; }