Bluetooth: Add support for reading LE supported states
authorJohan Hedberg <johan.hedberg@intel.com>
Tue, 22 Jan 2013 12:02:01 +0000 (14:02 +0200)
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>
Wed, 23 Jan 2013 04:09:16 +0000 (02:09 -0200)
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 <johan.hedberg@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
include/net/bluetooth/hci.h
include/net/bluetooth/hci_core.h
net/bluetooth/hci_event.c

index f1766a6f495418f24522364874dededa185c9ccc..7f12c25f1fcaa763a697d80ebf95a06124c3adc8 100644 (file)
@@ -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
 
index d6ed4ac18d834b99ba97b05fc655ba15e0919039..bcf8ffe2a84388e09ab3e5f68f2bd3991d7f51d6 100644 (file)
@@ -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;
index d2fee64b728c8f7bb2cd460901e31412f5fb63c2..d4fcba6ec23edf33442f5a9ec3896193b0f4ff48 100644 (file)
@@ -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;