From e21ec2652c54dbc8abbf84039b43fbd3be0b5ebc Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 26 Sep 2008 00:05:27 -0700 Subject: Don't do bonding_process_complete upon link_key_notify --- src/dbus-hci.c | 42 +++++++++++++++++++++++++++++++++++++----- src/dbus-hci.h | 1 + src/device.c | 34 ++++++++++++++++++++++++++++++++-- src/device.h | 4 +++- src/security.c | 5 ++--- 5 files changed, 75 insertions(+), 11 deletions(-) diff --git a/src/dbus-hci.c b/src/dbus-hci.c index e480eb7e..795df0a3 100644 --- a/src/dbus-hci.c +++ b/src/dbus-hci.c @@ -518,6 +518,9 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer, bonding = adapter_get_bonding_info(adapter); + if (bacmp(&bonding->bdaddr, peer)) + bonding = NULL; + if (status == 0) { device = adapter_get_device(connection, adapter, peer_addr); if (!device) { @@ -547,12 +550,13 @@ 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) { - device_set_paired(connection, device, bonding); + if (device_set_paired(connection, device, bonding) && bonding) + adapter_free_bonding_request(adapter); return; } proceed: - if (!bonding || bacmp(&bonding->bdaddr, peer)) + if (!bonding) return; /* skip: no bonding req pending */ if (bonding->cancel) @@ -996,12 +1000,38 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status, adapter_set_state(adapter, state); } +void hcid_dbus_link_key_notify(bdaddr_t *local, bdaddr_t *peer) +{ + char peer_addr[18]; + struct btd_device *device; + struct btd_adapter *adapter; + struct bonding_request_info *bonding; + + adapter = manager_find_adapter(local); + if (!adapter) { + error("No matching adapter found"); + return; + } + + ba2str(peer, peer_addr); + + device = adapter_find_device(adapter, peer_addr); + + bonding = adapter_get_bonding_info(adapter); + + if (!device_get_connected(device)) + device_set_secmode3_conn(device, TRUE); + else if (!bonding) + hcid_dbus_bonding_process_complete(local, peer, 0); +} + void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle, bdaddr_t *peer) { char peer_addr[18]; struct btd_adapter *adapter; struct bonding_request_info *bonding; + struct btd_device *device; adapter = manager_find_adapter(local); if (!adapter) { @@ -1011,6 +1041,8 @@ void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle, ba2str(peer, peer_addr); + device = adapter_get_device(connection, adapter, peer_addr); + if (status) { struct pending_auth_info *auth; @@ -1020,13 +1052,13 @@ void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle, adapter_remove_auth_request(adapter, peer); + if (device) + device_set_secmode3_conn(device, FALSE); + bonding = adapter_get_bonding_info(adapter); if (bonding) bonding->hci_status = status; } else { - struct btd_device *device; - - device = adapter_find_device(adapter, peer_addr); if (device) device_set_connected(connection, device, TRUE); diff --git a/src/dbus-hci.h b/src/dbus-hci.h index fb9dac96..f6547ea4 100644 --- a/src/dbus-hci.h +++ b/src/dbus-hci.h @@ -45,6 +45,7 @@ int hcid_dbus_set_io_cap(bdaddr_t *local, bdaddr_t *remote, int hcid_dbus_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey); int hcid_dbus_user_passkey(bdaddr_t *sba, bdaddr_t *dba); int hcid_dbus_user_notify(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey); +void hcid_dbus_link_key_notify(bdaddr_t *local, bdaddr_t *peer); int unregister_adapter_path(const char *path); diff --git a/src/device.c b/src/device.c index 59e48904..4f5e3c37 100644 --- a/src/device.c +++ b/src/device.c @@ -82,6 +82,11 @@ struct btd_device { /* For Secure Simple Pairing */ uint8_t cap; uint8_t auth; + + gboolean connected; + + /* Whether were creating a security mode 3 connection */ + gboolean secmode3; }; struct browse_req { @@ -568,9 +573,16 @@ static GDBusSignalTable device_signals[] = { { } }; +gboolean device_get_connected(struct btd_device *device) +{ + return device->connected; +} + void device_set_connected(DBusConnection *conn, struct btd_device *device, gboolean connected) { + device->connected = connected; + if (!connected && device->discov_timer) { g_source_remove(device->discov_timer); device->discov_timer = 0; @@ -580,6 +592,22 @@ void device_set_connected(DBusConnection *conn, struct btd_device *device, DEVICE_INTERFACE, "Connected", DBUS_TYPE_BOOLEAN, &connected); + + if (connected && device->secmode3) { + struct btd_adapter *adapter = device_get_adapter(device); + bdaddr_t sba; + + adapter_get_address(adapter, &sba); + + device->secmode3 = FALSE; + + hcid_dbus_bonding_process_complete(&sba, &device->bdaddr, 0); + } +} + +void device_set_secmode3_conn(struct btd_device *device, gboolean enable) +{ + device->secmode3 = enable; } struct btd_device *device_create(DBusConnection *conn, struct btd_adapter *adapter, @@ -1274,7 +1302,7 @@ static gboolean start_discovery(gpointer user_data) return FALSE; } -void device_set_paired(DBusConnection *conn, struct btd_device *device, +gboolean device_set_paired(DBusConnection *conn, struct btd_device *device, struct bonding_request_info *bonding) { dbus_bool_t paired = TRUE; @@ -1286,7 +1314,7 @@ void device_set_paired(DBusConnection *conn, struct btd_device *device, DBUS_TYPE_BOOLEAN, &paired); if (device->discov_timer) - return; + return FALSE; /* If we were initiators start service discovery immediately. * However if the other end was the initator wait a few seconds @@ -1299,6 +1327,8 @@ void device_set_paired(DBusConnection *conn, struct btd_device *device, device->discov_timer = g_timeout_add(DISCOVERY_TIMER, start_discovery, device); + + return TRUE; } int btd_register_device_driver(struct btd_device_driver *driver) diff --git a/src/device.h b/src/device.h index 099ecbbc..126426df 100644 --- a/src/device.h +++ b/src/device.h @@ -42,10 +42,12 @@ 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_set_paired(DBusConnection *conn, struct btd_device *device, +gboolean 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, gboolean connected); +void device_set_secmode3_conn(struct btd_device *device, gboolean enable); #define BTD_UUIDS(args...) ((const char *[]) { args, NULL } ) diff --git a/src/security.c b/src/security.c index 964fb5ba..18fbe590 100644 --- a/src/security.c +++ b/src/security.c @@ -367,7 +367,7 @@ static void link_key_notify(int dev, bdaddr_t *sba, void *ptr) DISCONNECT_CP_SIZE, &cp); } } else - hcid_dbus_bonding_process_complete(sba, dba, 0); + hcid_dbus_link_key_notify(sba, dba); io_data[dev_id].pin_length = -1; } @@ -775,8 +775,7 @@ static inline void auth_complete(int dev, bdaddr_t *sba, void *ptr) if (get_bdaddr(dev, sba, btohs(evt->handle), &dba) < 0) return; - if (evt->status) - hcid_dbus_bonding_process_complete(sba, &dba, evt->status); + hcid_dbus_bonding_process_complete(sba, &dba, evt->status); } static inline void conn_request(int dev, bdaddr_t *sba, void *ptr) -- cgit