From 013d376e47dc68ec385e9f88d6bc6c07c921ee1a Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 25 Sep 2008 19:47:09 -0700 Subject: Do service discovery also for pairings initiated from the other side --- src/dbus-hci.c | 69 +++++++++++++++++++++------------------------------------- src/device.c | 37 +++++++++++++++++++++++++++++++ src/device.h | 3 +++ 3 files changed, 65 insertions(+), 44 deletions(-) diff --git a/src/dbus-hci.c b/src/dbus-hci.c index e003e084..6713f7b5 100644 --- a/src/dbus-hci.c +++ b/src/dbus-hci.c @@ -545,7 +545,8 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer, adapter_remove_auth_request(adapter, peer); - /* If this is a new pairing send the appropriate signal for it */ + /* If this is a new pairing send the appropriate signal for it + * and proceed with service discovery */ if (status == 0) { const char *dev_path; dbus_bool_t paired = TRUE; @@ -556,31 +557,32 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer, dbus_connection_emit_property_changed(connection, dev_path, DEVICE_INTERFACE, "Paired", DBUS_TYPE_BOOLEAN, &paired); + + /* 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 + device_schedule_service_discovery(device); + + return; } proceed: if (!bonding || bacmp(&bonding->bdaddr, peer)) return; /* skip: no bonding req pending */ - if (bonding->cancel) { - /* reply authentication canceled */ + if (bonding->cancel) reply = new_authentication_return(bonding->msg, - HCI_OE_USER_ENDED_CONNECTION); - g_dbus_send_message(connection, reply); - goto cleanup; - } - - if (status) { + HCI_OE_USER_ENDED_CONNECTION); + else reply = new_authentication_return(bonding->msg, status); - dbus_connection_send(connection, reply, NULL); - dbus_message_unref(reply); - } else { - device_set_temporary(device, FALSE); - device_browse(device, bonding->conn, - bonding->msg, NULL); - } -cleanup: + g_dbus_send_message(connection, reply); + adapter_free_bonding_request(adapter); } @@ -1018,9 +1020,7 @@ void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle, bdaddr_t *peer) { char peer_addr[18]; - const char *paddr = peer_addr; struct btd_adapter *adapter; - const gchar *dev_path; struct bonding_request_info *bonding; adapter = manager_find_adapter(local); @@ -1045,17 +1045,10 @@ void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle, bonding->hci_status = status; } else { struct btd_device *device; - gboolean connected = TRUE; - device = adapter_find_device(adapter, paddr); - if (device) { - dev_path = device_get_path(device); - - dbus_connection_emit_property_changed(connection, - dev_path, DEVICE_INTERFACE, - "Connected", DBUS_TYPE_BOOLEAN, - &connected); - } + device = adapter_find_device(adapter, peer_addr); + if (device) + device_set_connected(connection, device, TRUE); /* add in the active connetions list */ adapter_add_active_conn(adapter, peer, handle); @@ -1067,17 +1060,12 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status, { DBusMessage *reply; char peer_addr[18]; - const char *paddr = peer_addr; struct btd_adapter *adapter; struct btd_device *device; struct active_conn_info *dev; - gboolean connected = FALSE; struct pending_auth_info *auth; - const gchar *dev_path; uint16_t dev_id; struct bonding_request_info *bonding; - bdaddr_t bdaddr; - char addr[18]; if (status) { error("Disconnection failed: 0x%02x", status); @@ -1129,19 +1117,12 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status, adapter_remove_active_conn(adapter, dev); - device = adapter_find_device(adapter, paddr); + device = adapter_find_device(adapter, peer_addr); if (device) { - device_get_address(device, &bdaddr); - ba2str(&bdaddr, addr); - - dev_path = device_get_path(device); + device_set_connected(connection, device, FALSE); - dbus_connection_emit_property_changed(connection, - dev_path, DEVICE_INTERFACE, - "Connected", DBUS_TYPE_BOOLEAN, - &connected); if (device_is_temporary(device)) { - debug("Removing temporary device %s", addr); + debug("Removing temporary device %s", peer_addr); adapter_remove_device(connection, adapter, device); } } diff --git a/src/device.c b/src/device.c index 9b28ae41..b694d299 100644 --- a/src/device.c +++ b/src/device.c @@ -58,6 +58,7 @@ #define DEFAULT_XML_BUF_SIZE 1024 #define DISCONNECT_TIMER 2 +#define DISCOVERY_TIMER 2000 struct btd_driver_data { struct btd_device_driver *driver; @@ -76,6 +77,7 @@ struct btd_device { int discov_active; /* Service discovery active */ char *discov_requestor; /* discovery requestor unique name */ guint discov_listener; + guint discov_timer; /* For Secure Simple Pairing */ uint8_t cap; @@ -566,6 +568,20 @@ static GDBusSignalTable device_signals[] = { { } }; +void device_set_connected(DBusConnection *conn, struct btd_device *device, + gboolean connected) +{ + if (!connected && device->discov_timer) { + g_source_remove(device->discov_timer); + device->discov_timer = 0; + } + + dbus_connection_emit_property_changed(conn, device->path, + DEVICE_INTERFACE, + "Connected", DBUS_TYPE_BOOLEAN, + &connected); +} + struct btd_device *device_create(DBusConnection *conn, struct btd_adapter *adapter, const gchar *address) { @@ -1239,6 +1255,27 @@ uint8_t device_get_auth(struct btd_device *device) return device->auth; } +static gboolean start_discovery(gpointer user_data) +{ + struct btd_device *device = user_data; + + device_browse(device, NULL, NULL, NULL); + + device->discov_timer = 0; + + return FALSE; +} + +void device_schedule_service_discovery(struct btd_device *device) +{ + if (device->discov_timer) + return; + + device->discov_timer = g_timeout_add(DISCOVERY_TIMER, + start_discovery, + device); +} + int btd_register_device_driver(struct btd_device_driver *driver) { device_drivers = g_slist_append(device_drivers, driver); diff --git a/src/device.h b/src/device.h index d2331173..af6a8755 100644 --- a/src/device.h +++ b/src/device.h @@ -42,6 +42,9 @@ 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); +void device_schedule_service_discovery(struct btd_device *device); +void device_set_connected(DBusConnection *conn, struct btd_device *device, + gboolean connected); #define BTD_UUIDS(args...) ((const char *[]) { args, NULL } ) -- cgit