diff mbox series

[3/4] Bluetooth: Add support for sending LE PHY Update event over mgmt

Message ID 20210722053843.6691-4-ayush.garg@samsung.com
State New
Headers show
Series [1/4] Bluetooth: Fix incorrect parsing of LE_PHY params | expand

Commit Message

Ayush Garg July 22, 2021, 5:38 a.m. UTC
The HCI_LE_PHY_Update_Complete event should be sent to
upper layers in case of autonomous PHY update made by
the controller or HCI_LE_SET_PHY command succeeded.
This change will let user know immediately whenever
controller change LE PHYs for a particular connection.

> HCI Event: LE Meta Event (0x3e) plen 6
	  LE PHY Update Complete (0x0c)
		Status: Success (0x00)
		Handle: 0
		TX PHY: LE 2M (0x02)
		RX PHY: LE 2M (0x02)
@ MGMT Event: LE PHY Update Complete (0x002f) plen 12
		LE Address: 45:18:F8:CF:23:7E (Resolvable)
		Status: Success (0x00)
		Updated PHYs: 0x1800
		  LE 2M TX
		  LE 2M RX

Reviewed-by: Anupam Roy <anupam.r@samsung.com>
Signed-off-by: Ayush Garg <ayush.garg@samsung.com>
---
 include/net/bluetooth/hci_core.h |  1 +
 include/net/bluetooth/mgmt.h     |  7 +++++++
 net/bluetooth/hci_event.c        | 11 ++++++-----
 net/bluetooth/mgmt.c             | 34 ++++++++++++++++++++++++++++++++
 4 files changed, 48 insertions(+), 5 deletions(-)

Comments

Marcel Holtmann July 22, 2021, 2:43 p.m. UTC | #1
Hi Ayush,

> The HCI_LE_PHY_Update_Complete event should be sent to
> upper layers in case of autonomous PHY update made by
> the controller or HCI_LE_SET_PHY command succeeded.
> This change will let user know immediately whenever
> controller change LE PHYs for a particular connection.
> 
>> HCI Event: LE Meta Event (0x3e) plen 6
> 	  LE PHY Update Complete (0x0c)
> 		Status: Success (0x00)
> 		Handle: 0
> 		TX PHY: LE 2M (0x02)
> 		RX PHY: LE 2M (0x02)
> @ MGMT Event: LE PHY Update Complete (0x002f) plen 12
> 		LE Address: 45:18:F8:CF:23:7E (Resolvable)
> 		Status: Success (0x00)
> 		Updated PHYs: 0x1800
> 		  LE 2M TX
> 		  LE 2M RX

I am not in favor of reporting this via mgmt. It is rather pointless to send this out here. I rather prefer that this is added via auxiliary CMSG data to the GATT and all other L2CAP sockets that opted in for wanting to know.

Regards

Marcel
diff mbox series

Patch

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 257467f9d28d..3a5c310ec937 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1835,6 +1835,7 @@  void mgmt_advertising_removed(struct sock *sk, struct hci_dev *hdev,
 			      u8 instance);
 void mgmt_adv_monitor_removed(struct hci_dev *hdev, u16 handle);
 int mgmt_phy_configuration_changed(struct hci_dev *hdev, struct sock *skip);
+void mgmt_le_phy_update(struct hci_dev *hdev, struct hci_conn *conn, u8 status);
 int mgmt_add_adv_patterns_monitor_complete(struct hci_dev *hdev, u8 status);
 int mgmt_remove_adv_monitor_complete(struct hci_dev *hdev, u8 status);
 
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 23a0524061b7..54800c4883fc 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -1100,6 +1100,13 @@  struct mgmt_ev_controller_resume {
 	struct mgmt_addr_info addr;
 } __packed;
 
+#define MGMT_EV_LE_PHY_UPDATE_COMPLETE	0x002f
+struct mgmt_ev_le_phy_update_complete {
+	struct mgmt_addr_info addr;
+	__u8	status;
+	__le32	phys;
+} __packed;
+
 #define MGMT_WAKE_REASON_NON_BT_WAKE		0x0
 #define MGMT_WAKE_REASON_UNEXPECTED		0x1
 #define MGMT_WAKE_REASON_REMOTE_WAKE		0x2
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 1c3018202564..effe525e5272 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -5970,17 +5970,18 @@  static void hci_le_phy_update_evt(struct hci_dev *hdev, struct sk_buff *skb)
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
 
-	if (ev->status)
-		return;
-
 	hci_dev_lock(hdev);
 
 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
 	if (!conn)
 		goto unlock;
 
-	conn->le_tx_phy = ev->tx_phy;
-	conn->le_rx_phy = ev->rx_phy;
+	if (!ev->status) {
+		conn->le_tx_phy = ev->tx_phy;
+		conn->le_rx_phy = ev->rx_phy;
+	}
+
+	mgmt_le_phy_update(hdev, conn, ev->status);
 
 unlock:
 	hci_dev_unlock(hdev);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 3663f880df11..683e4b66f810 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -172,6 +172,7 @@  static const u16 mgmt_events[] = {
 	MGMT_EV_ADV_MONITOR_REMOVED,
 	MGMT_EV_CONTROLLER_SUSPEND,
 	MGMT_EV_CONTROLLER_RESUME,
+	MGMT_EV_LE_PHY_UPDATE_COMPLETE,
 };
 
 static const u16 mgmt_untrusted_commands[] = {
@@ -3611,6 +3612,39 @@  static int set_phy_configuration(struct sock *sk, struct hci_dev *hdev,
 	return err;
 }
 
+void mgmt_le_phy_update(struct hci_dev *hdev, struct hci_conn *conn,
+			u8 status)
+{
+	struct mgmt_ev_le_phy_update_complete ev;
+	u32 phys = 0;
+
+	memset(&ev, 0, sizeof(ev));
+
+	bacpy(&ev.addr.bdaddr, &conn->dst);
+	ev.addr.type = link_to_bdaddr(conn->type, conn->dst_type);
+
+	ev.status = status;
+
+	if (conn->le_tx_phy == HCI_LE_READ_PHY_1M)
+		phys |= MGMT_PHY_LE_1M_TX;
+	else if (conn->le_tx_phy == HCI_LE_READ_PHY_2M)
+		phys |= MGMT_PHY_LE_2M_TX;
+	else if (conn->le_tx_phy == HCI_LE_READ_PHY_CODED)
+		phys |= MGMT_PHY_LE_CODED_TX;
+
+	if (conn->le_rx_phy == HCI_LE_READ_PHY_1M)
+		phys |= MGMT_PHY_LE_1M_RX;
+	else if (conn->le_rx_phy == HCI_LE_READ_PHY_2M)
+		phys |= MGMT_PHY_LE_2M_RX;
+	else if (conn->le_rx_phy == HCI_LE_READ_PHY_CODED)
+		phys |= MGMT_PHY_LE_CODED_RX;
+
+	ev.phys = cpu_to_le32(phys);
+
+	mgmt_event(MGMT_EV_LE_PHY_UPDATE_COMPLETE, hdev, &ev, sizeof(ev),
+		   NULL);
+}
+
 static int set_blocked_keys(struct sock *sk, struct hci_dev *hdev, void *data,
 			    u16 len)
 {