summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2008-06-12 11:50:27 +0000
committerJohan Hedberg <johan.hedberg@nokia.com>2008-06-12 11:50:27 +0000
commit32c66136e4c4447a483dd42dcb1803a16c2ca3f8 (patch)
tree6181f9b96943815cba919b062d82861eac78cf27
parent7eca97cf8464cf1863a08e514c9ac7a8e0400f1c (diff)
Track agent request status in conjunction with authentication requests
-rw-r--r--hcid/adapter.c42
-rw-r--r--hcid/adapter.h1
-rw-r--r--hcid/dbus-hci.c66
3 files changed, 94 insertions, 15 deletions
diff --git a/hcid/adapter.c b/hcid/adapter.c
index 7e434965..281dd86c 100644
--- a/hcid/adapter.c
+++ b/hcid/adapter.c
@@ -273,7 +273,7 @@ void adapter_auth_request_replied(struct adapter *adapter, bdaddr_t *dba)
auth = l->data;
- auth->replied = 1;
+ auth->replied = TRUE;
}
struct pending_auth_info *adapter_find_auth_request(struct adapter *adapter,
@@ -360,11 +360,32 @@ int pending_remote_name_cancel(struct adapter *adapter)
return err;
}
+static int auth_info_agent_cmp(const void *a, const void *b)
+{
+ const struct pending_auth_info *auth = a;
+ const struct agent *agent = b;
+
+ if (auth->agent == agent)
+ return 0;
+
+ return -1;
+}
+
static void device_agent_removed(struct agent *agent, void *user_data)
{
struct device *device = user_data;
+ struct pending_auth_info *auth;
+ GSList *l;
device->agent = NULL;
+
+ l = g_slist_find_custom(device->adapter->auth_reqs, agent,
+ auth_info_agent_cmp);
+ if (!l)
+ return;
+
+ auth = l->data;
+ auth->agent = NULL;
}
static struct bonding_request_info *bonding_request_new(DBusConnection *conn,
@@ -2743,6 +2764,8 @@ static void create_bond_req_exit(void *user_data)
auth = adapter_find_auth_request(adapter, &adapter->bonding->bdaddr);
if (auth) {
cancel_auth_request(auth, adapter->dev_id);
+ if (auth->agent)
+ agent_cancel(auth->agent);
adapter_remove_auth_request(adapter, &adapter->bonding->bdaddr);
}
@@ -2881,9 +2904,11 @@ static DBusMessage *adapter_cancel_bonding(DBusConnection *conn,
*/
g_io_channel_close(adapter->bonding->io);
return not_authorized(msg);
- } else
- cancel_auth_request(auth_req, adapter->dev_id);
+ }
+ cancel_auth_request(auth_req, adapter->dev_id);
+ if (auth_req->agent)
+ agent_cancel(auth_req->agent);
adapter_remove_auth_request(adapter, &bdaddr);
}
@@ -4080,7 +4105,18 @@ static DBusMessage *find_device(DBusConnection *conn,
static void agent_removed(struct agent *agent, struct adapter *adapter)
{
+ struct pending_auth_info *auth;
+ GSList *l;
+
adapter->agent = NULL;
+
+ l = g_slist_find_custom(adapter->auth_reqs, agent,
+ auth_info_agent_cmp);
+ if (!l)
+ return;
+
+ auth = l->data;
+ auth->agent = NULL;
}
static DBusMessage *register_agent(DBusConnection *conn,
diff --git a/hcid/adapter.h b/hcid/adapter.h
index cf5bb5f9..f6ed7a22 100644
--- a/hcid/adapter.h
+++ b/hcid/adapter.h
@@ -76,6 +76,7 @@ struct pending_auth_info {
auth_type_t type;
bdaddr_t bdaddr;
gboolean replied; /* If we've already replied to the request */
+ struct agent *agent; /* Agent associated with the request */
};
struct active_conn_info {
diff --git a/hcid/dbus-hci.c b/hcid/dbus-hci.c
index ef283db8..300181ec 100644
--- a/hcid/dbus-hci.c
+++ b/hcid/dbus-hci.c
@@ -841,6 +841,7 @@ static void pincode_cb(struct agent *agent, DBusError *err, const char *pincode,
bdaddr_t sba, dba;
size_t len;
int dev;
+ struct pending_auth_info *auth;
/* No need to reply anything if the authentication already failed */
if (adapter->bonding && adapter->bonding->hci_status)
@@ -853,9 +854,12 @@ static void pincode_cb(struct agent *agent, DBusError *err, const char *pincode,
return;
}
+
str2ba(adapter->address, &sba);
str2ba(device->address, &dba);
+ auth = adapter_find_auth_request(adapter, &dba);
+
if (err) {
hci_send_cmd(dev, OGF_LINK_CTL,
OCF_PIN_CODE_NEG_REPLY, 6, &dba);
@@ -873,7 +877,10 @@ 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);
+ if (auth) {
+ auth->replied = TRUE;
+ auth->agent = NULL;
+ }
hci_close_dev(dev);
}
@@ -910,9 +917,13 @@ int hcid_dbus_request_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci)
ret = agent_request_pincode(agent, device,
(agent_pincode_cb) pincode_cb,
device);
- if (ret == 0)
- adapter_new_auth_request(adapter, &ci->bdaddr,
+ if (ret == 0) {
+ struct pending_auth_info *auth;
+ auth = adapter_new_auth_request(adapter, &ci->bdaddr,
AUTH_TYPE_PINCODE);
+ auth->agent = agent;
+ }
+
return ret;
@@ -922,7 +933,6 @@ old_fallback:
if (ret == 0)
adapter_new_auth_request(adapter, &ci->bdaddr,
AUTH_TYPE_PINCODE);
-
return ret;
}
@@ -932,6 +942,7 @@ static void confirm_cb(struct agent *agent, DBusError *err, void *user_data)
struct adapter *adapter = device->adapter;
user_confirm_reply_cp cp;
int dd;
+ struct pending_auth_info *auth;
/* No need to reply anything if the authentication already failed */
if (adapter->bonding && adapter->bonding->hci_status)
@@ -946,6 +957,8 @@ static void confirm_cb(struct agent *agent, DBusError *err, void *user_data)
memset(&cp, 0, sizeof(cp));
str2ba(device->address, &cp.bdaddr);
+ auth = adapter_find_auth_request(adapter, &cp.bdaddr);
+
if (err)
hci_send_cmd(dd, OGF_LINK_CTL, OCF_USER_CONFIRM_NEG_REPLY,
USER_CONFIRM_REPLY_CP_SIZE, &cp);
@@ -953,7 +966,10 @@ 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);
+ if (auth) {
+ auth->replied = TRUE;
+ auth->agent = FALSE;
+ }
hci_close_dev(dd);
}
@@ -966,6 +982,7 @@ static void passkey_cb(struct agent *agent, DBusError *err, uint32_t passkey,
user_passkey_reply_cp cp;
bdaddr_t dba;
int dd;
+ struct pending_auth_info *auth;
/* No need to reply anything if the authentication already failed */
if (adapter->bonding && adapter->bonding->hci_status)
@@ -983,6 +1000,8 @@ static void passkey_cb(struct agent *agent, DBusError *err, uint32_t passkey,
bacpy(&cp.bdaddr, &dba);
cp.passkey = passkey;
+ auth = adapter_find_auth_request(adapter, &dba);
+
if (err)
hci_send_cmd(dd, OGF_LINK_CTL,
OCF_USER_PASSKEY_NEG_REPLY, 6, &dba);
@@ -990,7 +1009,10 @@ 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);
+ if (auth) {
+ auth->replied = TRUE;
+ auth->agent = NULL;
+ }
hci_close_dev(dd);
}
@@ -1032,6 +1054,7 @@ int hcid_dbus_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey)
struct agent *agent;
char addr[18];
uint8_t type;
+ struct pending_auth_info *auth;
adapter = manager_find_adapter(sba);
if (!adapter) {
@@ -1060,8 +1083,6 @@ 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;
@@ -1086,7 +1107,8 @@ int hcid_dbus_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey)
return -1;
}
- adapter_new_auth_request(adapter, dba, AUTH_TYPE_CONFIRM);
+ auth = adapter_new_auth_request(adapter, dba, AUTH_TYPE_CONFIRM);
+ auth->agent = agent;
return 0;
}
@@ -1097,6 +1119,7 @@ int hcid_dbus_user_passkey(bdaddr_t *sba, bdaddr_t *dba)
struct device *device;
struct agent *agent;
char addr[18];
+ struct pending_auth_info *auth;
adapter = manager_find_adapter(sba);
if (!adapter) {
@@ -1122,7 +1145,8 @@ int hcid_dbus_user_passkey(bdaddr_t *sba, bdaddr_t *dba)
return -1;
}
- adapter_new_auth_request(adapter, dba, AUTH_TYPE_PASSKEY);
+ auth = adapter_new_auth_request(adapter, dba, AUTH_TYPE_PASSKEY);
+ auth->agent = agent;
return 0;
}
@@ -1133,6 +1157,7 @@ int hcid_dbus_user_notify(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey)
struct device *device;
struct agent *agent;
char addr[18];
+ struct pending_auth_info *auth;
adapter = manager_find_adapter(sba);
if (!adapter) {
@@ -1158,7 +1183,8 @@ int hcid_dbus_user_notify(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey)
return -1;
}
- adapter_new_auth_request(adapter, dba, AUTH_TYPE_NOTIFY);
+ auth = adapter_new_auth_request(adapter, dba, AUTH_TYPE_NOTIFY);
+ auth->agent = agent;
return 0;
}
@@ -1173,6 +1199,7 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer,
struct device *device;
struct bonding_request_info *bonding;
gboolean paired = TRUE;
+ struct pending_auth_info *auth;
debug("hcid_dbus_bonding_process_complete: status=%02x", status);
@@ -1191,11 +1218,15 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer,
adapter->path, peer);
}
- if (!adapter_find_auth_request(adapter, peer)) {
+ auth = adapter_find_auth_request(adapter, peer);
+ if (!auth) {
debug("hcid_dbus_bonding_process_complete: no pending auth request");
goto proceed;
}
+ if (auth->agent)
+ agent_cancel(auth->agent);
+
adapter_remove_auth_request(adapter, peer);
if (status)
@@ -1977,10 +2008,16 @@ void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle,
ba2str(peer, peer_addr);
if (status) {
+ struct pending_auth_info *auth;
+
cancel_passkey_agent_requests(adapter->passkey_agents,
adapter->path, peer);
release_passkey_agents(adapter, peer);
+ auth = adapter_find_auth_request(adapter, peer);
+ if (auth && auth->agent)
+ agent_cancel(auth->agent);
+
adapter_remove_auth_request(adapter, peer);
if (adapter->bonding)
@@ -2022,6 +2059,7 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status,
struct active_conn_info *dev;
GSList *l;
gboolean connected = FALSE;
+ struct pending_auth_info *auth;
if (status) {
error("Disconnection failed: 0x%02x", status);
@@ -2052,6 +2090,10 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status,
&dev->bdaddr);
release_passkey_agents(adapter, &dev->bdaddr);
+ auth = adapter_find_auth_request(adapter, &dev->bdaddr);
+ if (auth && auth->agent)
+ agent_cancel(auth->agent);
+
adapter_remove_auth_request(adapter, &dev->bdaddr);
/* Check if there is a pending CreateBonding request */