From 60e77321985ab599fac010afdc465c3e30281a06 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 22 Jan 2013 14:01:59 +0200 Subject: Bluetooth: Add LE Local Features reading support To be able to make the appropriate decisions for some LE procedures we need to know the LE features that the local controller supports. Therefore, it's important to have the LE Read Local Supported Features HCI comand as part of the HCI init sequence. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- include/net/bluetooth/hci.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/net/bluetooth/hci.h') diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 45eee08157bb..521eefa033e7 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -943,6 +943,12 @@ struct hci_rp_le_read_buffer_size { __u8 le_max_pkt; } __packed; +#define HCI_OP_LE_READ_LOCAL_FEATURES 0x2003 +struct hci_rp_le_read_local_features { + __u8 status; + __u8 features[8]; +} __packed; + #define HCI_OP_LE_READ_ADV_TX_POWER 0x2007 struct hci_rp_le_read_adv_tx_power { __u8 status; -- cgit v1.2.3 From cf1d081f6597a45e5ff63f55c893494a8ae1cdaf Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 22 Jan 2013 14:02:00 +0200 Subject: Bluetooth: Add support for reading LE White List Size The LE White List Size is necessary to be known before attempting to feed the controller with any addresses intended for the white list. This patch adds the necessary HCI command sending to the HCI init sequence. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- include/net/bluetooth/hci.h | 6 ++++++ include/net/bluetooth/hci_core.h | 1 + net/bluetooth/hci_event.c | 20 ++++++++++++++++++++ 3 files changed, 27 insertions(+) (limited to 'include/net/bluetooth/hci.h') diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 521eefa033e7..f1766a6f4954 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -1001,6 +1001,12 @@ struct hci_cp_le_create_conn { #define HCI_OP_LE_CREATE_CONN_CANCEL 0x200e +#define HCI_OP_LE_READ_WHITE_LIST_SIZE 0x200f +struct hci_rp_le_read_white_list_size { + __u8 status; + __u8 size; +} __packed; + #define HCI_OP_LE_CONN_UPDATE 0x2013 struct hci_cp_le_conn_update { __le16 handle; diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 3f607c94e213..d6ed4ac18d83 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -153,6 +153,7 @@ struct hci_dev { __u8 features[8]; __u8 host_features[8]; __u8 le_features[8]; + __u8 le_white_list_size; __u8 commands[64]; __u8 hci_ver; __u16 hci_rev; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 07c8c79a9fd1..d2fee64b728c 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -614,6 +614,9 @@ static void le_setup(struct hci_dev *hdev) /* Read LE Advertising Channel TX Power */ hci_send_cmd(hdev, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); + + /* Read LE White List Size */ + hci_send_cmd(hdev, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL); } static void hci_setup(struct hci_dev *hdev) @@ -1306,6 +1309,19 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, } } +static void hci_cc_le_read_white_list_size(struct hci_dev *hdev, + struct sk_buff *skb) +{ + struct hci_rp_le_read_white_list_size *rp = (void *) skb->data; + + BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size); + + if (!rp->status) + hdev->le_white_list_size = rp->size; + + hci_req_complete(hdev, HCI_OP_LE_READ_WHITE_LIST_SIZE, rp->status); +} + static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_rp_le_ltk_reply *rp = (void *) skb->data; @@ -2684,6 +2700,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_cc_le_set_scan_enable(hdev, skb); break; + case HCI_OP_LE_READ_WHITE_LIST_SIZE: + hci_cc_le_read_white_list_size(hdev, skb); + break; + case HCI_OP_LE_LTK_REPLY: hci_cc_le_ltk_reply(hdev, skb); break; -- cgit v1.2.3 From 9b008c0457e583e10e62d1215bed6ab26ee54906 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 22 Jan 2013 14:02:01 +0200 Subject: Bluetooth: Add support for reading LE supported states The LE supported states indicate the states and state combinations that the link layer supports. This is important information for knowing what operations are possible when dealing with multiple connected devices. This patch adds reading of the supported states to the HCI init sequence. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- include/net/bluetooth/hci.h | 6 ++++++ include/net/bluetooth/hci_core.h | 1 + net/bluetooth/hci_event.c | 20 ++++++++++++++++++++ 3 files changed, 27 insertions(+) (limited to 'include/net/bluetooth/hci.h') diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index f1766a6f4954..7f12c25f1fca 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -1045,6 +1045,12 @@ struct hci_rp_le_ltk_neg_reply { __le16 handle; } __packed; +#define HCI_OP_LE_READ_SUPPORTED_STATES 0x201c +struct hci_rp_le_read_supported_states { + __u8 status; + __u8 le_states[8]; +} __packed; + /* ---- HCI Events ---- */ #define HCI_EV_INQUIRY_COMPLETE 0x01 diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index d6ed4ac18d83..bcf8ffe2a843 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -154,6 +154,7 @@ struct hci_dev { __u8 host_features[8]; __u8 le_features[8]; __u8 le_white_list_size; + __u8 le_states[8]; __u8 commands[64]; __u8 hci_ver; __u16 hci_rev; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index d2fee64b728c..d4fcba6ec23e 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -617,6 +617,9 @@ static void le_setup(struct hci_dev *hdev) /* Read LE White List Size */ hci_send_cmd(hdev, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL); + + /* Read LE Supported States */ + hci_send_cmd(hdev, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); } static void hci_setup(struct hci_dev *hdev) @@ -1346,6 +1349,19 @@ static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status); } +static void hci_cc_le_read_supported_states(struct hci_dev *hdev, + struct sk_buff *skb) +{ + struct hci_rp_le_read_supported_states *rp = (void *) skb->data; + + BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); + + if (!rp->status) + memcpy(hdev->le_states, rp->le_states, 8); + + hci_req_complete(hdev, HCI_OP_LE_READ_SUPPORTED_STATES, rp->status); +} + static void hci_cc_write_le_host_supported(struct hci_dev *hdev, struct sk_buff *skb) { @@ -2712,6 +2728,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_cc_le_ltk_neg_reply(hdev, skb); break; + case HCI_OP_LE_READ_SUPPORTED_STATES: + hci_cc_le_read_supported_states(hdev, skb); + break; + case HCI_OP_WRITE_LE_HOST_SUPPORTED: hci_cc_write_le_host_supported(hdev, skb); break; -- cgit v1.2.3