mirror of https://github.com/labapart/gattlib
Manage device state during its life cycle
parent
0c1334c5b4
commit
709b76019e
|
@ -40,6 +40,8 @@ static void _on_device_connect(gatt_connection_t* connection) {
|
|||
}
|
||||
conn_context->dbus_objects = g_dbus_object_manager_get_objects(device_manager);
|
||||
|
||||
gattlib_device_set_state(conn_context->adapter, connection->device_id, CONNECTED);
|
||||
|
||||
gattlib_on_connected_device(connection);
|
||||
}
|
||||
|
||||
|
@ -183,6 +185,16 @@ int gattlib_connect(void *adapter, const char *dst,
|
|||
|
||||
get_device_path_from_mac(adapter_name, dst, object_path, sizeof(object_path));
|
||||
|
||||
gatt_connection_t* connection = gattlib_device_get_device(adapter, object_path);
|
||||
if (connection == NULL) {
|
||||
GATTLIB_LOG(GATTLIB_DEBUG, "gattlib_connect: Cannot find connection %s", dst);
|
||||
return GATTLIB_INVALID_PARAMETER;
|
||||
} else if (connection->state != DISCONNECTED) {
|
||||
GATTLIB_LOG(GATTLIB_DEBUG, "gattlib_connect: Cannot connect to '%s'. Device is in state %s",
|
||||
dst, device_state_str[connection->state]);
|
||||
return GATTLIB_BUSY;
|
||||
}
|
||||
|
||||
gattlib_context_t* conn_context = calloc(sizeof(gattlib_context_t), 1);
|
||||
if (conn_context == NULL) {
|
||||
GATTLIB_LOG(GATTLIB_DEBUG, "gattlib_connect: Cannot allocate context");
|
||||
|
@ -190,18 +202,14 @@ int gattlib_connect(void *adapter, const char *dst,
|
|||
}
|
||||
conn_context->adapter = gattlib_adapter;
|
||||
|
||||
gatt_connection_t* connection = calloc(sizeof(gatt_connection_t), 1);
|
||||
if (connection == NULL) {
|
||||
GATTLIB_LOG(GATTLIB_DEBUG, "gattlib_connect: Cannot allocate connection");
|
||||
ret = GATTLIB_OUT_OF_MEMORY;
|
||||
goto FREE_CONN_CONTEXT;
|
||||
}
|
||||
|
||||
connection->context = conn_context;
|
||||
connection->on_connection.callback.connection_handler = connect_cb;
|
||||
connection->on_connection.user_data = user_data;
|
||||
|
||||
GATTLIB_LOG(GATTLIB_DEBUG, "Connect bluetooth device %s", dst);
|
||||
GATTLIB_LOG(GATTLIB_DEBUG, "Connecting bluetooth device %s", dst);
|
||||
|
||||
// Mark the device has disconnected
|
||||
gattlib_device_set_state(connection->adapter, connection->device_id, CONNECTING);
|
||||
|
||||
OrgBluezDevice1* device = org_bluez_device1_proxy_new_for_bus_sync(
|
||||
G_BUS_TYPE_SYSTEM,
|
||||
|
@ -219,7 +227,7 @@ int gattlib_connect(void *adapter, const char *dst,
|
|||
} else {
|
||||
GATTLIB_LOG(GATTLIB_ERROR, "gattlib_connect: Failed to connect to DBus Bluez Device");
|
||||
}
|
||||
goto FREE_CONNECTION;
|
||||
goto FREE_CONNECTION_CONTEXT;
|
||||
} else {
|
||||
conn_context->device = device;
|
||||
conn_context->device_object_path = strdup(object_path);
|
||||
|
@ -263,10 +271,7 @@ FREE_DEVICE:
|
|||
free(conn_context->device_object_path);
|
||||
g_object_unref(conn_context->device);
|
||||
|
||||
FREE_CONNECTION:
|
||||
free(connection);
|
||||
|
||||
FREE_CONN_CONTEXT:
|
||||
FREE_CONNECTION_CONTEXT:
|
||||
free(conn_context);
|
||||
|
||||
// destroy default adapter
|
||||
|
@ -289,9 +294,13 @@ FREE_CONN_CONTEXT:
|
|||
*/
|
||||
void gattlib_connection_free(gatt_connection_t* connection) {
|
||||
gattlib_context_t* conn_context;
|
||||
void* adapter;
|
||||
char* device_id;
|
||||
|
||||
g_mutex_lock(&connection->device_mutex);
|
||||
conn_context = connection->context;
|
||||
adapter = conn_context->adapter;
|
||||
device_id = connection->device_id;
|
||||
|
||||
// Remove signal
|
||||
if (conn_context->on_handle_device_property_change_id != 0) {
|
||||
|
@ -326,10 +335,10 @@ void gattlib_connection_free(gatt_connection_t* connection) {
|
|||
free(connection->context);
|
||||
connection->context = NULL;
|
||||
|
||||
g_mutex_unlock(&connection->device_mutex);
|
||||
// Mark the device has disconnected
|
||||
gattlib_device_set_state(adapter, device_id, DISCONNECTED);
|
||||
|
||||
// And finally free the connection
|
||||
free(connection);
|
||||
g_mutex_unlock(&connection->device_mutex);
|
||||
}
|
||||
|
||||
int gattlib_disconnect(gatt_connection_t* connection, bool wait_disconnection) {
|
||||
|
@ -349,9 +358,14 @@ int gattlib_disconnect(gatt_connection_t* connection, bool wait_disconnection) {
|
|||
GATTLIB_LOG(GATTLIB_ERROR, "Cannot disconnect - connection context is not valid.");
|
||||
ret = GATTLIB_NOT_SUPPORTED;
|
||||
goto EXIT;
|
||||
} else if (connection->state != CONNECTED) {
|
||||
GATTLIB_LOG(GATTLIB_ERROR, "Cannot disconnect - connection is not in connected state (state=%s).",
|
||||
device_state_str[connection->state]);
|
||||
ret = GATTLIB_BUSY;
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
GATTLIB_LOG(GATTLIB_DEBUG, "Disconnect bluetooth device %s", conn_context->device_object_path);
|
||||
GATTLIB_LOG(GATTLIB_DEBUG, "Disconnecting bluetooth device %s", conn_context->device_object_path);
|
||||
|
||||
org_bluez_device1_call_disconnect_sync(conn_context->device, NULL, &error);
|
||||
if (error) {
|
||||
|
@ -359,6 +373,9 @@ int gattlib_disconnect(gatt_connection_t* connection, bool wait_disconnection) {
|
|||
g_error_free(error);
|
||||
}
|
||||
|
||||
// Mark the device has disconnected
|
||||
gattlib_device_set_state(connection->adapter, connection->device_id, DISCONNECTING);
|
||||
|
||||
//Note: Signals and memory will be removed/clean on disconnction callback
|
||||
// See _gattlib_clean_on_disconnection()
|
||||
|
||||
|
|
|
@ -143,12 +143,9 @@ static void device_manager_on_added_device1_signal(const char* device1_path, str
|
|||
|
||||
//TODO: Add support for connected device with 'gboolean org_bluez_device1_get_connected (OrgBluezDevice1 *object);'
|
||||
// When the device is connected, we potentially need to initialize some attributes
|
||||
ret = gattlib_device_set_state(gattlib_adapter, address, DISCONNECTED);
|
||||
|
||||
ret = gattlib_device_set_state(gattlib_adapter, device1_path, DISCONNECTED);
|
||||
if (ret == GATTLIB_SUCCESS) {
|
||||
if (gattlib_adapter->ble_scan.enabled_filters & GATTLIB_DISCOVER_FILTER_NOTIFY_CHANGE) {
|
||||
gattlib_on_discovered_device(gattlib_adapter, device1);
|
||||
}
|
||||
gattlib_on_discovered_device(gattlib_adapter, device1);
|
||||
}
|
||||
|
||||
g_rec_mutex_unlock(&gattlib_adapter->mutex);
|
||||
|
@ -226,40 +223,28 @@ on_interface_proxy_properties_changed (GDBusObjectManagerClient *device_manager,
|
|||
return;
|
||||
}
|
||||
|
||||
const char* device_mac_address = org_bluez_device1_get_address(device1);
|
||||
|
||||
// Check if the device has been disconnected
|
||||
GVariantDict dict;
|
||||
g_variant_dict_init(&dict, changed_properties);
|
||||
GVariant* connected = g_variant_dict_lookup_value(&dict, "Connected", NULL);
|
||||
GVariant* rssi = g_variant_dict_lookup_value(&dict, "RSSI", NULL);
|
||||
GVariant* has_rssi = g_variant_dict_lookup_value(&dict, "RSSI", NULL);
|
||||
GVariant* has_manufacturer_data = g_variant_dict_lookup_value(&dict, "ManufacturerData", NULL);
|
||||
|
||||
g_mutex_lock(&gattlib_adapter->ble_scan.discovered_devices_mutex);
|
||||
g_rec_mutex_lock(&gattlib_adapter->mutex);
|
||||
|
||||
// Check if the device is already part of the list
|
||||
GSList *found_device = g_slist_find_custom(gattlib_adapter->ble_scan.discovered_devices, device_mac_address, (GCompareFunc)g_ascii_strcasecmp);
|
||||
enum _gattlib_device_state old_device_state = gattlib_device_get_state(gattlib_adapter, proxy_object_path);
|
||||
|
||||
if (connected && !g_variant_get_boolean(connected)) {
|
||||
// The device has been disconnected. We will remove it from the list of discovered device.
|
||||
// In case the device has been found again, it will be seen as a new device
|
||||
|
||||
GATTLIB_LOG(GATTLIB_INFO, "Device %s has been disconnected", device_mac_address);
|
||||
|
||||
if (found_device) {
|
||||
gattlib_adapter->ble_scan.discovered_devices = g_slist_remove(gattlib_adapter->ble_scan.discovered_devices, found_device);
|
||||
}
|
||||
} else if (rssi) {
|
||||
// First time this device is in the list
|
||||
if (found_device == NULL) {
|
||||
// Add the device to the list
|
||||
gattlib_adapter->ble_scan.discovered_devices = g_slist_append(gattlib_adapter->ble_scan.discovered_devices, g_strdup(device_mac_address));
|
||||
gattlib_on_discovered_device(gattlib_adapter, device1);
|
||||
if (old_device_state == NOT_FOUND) {
|
||||
if (has_rssi || has_manufacturer_data) {
|
||||
int ret = gattlib_device_set_state(gattlib_adapter, proxy_object_path, DISCONNECTED);
|
||||
if (ret == GATTLIB_SUCCESS) {
|
||||
gattlib_on_discovered_device(gattlib_adapter, device1);
|
||||
}
|
||||
}
|
||||
}
|
||||
g_mutex_unlock(&gattlib_adapter->ble_scan.discovered_devices_mutex);
|
||||
|
||||
g_rec_mutex_unlock(&gattlib_adapter->mutex);
|
||||
|
||||
g_variant_dict_end(&dict);
|
||||
|
||||
g_object_unref(device1);
|
||||
}
|
||||
}
|
||||
|
@ -549,9 +534,15 @@ EXIT:
|
|||
return GATTLIB_SUCCESS;
|
||||
}
|
||||
|
||||
int gattlib_adapter_close(void* adapter)
|
||||
{
|
||||
int gattlib_adapter_close(void* adapter) {
|
||||
struct gattlib_adapter *gattlib_adapter = adapter;
|
||||
bool are_devices_disconnected;
|
||||
|
||||
are_devices_disconnected = gattlib_devices_are_disconnected(adapter);
|
||||
if (!are_devices_disconnected) {
|
||||
GATTLIB_LOG(GATTLIB_ERROR, "Adapter cannot be closed as some devices are not disconnected");
|
||||
return GATTLIB_BUSY;
|
||||
}
|
||||
|
||||
g_mutex_lock(&m_adapter_list_mutex);
|
||||
GSList *adapter_entry = g_slist_find(m_adapter_list, adapter);
|
||||
|
|
Loading…
Reference in New Issue