Bluetooth: Store default and maximum LE data length settings
authorMarcel Holtmann <marcel@holtmann.org>
Sat, 20 Dec 2014 15:28:40 +0000 (16:28 +0100)
committerJohan Hedberg <johan.hedberg@intel.com>
Sat, 20 Dec 2014 15:52:21 +0000 (17:52 +0200)
When the controller supports the LE Data Length Extension feature, the
default and maximum data length are read and now stored.

For backwards compatibility all values are initialized to the data
length values from Bluetooth 4.1 and earlier specifications.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
include/net/bluetooth/hci_core.h
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c

index 79724c87ab004eb57e6e623b68b91fbea44f6f1b..f20f6bd668bdc411f435b8858f100656bd9ec77e 100644 (file)
@@ -220,6 +220,12 @@ struct hci_dev {
        __u16           le_conn_max_interval;
        __u16           le_conn_latency;
        __u16           le_supv_timeout;
+       __u16           le_def_tx_len;
+       __u16           le_def_tx_time;
+       __u16           le_max_tx_len;
+       __u16           le_max_tx_time;
+       __u16           le_max_rx_len;
+       __u16           le_max_rx_time;
        __u16           discov_interleaved_timeout;
        __u16           conn_info_min_age;
        __u16           conn_info_max_age;
index 01e35ef6d2014f707ca706e4bdf8c06089cfd5d5..47f0311d10064886f3aaed329e62120de887a582 100644 (file)
@@ -2896,6 +2896,12 @@ struct hci_dev *hci_alloc_dev(void)
        hdev->le_conn_max_interval = 0x0038;
        hdev->le_conn_latency = 0x0000;
        hdev->le_supv_timeout = 0x002a;
+       hdev->le_def_tx_len = 0x001b;
+       hdev->le_def_tx_time = 0x0148;
+       hdev->le_max_tx_len = 0x001b;
+       hdev->le_max_tx_time = 0x0148;
+       hdev->le_max_rx_len = 0x001b;
+       hdev->le_max_rx_time = 0x0148;
 
        hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
        hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
index a412eb1e1f6143283737013064581e71f9361dac..a3055e90a5bbfa2b1dd89212fa07ba6c7f9085c6 100644 (file)
@@ -1280,6 +1280,55 @@ static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
        memcpy(hdev->le_states, rp->le_states, 8);
 }
 
+static void hci_cc_le_read_def_data_len(struct hci_dev *hdev,
+                                       struct sk_buff *skb)
+{
+       struct hci_rp_le_read_def_data_len *rp = (void *) skb->data;
+
+       BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
+
+       if (rp->status)
+               return;
+
+       hdev->le_def_tx_len = le16_to_cpu(rp->tx_len);
+       hdev->le_def_tx_time = le16_to_cpu(rp->tx_time);
+}
+
+static void hci_cc_le_write_def_data_len(struct hci_dev *hdev,
+                                        struct sk_buff *skb)
+{
+       struct hci_cp_le_write_def_data_len *sent;
+       __u8 status = *((__u8 *) skb->data);
+
+       BT_DBG("%s status 0x%2.2x", hdev->name, status);
+
+       if (status)
+               return;
+
+       sent = hci_sent_cmd_data(hdev, HCI_OP_LE_WRITE_DEF_DATA_LEN);
+       if (!sent)
+               return;
+
+       hdev->le_def_tx_len = le16_to_cpu(sent->tx_len);
+       hdev->le_def_tx_time = le16_to_cpu(sent->tx_time);
+}
+
+static void hci_cc_le_read_max_data_len(struct hci_dev *hdev,
+                                       struct sk_buff *skb)
+{
+       struct hci_rp_le_read_max_data_len *rp = (void *) skb->data;
+
+       BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
+
+       if (rp->status)
+               return;
+
+       hdev->le_max_tx_len = le16_to_cpu(rp->tx_len);
+       hdev->le_max_tx_time = le16_to_cpu(rp->tx_time);
+       hdev->le_max_rx_len = le16_to_cpu(rp->rx_len);
+       hdev->le_max_rx_time = le16_to_cpu(rp->rx_time);
+}
+
 static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
                                           struct sk_buff *skb)
 {
@@ -2847,6 +2896,18 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
                hci_cc_le_read_supported_states(hdev, skb);
                break;
 
+       case HCI_OP_LE_READ_DEF_DATA_LEN:
+               hci_cc_le_read_def_data_len(hdev, skb);
+               break;
+
+       case HCI_OP_LE_WRITE_DEF_DATA_LEN:
+               hci_cc_le_write_def_data_len(hdev, skb);
+               break;
+
+       case HCI_OP_LE_READ_MAX_DATA_LEN:
+               hci_cc_le_read_max_data_len(hdev, skb);
+               break;
+
        case HCI_OP_WRITE_LE_HOST_SUPPORTED:
                hci_cc_write_le_host_supported(hdev, skb);
                break;