From 561aafbcb2e3f8fee11d3781f866c7b4c4f93a28 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 4 Jan 2012 13:31:59 +0200 Subject: Bluetooth: Add initial mgmt_confirm_name support This patch adds initial support for mgmt_confirm_name. It adds the necessary tracking of the name state by extending the inquiry cache. The actual name resolving operation (to be done once inquiry is finished) is not yet part of this patch. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 51 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 8 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 001307f81057..9302c3c25568 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1533,9 +1533,9 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff * data.clock_offset = info->clock_offset; data.rssi = 0x00; data.ssp_mode = 0x00; - hci_inquiry_cache_update(hdev, &data); + hci_inquiry_cache_update(hdev, &data, false); mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, - info->dev_class, 0, NULL); + info->dev_class, 0, 1, NULL); } hci_dev_unlock(hdev); @@ -2572,10 +2572,10 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct data.clock_offset = info->clock_offset; data.rssi = info->rssi; data.ssp_mode = 0x00; - hci_inquiry_cache_update(hdev, &data); + hci_inquiry_cache_update(hdev, &data, false); mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, info->dev_class, info->rssi, - NULL); + 1, NULL); } } else { struct inquiry_info_with_rssi *info = (void *) (skb->data + 1); @@ -2589,10 +2589,10 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct data.clock_offset = info->clock_offset; data.rssi = info->rssi; data.ssp_mode = 0x00; - hci_inquiry_cache_update(hdev, &data); + hci_inquiry_cache_update(hdev, &data, false); mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, info->dev_class, info->rssi, - NULL); + 1, NULL); } } @@ -2710,6 +2710,31 @@ static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *s BT_DBG("%s status %d", hdev->name, ev->status); } +static inline bool eir_has_complete_name(u8 *data, size_t data_len) +{ + u8 field_len; + size_t parsed; + + for (parsed = 0; parsed < data_len - 1; parsed += field_len) { + field_len = data[0]; + + if (field_len == 0) + break; + + parsed += field_len + 1; + + if (parsed > data_len) + break; + + if (data[1] == EIR_NAME_COMPLETE) + return true; + + data += field_len + 1; + } + + return false; +} + static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct inquiry_data data; @@ -2724,6 +2749,8 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct hci_dev_lock(hdev); for (; num_rsp; num_rsp--, info++) { + bool name_known; + bacpy(&data.bdaddr, &info->bdaddr); data.pscan_rep_mode = info->pscan_rep_mode; data.pscan_period_mode = info->pscan_period_mode; @@ -2732,9 +2759,17 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct data.clock_offset = info->clock_offset; data.rssi = info->rssi; data.ssp_mode = 0x01; - hci_inquiry_cache_update(hdev, &data); + + if (test_bit(HCI_MGMT, &hdev->flags)) + name_known = eir_has_complete_name(info->data, + sizeof(info->data)); + else + name_known = true; + + hci_inquiry_cache_update(hdev, &data, name_known); mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, - info->dev_class, info->rssi, info->data); + info->dev_class, info->rssi, + !name_known, info->data); } hci_dev_unlock(hdev); -- cgit v1.2.3 From 3175405b906a85ed2bad21e09c444266e4a05a8e Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 4 Jan 2012 13:39:52 +0200 Subject: Bluetooth: Return updated name state with hci_inquiry_cache_update If user-space has already confirmed the name for a remote device we shouldn't request confirmation again. The simplest way to do this is to return the name state from hci_inquiry_cache_update (if it is anything else than unknown then we do not need confirmation from user-space). Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 9302c3c25568..d4d20df9fbbf 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1525,6 +1525,8 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff * hci_dev_lock(hdev); for (; num_rsp; num_rsp--, info++) { + bool name_known; + bacpy(&data.bdaddr, &info->bdaddr); data.pscan_rep_mode = info->pscan_rep_mode; data.pscan_period_mode = info->pscan_period_mode; @@ -1533,9 +1535,10 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff * data.clock_offset = info->clock_offset; data.rssi = 0x00; data.ssp_mode = 0x00; - hci_inquiry_cache_update(hdev, &data, false); + + name_known = hci_inquiry_cache_update(hdev, &data, false); mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, - info->dev_class, 0, 1, NULL); + info->dev_class, 0, !name_known, NULL); } hci_dev_unlock(hdev); @@ -2551,6 +2554,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct { struct inquiry_data data; int num_rsp = *((__u8 *) skb->data); + bool name_known; BT_DBG("%s num_rsp %d", hdev->name, num_rsp); @@ -2572,10 +2576,12 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct data.clock_offset = info->clock_offset; data.rssi = info->rssi; data.ssp_mode = 0x00; - hci_inquiry_cache_update(hdev, &data, false); + + name_known = hci_inquiry_cache_update(hdev, &data, + false); mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, info->dev_class, info->rssi, - 1, NULL); + !name_known, NULL); } } else { struct inquiry_info_with_rssi *info = (void *) (skb->data + 1); @@ -2589,10 +2595,11 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct data.clock_offset = info->clock_offset; data.rssi = info->rssi; data.ssp_mode = 0x00; - hci_inquiry_cache_update(hdev, &data, false); + name_known = hci_inquiry_cache_update(hdev, &data, + false); mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, info->dev_class, info->rssi, - 1, NULL); + !name_known, NULL); } } @@ -2766,7 +2773,7 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct else name_known = true; - hci_inquiry_cache_update(hdev, &data, name_known); + name_known = hci_inquiry_cache_update(hdev, &data, name_known); mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, info->dev_class, info->rssi, !name_known, info->data); -- cgit v1.2.3 From ff9ef5787046c3fd20cf9f7ca1cd70260c1eedb9 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 4 Jan 2012 14:23:45 +0200 Subject: Bluetooth: Add discovery state tracking This patch adds proper state tracking to the device discovery process. This makes it possible to return appropriate errors when trying to stop a non-active discovery or start discovery when it is already ongoing. Once name resolving is implemented this also makes it possible to know what the right action to do is when a remote name lookup is cancelled. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index d4d20df9fbbf..43d69569a0d5 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -65,7 +65,7 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) clear_bit(HCI_INQUIRY, &hdev->flags); hci_dev_lock(hdev); - mgmt_discovering(hdev, 0); + hci_discovery_set_state(hdev, DISCOVERY_STOPPED); hci_dev_unlock(hdev); hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status); @@ -1119,7 +1119,7 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) set_bit(HCI_INQUIRY, &hdev->flags); hci_dev_lock(hdev); - mgmt_discovering(hdev, 1); + hci_discovery_set_state(hdev, DISCOVERY_ACTIVE); hci_dev_unlock(hdev); } @@ -1507,7 +1507,7 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff return; hci_dev_lock(hdev); - mgmt_discovering(hdev, 0); + hci_discovery_set_state(hdev, DISCOVERY_STOPPED); hci_dev_unlock(hdev); } -- cgit v1.2.3 From 30dc78e1a2bcbe2a0fca7aa44dfded4bb0db6148 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 4 Jan 2012 15:44:20 +0200 Subject: Bluetooth: Add name resolving support for mgmt based discovery This patch adds the necessary logic to perform name lookups after inquiry completes. This is done by checking for entries in the resolve list after each inquiry complete and remote name complete HCI event. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 81 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 4 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 43d69569a0d5..089dff80ccb0 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1119,7 +1119,7 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) set_bit(HCI_INQUIRY, &hdev->flags); hci_dev_lock(hdev); - hci_discovery_set_state(hdev, DISCOVERY_ACTIVE); + hci_discovery_set_state(hdev, DISCOVERY_INQUIRY); hci_dev_unlock(hdev); } @@ -1271,6 +1271,50 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev, return 1; } +static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e) +{ + struct hci_cp_remote_name_req cp; + + memset(&cp, 0, sizeof(cp)); + + bacpy(&cp.bdaddr, &e->data.bdaddr); + cp.pscan_rep_mode = e->data.pscan_rep_mode; + cp.pscan_mode = e->data.pscan_mode; + cp.clock_offset = e->data.clock_offset; + + return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); +} + +static void hci_resolve_next_name(struct hci_dev *hdev, bdaddr_t *bdaddr) +{ + struct discovery_state *discov = &hdev->discovery; + struct inquiry_entry *e; + + if (discov->state == DISCOVERY_STOPPING) + goto discov_complete; + + if (discov->state != DISCOVERY_RESOLVING) + return; + + e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING); + if (e) { + e->name_state = NAME_KNOWN; + list_del(&e->list); + } + + if (list_empty(&discov->resolve)) + goto discov_complete; + + e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); + if (hci_resolve_name(hdev, e) == 0) { + e->name_state = NAME_PENDING; + return; + } + +discov_complete: + hci_discovery_set_state(hdev, DISCOVERY_STOPPED); +} + static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) { struct hci_cp_remote_name_req *cp; @@ -1289,6 +1333,9 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) hci_dev_lock(hdev); + if (test_bit(HCI_MGMT, &hdev->flags)) + hci_resolve_next_name(hdev, &cp->bdaddr); + conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); if (!conn) goto unlock; @@ -1496,6 +1543,8 @@ static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); + struct discovery_state *discov = &hdev->discovery; + struct inquiry_entry *e; BT_DBG("%s status %d", hdev->name, status); @@ -1506,8 +1555,28 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) return; + if (!test_bit(HCI_MGMT, &hdev->flags)) + return; + hci_dev_lock(hdev); - hci_discovery_set_state(hdev, DISCOVERY_STOPPED); + + if (discov->state != DISCOVERY_INQUIRY) + goto unlock; + + if (list_empty(&discov->resolve)) { + hci_discovery_set_state(hdev, DISCOVERY_STOPPED); + goto unlock; + } + + e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); + if (e && hci_resolve_name(hdev, e) == 0) { + e->name_state = NAME_PENDING; + hci_discovery_set_state(hdev, DISCOVERY_RESOLVING); + } else { + hci_discovery_set_state(hdev, DISCOVERY_STOPPED); + } + +unlock: hci_dev_unlock(hdev); } @@ -1807,8 +1876,12 @@ static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb hci_dev_lock(hdev); - if (ev->status == 0 && test_bit(HCI_MGMT, &hdev->flags)) - mgmt_remote_name(hdev, &ev->bdaddr, ev->name); + if (test_bit(HCI_MGMT, &hdev->flags)) { + if (ev->status == 0) + mgmt_remote_name(hdev, &ev->bdaddr, ev->name); + + hci_resolve_next_name(hdev, &ev->bdaddr); + } conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); if (!conn) -- cgit v1.2.3 From 25e89e99b4a54a2cb6e27b4675cd71a3d8a9b3fc Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 4 Jan 2012 12:41:58 +0200 Subject: Bluetooth: Process num completed data blocks event Adds support for Number Of Completed Data Blocks Event. Signed-off-by: Andrei Emeltchenko Acked-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/hci_event.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 089dff80ccb0..0466ed9c1b47 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -2408,6 +2408,56 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s queue_work(hdev->workqueue, &hdev->tx_work); } +static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev, + struct sk_buff *skb) +{ + struct hci_ev_num_comp_blocks *ev = (void *) skb->data; + int i; + + if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) { + BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode); + return; + } + + if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) + + ev->num_hndl * sizeof(struct hci_comp_blocks_info)) { + BT_DBG("%s bad parameters", hdev->name); + return; + } + + BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks, + ev->num_hndl); + + for (i = 0; i < ev->num_hndl; i++) { + struct hci_comp_blocks_info *info = &ev->handles[i]; + struct hci_conn *conn; + __u16 handle, block_count; + + handle = __le16_to_cpu(info->handle); + block_count = __le16_to_cpu(info->blocks); + + conn = hci_conn_hash_lookup_handle(hdev, handle); + if (!conn) + continue; + + conn->sent -= block_count; + + switch (conn->type) { + case ACL_LINK: + hdev->block_cnt += block_count; + if (hdev->block_cnt > hdev->num_blocks) + hdev->block_cnt = hdev->num_blocks; + break; + + default: + BT_ERR("Unknown type %d conn %p", conn->type, conn); + break; + } + } + + queue_work(hdev->workqueue, &hdev->tx_work); +} + static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_mode_change *ev = (void *) skb->data; @@ -3386,6 +3436,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) hci_remote_oob_data_request_evt(hdev, skb); break; + case HCI_EV_NUM_COMP_BLOCKS: + hci_num_comp_blocks_evt(hdev, skb); + break; + default: BT_DBG("%s event 0x%x", hdev->name, event); break; -- cgit v1.2.3 From a8b2d5c2cfe1c6398e3fdd4372c4ae7f74fb4493 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sun, 8 Jan 2012 23:11:15 +0200 Subject: Bluetooth: Move mgmt related flags from hdev->flags to hdev->dev_flags There's no point in exposing these to user-space (which is what happens to everything in hdev->flags) so move them to dev_flags instead. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 0466ed9c1b47..2d39ede1f202 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -211,7 +211,7 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_lock(hdev); - if (test_bit(HCI_MGMT, &hdev->flags)) + if (test_bit(HCI_MGMT, &hdev->dev_flags)) mgmt_set_local_name_complete(hdev, sent, status); if (status == 0) @@ -890,7 +890,7 @@ static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_lock(hdev); - if (test_bit(HCI_MGMT, &hdev->flags)) + if (test_bit(HCI_MGMT, &hdev->dev_flags)) mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status); if (rp->status != 0) @@ -916,7 +916,7 @@ static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_lock(hdev); - if (test_bit(HCI_MGMT, &hdev->flags)) + if (test_bit(HCI_MGMT, &hdev->dev_flags)) mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr, rp->status); @@ -951,7 +951,7 @@ static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_lock(hdev); - if (test_bit(HCI_MGMT, &hdev->flags)) + if (test_bit(HCI_MGMT, &hdev->dev_flags)) mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, rp->status); @@ -967,7 +967,7 @@ static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, hci_dev_lock(hdev); - if (test_bit(HCI_MGMT, &hdev->flags)) + if (test_bit(HCI_MGMT, &hdev->dev_flags)) mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr, rp->status); @@ -982,7 +982,7 @@ static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_lock(hdev); - if (test_bit(HCI_MGMT, &hdev->flags)) + if (test_bit(HCI_MGMT, &hdev->dev_flags)) mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, rp->status); @@ -998,7 +998,7 @@ static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, hci_dev_lock(hdev); - if (test_bit(HCI_MGMT, &hdev->flags)) + if (test_bit(HCI_MGMT, &hdev->dev_flags)) mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr, rp->status); @@ -1110,7 +1110,7 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) hci_req_complete(hdev, HCI_OP_INQUIRY, status); hci_conn_check_pending(hdev); hci_dev_lock(hdev); - if (test_bit(HCI_MGMT, &hdev->flags)) + if (test_bit(HCI_MGMT, &hdev->dev_flags)) mgmt_start_discovery_failed(hdev, status); hci_dev_unlock(hdev); return; @@ -1333,7 +1333,7 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) hci_dev_lock(hdev); - if (test_bit(HCI_MGMT, &hdev->flags)) + if (test_bit(HCI_MGMT, &hdev->dev_flags)) hci_resolve_next_name(hdev, &cp->bdaddr); conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); @@ -1555,7 +1555,7 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) return; - if (!test_bit(HCI_MGMT, &hdev->flags)) + if (!test_bit(HCI_MGMT, &hdev->dev_flags)) return; hci_dev_lock(hdev); @@ -1876,7 +1876,7 @@ static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb hci_dev_lock(hdev); - if (test_bit(HCI_MGMT, &hdev->flags)) { + if (test_bit(HCI_MGMT, &hdev->dev_flags)) { if (ev->status == 0) mgmt_remote_name(hdev, &ev->bdaddr, ev->name); @@ -2505,10 +2505,10 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff hci_conn_put(conn); } - if (!test_bit(HCI_PAIRABLE, &hdev->flags)) + if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags)) hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, sizeof(ev->bdaddr), &ev->bdaddr); - else if (test_bit(HCI_MGMT, &hdev->flags)) { + else if (test_bit(HCI_MGMT, &hdev->dev_flags)) { u8 secure; if (conn->pending_sec_level == BT_SECURITY_HIGH) @@ -2532,7 +2532,7 @@ static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff BT_DBG("%s", hdev->name); - if (!test_bit(HCI_LINK_KEYS, &hdev->flags)) + if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags)) return; hci_dev_lock(hdev); @@ -2547,7 +2547,7 @@ static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff BT_DBG("%s found key type %u for %s", hdev->name, key->type, batostr(&ev->bdaddr)); - if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) && + if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) && key->type == HCI_LK_DEBUG_COMBINATION) { BT_DBG("%s ignoring debug key", hdev->name); goto not_found; @@ -2609,7 +2609,7 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff hci_conn_put(conn); } - if (test_bit(HCI_LINK_KEYS, &hdev->flags)) + if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags)) hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key, ev->key_type, pin_len); @@ -2890,7 +2890,7 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct data.rssi = info->rssi; data.ssp_mode = 0x01; - if (test_bit(HCI_MGMT, &hdev->flags)) + if (test_bit(HCI_MGMT, &hdev->dev_flags)) name_known = eir_has_complete_name(info->data, sizeof(info->data)); else @@ -2939,10 +2939,10 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff hci_conn_hold(conn); - if (!test_bit(HCI_MGMT, &hdev->flags)) + if (!test_bit(HCI_MGMT, &hdev->dev_flags)) goto unlock; - if (test_bit(HCI_PAIRABLE, &hdev->flags) || + if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) || (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) { struct hci_cp_io_capability_reply cp; @@ -3005,7 +3005,7 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev, hci_dev_lock(hdev); - if (!test_bit(HCI_MGMT, &hdev->flags)) + if (!test_bit(HCI_MGMT, &hdev->dev_flags)) goto unlock; conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); @@ -3071,7 +3071,7 @@ static inline void hci_user_passkey_request_evt(struct hci_dev *hdev, hci_dev_lock(hdev); - if (test_bit(HCI_MGMT, &hdev->flags)) + if (test_bit(HCI_MGMT, &hdev->dev_flags)) mgmt_user_passkey_request(hdev, &ev->bdaddr); hci_dev_unlock(hdev); @@ -3130,7 +3130,7 @@ static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev, hci_dev_lock(hdev); - if (!test_bit(HCI_MGMT, &hdev->flags)) + if (!test_bit(HCI_MGMT, &hdev->dev_flags)) goto unlock; data = hci_find_remote_oob_data(hdev, &ev->bdaddr); -- cgit v1.2.3 From 44b5f7d0cb1939497a0858d9f43d89f039f85887 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sun, 8 Jan 2012 23:39:40 +0200 Subject: Bluetooth: Fix resetting HCI_MGMT flag The HCI_MGMT flag should not be cleared when resetting a HCI device. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 2d39ede1f202..f3dafae6e1db 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -195,7 +195,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) hci_req_complete(hdev, HCI_OP_RESET, status); - hdev->dev_flags = 0; + /* Reset all flags, except persistent ones like HCI_MGMT */ + hdev->dev_flags &= BIT(HCI_MGMT); } static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) -- cgit v1.2.3 From 7d262f86f6b73efb500be9d9242ef0673221493d Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Tue, 10 Jan 2012 18:20:49 -0300 Subject: Bluetooth: Add 'eir_len' param to mgmt_device_found() This patch adds a new parameter to mgmt_device_found() to inform the length of 'eir' pointer. EIR data from LE advertising report event doesn't have a fixed length as EIR data from extended inquiry result event does. We needed to change mgmt_device_found() so it copies 'eir_len' bytes instead of HCI_MAX_EIR_LENGTH. Signed-off-by: Andre Guedes Acked-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/hci_event.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index f3dafae6e1db..3323dc6c9868 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1608,7 +1608,8 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff * name_known = hci_inquiry_cache_update(hdev, &data, false); mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, - info->dev_class, 0, !name_known, NULL); + info->dev_class, 0, !name_known, + NULL, 0); } hci_dev_unlock(hdev); @@ -2705,7 +2706,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct false); mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, info->dev_class, info->rssi, - !name_known, NULL); + !name_known, NULL, 0); } } else { struct inquiry_info_with_rssi *info = (void *) (skb->data + 1); @@ -2723,7 +2724,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct false); mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, info->dev_class, info->rssi, - !name_known, NULL); + !name_known, NULL, 0); } } @@ -2900,7 +2901,8 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct name_known = hci_inquiry_cache_update(hdev, &data, name_known); mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, info->dev_class, info->rssi, - !name_known, info->data); + !name_known, info->data, + sizeof(info->data)); } hci_dev_unlock(hdev); -- cgit v1.2.3 From 3c9e919511f87f10491628c6b44bc4675822f307 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Tue, 10 Jan 2012 18:20:50 -0300 Subject: Bluetooth: Report LE devices Devices found during LE scan should be reported to userspace through mgmt_device_found events. Signed-off-by: Andre Guedes Acked-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/hci_event.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 3323dc6c9868..42d63522270f 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -3208,6 +3208,7 @@ static inline void hci_le_adv_report_evt(struct hci_dev *hdev, { u8 num_reports = skb->data[0]; void *ptr = &skb->data[1]; + s8 rssi; hci_dev_lock(hdev); @@ -3216,6 +3217,10 @@ static inline void hci_le_adv_report_evt(struct hci_dev *hdev, hci_add_adv_entry(hdev, ev); + rssi = ev->data[ev->length]; + mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type, + NULL, rssi, 0, ev->data, ev->length); + ptr += sizeof(*ev) + ev->length + 1; } -- cgit v1.2.3 From 7005ff1780ca7ad5ed2ec710ad35affc48362ebf Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 18 Jan 2012 16:14:43 +0200 Subject: Bluetooth: Fix clearing persistent flags There are several other dev_flags besided HCI_MGMT that should not be cleared upon reset. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 42d63522270f..54132a909ea5 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -195,8 +195,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) hci_req_complete(hdev, HCI_OP_RESET, status); - /* Reset all flags, except persistent ones like HCI_MGMT */ - hdev->dev_flags &= BIT(HCI_MGMT); + /* Reset all flags, except persistent ones */ + hdev->dev_flags &= BIT(HCI_MGMT) | BIT(HCI_SETUP) | BIT(HCI_AUTO_OFF); } static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) -- cgit v1.2.3 From afc747a600ff2e3a4eef8f312fc766608a1360e2 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sun, 15 Jan 2012 18:11:07 +0200 Subject: Bluetooth: Rename mgmt connected events to match user space User space uses device_(dis)connected instead of just (dis)connected so rename the defines and functions to match this. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 54132a909ea5..e13ce945afc4 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1643,7 +1643,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s conn->state = BT_CONFIG; hci_conn_hold(conn); conn->disc_timeout = HCI_DISCONN_TIMEOUT; - mgmt_connected(hdev, &ev->bdaddr, conn->type, + mgmt_device_connected(hdev, &ev->bdaddr, conn->type, conn->dst_type); } else conn->state = BT_CONNECTED; @@ -1789,7 +1789,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff if (ev->status != 0) mgmt_disconnect_failed(hdev, &conn->dst, ev->status); else - mgmt_disconnected(hdev, &conn->dst, conn->type, + mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type); } @@ -3188,7 +3188,7 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff goto unlock; } - mgmt_connected(hdev, &ev->bdaddr, conn->type, conn->dst_type); + mgmt_device_connected(hdev, &ev->bdaddr, conn->type, conn->dst_type); conn->sec_level = BT_SECURITY_LOW; conn->handle = __le16_to_cpu(ev->handle); -- cgit v1.2.3 From 4ddb1930f91b7395a760cd4a8cf1b2a87011571c Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sun, 15 Jan 2012 20:04:43 +0200 Subject: Bluetooth: Rename eir_has_complete_name to eir_has_data_type This allows for other uses such as checking for an embedded class of device value in order to decide whether to append the class or not. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index e13ce945afc4..d256042a83cf 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -2842,7 +2842,7 @@ static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *s BT_DBG("%s status %d", hdev->name, ev->status); } -static inline bool eir_has_complete_name(u8 *data, size_t data_len) +static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type) { u8 field_len; size_t parsed; @@ -2858,7 +2858,7 @@ static inline bool eir_has_complete_name(u8 *data, size_t data_len) if (parsed > data_len) break; - if (data[1] == EIR_NAME_COMPLETE) + if (data[1] == type) return true; data += field_len + 1; @@ -2893,8 +2893,9 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct data.ssp_mode = 0x01; if (test_bit(HCI_MGMT, &hdev->dev_flags)) - name_known = eir_has_complete_name(info->data, - sizeof(info->data)); + name_known = eir_has_data_type(info->data, + sizeof(info->data), + EIR_NAME_COMPLETE); else name_known = true; -- cgit v1.2.3 From 6759a67579a927f2a92f398cf67555e6cc92d0ff Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sun, 15 Jan 2012 20:51:14 +0200 Subject: Bluetooth: Move eir_has_data_field to hci_core.h This makes the function accessible from all places it's needed (e.g. mgmt.c and hci_event.c). Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 25 ------------------------- 1 file changed, 25 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index d256042a83cf..e93afebdcf84 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -2842,31 +2842,6 @@ static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *s BT_DBG("%s status %d", hdev->name, ev->status); } -static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type) -{ - u8 field_len; - size_t parsed; - - for (parsed = 0; parsed < data_len - 1; parsed += field_len) { - field_len = data[0]; - - if (field_len == 0) - break; - - parsed += field_len + 1; - - if (parsed > data_len) - break; - - if (data[1] == type) - return true; - - data += field_len + 1; - } - - return false; -} - static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct inquiry_data data; -- cgit v1.2.3 From 51a8efd7d02c13cb1c6fdd1cd66788792a3fcc7c Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 16 Jan 2012 06:10:31 +0200 Subject: Bluetooth: Rename conn->pend to conn->flags These flags can and will be used for more general purpose values than just pending state transitions so the more common name "flags" makes more sense than "pend". Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index e93afebdcf84..d9a8618ae156 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1344,7 +1344,7 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) if (!hci_outgoing_auth_needed(hdev, conn)) goto unlock; - if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { + if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { struct hci_cp_auth_requested cp; cp.handle = __cpu_to_le16(conn->handle); hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); @@ -1461,9 +1461,9 @@ static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status) conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); if (conn) { - clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend); + clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); - if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend)) + if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) hci_sco_setup(conn, status); } @@ -1488,9 +1488,9 @@ static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status) conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); if (conn) { - clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend); + clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); - if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend)) + if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) hci_sco_setup(conn, status); } @@ -1817,7 +1817,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s if (!ev->status) { if (!(conn->ssp_mode > 0 && hdev->ssp_mode > 0) && - test_bit(HCI_CONN_REAUTH_PEND, &conn->pend)) { + test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) { BT_INFO("re-auth of legacy device is not possible."); } else { conn->link_mode |= HCI_LM_AUTH; @@ -1827,8 +1827,8 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s mgmt_auth_failed(hdev, &conn->dst, ev->status); } - clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); - clear_bit(HCI_CONN_REAUTH_PEND, &conn->pend); + clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); + clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags); if (conn->state == BT_CONFIG) { if (!ev->status && hdev->ssp_mode > 0 && conn->ssp_mode > 0) { @@ -1850,7 +1850,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s hci_conn_put(conn); } - if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) { + if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) { if (!ev->status) { struct hci_cp_set_conn_encrypt cp; cp.handle = ev->handle; @@ -1858,7 +1858,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp); } else { - clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); + clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); hci_encrypt_cfm(conn, ev->status, 0x00); } } @@ -1892,7 +1892,7 @@ static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb if (!hci_outgoing_auth_needed(hdev, conn)) goto unlock; - if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { + if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { struct hci_cp_auth_requested cp; cp.handle = __cpu_to_le16(conn->handle); hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); @@ -1923,7 +1923,7 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff * conn->link_mode &= ~HCI_LM_ENCRYPT; } - clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); + clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); if (conn->state == BT_CONFIG) { if (!ev->status) @@ -1952,7 +1952,7 @@ static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct if (!ev->status) conn->link_mode |= HCI_LM_SECURE; - clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); + clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); hci_key_change_cfm(conn, ev->status); } @@ -2336,7 +2336,7 @@ static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb conn->link_mode |= HCI_LM_MASTER; } - clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend); + clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags); hci_role_switch_cfm(conn, ev->status, ev->role); } @@ -2474,14 +2474,14 @@ static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb conn->mode = ev->mode; conn->interval = __le16_to_cpu(ev->interval); - if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) { + if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) { if (conn->mode == HCI_CM_ACTIVE) conn->power_save = 1; else conn->power_save = 0; } - if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend)) + if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) hci_sco_setup(conn, ev->status); } @@ -3013,7 +3013,7 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev, /* If we're not the initiators request authorization to * proceed from user space (mgmt_user_confirm with * confirm_hint set to 1). */ - if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { + if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { BT_DBG("Confirming auto-accept as acceptor"); confirm_hint = 1; goto confirm; @@ -3074,7 +3074,7 @@ static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_ * initiated the authentication. A traditional auth_complete * event gets always produced as initiator and is also mapped to * the mgmt_auth_failed event */ - if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0) + if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0) mgmt_auth_failed(hdev, &conn->dst, ev->status); hci_conn_put(conn); -- cgit v1.2.3 From a0c808b373e89aecc3ecae4cbdcdeff68aa12e3e Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 16 Jan 2012 09:49:58 +0200 Subject: Bluetooth: Convert hdev->out to a bool type The hdev->out variable is essentially a boolean so the type 'bool' makes more sense than u8. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index d9a8618ae156..f6c13153a5e7 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1154,7 +1154,7 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) if (!conn) { conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr); if (conn) { - conn->out = 1; + conn->out = true; conn->link_mode |= HCI_LM_MASTER; } else BT_ERR("No memory for new connection"); @@ -1526,7 +1526,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status) conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr); if (conn) { conn->dst_type = cp->peer_addr_type; - conn->out = 1; + conn->out = true; } else { BT_ERR("No memory for new connection"); } -- cgit v1.2.3 From b644ba33699711630099efc58a4efc225560aceb Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 17 Jan 2012 21:48:47 +0200 Subject: Bluetooth: Update device_connected and device_found events to latest API This patch updates mgmt_ev_device_connected and mgmt_ev_device found to include an EIR-encoded remote name and class whenever possible. With this addition the mgmt_ev_remote_name event becomes unnecessary and can be removed. Since the connected event doesn't map to hci_conn_complete anymore a HCI_CONN_MGMT_CONNECTED flag is added to track when mgmt has been notified about a connection. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 78 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 22 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index f6c13153a5e7..f0b08ab734d7 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1286,11 +1286,36 @@ static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); } -static void hci_resolve_next_name(struct hci_dev *hdev, bdaddr_t *bdaddr) +static bool hci_resolve_next_name(struct hci_dev *hdev) { struct discovery_state *discov = &hdev->discovery; struct inquiry_entry *e; + if (list_empty(&discov->resolve)) + return false; + + e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); + if (hci_resolve_name(hdev, e) == 0) { + e->name_state = NAME_PENDING; + return true; + } + + return false; +} + +static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn, + bdaddr_t *bdaddr, u8 *name, u8 name_len) +{ + struct discovery_state *discov = &hdev->discovery; + struct inquiry_entry *e; + + if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) + mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, + name, name_len, conn->dev_class); + + if (discov->state == DISCOVERY_STOPPED) + return; + if (discov->state == DISCOVERY_STOPPING) goto discov_complete; @@ -1301,16 +1326,13 @@ static void hci_resolve_next_name(struct hci_dev *hdev, bdaddr_t *bdaddr) if (e) { e->name_state = NAME_KNOWN; list_del(&e->list); + if (name) + mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00, + e->data.rssi, name, name_len); } - if (list_empty(&discov->resolve)) - goto discov_complete; - - e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); - if (hci_resolve_name(hdev, e) == 0) { - e->name_state = NAME_PENDING; + if (hci_resolve_next_name(hdev)) return; - } discov_complete: hci_discovery_set_state(hdev, DISCOVERY_STOPPED); @@ -1334,10 +1356,11 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) hci_dev_lock(hdev); + conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); + if (test_bit(HCI_MGMT, &hdev->dev_flags)) - hci_resolve_next_name(hdev, &cp->bdaddr); + hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0); - conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); if (!conn) goto unlock; @@ -1643,8 +1666,6 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s conn->state = BT_CONFIG; hci_conn_hold(conn); conn->disc_timeout = HCI_DISCONN_TIMEOUT; - mgmt_device_connected(hdev, &ev->bdaddr, conn->type, - conn->dst_type); } else conn->state = BT_CONNECTED; @@ -1785,7 +1806,8 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff if (ev->status == 0) conn->state = BT_CLOSED; - if (conn->type == ACL_LINK || conn->type == LE_LINK) { + if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) && + (conn->type == ACL_LINK || conn->type == LE_LINK)) { if (ev->status != 0) mgmt_disconnect_failed(hdev, &conn->dst, ev->status); else @@ -1878,14 +1900,18 @@ static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb hci_dev_lock(hdev); - if (test_bit(HCI_MGMT, &hdev->dev_flags)) { - if (ev->status == 0) - mgmt_remote_name(hdev, &ev->bdaddr, ev->name); + conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); - hci_resolve_next_name(hdev, &ev->bdaddr); - } + if (!test_bit(HCI_MGMT, &hdev->dev_flags)) + goto check_auth; - conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); + if (ev->status == 0) + hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name, + strnlen(ev->name, HCI_MAX_NAME_LENGTH)); + else + hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0); + +check_auth: if (!conn) goto unlock; @@ -1994,7 +2020,10 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff bacpy(&cp.bdaddr, &conn->dst); cp.pscan_rep_mode = 0x02; hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); - } + } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) + mgmt_device_connected(hdev, &conn->dst, conn->type, + conn->dst_type, NULL, 0, + conn->dev_class); if (!hci_outgoing_auth_needed(hdev, conn)) { conn->state = BT_CONNECTED; @@ -2763,7 +2792,10 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b bacpy(&cp.bdaddr, &conn->dst); cp.pscan_rep_mode = 0x02; hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); - } + } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) + mgmt_device_connected(hdev, &conn->dst, conn->type, + conn->dst_type, NULL, 0, + conn->dev_class); if (!hci_outgoing_auth_needed(hdev, conn)) { conn->state = BT_CONNECTED; @@ -3164,7 +3196,9 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff goto unlock; } - mgmt_device_connected(hdev, &ev->bdaddr, conn->type, conn->dst_type); + if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) + mgmt_device_connected(hdev, &ev->bdaddr, conn->type, + conn->dst_type, NULL, 0, 0); conn->sec_level = BT_SECURITY_LOW; conn->handle = __le16_to_cpu(ev->handle); -- cgit v1.2.3 From 58a681ef1455aef9caad1d41073868fb399373f6 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 16 Jan 2012 06:47:28 +0200 Subject: Bluetooth: Merge boolean members of struct hci_conn into flags Now that the flags member of struct hci_conn is supposed to accommodate any boolean type values we can easily merge all boolean members into it. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index f0b08ab734d7..02ad53801732 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1264,7 +1264,8 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev, /* Only request authentication for SSP connections or non-SSP * devices with sec_level HIGH or if MITM protection is requested */ - if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) && + if (!(hdev->ssp_mode > 0 && + test_bit(HCI_CONN_SSP_ENABLED, &conn->flags)) && conn->pending_sec_level != BT_SECURITY_HIGH && !(conn->auth_type & 0x01)) return 0; @@ -1838,7 +1839,8 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s goto unlock; if (!ev->status) { - if (!(conn->ssp_mode > 0 && hdev->ssp_mode > 0) && + if (!(test_bit(HCI_CONN_SSP_ENABLED, &conn->flags) && + hdev->ssp_mode > 0) && test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) { BT_INFO("re-auth of legacy device is not possible."); } else { @@ -1853,7 +1855,8 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags); if (conn->state == BT_CONFIG) { - if (!ev->status && hdev->ssp_mode > 0 && conn->ssp_mode > 0) { + if (!ev->status && hdev->ssp_mode > 0 && + test_bit(HCI_CONN_SSP_ENABLED, &conn->flags)) { struct hci_cp_set_conn_encrypt cp; cp.handle = ev->handle; cp.encrypt = 0x01; @@ -2505,9 +2508,9 @@ static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) { if (conn->mode == HCI_CM_ACTIVE) - conn->power_save = 1; + set_bit(HCI_CONN_POWER_SAVE, &conn->flags); else - conn->power_save = 0; + clear_bit(HCI_CONN_POWER_SAVE, &conn->flags); } if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) @@ -2780,7 +2783,8 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b if (ie) ie->data.ssp_mode = (ev->features[0] & 0x01); - conn->ssp_mode = (ev->features[0] & 0x01); + if (ev->features[0] & 0x01) + set_bit(HCI_CONN_SSP_ENABLED, &conn->flags); } if (conn->state != BT_CONFIG) @@ -2962,7 +2966,7 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff conn->auth_type = hci_get_auth_req(conn); cp.authentication = conn->auth_type; - if ((conn->out == 0x01 || conn->remote_oob == 0x01) && + if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) && hci_find_remote_oob_data(hdev, &conn->dst)) cp.oob_data = 0x01; else @@ -2998,8 +3002,9 @@ static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *s goto unlock; conn->remote_cap = ev->capability; - conn->remote_oob = ev->oob_data; conn->remote_auth = ev->authentication; + if (ev->oob_data) + set_bit(HCI_CONN_REMOTE_OOB, &conn->flags); unlock: hci_dev_unlock(hdev); -- cgit v1.2.3 From 84bde9d6c0e6830f4a8685a5d237965053118bf9 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 25 Jan 2012 14:21:06 +0200 Subject: Bluetooth: Convert hdev->ssp_mode to a flag The ssp_mode is essentially just a boolean so it's more appropriate to have it simply as a flag in hdev->dev_flags. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 02ad53801732..eb198ccbc10d 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -429,7 +429,10 @@ static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) if (rp->status) return; - hdev->ssp_mode = rp->mode; + if (rp->mode) + set_bit(HCI_SSP_ENABLED, &hdev->dev_flags); + else + clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags); } static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) @@ -446,7 +449,10 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) if (!sent) return; - hdev->ssp_mode = *((__u8 *) sent); + if (*((u8 *) sent)) + set_bit(HCI_SSP_ENABLED, &hdev->dev_flags); + else + clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags); } static u8 hci_get_inquiry_mode(struct hci_dev *hdev) @@ -1264,7 +1270,7 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev, /* Only request authentication for SSP connections or non-SSP * devices with sec_level HIGH or if MITM protection is requested */ - if (!(hdev->ssp_mode > 0 && + if (!(test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) && test_bit(HCI_CONN_SSP_ENABLED, &conn->flags)) && conn->pending_sec_level != BT_SECURITY_HIGH && !(conn->auth_type & 0x01)) @@ -1840,7 +1846,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s if (!ev->status) { if (!(test_bit(HCI_CONN_SSP_ENABLED, &conn->flags) && - hdev->ssp_mode > 0) && + test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) && test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) { BT_INFO("re-auth of legacy device is not possible."); } else { @@ -1855,7 +1861,8 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags); if (conn->state == BT_CONFIG) { - if (!ev->status && hdev->ssp_mode > 0 && + if (!ev->status && + test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) && test_bit(HCI_CONN_SSP_ENABLED, &conn->flags)) { struct hci_cp_set_conn_encrypt cp; cp.handle = ev->handle; -- cgit v1.2.3 From aa64a8b500e61c33c17f1d5e7de0cc154489c59e Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 18 Jan 2012 21:33:12 +0200 Subject: Bluetooth: Add a convenience function to check for SSP enabled It's a very common test to see if both the local and the remote device have SSP enabled. By creating a simple function to test this we can shorten many if-statements in the code. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index eb198ccbc10d..6fb9016652b7 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1270,8 +1270,7 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev, /* Only request authentication for SSP connections or non-SSP * devices with sec_level HIGH or if MITM protection is requested */ - if (!(test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) && - test_bit(HCI_CONN_SSP_ENABLED, &conn->flags)) && + if (!hci_conn_ssp_enabled(conn) && conn->pending_sec_level != BT_SECURITY_HIGH && !(conn->auth_type & 0x01)) return 0; @@ -1845,9 +1844,8 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s goto unlock; if (!ev->status) { - if (!(test_bit(HCI_CONN_SSP_ENABLED, &conn->flags) && - test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) && - test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) { + if (!hci_conn_ssp_enabled(conn) && + test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) { BT_INFO("re-auth of legacy device is not possible."); } else { conn->link_mode |= HCI_LM_AUTH; @@ -1861,9 +1859,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags); if (conn->state == BT_CONFIG) { - if (!ev->status && - test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) && - test_bit(HCI_CONN_SSP_ENABLED, &conn->flags)) { + if (!ev->status && hci_conn_ssp_enabled(conn)) { struct hci_cp_set_conn_encrypt cp; cp.handle = ev->handle; cp.encrypt = 0x01; -- cgit v1.2.3 From 7a7f1e7c857959f5298020969741e389f21edbae Mon Sep 17 00:00:00 2001 From: Hemant Gupta Date: Mon, 16 Jan 2012 13:34:29 +0530 Subject: Bluetooth: Send correct response to IO Capability Request This patch sends correct IO Capability response to remote device in case Local Device supports KeyBoardDisplay IO Capability as this capability is not valid as per BT spec for IO capability Request Reply Command. This capability is mapped to DisplayYesNo which is in accordance with BT spec. Signed-off-by: Hemant Gupta Acked-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/hci_event.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 6fb9016652b7..041a35eb25c6 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -2965,7 +2965,10 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff struct hci_cp_io_capability_reply cp; bacpy(&cp.bdaddr, &ev->bdaddr); - cp.capability = conn->io_capability; + /* Change the IO capability from KeyboardDisplay + * to DisplayYesNo as it is not supported by BT spec. */ + cp.capability = (conn->io_capability == 0x04) ? + 0x01 : conn->io_capability; conn->auth_type = hci_get_auth_req(conn); cp.authentication = conn->auth_type; -- cgit v1.2.3 From 95947a391ebe685b9870cd25cac1433aedf5d49c Mon Sep 17 00:00:00 2001 From: Hemant Gupta Date: Mon, 23 Jan 2012 15:36:11 +0530 Subject: Bluetooth: Fix clearing of debug and linkkey flags This patch fixes clearing of HCI_LINK_KEYS and HCI_DEBUG_KEYS dev_flags while resetting. Without this patch pairing does not work over management interface for BR-EDR devices. Signed-off-by: Hemant Gupta Acked-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/hci_event.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 041a35eb25c6..a86f82b11316 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -196,7 +196,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) hci_req_complete(hdev, HCI_OP_RESET, status); /* Reset all flags, except persistent ones */ - hdev->dev_flags &= BIT(HCI_MGMT) | BIT(HCI_SETUP) | BIT(HCI_AUTO_OFF); + hdev->dev_flags &= BIT(HCI_MGMT) | BIT(HCI_SETUP) | BIT(HCI_AUTO_OFF) | + BIT(HCI_LINK_KEYS) | BIT(HCI_DEBUG_KEYS); } static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) -- cgit v1.2.3 From c9839a11c0e460a2457e7cac76650d07773e6c3b Mon Sep 17 00:00:00 2001 From: Vinicius Costa Gomes Date: Thu, 2 Feb 2012 21:08:01 -0300 Subject: Bluetooth: Use the updated key structures for handling LTKs This updates all the users of the older way, that was using the link_keys list to store the SMP keys, to use the new way. This includes defining new types for the keys, we have a type for each combination of STK/LTK and Master/Slave. Signed-off-by: Vinicius Costa Gomes Acked-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/hci_event.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index a86f82b11316..23dbb31f0423 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -3256,7 +3256,7 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev, struct hci_cp_le_ltk_reply cp; struct hci_cp_le_ltk_neg_reply neg; struct hci_conn *conn; - struct link_key *ltk; + struct smp_ltk *ltk; BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle)); @@ -3272,10 +3272,17 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev, memcpy(cp.ltk, ltk->val, sizeof(ltk->val)); cp.handle = cpu_to_le16(conn->handle); - conn->pin_length = ltk->pin_len; + + if (ltk->authenticated) + conn->sec_level = BT_SECURITY_HIGH; hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); + if (ltk->type & HCI_SMP_STK) { + list_del(<k->list); + kfree(ltk); + } + hci_dev_unlock(hdev); return; -- cgit v1.2.3 From c599008f8f999dab8cb4a6404be99bdc4716ba15 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Fri, 3 Feb 2012 17:47:57 -0300 Subject: Bluetooth: LE scan should send Discovering events Send MGMT Discovering events once LE scan starts/stops so the userspace can track when local adapters are discovering LE devices. This way, we also keep the same behavior of inquiry which sends MGMT Discovering events once inquiry starts/stops even if it is triggered by an external tool (e.g. hcitool). Signed-off-by: Andre Guedes Acked-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/hci_event.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 23dbb31f0423..8971c18205c0 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1056,12 +1056,17 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, hci_dev_lock(hdev); hci_adv_entries_clear(hdev); + hci_discovery_set_state(hdev, DISCOVERY_LE_SCAN); hci_dev_unlock(hdev); break; case LE_SCANNING_DISABLED: clear_bit(HCI_LE_SCAN, &hdev->dev_flags); + hci_dev_lock(hdev); + hci_discovery_set_state(hdev, DISCOVERY_STOPPED); + hci_dev_unlock(hdev); + schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT); break; -- cgit v1.2.3 From 7ba8b4be38e7c83b2b13333a82a0ecde921a7390 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Fri, 3 Feb 2012 17:47:59 -0300 Subject: Bluetooth: Add hci_do_le_scan() This patch adds to hci_core the hci_do_le_scan function which should be used to scan LE devices. In order to enable LE scan, hci_do_le_scan() sends commands (Set LE Scan Parameters and Set LE Scan Enable) to the controller and waits for its results. If commands were executed successfully a delayed work is scheduled to disable the ongoing scanning after some amount of time. This function blocks. Signed-off-by: Andre Guedes Acked-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/hci_event.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 8971c18205c0..97152d9d7116 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1031,6 +1031,8 @@ static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) __u8 status = *((__u8 *) skb->data); BT_DBG("%s status 0x%x", hdev->name, status); + + hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status); } static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, @@ -1041,15 +1043,17 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, BT_DBG("%s status 0x%x", hdev->name, status); - if (status) - return; - cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE); if (!cp) return; switch (cp->enable) { case LE_SCANNING_ENABLED: + hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status); + + if (status) + return; + set_bit(HCI_LE_SCAN, &hdev->dev_flags); cancel_delayed_work_sync(&hdev->adv_work); @@ -1061,6 +1065,9 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, break; case LE_SCANNING_DISABLED: + if (status) + return; + clear_bit(HCI_LE_SCAN, &hdev->dev_flags); hci_dev_lock(hdev); -- cgit v1.2.3 From 3fd2415363629b779549705f341e0645e32c1ad5 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Fri, 3 Feb 2012 17:48:01 -0300 Subject: Bluetooth: MGMT start discovery LE-Only support This patch adds LE-Only discovery procedure support to MGMT Start Discovery command. Signed-off-by: Andre Guedes Acked-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/hci_event.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 97152d9d7116..ad5f37b13f77 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1033,6 +1033,13 @@ static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) BT_DBG("%s status 0x%x", hdev->name, status); hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status); + + if (status) { + hci_dev_lock(hdev); + mgmt_start_discovery_failed(hdev, status); + hci_dev_unlock(hdev); + return; + } } static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, @@ -1051,8 +1058,12 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, case LE_SCANNING_ENABLED: hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status); - if (status) + if (status) { + hci_dev_lock(hdev); + mgmt_start_discovery_failed(hdev, status); + hci_dev_unlock(hdev); return; + } set_bit(HCI_LE_SCAN, &hdev->dev_flags); -- cgit v1.2.3 From 88c3df13ca06718e5a8f509ae9cbb1228c10d537 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 9 Feb 2012 14:27:38 +0200 Subject: Bluetooth: Update mgmt_disconnect to match latest API This patch adds an address type parameter to the disconnect command and response in order to match the latest mgmt API specification. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index ad5f37b13f77..f0c822db28d9 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1550,6 +1550,28 @@ static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status) hci_dev_unlock(hdev); } +static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) +{ + struct hci_cp_disconnect *cp; + struct hci_conn *conn; + + if (!status) + return; + + cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT); + if (!cp) + return; + + hci_dev_lock(hdev); + + conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); + if (conn) + mgmt_disconnect_failed(hdev, &conn->dst, conn->type, + conn->dst_type, status); + + hci_dev_unlock(hdev); +} + static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status) { struct hci_cp_le_create_conn *cp; @@ -1839,7 +1861,8 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) && (conn->type == ACL_LINK || conn->type == LE_LINK)) { if (ev->status != 0) - mgmt_disconnect_failed(hdev, &conn->dst, ev->status); + mgmt_disconnect_failed(hdev, &conn->dst, conn->type, + conn->dst_type, ev->status); else mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type); @@ -2350,8 +2373,7 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) break; case HCI_OP_DISCONNECT: - if (ev->status != 0) - mgmt_disconnect_failed(hdev, NULL, ev->status); + hci_cs_disconnect(hdev, ev->status); break; case HCI_OP_LE_CREATE_CONN: -- cgit v1.2.3 From 272d90df2d4d065e782cafb08358bd8918bf703a Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 9 Feb 2012 15:26:12 +0200 Subject: Bluetooth: Add address type to user_confirm and user_passkey messages This patch upadate the user confirm and user passkey mgmt messages to match the latest API specification by adding an address type parameter to them. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index f0c822db28d9..3bf3f4d59bcc 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -960,8 +960,8 @@ static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_lock(hdev); if (test_bit(HCI_MGMT, &hdev->dev_flags)) - mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, - rp->status); + mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, + 0, rp->status); hci_dev_unlock(hdev); } @@ -977,6 +977,7 @@ static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, if (test_bit(HCI_MGMT, &hdev->dev_flags)) mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr, + ACL_LINK, 0, rp->status); hci_dev_unlock(hdev); @@ -991,8 +992,8 @@ static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_lock(hdev); if (test_bit(HCI_MGMT, &hdev->dev_flags)) - mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, - rp->status); + mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK, + 0, rp->status); hci_dev_unlock(hdev); } @@ -1008,6 +1009,7 @@ static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, if (test_bit(HCI_MGMT, &hdev->dev_flags)) mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr, + ACL_LINK, 0, rp->status); hci_dev_unlock(hdev); @@ -3123,7 +3125,7 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev, } confirm: - mgmt_user_confirm_request(hdev, &ev->bdaddr, ev->passkey, + mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey, confirm_hint); unlock: @@ -3140,7 +3142,7 @@ static inline void hci_user_passkey_request_evt(struct hci_dev *hdev, hci_dev_lock(hdev); if (test_bit(HCI_MGMT, &hdev->dev_flags)) - mgmt_user_passkey_request(hdev, &ev->bdaddr); + mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0); hci_dev_unlock(hdev); } -- cgit v1.2.3 From bab73cb68435232ba78a4bd1ac1a85862e3be0bb Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 9 Feb 2012 16:07:29 +0200 Subject: Bluetooth: Add address type to mgmt_ev_auth_failed This patch updates the Authentication Failed mgmt event to match the latest API specification by adding an address type to it. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 3bf3f4d59bcc..b0784ee5f8b9 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1901,7 +1901,8 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s conn->sec_level = conn->pending_sec_level; } } else { - mgmt_auth_failed(hdev, &conn->dst, ev->status); + mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type, + ev->status); } clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); @@ -3166,7 +3167,8 @@ static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_ * event gets always produced as initiator and is also mapped to * the mgmt_auth_failed event */ if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0) - mgmt_auth_failed(hdev, &conn->dst, ev->status); + mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type, + ev->status); hci_conn_put(conn); -- cgit v1.2.3 From 33ef95ed30283eb17c686a815caf1d33e966fe4a Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 16 Feb 2012 23:56:27 +0200 Subject: Bluetooth: mgmt: Add support for Set Link Security command The Set Link Security mgmt command is used to enable or disable link level security, also known as Security Mode 3. This is rarely enabled in modern systems but the command needs to be available for completeness, qualification purposes and those few systems that actually want to enable it. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index b0784ee5f8b9..239e9fb8f7c5 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -254,6 +254,9 @@ static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb) clear_bit(HCI_AUTH, &hdev->flags); } + if (test_bit(HCI_MGMT, &hdev->dev_flags)) + mgmt_auth_enable_complete(hdev, status); + hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status); } -- cgit v1.2.3 From ed2c4ee360709ca838efa0ea4d6295590aff3d24 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 17 Feb 2012 00:56:28 +0200 Subject: Bluetooth: mgmt: Add support for Set SSP command The Set SSP mgmt command can be used for enabling and disabling Secure Simple Pairing support for controllers that support it. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 239e9fb8f7c5..179d127601fc 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -447,7 +447,7 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) BT_DBG("%s status 0x%x", hdev->name, status); if (status) - return; + goto done; sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE); if (!sent) @@ -457,6 +457,10 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) set_bit(HCI_SSP_ENABLED, &hdev->dev_flags); else clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags); + +done: + if (test_bit(HCI_MGMT, &hdev->dev_flags)) + mgmt_ssp_enable_complete(hdev, status); } static u8 hci_get_inquiry_mode(struct hci_dev *hdev) -- cgit v1.2.3 From 343f935bfa44189c68527102c409286b0cfc4526 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Fri, 17 Feb 2012 20:39:37 -0300 Subject: Bluetooth: Merge INQUIRY and LE_SCAN discovery states This patch merges DISCOVERY_INQUIRY and DISCOVERY_LE_SCAN states into a new state called DISCOVERY_FINDING. From the discovery perspective, we are pretty much worried about to know just if we are finding devices than what exactly phase of "finding devices" (inquiry or LE scan) we are currently running. Besides, to know if the controller is performing inquiry or LE scan we should check HCI_INQUIRY or HCI_LE_SCAN bits in hdev flags. Moreover, merging this two states will simplify the discovery state machine and will keep interleaved discovery implementation simpler. Signed-off-by: Andre Guedes Acked-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/hci_event.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 179d127601fc..9aea7b898821 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1080,7 +1080,7 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, hci_dev_lock(hdev); hci_adv_entries_clear(hdev); - hci_discovery_set_state(hdev, DISCOVERY_LE_SCAN); + hci_discovery_set_state(hdev, DISCOVERY_FINDING); hci_dev_unlock(hdev); break; @@ -1159,7 +1159,7 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) set_bit(HCI_INQUIRY, &hdev->flags); hci_dev_lock(hdev); - hci_discovery_set_state(hdev, DISCOVERY_INQUIRY); + hci_discovery_set_state(hdev, DISCOVERY_FINDING); hci_dev_unlock(hdev); } @@ -1645,7 +1645,7 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff hci_dev_lock(hdev); - if (discov->state != DISCOVERY_INQUIRY) + if (discov->state != DISCOVERY_FINDING) goto unlock; if (list_empty(&discov->resolve)) { -- cgit v1.2.3 From 5e0452c00a2e4b04ec1482248c897dacf106f1df Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Fri, 17 Feb 2012 20:39:38 -0300 Subject: Bluetooth: Interleaved discovery support This patch adds interleaved discovery support to MGMT Start Discovery command. In case interleaved discovery is not supported (not a dual mode device), we perform BR/EDR or LE-only discovery according to the device capabilities. Signed-off-by: Andre Guedes Acked-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/hci_event.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 9aea7b898821..04fb1f02dfcc 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1090,11 +1090,16 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, clear_bit(HCI_LE_SCAN, &hdev->dev_flags); - hci_dev_lock(hdev); - hci_discovery_set_state(hdev, DISCOVERY_STOPPED); - hci_dev_unlock(hdev); - schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT); + + if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED) { + mgmt_interleaved_discovery(hdev); + } else { + hci_dev_lock(hdev); + hci_discovery_set_state(hdev, DISCOVERY_STOPPED); + hci_dev_unlock(hdev); + } + break; default: -- cgit v1.2.3 From 470fe1b540fb50ba8ce01e0ac985602e8fbb108c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 20 Feb 2012 14:50:30 +0100 Subject: Bluetooth: Split sending for HCI raw and control sockets The sending functions for HCI raw and control sockets have nothing in common except that they iterate over the socket list. Split them into two so they can do their job more efficient. In addition the code becomes more readable. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/hci_event.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 04fb1f02dfcc..e69db4a7b3ef 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -3571,7 +3571,7 @@ void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data) bt_cb(skb)->pkt_type = HCI_EVENT_PKT; skb->dev = (void *) hdev; - hci_send_to_sock(hdev, skb, NULL); + hci_send_to_sock(hdev, skb); kfree_skb(skb); } -- cgit v1.2.3 From 040030ef7d907107e6489b39da518bdf94136d68 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 20 Feb 2012 14:50:37 +0100 Subject: Bluetooth: Remove HCI notifier handling The HCI notifier handling was never used outside of Bluetooth core layer and thus remove it and replace it with direct function calls. Also move the stack internal event generation into the HCI socket layer. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/hci_event.c | 29 ----------------------------- 1 file changed, 29 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index e69db4a7b3ef..f00faf0ac32f 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -3547,33 +3546,5 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) hdev->stat.evt_rx++; } -/* Generate internal stack event */ -void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data) -{ - struct hci_event_hdr *hdr; - struct hci_ev_stack_internal *ev; - struct sk_buff *skb; - - skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC); - if (!skb) - return; - - hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE); - hdr->evt = HCI_EV_STACK_INTERNAL; - hdr->plen = sizeof(*ev) + dlen; - - ev = (void *) skb_put(skb, sizeof(*ev) + dlen); - ev->type = type; - memcpy(ev->data, data, dlen); - - bt_cb(skb)->incoming = 1; - __net_timestamp(skb); - - bt_cb(skb)->pkt_type = HCI_EVENT_PKT; - skb->dev = (void *) hdev; - hci_send_to_sock(hdev, skb); - kfree_skb(skb); -} - module_param(enable_le, bool, 0644); MODULE_PARM_DESC(enable_le, "Enable LE support"); -- cgit v1.2.3 From d7b7e79688c07b445bc52adfedf9a176be156f4b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 20 Feb 2012 21:47:49 +0100 Subject: Bluetooth: Set supported settings based on enabled HS and/or LE Since neither High Speed (HS) nor Low Energy (LE) are fully implemented yet, only expose them in supported settings when enabled. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/hci_event.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index f00faf0ac32f..5d0f92a948c2 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -44,8 +44,6 @@ #include #include -static bool enable_le; - /* Handle HCI Event packets */ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) @@ -3545,6 +3543,3 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) kfree_skb(skb); hdev->stat.evt_rx++; } - -module_param(enable_le, bool, 0644); -MODULE_PARM_DESC(enable_le, "Enable LE support"); -- cgit v1.2.3 From a297e97cf7228467a8c5c76216945ccf029ae2a4 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 21 Feb 2012 17:55:47 +0200 Subject: Bluetooth: Fix clearing of persistent dev_flags Now that most flags are persistent, only the LE_SCAN flag should be cleared after a reset. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 5d0f92a948c2..2a5d05c05e35 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -192,9 +192,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) hci_req_complete(hdev, HCI_OP_RESET, status); - /* Reset all flags, except persistent ones */ - hdev->dev_flags &= BIT(HCI_MGMT) | BIT(HCI_SETUP) | BIT(HCI_AUTO_OFF) | - BIT(HCI_LINK_KEYS) | BIT(HCI_DEBUG_KEYS); + /* Reset all non-persistent flags */ + hdev->dev_flags &= ~(BIT(HCI_LE_SCAN)); } static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) -- cgit v1.2.3 From 47990ea09d393da8fb6cf284f4dba704c3661973 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 22 Feb 2012 11:58:37 +0200 Subject: Bluetooth: mgmt: Make Set Link Security callable while powered off This patch makes it possible to change the Link Security setting while powered off and have it automatically enabled when powering on a device. To track the desired state once powered on a new HCI_LINK_SECURITY flag is added. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 2a5d05c05e35..5fb1ee516d3a 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -594,6 +594,12 @@ static void hci_setup(struct hci_dev *hdev) sizeof(cp), &cp); } + if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) { + u8 enable = 1; + hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, + sizeof(enable), &enable); + } + if (hdev->features[4] & LMP_LE) hci_set_le_support(hdev); } -- cgit v1.2.3 From 2e99b0afc7445769bb886dc14a31aaa0dc17c4b5 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 22 Feb 2012 12:28:39 +0200 Subject: Bluetooth: Remove unneeded hci_cc_read_ssp_mode function The kernel has no need to track the hci_read_ssp_mode command since it has the hci_sent_cmd_data function to check what value was set when hci_write_ssp_mode completes. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 5fb1ee516d3a..1b1c3480a24d 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -420,21 +420,6 @@ static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status); } -static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) -{ - struct hci_rp_read_ssp_mode *rp = (void *) skb->data; - - BT_DBG("%s status 0x%x", hdev->name, rp->status); - - if (rp->status) - return; - - if (rp->mode) - set_bit(HCI_SSP_ENABLED, &hdev->dev_flags); - else - clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags); -} - static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); @@ -2201,10 +2186,6 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk hci_cc_host_buffer_size(hdev, skb); break; - case HCI_OP_READ_SSP_MODE: - hci_cc_read_ssp_mode(hdev, skb); - break; - case HCI_OP_WRITE_SSP_MODE: hci_cc_write_ssp_mode(hdev, skb); break; -- cgit v1.2.3 From c0ecddc2507da980af307aae40d6bcdea4c195dc Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 22 Feb 2012 12:38:31 +0200 Subject: Bluetooth: mgmt: Make Set SSP command callable while powered off This patch makes it possible to enable SSP through mgmt even when powered off. The setting will then get automatically actiated when powering on. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 1b1c3480a24d..240dc1640c04 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -427,21 +427,18 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) BT_DBG("%s status 0x%x", hdev->name, status); - if (status) - goto done; - sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE); if (!sent) return; - if (*((u8 *) sent)) - set_bit(HCI_SSP_ENABLED, &hdev->dev_flags); - else - clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags); - -done: if (test_bit(HCI_MGMT, &hdev->dev_flags)) - mgmt_ssp_enable_complete(hdev, status); + mgmt_ssp_enable_complete(hdev, *((u8 *) sent), status); + else if (!status) { + if (*((u8 *) sent)) + set_bit(HCI_SSP_ENABLED, &hdev->dev_flags); + else + clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags); + } } static u8 hci_get_inquiry_mode(struct hci_dev *hdev) @@ -560,7 +557,8 @@ static void hci_setup(struct hci_dev *hdev) if (hdev->hci_ver > BLUETOOTH_VER_1_1) hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); - if (hdev->features[6] & LMP_SIMPLE_PAIR) { + if (hdev->features[6] & LMP_SIMPLE_PAIR && + test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { u8 mode = 0x01; hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode); } -- cgit v1.2.3 From 54d04dbbb933e8a49429d602b847e367782267e9 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 22 Feb 2012 15:47:48 +0200 Subject: Bluetooth: Explicitly clear EIR data upon hci_dev setup Some controllers preserve their EIR data even after a reset so we need to explicitly clear this during the device setup procedure. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 240dc1640c04..3476d5c7b02d 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -557,10 +557,19 @@ static void hci_setup(struct hci_dev *hdev) if (hdev->hci_ver > BLUETOOTH_VER_1_1) hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); - if (hdev->features[6] & LMP_SIMPLE_PAIR && - test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { - u8 mode = 0x01; - hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode); + if (hdev->features[6] & LMP_SIMPLE_PAIR) { + if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { + u8 mode = 0x01; + hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, + sizeof(mode), &mode); + } else { + struct hci_cp_write_eir cp; + + memset(hdev->eir, 0, sizeof(hdev->eir)); + memset(&cp, 0, sizeof(cp)); + + hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp); + } } if (hdev->features[3] & LMP_RSSI_INQ) -- cgit v1.2.3 From 06199cf86a84206cfdc96b8dc02d5c27efa8c60f Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 22 Feb 2012 16:37:11 +0200 Subject: Bluetooth: mgmt: Implement Set LE command This patch implements support for the Set LE mgmt command. Now, in addition to the enable_le module parameter user space needs to send an explicit Enable LE command to enable LE support. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 3476d5c7b02d..498b71a0579a 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -539,7 +539,7 @@ static void hci_set_le_support(struct hci_dev *hdev) memset(&cp, 0, sizeof(cp)); - if (enable_le) { + if (enable_le && test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { cp.le = 1; cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR); } @@ -1130,10 +1130,15 @@ static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_cp_read_local_ext_features cp; + struct hci_cp_write_le_host_supported *sent; __u8 status = *((__u8 *) skb->data); BT_DBG("%s status 0x%x", hdev->name, status); + sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED); + if (sent && test_bit(HCI_MGMT, &hdev->dev_flags)) + mgmt_le_enable_complete(hdev, sent->le, status); + if (status) return; -- cgit v1.2.3 From f51d5b248981d05269e4f83ab8f8ed7ed494fe33 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 22 Feb 2012 18:17:32 +0200 Subject: Bluetooth: mgmt: Fix updating EIR when updating the name Whenever we update the local device name the EIR data also needs to be updated to reflect this. The update_eir() function in mgmt.c depends on hdev->dev_name to be up to date so the patch also makes sure that the mgmt function is called from hci_event.c after the update has happened. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 498b71a0579a..e44e3fd68628 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -209,12 +209,12 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_lock(hdev); - if (test_bit(HCI_MGMT, &hdev->dev_flags)) - mgmt_set_local_name_complete(hdev, sent, status); - if (status == 0) memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); + if (test_bit(HCI_MGMT, &hdev->dev_flags)) + mgmt_set_local_name_complete(hdev, sent, status); + hci_dev_unlock(hdev); } -- cgit v1.2.3 From 7f9a903c57bb42b9f7ad8fb7867859d3252229ab Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 22 Feb 2012 18:38:01 +0100 Subject: Bluetooth: Send management event for class of device changes Currently there are no events to other management sockets if the class of device got changed. So make sure they are sent. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/hci_event.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index e44e3fd68628..c79ffb955554 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -350,14 +350,19 @@ static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) BT_DBG("%s status 0x%x", hdev->name, status); - if (status) - return; - sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV); if (!sent) return; - memcpy(hdev->dev_class, sent, 3); + hci_dev_lock(hdev); + + if (status == 0) + memcpy(hdev->dev_class, sent, 3); + + if (test_bit(HCI_MGMT, &hdev->dev_flags)) + mgmt_set_class_of_dev_complete(hdev, sent, status); + + hci_dev_unlock(hdev); } static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) -- cgit v1.2.3 From db99b5fc77e6cec47d80703b471f1efe04527d2f Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 22 Feb 2012 20:14:22 +0200 Subject: Bluetooth: Fix read_name updating when HCI_SETUP is not set The local name should only be updated as a consequence of a hci_read_local_name if we are in the HCI_SETUP state. In all other scenarios it should only be updated through hci_write_local_name. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index c79ffb955554..9917fe3d1d18 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -227,7 +227,8 @@ static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) if (rp->status) return; - memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH); + if (test_bit(HCI_SETUP, &hdev->dev_flags)) + memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH); } static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb) -- cgit v1.2.3 From 28cc7bde5978cbc58c9026123fa5f33b62ad66b3 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 22 Feb 2012 21:06:55 +0200 Subject: Bluetooth: mgmt: Allow local name changes while powered off This patch makes it possible to set the local name before powering on the device. The name will be applied using the hci_write_local_name command once the device gets powered on. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 9917fe3d1d18..9b30587c0de6 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -209,11 +209,10 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_lock(hdev); - if (status == 0) - memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); - if (test_bit(HCI_MGMT, &hdev->dev_flags)) mgmt_set_local_name_complete(hdev, sent, status); + else if (!status) + memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); hci_dev_unlock(hdev); } @@ -563,6 +562,14 @@ static void hci_setup(struct hci_dev *hdev) if (hdev->hci_ver > BLUETOOTH_VER_1_1) hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); + if (!test_bit(HCI_SETUP, &hdev->dev_flags) && + test_bit(HCI_MGMT, &hdev->dev_flags)) { + struct hci_cp_write_local_name cp; + + memcpy(cp.name, hdev->dev_name, sizeof(cp.name)); + hci_send_cmd(hdev, HCI_OP_WRITE_LOCAL_NAME, sizeof(cp), &cp); + } + if (hdev->features[6] & LMP_SIMPLE_PAIR) { if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { u8 mode = 0x01; -- cgit v1.2.3 From 388fc8faf200f80159353eb86cde4ab75d0a0bbd Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 23 Feb 2012 00:38:59 +0200 Subject: Bluetooth: mgmt: Add legacy pairing info to dev_found events This patch makes sure that legacy pairing vs SSP infomation gets properly propageted to the device_found events in the form of the legacy pairing flag. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 9b30587c0de6..276f3ac06089 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1696,7 +1696,7 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff * hci_dev_lock(hdev); for (; num_rsp; num_rsp--, info++) { - bool name_known; + bool name_known, ssp; bacpy(&data.bdaddr, &info->bdaddr); data.pscan_rep_mode = info->pscan_rep_mode; @@ -1707,9 +1707,9 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff * data.rssi = 0x00; data.ssp_mode = 0x00; - name_known = hci_inquiry_cache_update(hdev, &data, false); + name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp); mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, - info->dev_class, 0, !name_known, + info->dev_class, 0, !name_known, ssp, NULL, 0); } @@ -2783,7 +2783,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct { struct inquiry_data data; int num_rsp = *((__u8 *) skb->data); - bool name_known; + bool name_known, ssp; BT_DBG("%s num_rsp %d", hdev->name, num_rsp); @@ -2807,10 +2807,10 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct data.ssp_mode = 0x00; name_known = hci_inquiry_cache_update(hdev, &data, - false); + false, &ssp); mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, info->dev_class, info->rssi, - !name_known, NULL, 0); + !name_known, ssp, NULL, 0); } } else { struct inquiry_info_with_rssi *info = (void *) (skb->data + 1); @@ -2825,10 +2825,10 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct data.rssi = info->rssi; data.ssp_mode = 0x00; name_known = hci_inquiry_cache_update(hdev, &data, - false); + false, &ssp); mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, info->dev_class, info->rssi, - !name_known, NULL, 0); + !name_known, ssp, NULL, 0); } } @@ -2964,7 +2964,7 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct hci_dev_lock(hdev); for (; num_rsp; num_rsp--, info++) { - bool name_known; + bool name_known, ssp; bacpy(&data.bdaddr, &info->bdaddr); data.pscan_rep_mode = info->pscan_rep_mode; @@ -2982,10 +2982,11 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct else name_known = true; - name_known = hci_inquiry_cache_update(hdev, &data, name_known); + name_known = hci_inquiry_cache_update(hdev, &data, name_known, + &ssp); mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, info->dev_class, info->rssi, - !name_known, info->data, + !name_known, ssp, info->data, sizeof(info->data)); } @@ -3310,7 +3311,8 @@ static inline void hci_le_adv_report_evt(struct hci_dev *hdev, rssi = ev->data[ev->length]; mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type, - NULL, rssi, 0, ev->data, ev->length); + NULL, rssi, 0, 1, ev->data, + ev->length); ptr += sizeof(*ev) + ev->length + 1; } -- cgit v1.2.3 From 69775ff6d101ccf435bd26ae822c24bbb20e11cf Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 23 Feb 2012 16:50:05 +0200 Subject: Bluetooth: Set DISCOVERY_STOPPED if controller resets If controller is reset during the discovery procedure, Start Discovery command stops working. This can be easily reproduced by running "hciconfig hci0 reset" while discovering devices, for instance. We should force discovery state to DISCOVERY_STOPPED in case we receive a reset command complete event. Otherwise we may stuck in one of the active discovery states (DISCOVERY_INQUIRY, DISCOVERY_LE_SCAN and DISCOVERY_RESOLVING) and subsequent Start Discovery commands will simply fail. Signed-off-by: Andre Guedes Acked-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/hci_event.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 276f3ac06089..3d1eef0df2a3 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -194,6 +194,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) /* Reset all non-persistent flags */ hdev->dev_flags &= ~(BIT(HCI_LE_SCAN)); + + hdev->discovery.state = DISCOVERY_STOPPED; } static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) -- cgit v1.2.3 From 08c79b6133b70a6e3d462d11a89c80259ac66ec7 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 23 Feb 2012 22:31:51 +0200 Subject: Bluetooth: mgmt: Add flags parameter to device_connected This patch updates the Device Connected events to match the latest API by adding a flags parameter to them. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 3d1eef0df2a3..fb6543b60dec 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1368,7 +1368,7 @@ static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn, struct inquiry_entry *e; if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) - mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, + mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name, name_len, conn->dev_class); if (discov->state == DISCOVERY_STOPPED) @@ -2104,7 +2104,7 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) mgmt_device_connected(hdev, &conn->dst, conn->type, - conn->dst_type, NULL, 0, + conn->dst_type, 0, NULL, 0, conn->dev_class); if (!hci_outgoing_auth_needed(hdev, conn)) { @@ -2872,7 +2872,7 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) mgmt_device_connected(hdev, &conn->dst, conn->type, - conn->dst_type, NULL, 0, + conn->dst_type, 0, NULL, 0, conn->dev_class); if (!hci_outgoing_auth_needed(hdev, conn)) { @@ -3282,7 +3282,7 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) mgmt_device_connected(hdev, &ev->bdaddr, conn->type, - conn->dst_type, NULL, 0, 0); + conn->dst_type, 0, NULL, 0, 0); conn->sec_level = BT_SECURITY_LOW; conn->handle = __le16_to_cpu(ev->handle); -- cgit v1.2.3 From 3159d3843aa628b0ee9e8ef4b4fe8c935500c03f Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 24 Feb 2012 13:47:56 +0200 Subject: Bluetooth: Fix init request completion with old controllers With Bluetooth 1.1 controllers the last command in the HCI init sequence will be a write_local_name, however there was no callback to indicate init request completion in this case. This patch fixes the issue by adding the necessary callback to the write_local_name_complete handler. Signed-off-by: Johan Hedberg --- net/bluetooth/hci_event.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index fb6543b60dec..3e817fed7706 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -217,6 +217,8 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); hci_dev_unlock(hdev); + + hci_req_complete(hdev, HCI_OP_WRITE_LOCAL_NAME, status); } static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) -- cgit v1.2.3 From 28b8df77449faa03b573638e089a855f8d25e0ed Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 24 Feb 2012 12:45:44 +0200 Subject: Bluetooth: Fix init request completion with AMP controllers Mark request status as done for Read Local Version HCI command. In AMP initialization this HCI command is the last and needs to be completed. Signed-off-by: Andrei Emeltchenko Signed-off-by: Johan Hedberg --- net/bluetooth/hci_event.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 3e817fed7706..e920cd520a82 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -620,7 +620,7 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) BT_DBG("%s status 0x%x", hdev->name, rp->status); if (rp->status) - return; + goto done; hdev->hci_ver = rp->hci_ver; hdev->hci_rev = __le16_to_cpu(rp->hci_rev); @@ -634,6 +634,9 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) if (test_bit(HCI_INIT, &hdev->flags)) hci_setup(hdev); + +done: + hci_req_complete(hdev, HCI_OP_READ_LOCAL_VERSION, rp->status); } static void hci_setup_link_policy(struct hci_dev *hdev) -- cgit v1.2.3 From 8f984dfaf0bfa1355548cfba00473c8fa8e22d6e Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 28 Feb 2012 01:07:22 +0200 Subject: Bluetooth: Remove redundant read_host_features commands Previously the write_le_enable would trigger a read_host_features command but since we have access to the value LE support was set to we can simply just clear or set the bit in hdev->host_features. This also removes a second unnecessary read_host_features command from the device initialization procedure since LE is only enabled after the first read_host_features command completes. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 59 +++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 25 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index e920cd520a82..488fdbcfe762 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -542,20 +542,6 @@ static void hci_setup_event_mask(struct hci_dev *hdev) hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events); } -static void hci_set_le_support(struct hci_dev *hdev) -{ - struct hci_cp_write_le_host_supported cp; - - memset(&cp, 0, sizeof(cp)); - - if (enable_le && test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { - cp.le = 1; - cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR); - } - - hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp); -} - static void hci_setup(struct hci_dev *hdev) { if (hdev->dev_type != HCI_BREDR) @@ -608,9 +594,6 @@ static void hci_setup(struct hci_dev *hdev) hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable), &enable); } - - if (hdev->features[4] & LMP_LE) - hci_set_le_support(hdev); } static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) @@ -730,6 +713,22 @@ static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb hdev->features[6], hdev->features[7]); } +static void hci_set_le_support(struct hci_dev *hdev) +{ + struct hci_cp_write_le_host_supported cp; + + memset(&cp, 0, sizeof(cp)); + + if (enable_le && test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { + cp.le = 1; + cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR); + } + + if (cp.le != !!(hdev->host_features[0] & LMP_HOST_LE)) + hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, + sizeof(cp), &cp); +} + static void hci_cc_read_local_ext_features(struct hci_dev *hdev, struct sk_buff *skb) { @@ -738,7 +737,7 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev, BT_DBG("%s status 0x%x", hdev->name, rp->status); if (rp->status) - return; + goto done; switch (rp->page) { case 0: @@ -749,6 +748,10 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev, break; } + if (test_bit(HCI_INIT, &hdev->flags) && hdev->features[4] & LMP_LE) + hci_set_le_support(hdev); + +done: hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status); } @@ -1149,21 +1152,27 @@ static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev, struct sk_buff *skb) { - struct hci_cp_read_local_ext_features cp; struct hci_cp_write_le_host_supported *sent; __u8 status = *((__u8 *) skb->data); BT_DBG("%s status 0x%x", hdev->name, status); sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED); - if (sent && test_bit(HCI_MGMT, &hdev->dev_flags)) - mgmt_le_enable_complete(hdev, sent->le, status); - - if (status) + if (!sent) return; - cp.page = 0x01; - hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp); + if (!status) { + if (sent->le) + hdev->host_features[0] |= LMP_HOST_LE; + else + hdev->host_features[0] &= ~LMP_HOST_LE; + } + + if (test_bit(HCI_MGMT, &hdev->dev_flags) && + !test_bit(HCI_INIT, &hdev->flags)) + mgmt_le_enable_complete(hdev, sent->le, status); + + hci_req_complete(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, status); } static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) -- cgit v1.2.3 From 02b7cc62b6176748dc5b55e0ca9c965f73a5c300 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 28 Feb 2012 02:28:43 +0200 Subject: Bluetooth: Use LMP_HOST_SSP define instead of magic values This patch fixes the code to use the proper LMP_HOST_SSP define instead of magic values and thereby makes the code more readable. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 488fdbcfe762..8c3261db7611 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -2869,9 +2869,9 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b ie = hci_inquiry_cache_lookup(hdev, &conn->dst); if (ie) - ie->data.ssp_mode = (ev->features[0] & 0x01); + ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); - if (ev->features[0] & 0x01) + if (ev->features[0] & LMP_HOST_SSP) set_bit(HCI_CONN_SSP_ENABLED, &conn->flags); } @@ -3224,7 +3224,7 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_ ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); if (ie) - ie->data.ssp_mode = (ev->features[0] & 0x01); + ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); hci_dev_unlock(hdev); } -- cgit v1.2.3 From 95b23582d796305c66952188de2f5159b28be766 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sun, 12 Feb 2012 13:55:35 +0100 Subject: Bluetooth: Use NULL instead of integer for mgmt_device_connected param Last param of mgmt_device_connected is of pointer type, so use NULL instead of 0 for it. This fix following sparse warning: CHECK net/bluetooth/hci_event.c net/bluetooth/hci_event.c:3262:74: warning: Using plain integer as NULL pointer Signed-off-by: Szymon Janc Signed-off-by: Johan Hedberg --- net/bluetooth/hci_event.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 8c3261db7611..746f7d372258 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -3296,7 +3296,7 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) mgmt_device_connected(hdev, &ev->bdaddr, conn->type, - conn->dst_type, 0, NULL, 0, 0); + conn->dst_type, 0, NULL, 0, NULL); conn->sec_level = BT_SECURITY_LOW; conn->handle = __le16_to_cpu(ev->handle); -- cgit v1.2.3 From 00abfe4442864144a77f70b6b411d691bcb796bf Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Thu, 1 Mar 2012 00:37:10 -0300 Subject: Bluetooth: Fix coding style with breaking lines Our limit is 80 and broken lines should as right as possible. Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_event.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 746f7d372258..aee9556e1039 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1344,7 +1344,8 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev, return 1; } -static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e) +static inline int hci_resolve_name(struct hci_dev *hdev, + struct inquiry_entry *e) { struct hci_cp_remote_name_req cp; -- cgit v1.2.3 From 9f8ce967caed427f78d00bb6b07d79cb040a88bd Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 2 Mar 2012 03:06:04 +0200 Subject: Bluetooth: Fix clearing of HCI_PENDING_CLASS flag When doing reset HCI_PENDING_CLASS is one of the flags that should be cleared (since it's used for a pending HCI command and a reset clear all pending commands). Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index aee9556e1039..d6c41bbfe759 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -193,7 +193,7 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) hci_req_complete(hdev, HCI_OP_RESET, status); /* Reset all non-persistent flags */ - hdev->dev_flags &= ~(BIT(HCI_LE_SCAN)); + hdev->dev_flags &= ~(BIT(HCI_LE_SCAN) | BIT(HCI_PENDING_CLASS)); hdev->discovery.state = DISCOVERY_STOPPED; } -- cgit v1.2.3 From 2b4bf3974249da74f4aef1e9180d4beaf6332515 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 3 Mar 2012 00:19:06 +0200 Subject: Bluetooth: mgmt: Fix updating local name when powering on When powering on we need to apply whatever name has been set through mgmt_set_local_name. The appropriate place for this is mgmt_powered() and not hci_setup() since this needs to be applied also if the HCI init sequence was already completed but the adapter was still "powered off" from a mgmt perspective due the the HCI_AUTO_OFF still being set. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index d6c41bbfe759..6a817daf095b 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -552,14 +552,6 @@ static void hci_setup(struct hci_dev *hdev) if (hdev->hci_ver > BLUETOOTH_VER_1_1) hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); - if (!test_bit(HCI_SETUP, &hdev->dev_flags) && - test_bit(HCI_MGMT, &hdev->dev_flags)) { - struct hci_cp_write_local_name cp; - - memcpy(cp.name, hdev->dev_name, sizeof(cp.name)); - hci_send_cmd(hdev, HCI_OP_WRITE_LOCAL_NAME, sizeof(cp), &cp); - } - if (hdev->features[6] & LMP_SIMPLE_PAIR) { if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { u8 mode = 0x01; -- cgit v1.2.3 From 04124681f104c1980024ff249a34a77a249fd2bc Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Thu, 8 Mar 2012 01:25:00 -0300 Subject: Bluetooth: fix conding style issues all over the tree Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_event.c | 110 ++++++++++++++++++++++------------------------ 1 file changed, 53 insertions(+), 57 deletions(-) (limited to 'net/bluetooth/hci_event.c') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 6a817daf095b..badb7851d116 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -556,7 +556,7 @@ static void hci_setup(struct hci_dev *hdev) if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { u8 mode = 0x01; hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, - sizeof(mode), &mode); + sizeof(mode), &mode); } else { struct hci_cp_write_eir cp; @@ -577,14 +577,14 @@ static void hci_setup(struct hci_dev *hdev) struct hci_cp_read_local_ext_features cp; cp.page = 0x01; - hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, - sizeof(cp), &cp); + hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), + &cp); } if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) { u8 enable = 1; - hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, - sizeof(enable), &enable); + hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable), + &enable); } } @@ -628,8 +628,8 @@ static void hci_setup_link_policy(struct hci_dev *hdev) link_policy |= HCI_LP_PARK; link_policy = cpu_to_le16(link_policy); - hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, - sizeof(link_policy), &link_policy); + hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(link_policy), + &link_policy); } static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb) @@ -717,8 +717,8 @@ static void hci_set_le_support(struct hci_dev *hdev) } if (cp.le != !!(hdev->host_features[0] & LMP_HOST_LE)) - hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, - sizeof(cp), &cp); + hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), + &cp); } static void hci_cc_read_local_ext_features(struct hci_dev *hdev, @@ -976,8 +976,8 @@ static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_lock(hdev); if (test_bit(HCI_MGMT, &hdev->dev_flags)) - mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, - 0, rp->status); + mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0, + rp->status); hci_dev_unlock(hdev); } @@ -993,8 +993,7 @@ static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, if (test_bit(HCI_MGMT, &hdev->dev_flags)) mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr, - ACL_LINK, 0, - rp->status); + ACL_LINK, 0, rp->status); hci_dev_unlock(hdev); } @@ -1009,7 +1008,7 @@ static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb) if (test_bit(HCI_MGMT, &hdev->dev_flags)) mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK, - 0, rp->status); + 0, rp->status); hci_dev_unlock(hdev); } @@ -1025,8 +1024,7 @@ static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, if (test_bit(HCI_MGMT, &hdev->dev_flags)) mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr, - ACL_LINK, 0, - rp->status); + ACL_LINK, 0, rp->status); hci_dev_unlock(hdev); } @@ -1337,7 +1335,7 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev, } static inline int hci_resolve_name(struct hci_dev *hdev, - struct inquiry_entry *e) + struct inquiry_entry *e) { struct hci_cp_remote_name_req cp; @@ -1369,14 +1367,14 @@ static bool hci_resolve_next_name(struct hci_dev *hdev) } static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn, - bdaddr_t *bdaddr, u8 *name, u8 name_len) + bdaddr_t *bdaddr, u8 *name, u8 name_len) { struct discovery_state *discov = &hdev->discovery; struct inquiry_entry *e; if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) - mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, - name, name_len, conn->dev_class); + mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name, + name_len, conn->dev_class); if (discov->state == DISCOVERY_STOPPED) return; @@ -1393,7 +1391,7 @@ static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn, list_del(&e->list); if (name) mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00, - e->data.rssi, name, name_len); + e->data.rssi, name, name_len); } if (hci_resolve_next_name(hdev)) @@ -1602,7 +1600,7 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); if (conn) mgmt_disconnect_failed(hdev, &conn->dst, conn->type, - conn->dst_type, status); + conn->dst_type, status); hci_dev_unlock(hdev); } @@ -1718,8 +1716,8 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff * name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp); mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, - info->dev_class, 0, !name_known, ssp, - NULL, 0); + info->dev_class, 0, !name_known, ssp, NULL, + 0); } hci_dev_unlock(hdev); @@ -1770,7 +1768,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s struct hci_cp_read_remote_features cp; cp.handle = ev->handle; hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, - sizeof(cp), &cp); + sizeof(cp), &cp); } /* Set packet type for incoming connection */ @@ -1778,14 +1776,14 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s struct hci_cp_change_conn_ptype cp; cp.handle = ev->handle; cp.pkt_type = cpu_to_le16(conn->pkt_type); - hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, - sizeof(cp), &cp); + hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp), + &cp); } } else { conn->state = BT_CLOSED; if (conn->type == ACL_LINK) mgmt_connect_failed(hdev, &ev->bdaddr, conn->type, - conn->dst_type, ev->status); + conn->dst_type, ev->status); } if (conn->type == ACL_LINK) @@ -1850,8 +1848,8 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk else cp.role = 0x01; /* Remain slave */ - hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, - sizeof(cp), &cp); + hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), + &cp); } else { struct hci_cp_accept_sync_conn_req cp; @@ -1865,7 +1863,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk cp.retrans_effort = 0xff; hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, - sizeof(cp), &cp); + sizeof(cp), &cp); } } else { /* Connection rejected */ @@ -1900,7 +1898,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff conn->dst_type, ev->status); else mgmt_device_disconnected(hdev, &conn->dst, conn->type, - conn->dst_type); + conn->dst_type); } if (ev->status == 0) { @@ -1935,7 +1933,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s } } else { mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type, - ev->status); + ev->status); } clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); @@ -1996,7 +1994,7 @@ static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb if (ev->status == 0) hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name, - strnlen(ev->name, HCI_MAX_NAME_LENGTH)); + strnlen(ev->name, HCI_MAX_NAME_LENGTH)); else hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0); @@ -2111,8 +2109,8 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) mgmt_device_connected(hdev, &conn->dst, conn->type, - conn->dst_type, 0, NULL, 0, - conn->dev_class); + conn->dst_type, 0, NULL, 0, + conn->dev_class); if (!hci_outgoing_auth_needed(hdev, conn)) { conn->state = BT_CONNECTED; @@ -2524,7 +2522,7 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s } static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_ev_num_comp_blocks *ev = (void *) skb->data; int i; @@ -2816,10 +2814,10 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct data.ssp_mode = 0x00; name_known = hci_inquiry_cache_update(hdev, &data, - false, &ssp); + false, &ssp); mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, - info->dev_class, info->rssi, - !name_known, ssp, NULL, 0); + info->dev_class, info->rssi, + !name_known, ssp, NULL, 0); } } else { struct inquiry_info_with_rssi *info = (void *) (skb->data + 1); @@ -2834,10 +2832,10 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct data.rssi = info->rssi; data.ssp_mode = 0x00; name_known = hci_inquiry_cache_update(hdev, &data, - false, &ssp); + false, &ssp); mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, - info->dev_class, info->rssi, - !name_known, ssp, NULL, 0); + info->dev_class, info->rssi, + !name_known, ssp, NULL, 0); } } @@ -2879,8 +2877,8 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) mgmt_device_connected(hdev, &conn->dst, conn->type, - conn->dst_type, 0, NULL, 0, - conn->dev_class); + conn->dst_type, 0, NULL, 0, + conn->dev_class); if (!hci_outgoing_auth_needed(hdev, conn)) { conn->state = BT_CONNECTED; @@ -2986,17 +2984,16 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct if (test_bit(HCI_MGMT, &hdev->dev_flags)) name_known = eir_has_data_type(info->data, - sizeof(info->data), - EIR_NAME_COMPLETE); + sizeof(info->data), + EIR_NAME_COMPLETE); else name_known = true; name_known = hci_inquiry_cache_update(hdev, &data, name_known, - &ssp); + &ssp); mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, - info->dev_class, info->rssi, - !name_known, ssp, info->data, - sizeof(info->data)); + info->dev_class, info->rssi, !name_known, + ssp, info->data, sizeof(info->data)); } hci_dev_unlock(hdev); @@ -3157,7 +3154,7 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev, confirm: mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey, - confirm_hint); + confirm_hint); unlock: hci_dev_unlock(hdev); @@ -3198,7 +3195,7 @@ static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_ * the mgmt_auth_failed event */ if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0) mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type, - ev->status); + ev->status); hci_conn_put(conn); @@ -3223,7 +3220,7 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_ } static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_ev_remote_oob_data_request *ev = (void *) skb->data; struct oob_data *data; @@ -3289,7 +3286,7 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) mgmt_device_connected(hdev, &ev->bdaddr, conn->type, - conn->dst_type, 0, NULL, 0, NULL); + conn->dst_type, 0, NULL, 0, NULL); conn->sec_level = BT_SECURITY_LOW; conn->handle = __le16_to_cpu(ev->handle); @@ -3320,8 +3317,7 @@ static inline void hci_le_adv_report_evt(struct hci_dev *hdev, rssi = ev->data[ev->length]; mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type, - NULL, rssi, 0, 1, ev->data, - ev->length); + NULL, rssi, 0, 1, ev->data, ev->length); ptr += sizeof(*ev) + ev->length + 1; } -- cgit v1.2.3