adapter: Added support to open multiple time the same adapter

pull/277/head
Olivier Martin 2024-04-08 12:32:06 +02:00
parent dc009029fa
commit f609f7d507
3 changed files with 58 additions and 10 deletions

View File

@ -10,6 +10,38 @@
// It could happen when using Python wrapper.
GSList *m_adapter_list;
static int stricmp(char const *a, char const *b) {
for (;; a++, b++) {
int d = tolower((unsigned char)*a) - tolower((unsigned char)*b);
if (d != 0 || !*a)
return d;
}
}
static gint _is_adapter_id(gconstpointer a, gconstpointer b) {
const gattlib_adapter_t* adapter = a;
const char* adapter_id = b;
return stricmp(adapter->id, adapter_id);
}
gattlib_adapter_t* gattlib_adapter_from_id(const char* adapter_id) {
gattlib_adapter_t* adapter = NULL;
g_rec_mutex_lock(&m_gattlib_mutex);
GSList *adapter_entry = g_slist_find_custom(m_adapter_list, adapter_id, _is_adapter_id);
if (adapter_entry == NULL) {
goto EXIT;
}
adapter = adapter_entry->data;
EXIT:
g_rec_mutex_unlock(&m_gattlib_mutex);
return adapter;
}
bool gattlib_adapter_is_valid(gattlib_adapter_t* adapter) {
bool is_valid;

View File

@ -68,6 +68,9 @@ struct _gattlib_adapter {
// Context specific to the backend implementation (eg: dbus backend)
struct _gattlib_adapter_backend backend;
// BLE adapter id (could be its DBUS device path on Linux)
char* id;
// BLE adapter name
char* name;
@ -121,6 +124,7 @@ extern GSList *m_adapter_list;
// This structure is used for inter-thread communication
extern struct gattlib_signal m_gattlib_signal;
gattlib_adapter_t* gattlib_adapter_from_id(const char* adapter_id);
bool gattlib_adapter_is_valid(gattlib_adapter_t* adapter);
bool gattlib_adapter_is_scanning(gattlib_adapter_t* adapter);
int gattlib_adapter_ref(gattlib_adapter_t* adapter);

View File

@ -28,10 +28,21 @@ int gattlib_adapter_open(const char* adapter_name, gattlib_adapter_t** adapter)
adapter_name = GATTLIB_DEFAULT_ADAPTER;
}
GATTLIB_LOG(GATTLIB_DEBUG, "Open bluetooth adapter %s", adapter_name);
snprintf(object_path, sizeof(object_path), "/org/bluez/%s", adapter_name);
// Check if adapter has already be loaded
g_rec_mutex_lock(&m_gattlib_mutex);
*adapter = gattlib_adapter_from_id(object_path);
if (*adapter != NULL) {
GATTLIB_LOG(GATTLIB_DEBUG, "Bluetooth adapter %s has already been opened. Re-use it", adapter_name);
gattlib_adapter_ref(*adapter);
g_rec_mutex_unlock(&m_gattlib_mutex);
return GATTLIB_SUCCESS;
}
g_rec_mutex_unlock(&m_gattlib_mutex);
GATTLIB_LOG(GATTLIB_DEBUG, "Open bluetooth adapter %s", adapter_name);
adapter_proxy = org_bluez_adapter1_proxy_new_for_bus_sync(
G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
"org.bluez",
@ -58,6 +69,7 @@ int gattlib_adapter_open(const char* adapter_name, gattlib_adapter_t** adapter)
}
// Initialize stucture
gattlib_adapter->id = strdup(object_path);
gattlib_adapter->name = strdup(adapter_name);
gattlib_adapter->reference_counter = 1;
gattlib_adapter->backend.adapter_proxy = adapter_proxy;
@ -651,11 +663,6 @@ int gattlib_adapter_close(gattlib_adapter_t* adapter) {
bool are_devices_disconnected;
int ret = GATTLIB_SUCCESS;
//
// TODO: Should we use reference counting to be able to open multiple times an adapter
// without freeing it on the first gattlib_adapter_close()
//
g_rec_mutex_lock(&m_gattlib_mutex);
if (!gattlib_adapter_is_valid(adapter)) {
@ -689,9 +696,6 @@ int gattlib_adapter_close(gattlib_adapter_t* adapter) {
// Unref/Free the adapter
gattlib_adapter_unref(adapter);
// Remove adapter from the global list
m_adapter_list = g_slist_remove(m_adapter_list, adapter);
EXIT:
g_rec_mutex_unlock(&m_gattlib_mutex);
return ret;
@ -730,6 +734,11 @@ int gattlib_adapter_unref(gattlib_adapter_t* adapter) {
adapter->backend.adapter_proxy = NULL;
}
if (adapter->id != NULL) {
free(adapter->id);
adapter->id = NULL;
}
if (adapter->name != NULL) {
free(adapter->name);
adapter->name = NULL;
@ -737,6 +746,9 @@ int gattlib_adapter_unref(gattlib_adapter_t* adapter) {
gattlib_devices_free(adapter);
// Remove adapter from the global list
m_adapter_list = g_slist_remove(m_adapter_list, adapter);
free(adapter);
EXIT: