diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2008-10-08 23:54:10 +0200 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2008-10-08 23:54:10 +0200 |
commit | e4d0a3b9051923b015ce633f9385e5af126211fe (patch) | |
tree | 18f5a41d529123e5409e4d8ffcbb6b4369ee8dc8 | |
parent | a4145c63530b4c3575b7da5f117c0df352f939fc (diff) |
Fix the service discovery-upon-pairing logic
The original code seems to try to handle the situation of two opposite directed
pairing attempts (remote side starts dedicated bonding with us but someone
calls CreatePairedDevice on our side at the same time). I'm not sure how likely
this actually is or if it can even succeed, but the existing logic in the code
was nevertheless wrong. After this patch is at least in theory makes sense to
me (and is better commented if I forget what I was thinking when I wrote it).
-rw-r--r-- | src/dbus-hci.c | 3 | ||||
-rw-r--r-- | src/device.c | 26 | ||||
-rw-r--r-- | src/device.h | 2 |
3 files changed, 20 insertions, 11 deletions
diff --git a/src/dbus-hci.c b/src/dbus-hci.c index 2ae307e8..3abf6bdc 100644 --- a/src/dbus-hci.c +++ b/src/dbus-hci.c @@ -611,7 +611,8 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer, /* If this is a new pairing send the appropriate signal for it * and proceed with service discovery */ if (status == 0) { - if (device_set_paired(connection, device, bonding) && bonding) + device_set_paired(connection, device, bonding); + if (bonding) adapter_free_bonding_request(adapter); return; } diff --git a/src/device.c b/src/device.c index 81e39e0b..bd58f7c3 100644 --- a/src/device.c +++ b/src/device.c @@ -1275,7 +1275,7 @@ static gboolean start_discovery(gpointer user_data) return FALSE; } -gboolean device_set_paired(DBusConnection *conn, struct btd_device *device, +int device_set_paired(DBusConnection *conn, struct btd_device *device, struct bonding_request_info *bonding) { dbus_bool_t paired = TRUE; @@ -1286,22 +1286,30 @@ gboolean device_set_paired(DBusConnection *conn, struct btd_device *device, DEVICE_INTERFACE, "Paired", DBUS_TYPE_BOOLEAN, &paired); - if (device->discov_timer) - return FALSE; - /* If we were initiators start service discovery immediately. * However if the other end was the initator wait a few seconds * before SDP. This is due to potential IOP issues if the other * end starts doing SDP at the same time as us */ - if (bonding) - device_browse(device, bonding->conn, - bonding->msg, NULL); - else + if (bonding) { + /* If we are initiators remove any discovery timer and just + * start discovering services directly */ + if (device->discov_timer) { + g_source_remove(device->discov_timer); + device->discov_timer = 0; + } + + return device_browse(device, bonding->conn, bonding->msg, + NULL); + } + + /* If we are not initiators and there is no currently active discovery + * or discovery timer, set the discovery timer */ + if (!device->discov_active && !device->discov_timer) device->discov_timer = g_timeout_add(DISCOVERY_TIMER, start_discovery, device); - return TRUE; + return 0; } int btd_register_device_driver(struct btd_device_driver *driver) diff --git a/src/device.h b/src/device.h index 126426df..f977d7eb 100644 --- a/src/device.h +++ b/src/device.h @@ -42,7 +42,7 @@ void device_set_temporary(struct btd_device *device, gboolean temporary); void device_set_cap(struct btd_device *device, uint8_t cap); void device_set_auth(struct btd_device *device, uint8_t auth); uint8_t device_get_auth(struct btd_device *device); -gboolean device_set_paired(DBusConnection *conn, struct btd_device *device, +int device_set_paired(DBusConnection *conn, struct btd_device *device, struct bonding_request_info *bonding); gboolean device_get_connected(struct btd_device *device); void device_set_connected(DBusConnection *conn, struct btd_device *device, |