From 14a53664138a8407382745bb470045d1817b7801 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 27 Apr 2011 10:29:56 -0400 Subject: Bluetooth: Add basic discovery commands to the management interface This patch adds start_discovery and stop_discovery commands to the management interface. Right now their implementation is fairly simplistic and the parameters are fixed to what user space has defaulted to so far. This is the very initial phase for discovery implementation into the kernel. Next steps include name resolution, LE scanning and bdaddr type handling. Signed-off-by: Johan Hedberg Signed-off-by: Anderson Briglia Signed-off-by: Gustavo F. Padovan --- net/bluetooth/mgmt.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) (limited to 'net/bluetooth/mgmt.c') diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index c304688252b8..dbc248f27b1b 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1569,6 +1569,75 @@ static int remove_remote_oob_data(struct sock *sk, u16 index, return err; } +static int start_discovery(struct sock *sk, u16 index) +{ + u8 lap[3] = { 0x33, 0x8b, 0x9e }; + struct hci_cp_inquiry cp; + struct pending_cmd *cmd; + struct hci_dev *hdev; + int err; + + BT_DBG("hci%u", index); + + hdev = hci_dev_get(index); + if (!hdev) + return cmd_status(sk, index, MGMT_OP_START_DISCOVERY, ENODEV); + + hci_dev_lock_bh(hdev); + + cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, index, NULL, 0); + if (!cmd) { + err = -ENOMEM; + goto failed; + } + + memset(&cp, 0, sizeof(cp)); + memcpy(&cp.lap, lap, 3); + cp.length = 0x08; + cp.num_rsp = 0x00; + + err = hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); + if (err < 0) + mgmt_pending_remove(cmd); + +failed: + hci_dev_unlock_bh(hdev); + hci_dev_put(hdev); + + return err; +} + +static int stop_discovery(struct sock *sk, u16 index) +{ + struct hci_dev *hdev; + struct pending_cmd *cmd; + int err; + + BT_DBG("hci%u", index); + + hdev = hci_dev_get(index); + if (!hdev) + return cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY, ENODEV); + + hci_dev_lock_bh(hdev); + + cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, index, NULL, 0); + if (!cmd) { + err = -ENOMEM; + goto failed; + } + + err = hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL); + if (err < 0) + mgmt_pending_remove(cmd); + +failed: + hci_dev_unlock_bh(hdev); + hci_dev_put(hdev); + + return err; +} + int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) { unsigned char *buf; @@ -1677,7 +1746,12 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) err = remove_remote_oob_data(sk, index, buf + sizeof(*hdr), len); break; - + case MGMT_OP_START_DISCOVERY: + err = start_discovery(sk, index); + break; + case MGMT_OP_STOP_DISCOVERY: + err = stop_discovery(sk, index); + break; default: BT_DBG("Unknown op %u", opcode); err = cmd_status(sk, index, opcode, 0x01); -- cgit v1.2.3 From 314b2381a79c6bfe3ddc4ba3806ecb6aec27a3db Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 27 Apr 2011 10:29:57 -0400 Subject: Bluetooth: Add discovering event to the Management interface This patch adds a new event to the Management interface to track when local adapters are discovering remote devices. For now this only tracks BR/EDR discovery procedures. Signed-off-by: Johan Hedberg Signed-off-by: Anderson Briglia Signed-off-by: Gustavo F. Padovan --- net/bluetooth/mgmt.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'net/bluetooth/mgmt.c') diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index dbc248f27b1b..4542396fc856 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -2149,3 +2149,9 @@ int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name) return mgmt_event(MGMT_EV_REMOTE_NAME, index, &ev, sizeof(ev), NULL); } + +int mgmt_discovering(u16 index, u8 discovering) +{ + return mgmt_event(MGMT_EV_DISCOVERING, index, &discovering, + sizeof(discovering), NULL); +} -- cgit v1.2.3 From a770bb5aea84ee2509d4775f9959665f96da3b9d Mon Sep 17 00:00:00 2001 From: Waldemar Rymarkiewicz Date: Thu, 28 Apr 2011 12:07:59 +0200 Subject: Bluetooth: Add secure flag for mgmt_pin_code_req Extend the mgmt_pin_code_request interface to require secure pin code (16 digit) for authentication. This is a kernel part of the secure pin code requirement notification to user space agent. Code styling fix by Johan Hedberg. Signed-off-by: Waldemar Rymarkiewicz Signed-off-by: Johan Hedberg Signed-off-by: Gustavo F. Padovan --- net/bluetooth/mgmt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'net/bluetooth/mgmt.c') diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 4542396fc856..a7b4937d761c 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1942,11 +1942,12 @@ int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status) return mgmt_event(MGMT_EV_CONNECT_FAILED, index, &ev, sizeof(ev), NULL); } -int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr) +int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure) { struct mgmt_ev_pin_code_request ev; bacpy(&ev.bdaddr, bdaddr); + ev.secure = secure; return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, index, &ev, sizeof(ev), NULL); -- cgit v1.2.3 From 55bc1a378cc35f21a26e07af2ff2b71820808cd4 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 28 Apr 2011 11:28:56 -0700 Subject: Bluetooth: Add confirm_hint parameter to user confirmation requests When accepting a pairing request which fulfills the SSP auto-accept criteria we need to push the request all the way to the user for confirmation. This patch adds a new hint to the user_confirm_request management event so user space can know when to show a numeric comparison dialog and when to show a simple yes/no confirmation dialog. Signed-off-by: Johan Hedberg Signed-off-by: Gustavo F. Padovan --- net/bluetooth/mgmt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'net/bluetooth/mgmt.c') diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index a7b4937d761c..a1b0ec4e5178 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1995,13 +1995,15 @@ int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) return err; } -int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value) +int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value, + u8 confirm_hint) { struct mgmt_ev_user_confirm_request ev; BT_DBG("hci%u", index); bacpy(&ev.bdaddr, bdaddr); + ev.confirm_hint = confirm_hint; put_unaligned_le32(value, &ev.value); return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, index, &ev, sizeof(ev), -- cgit v1.2.3 From d25e28abe58d2bcedf6025a6ccc532c29a19046f Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 28 Apr 2011 11:28:59 -0700 Subject: Bluetooth: Fix link key persistent storage criteria Link keys should only be stored if very specific criteria of the authentication process are fulfilled. This patch essentially copies the criteria that user space has so far been using to the kernel side so that the management interface works properly. Signed-off-by: Johan Hedberg Signed-off-by: Gustavo F. Padovan --- net/bluetooth/mgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/bluetooth/mgmt.c') diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index a1b0ec4e5178..e1384fc6016c 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -945,7 +945,7 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len) for (i = 0; i < key_count; i++) { struct mgmt_key_info *key = &cp->keys[i]; - hci_add_link_key(hdev, 0, &key->bdaddr, key->val, key->type, + hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type, key->pin_len); } -- cgit v1.2.3 From 4748fed2d1a2a7a816277754498b8aa70850e051 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 28 Apr 2011 11:29:02 -0700 Subject: Bluetooth: Remove old_key_type from mgmt_ev_new_key User space shouldn't have any need for the old key type so remove it from the corresponding Management interface event. Signed-off-by: Johan Hedberg Signed-off-by: Gustavo F. Padovan --- net/bluetooth/mgmt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'net/bluetooth/mgmt.c') diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index e1384fc6016c..232ea8bfff19 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1858,7 +1858,7 @@ int mgmt_connectable(u16 index, u8 connectable) return ret; } -int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type) +int mgmt_new_key(u16 index, struct link_key *key) { struct mgmt_ev_new_key ev; @@ -1868,7 +1868,6 @@ int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type) ev.key.type = key->type; memcpy(ev.key.val, key->val, 16); ev.key.pin_len = key->pin_len; - ev.old_key_type = old_key_type; return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL); } -- cgit v1.2.3 From 4df378a10e31698df1679f3329301d773a654b61 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 28 Apr 2011 11:29:03 -0700 Subject: Bluetooth: Add store_hint parameter to mgmt_new_key Even for keys that shouldn't be stored some use cases require the knowledge of a new key having been created so that the conclusion of a successful pairing can be made. Therefore, always send the mgmt_new_key event but add a store_hint parameter to it to indicate to user space whether the key should be stored or not. Signed-off-by: Johan Hedberg Signed-off-by: Gustavo F. Padovan --- net/bluetooth/mgmt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'net/bluetooth/mgmt.c') diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 232ea8bfff19..2481d257ed98 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1858,12 +1858,13 @@ int mgmt_connectable(u16 index, u8 connectable) return ret; } -int mgmt_new_key(u16 index, struct link_key *key) +int mgmt_new_key(u16 index, struct link_key *key, u8 persistent) { struct mgmt_ev_new_key ev; memset(&ev, 0, sizeof(ev)); + ev.store_hint = persistent; bacpy(&ev.key.bdaddr, &key->bdaddr); ev.key.type = key->type; memcpy(ev.key.val, key->val, 16); -- cgit v1.2.3