summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2008-10-08 23:54:10 +0200
committerJohan Hedberg <johan.hedberg@nokia.com>2008-10-08 23:54:10 +0200
commite4d0a3b9051923b015ce633f9385e5af126211fe (patch)
tree18f5a41d529123e5409e4d8ffcbb6b4369ee8dc8
parenta4145c63530b4c3575b7da5f117c0df352f939fc (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.c3
-rw-r--r--src/device.c26
-rw-r--r--src/device.h2
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,