Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 60e77321 authored by Johan Hedberg's avatar Johan Hedberg Committed by Gustavo Padovan
Browse files

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: default avatarJohan Hedberg <johan.hedberg@intel.com>
Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
parent 5d0846d4
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -152,6 +152,7 @@ struct hci_dev {
	__u8		minor_class;
	__u8		features[8];
	__u8		host_features[8];
	__u8		le_features[8];
	__u8		commands[64];
	__u8		hci_ver;
	__u16		hci_rev;
+20 −0
Original line number Diff line number Diff line
@@ -609,6 +609,9 @@ static void le_setup(struct hci_dev *hdev)
	/* Read LE Buffer Size */
	hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);

	/* Read LE Local Supported Features */
	hci_send_cmd(hdev, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);

	/* Read LE Advertising Channel TX Power */
	hci_send_cmd(hdev, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
}
@@ -1090,6 +1093,19 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
	hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
}

static void hci_cc_le_read_local_features(struct hci_dev *hdev,
					  struct sk_buff *skb)
{
	struct hci_rp_le_read_local_features *rp = (void *) skb->data;

	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);

	if (!rp->status)
		memcpy(hdev->le_features, rp->features, 8);

	hci_req_complete(hdev, HCI_OP_LE_READ_LOCAL_FEATURES, rp->status);
}

static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
					struct sk_buff *skb)
{
@@ -2628,6 +2644,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
		hci_cc_le_read_buffer_size(hdev, skb);
		break;

	case HCI_OP_LE_READ_LOCAL_FEATURES:
		hci_cc_le_read_local_features(hdev, skb);
		break;

	case HCI_OP_LE_READ_ADV_TX_POWER:
		hci_cc_le_read_adv_tx_power(hdev, skb);
		break;