summaryrefslogtreecommitdiffstats
path: root/hcid
diff options
context:
space:
mode:
authorClaudio Takahasi <claudio.takahasi@openbossa.org>2006-08-25 14:03:52 +0000
committerClaudio Takahasi <claudio.takahasi@openbossa.org>2006-08-25 14:03:52 +0000
commit10dcd5fa6f6978b1ea76f370e87dc3f14e46ac0c (patch)
tree5ead42eaf538e7e6a98c6c314af26f1e3a6956fc /hcid
parentdbe289f011a9ecedf0f4cabb9f25c9564c8aa830 (diff)
Reduced CancelBonding reply time
Diffstat (limited to 'hcid')
-rw-r--r--hcid/dbus-adapter.c57
-rw-r--r--hcid/dbus.c120
-rw-r--r--hcid/dbus.h11
-rw-r--r--hcid/hcid.h2
-rw-r--r--hcid/security.c8
5 files changed, 106 insertions, 92 deletions
diff --git a/hcid/dbus-adapter.c b/hcid/dbus-adapter.c
index 07583d77..749dad6f 100644
--- a/hcid/dbus-adapter.c
+++ b/hcid/dbus-adapter.c
@@ -1792,7 +1792,8 @@ static DBusHandlerResult handle_dev_create_bonding_req(DBusConnection *conn, DBu
static DBusHandlerResult handle_dev_cancel_bonding_req(DBusConnection *conn, DBusMessage *msg, void *data)
{
struct hci_dbus_data *dbus_data = data;
- struct slist *l;
+ struct slist *la;
+ DBusMessage *reply;
DBusError err;
bdaddr_t peer_bdaddr;
const char *peer_addr;
@@ -1830,11 +1831,11 @@ static DBusHandlerResult handle_dev_cancel_bonding_req(DBusConnection *conn, DBu
if (dd < 0)
return error_no_such_adapter(conn, msg);
- dbus_data->bonding->cancel = dbus_message_ref(msg);
+ dbus_data->bonding->cancel = 1;
- l = slist_find(dbus_data->active_conn, &peer_bdaddr, active_conn_find_by_bdaddr);
+ la = slist_find(dbus_data->active_conn, &peer_bdaddr, active_conn_find_by_bdaddr);
- if (!l) {
+ if (!la) {
/* connection request is pending */
struct hci_request rq;
create_conn_cancel_cp cp;
@@ -1874,26 +1875,44 @@ static DBusHandlerResult handle_dev_cancel_bonding_req(DBusConnection *conn, DBu
*/
} else {
- struct active_conn_info *cinfo = l->data;
-
- /* for unlock PIN Code Request */
- hci_send_cmd(dd, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, &peer_bdaddr);
+ struct slist *lb;
+ struct active_conn_info *cinfo = la->data;
/*
- * Disconnect from the remote device for safety, maybe the
- * Controller already received the reply for PIN Code Request
- */
- if (dbus_data->bonding->disconnect) {
- if (hci_disconnect(dd, htobs(cinfo->handle), HCI_AUTHENTICATION_FAILURE, 1000) < 0)
- error("Disconnect failed");
+ * It is already connected, search in the pending passkey requests to
+ * figure out the current stage(waiting host passkey/remote passkey)
+ */
+ lb = slist_find(dbus_data->pending_bondings, &peer_bdaddr, pending_bonding_cmp);
+ if (lb) {
+ struct pending_bonding_info *pb = lb->data;
+ /* 0: waiting host passkey 1: waiting remote passkey */
+ if (pb->step) {
+ if (dbus_data->bonding->disconnect) {
+
+ /* disconnect and let disconnect handler reply create bonding */
+ if (hci_disconnect(dd, htobs(cinfo->handle), HCI_AUTHENTICATION_FAILURE, 1000) < 0)
+ error("Disconnect failed");
+ } else {
+ /*
+ * If disconnect can't be applied and the PIN Code Request
+ * was already replied it doesn't make sense cancel the
+ * remote passkey: return not authorized.
+ */
+
+ error_not_authorized(conn, msg);
+ goto failed;
+ }
+ } else {
+
+ /* for unlock PIN Code Request */
+ hci_send_cmd(dd, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, &peer_bdaddr);
+ }
}
-
- /*
- * If disconnect can't be applied and the PIN Code Request
- * was already replied let the Controller's timer to expire
- */
}
+ reply = dbus_message_new_method_return(msg);
+ send_reply_and_unref(conn, reply);
+failed:
hci_close_dev(dd);
return DBUS_HANDLER_RESULT_HANDLED;
diff --git a/hcid/dbus.c b/hcid/dbus.c
index f356f6ba..fc778757 100644
--- a/hcid/dbus.c
+++ b/hcid/dbus.c
@@ -77,8 +77,6 @@ void bonding_request_free(struct bonding_request_info *dev )
if (dev) {
if (dev->rq)
dbus_message_unref(dev->rq);
- if (dev->cancel)
- dbus_message_unref(dev->cancel);
free(dev);
}
}
@@ -675,16 +673,19 @@ int hcid_dbus_stop_device(uint16_t id)
return 0;
}
-static int pending_bonding_cmp(const void *p1, const void *p2)
+int pending_bonding_cmp(const void *p1, const void *p2)
{
- return p2 ? bacmp(p1, p2) : -1;
+ const struct pending_bonding_info *pb1 = p1;
+ const struct pending_bonding_info *pb2 = p2;
+
+ return p2 ? bacmp(&pb1->bdaddr, &pb2->bdaddr) : -1;
}
void hcid_dbus_pending_bonding_add(bdaddr_t *sba, bdaddr_t *dba)
{
char path[MAX_PATH_LENGTH], addr[18];
struct hci_dbus_data *pdata;
- bdaddr_t *peer;
+ struct pending_bonding_info *peer;
ba2str(sba, addr);
@@ -695,8 +696,10 @@ void hcid_dbus_pending_bonding_add(bdaddr_t *sba, bdaddr_t *dba)
return;
}
- peer = malloc(sizeof(bdaddr_t));
- bacpy(peer, dba);
+ peer = malloc(sizeof(*peer));
+ memset(peer, 0, sizeof(*peer));
+
+ bacpy(&peer->bdaddr, dba);
pdata->pending_bondings = slist_append(pdata->pending_bondings, peer);
}
@@ -796,14 +799,9 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer, const u
}
if (pdata->bonding->cancel) {
- /* reply the cancel bonding */
- message = dbus_message_new_method_return(pdata->bonding->cancel);
- send_reply_and_unref(connection, message);
-
/* reply authentication canceled */
error_authentication_canceled(connection, pdata->bonding->rq);
} else {
-
/* reply authentication success or an error */
message = dbus_msg_new_authentication_return(pdata->bonding->rq, status);
send_reply_and_unref(connection, message);
@@ -820,51 +818,6 @@ failed:
bt_free(peer_addr);
}
-void hcid_dbus_create_conn_cancel(bdaddr_t *local, void *ptr)
-{
- typedef struct {
- uint8_t status;
- bdaddr_t bdaddr;
- }__attribute__ ((packed)) ret_param_conn_cancel;
-
- char path[MAX_PATH_LENGTH];
- bdaddr_t tmp;
- ret_param_conn_cancel *ret = ptr + sizeof(evt_cmd_complete);
- DBusMessage *reply;
- char *local_addr, *peer_addr;
- struct hci_dbus_data *pdata;
- int id;
-
- baswap(&tmp, local); local_addr = batostr(&tmp);
- baswap(&tmp, &ret->bdaddr); peer_addr = batostr(&tmp);
-
- id = hci_devid(local_addr);
- if (id < 0) {
- error("No matching device id for %s", local_addr);
- goto failed;
- }
-
- snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, id);
- if (!dbus_connection_get_object_path_data(connection, path, (void *) &pdata)) {
- error("Getting %s path data failed!", path);
- goto failed;
- }
-
- if (!pdata->bonding || !pdata->bonding->cancel ||
- bacmp(&pdata->bonding->bdaddr, &ret->bdaddr))
- goto failed;
-
- if (!ret->status) {
- reply = dbus_message_new_method_return(pdata->bonding->cancel);
- send_reply_and_unref(connection, reply);
- } else
- error_failed(connection, pdata->bonding->cancel, bt_error(ret->status));
-
-failed:
- bt_free(local_addr);
- bt_free(peer_addr);
-}
-
void hcid_dbus_inquiry_start(bdaddr_t *local)
{
struct hci_dbus_data *pdata;
@@ -1301,11 +1254,6 @@ void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle, b
}
if (pdata->bonding->cancel) {
- /*
- * reply to cancel bonding was done in the cancel create connection
- * handler or in the beginning if the controller doesn't support
- * cancel cmd. Reply authentication canceled only.
- */
error_authentication_canceled(connection, pdata->bonding->rq);
/*
@@ -1426,14 +1374,9 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status, uint16_t handle
send_reply_and_unref(connection, message);
#endif
if (pdata->bonding->cancel) {
- /* reply the cancel bonding */
- message = dbus_message_new_method_return(pdata->bonding->cancel);
- send_reply_and_unref(connection, message);
-
/* reply authentication canceled */
error_authentication_canceled(connection, pdata->bonding->rq);
} else {
-
message = dbus_msg_new_authentication_return(pdata->bonding->rq, HCI_AUTHENTICATION_FAILURE);
send_reply_and_unref(connection, message);
}
@@ -2007,6 +1950,49 @@ failed:
bt_free(local_addr);
}
+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 hci_dbus_data *pdata;
+ char *local_addr;
+ ret_pin_code_req_reply *ret = ptr + sizeof(evt_cmd_complete);
+ struct slist *l;
+ char path[MAX_PATH_LENGTH];
+ bdaddr_t tmp;
+ int id;
+
+ baswap(&tmp, local); local_addr = batostr(&tmp);
+ id = hci_devid(local_addr);
+ if (id < 0) {
+ error("No matching device id for %s", local_addr);
+ goto failed;
+ }
+
+ snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, id);
+
+ if (!dbus_connection_get_object_path_data(connection, path, (void *) &pdata)) {
+ error("Getting %s path data failed!", path);
+ goto failed;
+ }
+
+ if (!pdata->pending_bondings)
+ goto failed;
+
+ l = slist_find(pdata->pending_bondings, &ret->bdaddr, pending_bonding_cmp);
+ if (l) {
+ struct pending_bonding_info *p = l->data;
+ p->step = 1;
+ }
+
+failed:
+ bt_free(local_addr);
+}
+
void create_bond_req_exit(const char *name, struct hci_dbus_data *pdata)
{
char path[MAX_PATH_LENGTH];
diff --git a/hcid/dbus.h b/hcid/dbus.h
index 0e0e95bb..90d7b325 100644
--- a/hcid/dbus.h
+++ b/hcid/dbus.h
@@ -86,10 +86,16 @@ struct discovered_dev_info {
struct bonding_request_info {
bdaddr_t bdaddr;
DBusMessage *rq;
- DBusMessage *cancel;
+ int cancel;
int disconnect; /* disconnect after finish */
};
+struct pending_bonding_info {
+ bdaddr_t bdaddr;
+ int step; /* 0: waiting host passkey 1:waiting remote passkey */
+
+};
+
struct active_conn_info {
bdaddr_t bdaddr;
uint16_t handle;
@@ -109,7 +115,7 @@ struct hci_dbus_data {
struct slist *passkey_agents;
struct bonding_request_info *bonding;
struct slist *active_conn;
- struct slist *pending_bondings;
+ struct slist *pending_bondings; /* track D-Bus and non D-Bus requests */
};
struct passkey_agent {
@@ -214,6 +220,7 @@ static inline DBusHandlerResult send_reply_and_unref(DBusConnection *conn, DBusM
int active_conn_find_by_bdaddr(const void *data, const void *user_data);
void bonding_request_free(struct bonding_request_info *dev);
+int pending_bonding_cmp(const void *p1, const void *p2);
int disc_device_append(struct slist **list, bdaddr_t *bdaddr, name_status_t name_status, int discover_type);
int disc_device_req_name(struct hci_dbus_data *dbus_data);
diff --git a/hcid/hcid.h b/hcid/hcid.h
index c7208222..7eb231f9 100644
--- a/hcid/hcid.h
+++ b/hcid/hcid.h
@@ -159,9 +159,9 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status, char
void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle, bdaddr_t *peer);
void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status, uint16_t handle, uint8_t reason);
void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer, const uint8_t status);
-void hcid_dbus_create_conn_cancel(bdaddr_t *local, void *ptr);
void hcid_dbus_setname_complete(bdaddr_t *local);
void hcid_dbus_setscan_enable_complete(bdaddr_t *local);
+void hcid_dbus_pin_code_reply(bdaddr_t *local, void *ptr);
void init_devices(void);
int add_device(uint16_t dev_id);
diff --git a/hcid/security.c b/hcid/security.c
index 98c00ca8..b5eca651 100644
--- a/hcid/security.c
+++ b/hcid/security.c
@@ -431,15 +431,17 @@ static inline void cmd_complete(int dev, bdaddr_t *sba, void *ptr)
case cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY_CANCEL):
hcid_dbus_inquiry_complete(sba);
break;
- case cmd_opcode_pack(OGF_LINK_CTL, OCF_CREATE_CONN_CANCEL):
- hcid_dbus_create_conn_cancel(sba, ptr);
- break;
case cmd_opcode_pack(OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME):
hcid_dbus_setname_complete(sba);
break;
case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE):
hcid_dbus_setscan_enable_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;
+
};
}