From 7eca97cf8464cf1863a08e514c9ac7a8e0400f1c Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 12 Jun 2008 11:11:01 +0000 Subject: Don't use raw HCI for tracking authentication request status --- hcid/adapter.c | 65 ++++++++++++++++++++++++++++++---------------------- hcid/adapter.h | 3 ++- hcid/dbus-hci.c | 29 ++++++----------------- hcid/dbus-hci.h | 1 - hcid/dbus-security.c | 13 +++++++++++ hcid/security.c | 4 ---- 6 files changed, 59 insertions(+), 56 deletions(-) diff --git a/hcid/adapter.c b/hcid/adapter.c index 1e22c510..7e434965 100644 --- a/hcid/adapter.c +++ b/hcid/adapter.c @@ -262,6 +262,20 @@ static int auth_req_cmp(const void *p1, const void *p2) return bda ? bacmp(&pb1->bdaddr, bda) : -1; } +void adapter_auth_request_replied(struct adapter *adapter, bdaddr_t *dba) +{ + GSList *l; + struct pending_auth_info *auth; + + l = g_slist_find_custom(adapter->auth_reqs, dba, auth_req_cmp); + if (!l) + return; + + auth = l->data; + + auth->replied = 1; +} + struct pending_auth_info *adapter_find_auth_request(struct adapter *adapter, bdaddr_t *dba) { @@ -2676,25 +2690,40 @@ cleanup: return FALSE; } -static void cancel_auth_request(int dd, auth_type_t type, bdaddr_t *bda) +static void cancel_auth_request(struct pending_auth_info *auth, int dev_id) { - switch (type) { + int dd; + + if (auth->replied) + return; + + dd = hci_open_dev(dev_id); + if (dd < 0) { + error("hci_open_dev: %s (%d)", strerror(errno), errno); + return; + } + + switch (auth->type) { case AUTH_TYPE_PINCODE: hci_send_cmd(dd, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, - 6, bda); + 6, &auth->bdaddr); break; case AUTH_TYPE_CONFIRM: hci_send_cmd(dd, OGF_LINK_CTL, OCF_USER_CONFIRM_NEG_REPLY, - 6, bda); + 6, &auth->bdaddr); break; case AUTH_TYPE_PASSKEY: hci_send_cmd(dd, OGF_LINK_CTL, OCF_USER_PASSKEY_NEG_REPLY, - 6, bda); + 6, &auth->bdaddr); break; case AUTH_TYPE_NOTIFY: /* User Notify doesn't require any reply */ break; } + + auth->replied = TRUE; + + hci_close_dev(dd); } static void create_bond_req_exit(void *user_data) @@ -2713,16 +2742,7 @@ static void create_bond_req_exit(void *user_data) auth = adapter_find_auth_request(adapter, &adapter->bonding->bdaddr); if (auth) { - if (!auth->replied) { - int dd; - - dd = hci_open_dev(adapter->dev_id); - if (dd >= 0) { - cancel_auth_request(dd, auth->type, &auth->bdaddr); - hci_close_dev(dd); - } - } - + cancel_auth_request(auth, adapter->dev_id); adapter_remove_auth_request(adapter, &adapter->bonding->bdaddr); } @@ -2861,19 +2881,8 @@ static DBusMessage *adapter_cancel_bonding(DBusConnection *conn, */ g_io_channel_close(adapter->bonding->io); return not_authorized(msg); - } else { - int dd = hci_open_dev(adapter->dev_id); - if (dd < 0) { - int err = errno; - error("Can't open hci%d: %s (%d)", - adapter->dev_id, strerror(err), err); - return failed_strerror(msg, err); - } - - cancel_auth_request(dd, auth_req->type, &auth_req->bdaddr); - - hci_close_dev(dd); - } + } else + cancel_auth_request(auth_req, adapter->dev_id); adapter_remove_auth_request(adapter, &bdaddr); } diff --git a/hcid/adapter.h b/hcid/adapter.h index 2e14bfc0..cf5bb5f9 100644 --- a/hcid/adapter.h +++ b/hcid/adapter.h @@ -75,7 +75,7 @@ struct bonding_request_info { struct pending_auth_info { auth_type_t type; bdaddr_t bdaddr; - int replied; /* If we've already replied to the request */ + gboolean replied; /* If we've already replied to the request */ }; struct active_conn_info { @@ -155,6 +155,7 @@ void dc_pending_timeout_cleanup(struct adapter *adapter); void remove_pending_device(struct adapter *adapter); +void adapter_auth_request_replied(struct adapter *adapter, bdaddr_t *dba); struct pending_auth_info *adapter_find_auth_request(struct adapter *adapter, bdaddr_t *dba); void adapter_remove_auth_request(struct adapter *adapter, bdaddr_t *dba); diff --git a/hcid/dbus-hci.c b/hcid/dbus-hci.c index 32a6c788..ef283db8 100644 --- a/hcid/dbus-hci.c +++ b/hcid/dbus-hci.c @@ -873,6 +873,7 @@ static void pincode_cb(struct agent *agent, DBusError *err, const char *pincode, hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr); done: + adapter_auth_request_replied(adapter, &dba); hci_close_dev(dev); } @@ -952,6 +953,8 @@ static void confirm_cb(struct agent *agent, DBusError *err, void *user_data) hci_send_cmd(dd, OGF_LINK_CTL, OCF_USER_CONFIRM_REPLY, USER_CONFIRM_REPLY_CP_SIZE, &cp); + adapter_auth_request_replied(adapter, &cp.bdaddr); + hci_close_dev(dd); } @@ -987,6 +990,8 @@ static void passkey_cb(struct agent *agent, DBusError *err, uint32_t passkey, hci_send_cmd(dd, OGF_LINK_CTL, OCF_USER_PASSKEY_REPLY, USER_PASSKEY_REPLY_CP_SIZE, &cp); + adapter_auth_request_replied(adapter, &dba); + hci_close_dev(dd); } @@ -1055,6 +1060,8 @@ int hcid_dbus_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey) hci_send_cmd(dd, OGF_LINK_CTL, OCF_USER_CONFIRM_REPLY, USER_CONFIRM_REPLY_CP_SIZE, &cp); + adapter_auth_request_replied(adapter, dba); + hci_close_dev(dd); return 0; @@ -2378,28 +2385,6 @@ void hcid_dbus_write_simple_pairing_mode_complete(bdaddr_t *local) hci_close_dev(dd); } -void hcid_dbus_pin_code_reply(bdaddr_t *local, void *ptr) -{ - typedef struct { - uint8_t status; - bdaddr_t bdaddr; - } __attribute__ ((packed)) ret_pin_code_req_reply; - - struct pending_auth_info *auth; - struct adapter *adapter; - ret_pin_code_req_reply *ret = ptr + EVT_CMD_COMPLETE_SIZE; - - adapter = manager_find_adapter(local); - if (!adapter) { - error("No matching adapter found"); - return; - } - - auth = adapter_find_auth_request(adapter, &ret->bdaddr); - if (auth) - auth->replied = 1; -} - int hcid_dbus_get_io_cap(bdaddr_t *local, bdaddr_t *remote, uint8_t *cap, uint8_t *auth) { diff --git a/hcid/dbus-hci.h b/hcid/dbus-hci.h index 87aa8a46..9f53957a 100644 --- a/hcid/dbus-hci.h +++ b/hcid/dbus-hci.h @@ -52,7 +52,6 @@ void hcid_dbus_setname_complete(bdaddr_t *local); void hcid_dbus_setscan_enable_complete(bdaddr_t *local); void hcid_dbus_write_class_complete(bdaddr_t *local); void hcid_dbus_write_simple_pairing_mode_complete(bdaddr_t *local); -void hcid_dbus_pin_code_reply(bdaddr_t *local, void *ptr); int hcid_dbus_get_io_cap(bdaddr_t *local, bdaddr_t *remote, uint8_t *cap, uint8_t *auth); int hcid_dbus_set_io_cap(bdaddr_t *local, bdaddr_t *remote, diff --git a/hcid/dbus-security.c b/hcid/dbus-security.c index 146c1190..8f587001 100644 --- a/hcid/dbus-security.c +++ b/hcid/dbus-security.c @@ -44,6 +44,7 @@ #include #include "adapter.h" +#include "manager.h" #include "hcid.h" #include "dbus-common.h" #include "dbus-service.h" @@ -110,10 +111,14 @@ static void passkey_agent_free(struct passkey_agent *agent) for (l = agent->pending_requests; l != NULL; l = l->next) { struct pending_agent_request *req = l->data; + struct adapter *adapter = manager_find_adapter(&req->sba); hci_send_cmd(req->dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, &req->bda); + if (adapter) + adapter_auth_request_replied(adapter, &req->bda); + send_cancel_request(req); } @@ -643,6 +648,7 @@ static void passkey_agent_reply(DBusPendingCall *call, void *user_data) { struct pending_agent_request *req = user_data; struct passkey_agent *agent = req->agent; + struct adapter *adapter = manager_find_adapter(&req->sba); pin_code_reply_cp pr; DBusMessage *message; DBusError err; @@ -712,6 +718,9 @@ fail: OCF_PIN_CODE_NEG_REPLY, 6, &req->bda); done: + if (adapter) + adapter_auth_request_replied(adapter, &req->bda); + if (message) dbus_message_unref(message); @@ -735,6 +744,7 @@ static int call_passkey_agent(DBusConnection *conn, bdaddr_t *dba) { struct pending_agent_request *req; + struct adapter *adapter = manager_find_adapter(sba); if (!agent) { debug("call_passkey_agent(): no agent available"); @@ -768,6 +778,9 @@ failed: send: hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, dba); + if (adapter) + adapter_auth_request_replied(adapter, &req->bda); + return -1; } diff --git a/hcid/security.c b/hcid/security.c index c5cfdb65..bc807377 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -570,10 +570,6 @@ static inline void cmd_complete(int dev, bdaddr_t *sba, void *ptr) case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_SIMPLE_PAIRING_MODE): hcid_dbus_write_simple_pairing_mode_complete(sba); break; - case cmd_opcode_pack(OGF_LINK_CTL, OCF_PIN_CODE_REPLY): - case cmd_opcode_pack(OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY): - hcid_dbus_pin_code_reply(sba, ptr); - break; }; } -- cgit