2021-07-22 06:00:59

by Ayush Garg

[permalink] [raw]
Subject: [PATCH 0/4] Bluetooth: Support for LE Set Preferred PHY

Hello Maintainers,

This patch set fixes some minor bugs and adds support for
BT 5.0 PHY based HCI command "HCI_OP_LE_SET_PHY" to request
controller to change connection specific PHY settings
(2M PHY, coded PHY etc.).

Ayush Garg (4):
Bluetooth: Fix incorrect parsing of LE_PHY params
Bluetooth: Implement BT_PHY setsocket option
Bluetooth: Add support for sending LE PHY Update event over mgmt
Bluetooth: Update LE TX & RX PHYs when connection established

include/net/bluetooth/bluetooth.h | 7 +++
include/net/bluetooth/hci.h | 28 +++++++++++
include/net/bluetooth/hci_core.h | 2 +
include/net/bluetooth/mgmt.h | 7 +++
net/bluetooth/hci_conn.c | 77 ++++++++++++++++++++++++++-----
net/bluetooth/hci_event.c | 62 +++++++++++++++++++++++--
net/bluetooth/l2cap_sock.c | 21 ++++++++-
net/bluetooth/mgmt.c | 34 ++++++++++++++
8 files changed, 220 insertions(+), 18 deletions(-)

--
2.17.1


2021-07-22 06:01:18

by Ayush Garg

[permalink] [raw]
Subject: [PATCH 1/4] Bluetooth: Fix incorrect parsing of LE_PHY params

This change is fixing the parsing of PHY LE CODED which is
represented with value 0x03 instead of 0x04 in LE PHY Update
Complete event.

> HCI Event: LE Meta Event (0x3e) plen 6
LE PHY Update Complete (0x0c)
Status: Success (0x00)
Handle: 0
TX PHY: LE Coded (0x03)
RX PHY: LE Coded (0x03)

Reviewed-by: Anupam Roy <[email protected]>
Signed-off-by: Ayush Garg <[email protected]>
---
include/net/bluetooth/hci.h | 4 ++++
net/bluetooth/hci_conn.c | 21 +++++++++------------
2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index b80415011dcd..56542a09ec43 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1681,6 +1681,10 @@ struct hci_cp_le_set_default_phy {
#define HCI_LE_SET_PHY_2M 0x02
#define HCI_LE_SET_PHY_CODED 0x04

+#define HCI_LE_READ_PHY_1M 0x01
+#define HCI_LE_READ_PHY_2M 0x02
+#define HCI_LE_READ_PHY_CODED 0x03
+
#define HCI_OP_LE_SET_EXT_SCAN_PARAMS 0x2041
struct hci_cp_le_set_ext_scan_params {
__u8 own_addr_type;
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 2b5059a56cda..383efd969840 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -1915,22 +1915,19 @@ u32 hci_conn_get_phy(struct hci_conn *conn)
break;

case LE_LINK:
- if (conn->le_tx_phy & HCI_LE_SET_PHY_1M)
- phys |= BT_PHY_LE_1M_TX;
-
- if (conn->le_rx_phy & HCI_LE_SET_PHY_1M)
- phys |= BT_PHY_LE_1M_RX;

- if (conn->le_tx_phy & HCI_LE_SET_PHY_2M)
+ if (conn->le_tx_phy == HCI_LE_READ_PHY_1M)
+ phys |= BT_PHY_LE_1M_TX;
+ else if (conn->le_tx_phy == HCI_LE_READ_PHY_2M)
phys |= BT_PHY_LE_2M_TX;
-
- if (conn->le_rx_phy & HCI_LE_SET_PHY_2M)
- phys |= BT_PHY_LE_2M_RX;
-
- if (conn->le_tx_phy & HCI_LE_SET_PHY_CODED)
+ else if (conn->le_tx_phy == HCI_LE_READ_PHY_CODED)
phys |= BT_PHY_LE_CODED_TX;

- if (conn->le_rx_phy & HCI_LE_SET_PHY_CODED)
+ if (conn->le_rx_phy == HCI_LE_READ_PHY_1M)
+ phys |= BT_PHY_LE_1M_RX;
+ else if (conn->le_rx_phy == HCI_LE_READ_PHY_2M)
+ phys |= BT_PHY_LE_2M_RX;
+ else if (conn->le_rx_phy == HCI_LE_READ_PHY_CODED)
phys |= BT_PHY_LE_CODED_RX;

break;
--
2.17.1

2021-07-22 06:01:31

by Ayush Garg

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

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 <[email protected]g.com>
Signed-off-by: Ayush Garg <[email protected]>
---
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(-)

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)
{
--
2.17.1

2021-07-22 06:01:48

by Ayush Garg

[permalink] [raw]
Subject: [PATCH 4/4] Bluetooth: Update LE TX & RX PHYs when connection established

The TX and RX PHYs will always be 1M if the established LE
connection is a legacy connection. These values may
differ in case of LE Extended connection.
This change will read and update the connection PHYs and
autonomously send LE PHY Update event if the connection
is LE Extended.

< HCI Command: LE Read PHY (0x08|0x0030) plen 2
Handle: 0
> HCI Event: Command Complete (0x0e) plen 8
LE Read PHY (0x08|0x0030) ncmd 1
Status: Success (0x00)
Handle: 0
TX PHY: LE 1M (0x01)
RX PHY: LE 1M (0x01)
@ MGMT Event: LE PHY Update Complete (0x002f) plen 12
LE Address: 45:18:F8:CF:23:7E (Resolvable)
Status: Success (0x00)
Updated PHYs: 0x0600
LE 1M TX
LE 1M RX

Reviewed-by: Anupam Roy <[email protected]>
Signed-off-by: Ayush Garg <[email protected]>
---
include/net/bluetooth/hci.h | 12 +++++++++
net/bluetooth/hci_event.c | 51 +++++++++++++++++++++++++++++++++++++
2 files changed, 63 insertions(+)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 06e10ccf2a1c..6073e8431ed5 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1670,6 +1670,18 @@ struct hci_rp_le_read_max_data_len {
__le16 rx_time;
} __packed;

+#define HCI_OP_LE_READ_PHY 0x2030
+struct hci_cp_le_read_phy {
+ __le16 handle;
+} __packed;
+
+struct hci_rp_le_read_phy {
+ __u8 status;
+ __le16 handle;
+ __u8 tx_phy;
+ __u8 rx_phy;
+} __packed;
+
#define HCI_OP_LE_SET_DEFAULT_PHY 0x2031
struct hci_cp_le_set_default_phy {
__u8 all_phys;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index effe525e5272..37ab2f2a1d06 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1196,6 +1196,31 @@ static void hci_cc_le_set_default_phy(struct hci_dev *hdev, struct sk_buff *skb)
hci_dev_unlock(hdev);
}

+static void hci_cc_le_read_phy(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_rp_le_read_phy *rp = (void *)skb->data;
+ struct hci_conn *conn;
+
+ BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
+
+ if (rp->status)
+ return;
+
+ hci_dev_lock(hdev);
+
+ conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
+ if (!conn)
+ goto unlock;
+
+ conn->le_tx_phy = rp->tx_phy;
+ conn->le_rx_phy = rp->rx_phy;
+
+ mgmt_le_phy_update(hdev, conn, 0);
+
+unlock:
+ hci_dev_unlock(hdev);
+}
+
static void hci_cc_le_set_adv_set_random_addr(struct hci_dev *hdev,
struct sk_buff *skb)
{
@@ -3642,6 +3667,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb,
hci_cc_le_read_transmit_power(hdev, skb);
break;

+ case HCI_OP_LE_READ_PHY:
+ hci_cc_le_read_phy(hdev, skb);
+ break;
+
default:
BT_DBG("%s opcode 0x%4.4x", hdev->name, *opcode);
break;
@@ -5229,6 +5258,17 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
goto unlock;
}

+ /* If this LE connection is not an extended connection, then LE
+ * PHYs will always be 1M at the time of connection establishment.
+ * So, set 1M as initial LE PHY values.
+ * But if this is LE Extended connection, then the PHY values
+ * can be 1M, 2M or CODED. So, In this case, read and update
+ * the values after the conn->state becomes connected and
+ * then, send the LE_PHY_UPDATE_COMPLETE event.
+ */
+ conn->le_tx_phy = HCI_LE_SET_PHY_1M;
+ conn->le_rx_phy = HCI_LE_SET_PHY_1M;
+
if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
mgmt_device_connected(hdev, conn, NULL, 0);

@@ -5267,6 +5307,17 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
hci_connect_cfm(conn, status);
}

+ /* If this is LE Extended connection and HCI_LE_READ_PHY
+ * command is supported, then update the LE PHYs.
+ */
+ if (use_ext_conn(hdev) && hdev->commands[35] & 0x10) {
+ struct hci_cp_le_read_phy cp;
+
+ cp.handle = __cpu_to_le16(conn->handle);
+
+ hci_send_cmd(hdev, HCI_OP_LE_READ_PHY, sizeof(cp), &cp);
+ }
+
params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst,
conn->dst_type);
if (params) {
--
2.17.1

2021-07-22 07:22:13

by bluez.test.bot

[permalink] [raw]
Subject: RE: Bluetooth: Support for LE Set Preferred PHY

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=519481

---Test result---

Test Summary:
CheckPatch PASS 3.62 seconds
GitLint FAIL 0.49 seconds
BuildKernel PASS 675.81 seconds
TestRunner: Setup PASS 439.04 seconds
TestRunner: l2cap-tester PASS 3.18 seconds
TestRunner: bnep-tester PASS 2.18 seconds
TestRunner: mgmt-tester PASS 34.44 seconds
TestRunner: rfcomm-tester PASS 2.46 seconds
TestRunner: sco-tester PASS 2.34 seconds
TestRunner: smp-tester FAIL 2.54 seconds
TestRunner: userchan-tester PASS 2.24 seconds

Details
##############################
Test: CheckPatch - PASS - 3.62 seconds
Run checkpatch.pl script with rule in .checkpatch.conf


##############################
Test: GitLint - FAIL - 0.49 seconds
Run gitlint with rule in .gitlint
Bluetooth: Fix incorrect parsing of LE_PHY params
8: B3 Line contains hard tab characters (\t): " LE PHY Update Complete (0x0c)"
9: B3 Line contains hard tab characters (\t): " Status: Success (0x00)"
10: B3 Line contains hard tab characters (\t): " Handle: 0"
11: B3 Line contains hard tab characters (\t): " TX PHY: LE Coded (0x03)"
12: B3 Line contains hard tab characters (\t): " RX PHY: LE Coded (0x03)"

Bluetooth: Implement BT_PHY setsocket option
7: B3 Line contains hard tab characters (\t): " Handle: 0"
8: B3 Line contains hard tab characters (\t): " All PHYs preference: 0x00"
9: B3 Line contains hard tab characters (\t): " TX PHYs preference: 0x02"
10: B3 Line contains hard tab characters (\t): " LE 2M"
11: B3 Line contains hard tab characters (\t): " RX PHYs preference: 0x02"
12: B3 Line contains hard tab characters (\t): " LE 2M"
13: B3 Line contains hard tab characters (\t): " PHY options preference: Reserved (0x0000)"
15: B3 Line contains hard tab characters (\t): " LE Set PHY (0x08|0x0032) ncmd 1"
16: B3 Line contains hard tab characters (\t): " Status: Success (0x00)"
18: B3 Line contains hard tab characters (\t): " LE PHY Update Complete (0x0c)"
19: B3 Line contains hard tab characters (\t): " Status: Success (0x00)"
20: B3 Line contains hard tab characters (\t): " Handle: 0"
21: B3 Line contains hard tab characters (\t): " TX PHY: LE 2M (0x02)"
22: B3 Line contains hard tab characters (\t): " RX PHY: LE 2M (0x02)"

Bluetooth: Add support for sending LE PHY Update event over mgmt
10: B3 Line contains hard tab characters (\t): " LE PHY Update Complete (0x0c)"
11: B3 Line contains hard tab characters (\t): " Status: Success (0x00)"
12: B3 Line contains hard tab characters (\t): " Handle: 0"
13: B3 Line contains hard tab characters (\t): " TX PHY: LE 2M (0x02)"
14: B3 Line contains hard tab characters (\t): " RX PHY: LE 2M (0x02)"
16: B3 Line contains hard tab characters (\t): " LE Address: 45:18:F8:CF:23:7E (Resolvable)"
17: B3 Line contains hard tab characters (\t): " Status: Success (0x00)"
18: B3 Line contains hard tab characters (\t): " Updated PHYs: 0x1800"
19: B3 Line contains hard tab characters (\t): " LE 2M TX"
20: B3 Line contains hard tab characters (\t): " LE 2M RX"

Bluetooth: Update LE TX & RX PHYs when connection established
11: B3 Line contains hard tab characters (\t): " Handle: 0"
13: B3 Line contains hard tab characters (\t): " LE Read PHY (0x08|0x0030) ncmd 1"
14: B3 Line contains hard tab characters (\t): " Status: Success (0x00)"
15: B3 Line contains hard tab characters (\t): " Handle: 0"
16: B3 Line contains hard tab characters (\t): " TX PHY: LE 1M (0x01)"
17: B3 Line contains hard tab characters (\t): " RX PHY: LE 1M (0x01)"
19: B3 Line contains hard tab characters (\t): " LE Address: 45:18:F8:CF:23:7E (Resolvable)"
20: B3 Line contains hard tab characters (\t): " Status: Success (0x00)"
21: B3 Line contains hard tab characters (\t): " Updated PHYs: 0x0600"
22: B3 Line contains hard tab characters (\t): " LE 1M TX"
23: B3 Line contains hard tab characters (\t): " LE 1M RX"


##############################
Test: BuildKernel - PASS - 675.81 seconds
Build Kernel with minimal configuration supports Bluetooth


##############################
Test: TestRunner: Setup - PASS - 439.04 seconds
Setup environment for running Test Runner


##############################
Test: TestRunner: l2cap-tester - PASS - 3.18 seconds
Run test-runner with l2cap-tester
Total: 40, Passed: 40 (100.0%), Failed: 0, Not Run: 0

##############################
Test: TestRunner: bnep-tester - PASS - 2.18 seconds
Run test-runner with bnep-tester
Total: 1, Passed: 1 (100.0%), Failed: 0, Not Run: 0

##############################
Test: TestRunner: mgmt-tester - PASS - 34.44 seconds
Run test-runner with mgmt-tester
Total: 448, Passed: 445 (99.3%), Failed: 0, Not Run: 3

##############################
Test: TestRunner: rfcomm-tester - PASS - 2.46 seconds
Run test-runner with rfcomm-tester
Total: 9, Passed: 9 (100.0%), Failed: 0, Not Run: 0

##############################
Test: TestRunner: sco-tester - PASS - 2.34 seconds
Run test-runner with sco-tester
Total: 8, Passed: 8 (100.0%), Failed: 0, Not Run: 0

##############################
Test: TestRunner: smp-tester - FAIL - 2.54 seconds
Run test-runner with smp-tester
Total: 8, Passed: 7 (87.5%), Failed: 1, Not Run: 0

Failed Test Cases
SMP Client - SC Request 2 Failed 0.036 seconds

##############################
Test: TestRunner: userchan-tester - PASS - 2.24 seconds
Run test-runner with userchan-tester
Total: 3, Passed: 3 (100.0%), Failed: 0, Not Run: 0



---
Regards,
Linux Bluetooth


Attachments:
l2cap-tester.log (43.31 kB)
bnep-tester.log (3.47 kB)
mgmt-tester.log (602.37 kB)
rfcomm-tester.log (11.40 kB)
sco-tester.log (9.68 kB)
smp-tester.log (11.43 kB)
userchan-tester.log (5.33 kB)
Download all attachments

2021-07-22 14:44:24

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCH 3/4] Bluetooth: Add support for sending LE PHY Update event over mgmt

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