2021-04-12 08:34:27

by Kiran K

[permalink] [raw]
Subject: [PATCH v2 1/3] Bluetooth: add support to enumerate codec capabilities

add support to enumerate local supported codec capabilities

< HCI Command: Read Local Suppor.. (0x04|0x000e) plen 7
Codec: mSBC (0x05)
Logical Transport Type: 0x00
Direction: Input (Host to Controller) (0x00)
> HCI Event: Command Complete (0x0e) plen 12
Read Local Supported Codec Capabilities (0x04|0x000e) ncmd 1
Status: Success (0x00)
Number of codec capabilities: 1
Capabilities #0:
00 00 11 15 02 33

Signed-off-by: Kiran K <[email protected]>
Signed-off-by: Chethan T N <[email protected]>
Signed-off-by: Srivatsa Ravishankar <[email protected]>
---
* changes in v2
add skb->len check before accessing event data

include/net/bluetooth/hci.h | 7 ++++
net/bluetooth/hci_event.c | 68 +++++++++++++++++++++++++++++++++++++
2 files changed, 75 insertions(+)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index ea4ae551c426..e3f7771fe84f 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1314,6 +1314,13 @@ struct hci_rp_read_local_pairing_opts {
__u8 max_key_size;
} __packed;

+#define HCI_OP_READ_LOCAL_CODEC_CAPS 0x100e
+struct hci_op_read_local_codec_caps {
+ __u8 codec_id[5];
+ __u8 transport;
+ __u8 direction;
+} __packed;
+
#define HCI_OP_READ_PAGE_SCAN_ACTIVITY 0x0c1b
struct hci_rp_read_page_scan_activity {
__u8 status;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 5e99968939ce..a4b905a76c1b 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -887,6 +887,70 @@ static void hci_cc_read_data_block_size(struct hci_dev *hdev,
hdev->block_cnt, hdev->block_len);
}

+static void hci_cc_read_local_codecs(struct hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ __u8 num_codecs;
+ struct hci_op_read_local_codec_caps caps;
+
+ if (skb->len < sizeof(caps))
+ return;
+
+ bt_dev_dbg(hdev, "status 0x%2.2x", skb->data[0]);
+
+ if (skb->data[0])
+ return;
+
+ /* enumerate standard codecs */
+ skb_pull(skb, 1);
+
+ if (skb->len < 1)
+ return;
+
+ num_codecs = skb->data[0];
+
+ bt_dev_dbg(hdev, "Number of standard codecs: %u", num_codecs);
+
+ skb_pull(skb, 1);
+
+ if (skb->len < num_codecs)
+ return;
+
+ while (num_codecs--) {
+ caps.codec_id[0] = skb->data[0];
+ caps.transport = 0x00;
+ caps.direction = 0x00;
+
+ hci_send_cmd(hdev, HCI_OP_READ_LOCAL_CODEC_CAPS, sizeof(caps),
+ &caps);
+
+ skb_pull(skb, 1);
+ }
+
+ /* enumerate vendor specific codecs */
+ if (skb->len < 1)
+ return;
+
+ num_codecs = skb->data[0];
+ skb_pull(skb, 1);
+
+ bt_dev_dbg(hdev, "Number of vendor specific codecs: %u", num_codecs);
+
+ if (skb->len < (num_codecs * 4))
+ return;
+
+ while (num_codecs--) {
+ caps.codec_id[0] = 0xFF;
+ memcpy(&caps.codec_id[1], skb->data, 4);
+ caps.transport = 0x00;
+ caps.direction = 0x00;
+
+ hci_send_cmd(hdev, HCI_OP_READ_LOCAL_CODEC_CAPS, sizeof(caps),
+ &caps);
+ skb_pull(skb, 4);
+ }
+}
+
static void hci_cc_read_clock(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_rp_read_clock *rp = (void *) skb->data;
@@ -3437,6 +3501,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb,
hci_cc_read_data_block_size(hdev, skb);
break;

+ case HCI_OP_READ_LOCAL_CODECS:
+ hci_cc_read_local_codecs(hdev, skb);
+ break;
+
case HCI_OP_READ_FLOW_CONTROL_MODE:
hci_cc_read_flow_control_mode(hdev, skb);
break;
--
2.17.1


2021-04-12 08:35:52

by Kiran K

[permalink] [raw]
Subject: [PATCH v2 3/3] Bluetooth: cache local supported codec capabilities

Cache the codec information in the driver and this data can
be exposed to user space audio modules via getsockopt

Signed-off-by: Kiran K <[email protected]>
Signed-off-by: Chethan T N <[email protected]>
Signed-off-by: Srivatsa Ravishankar <[email protected]>
---
* changes in v2
add skb length check before accessing data

include/net/bluetooth/hci.h | 11 +++++++++++
include/net/bluetooth/hci_core.h | 13 ++++++++++++
net/bluetooth/hci_core.c | 31 +++++++++++++++++++++++++++++
net/bluetooth/hci_event.c | 34 ++++++++++++++++++++++++++++++++
4 files changed, 89 insertions(+)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 34eb9f4b027f..6b4344639ff7 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1323,6 +1323,17 @@ struct hci_op_read_local_codec_caps {
__u8 direction;
} __packed;

+struct hci_codec_caps {
+ __u8 len;
+ __u8 caps[];
+} __packed;
+
+struct hci_rp_read_local_codec_caps {
+ __u8 status;
+ __u8 num_caps;
+ struct hci_codec_caps caps[];
+} __packed;
+
#define HCI_OP_READ_PAGE_SCAN_ACTIVITY 0x0c1b
struct hci_rp_read_page_scan_activity {
__u8 status;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 2c19b02a805d..b40c7ed38d18 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -131,6 +131,14 @@ struct bdaddr_list {
u8 bdaddr_type;
};

+struct codec_list {
+ struct list_head list;
+ u8 transport;
+ u8 codec_id[5];
+ u8 num_caps;
+ struct hci_codec_caps caps[];
+};
+
struct bdaddr_list_with_irk {
struct list_head list;
bdaddr_t bdaddr;
@@ -534,6 +542,7 @@ struct hci_dev {
struct list_head pend_le_conns;
struct list_head pend_le_reports;
struct list_head blocked_keys;
+ struct list_head local_codecs;

struct hci_dev_stats stat;

@@ -1843,6 +1852,10 @@ void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand,

void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 *bdaddr_type);
+int hci_codec_list_add(struct list_head *list, struct hci_rp_read_local_codec_caps *rp,
+ __u32 len,
+ struct hci_op_read_local_codec_caps *sent);
+void hci_codec_list_clear(struct list_head *codec_list);

#define SCO_AIRMODE_MASK 0x0003
#define SCO_AIRMODE_CVSD 0x0000
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 230aeedd6d00..578f417d1904 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3561,6 +3561,35 @@ void hci_conn_params_clear_disabled(struct hci_dev *hdev)
BT_DBG("All LE disabled connection parameters were removed");
}

+int hci_codec_list_add(struct list_head *list, struct hci_rp_read_local_codec_caps *rp,
+ __u32 len,
+ struct hci_op_read_local_codec_caps *sent)
+{
+ struct codec_list *entry;
+
+ entry = kzalloc(sizeof(*entry) + len, GFP_KERNEL);
+ if (!entry)
+ return -ENOMEM;
+
+ memcpy(entry->codec_id, sent->codec_id, 5);
+ entry->transport = sent->transport;
+ entry->num_caps = rp->num_caps;
+ if (rp->num_caps)
+ memcpy(entry->caps, rp->caps, len);
+ list_add(&entry->list, list);
+
+ return 0;
+}
+
+void hci_codec_list_clear(struct list_head *codec_list)
+{
+ struct codec_list *c, *n;
+
+ list_for_each_entry_safe(c, n, codec_list, list) {
+ list_del(&c->list);
+ kfree(c);
+ }
+}
/* This function requires the caller holds hdev->lock */
static void hci_conn_params_clear_all(struct hci_dev *hdev)
{
@@ -3820,6 +3849,7 @@ struct hci_dev *hci_alloc_dev(void)
INIT_LIST_HEAD(&hdev->conn_hash.list);
INIT_LIST_HEAD(&hdev->adv_instances);
INIT_LIST_HEAD(&hdev->blocked_keys);
+ INIT_LIST_HEAD(&hdev->local_codecs);

INIT_WORK(&hdev->rx_work, hci_rx_work);
INIT_WORK(&hdev->cmd_work, hci_cmd_work);
@@ -4038,6 +4068,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
hci_conn_params_clear_all(hdev);
hci_discovery_filter_clear(hdev);
hci_blocked_keys_clear(hdev);
+ hci_codec_list_clear(&hdev->local_codecs);
hci_dev_unlock(hdev);

hci_dev_put(hdev);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 7ca3535f30de..f9ea3109d620 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1057,6 +1057,36 @@ static void hci_cc_read_local_codecs_v2(struct hci_dev *hdev,
}
}

+static void hci_cc_read_local_codec_caps(struct hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct hci_op_read_local_codec_caps *sent;
+ struct hci_rp_read_local_codec_caps *rp;
+
+ if (skb->len < sizeof(*rp))
+ return;
+
+ rp = (void *)skb->data;
+
+ bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
+
+ if (rp->status)
+ return;
+
+ sent = hci_sent_cmd_data(hdev, HCI_OP_READ_LOCAL_CODEC_CAPS);
+
+ if (!sent)
+ return;
+
+ hci_dev_lock(hdev);
+
+ bt_dev_info(hdev, "Adding Codec. No of caps: %u", rp->num_caps);
+
+ hci_codec_list_add(&hdev->local_codecs, rp, skb->len - 2, sent);
+
+ hci_dev_unlock(hdev);
+}
+
static void hci_cc_read_clock(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_rp_read_clock *rp = (void *) skb->data;
@@ -3615,6 +3645,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb,
hci_cc_read_local_codecs_v2(hdev, skb);
break;

+ case HCI_OP_READ_LOCAL_CODEC_CAPS:
+ hci_cc_read_local_codec_caps(hdev, skb);
+ break;
+
case HCI_OP_READ_FLOW_CONTROL_MODE:
hci_cc_read_flow_control_mode(hdev, skb);
break;
--
2.17.1

2021-04-12 21:51:36

by bluez.test.bot

[permalink] [raw]
Subject: RE: [v2,1/3] Bluetooth: add support to enumerate codec capabilities

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=465395

---Test result---

##############################
Test: CheckPatch - PASS


##############################
Test: CheckGitLint - PASS


##############################
Test: CheckBuildK - PASS


##############################
Test: CheckTestRunner: Setup - PASS


##############################
Test: CheckTestRunner: l2cap-tester - PASS
Total: 40, Passed: 34 (85.0%), Failed: 0, Not Run: 6

##############################
Test: CheckTestRunner: bnep-tester - PASS
Total: 1, Passed: 1 (100.0%), Failed: 0, Not Run: 0

##############################
Test: CheckTestRunner: mgmt-tester - FAIL
Total: 416, Passed: 394 (94.7%), Failed: 6, Not Run: 16

Failed Test Cases
Set connectable off (LE) - Success 2 Failed 0.016 seconds
Set connectable off (LE) - Success 3 Failed 0.016 seconds
Set connectable off (LE) - Success 4 Failed 0.016 seconds
Add Advertising - Success 13 (ADV_SCAN_IND) Failed 0.023 seconds
Add Advertising - Success 14 (ADV_NONCONN_IND) Failed 0.015 seconds
Add Advertising - Success 17 (Connectable -> off) Failed 0.020 seconds

##############################
Test: CheckTestRunner: rfcomm-tester - PASS
Total: 9, Passed: 9 (100.0%), Failed: 0, Not Run: 0

##############################
Test: CheckTestRunner: sco-tester - PASS
Total: 8, Passed: 8 (100.0%), Failed: 0, Not Run: 0

##############################
Test: CheckTestRunner: smp-tester - PASS
Total: 8, Passed: 8 (100.0%), Failed: 0, Not Run: 0

##############################
Test: CheckTestRunner: userchan-tester - PASS
Total: 3, Passed: 3 (100.0%), Failed: 0, Not Run: 0



---
Regards,
Linux Bluetooth


Attachments:
l2cap-tester.log (42.33 kB)
bnep-tester.log (3.45 kB)
mgmt-tester.log (534.47 kB)
rfcomm-tester.log (11.38 kB)
sco-tester.log (9.66 kB)
smp-tester.log (11.53 kB)
userchan-tester.log (5.31 kB)
Download all attachments

2021-04-13 23:18:02

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] Bluetooth: add support to enumerate codec capabilities

Hi Kiran,

> add support to enumerate local supported codec capabilities
>
> < HCI Command: Read Local Suppor.. (0x04|0x000e) plen 7
> Codec: mSBC (0x05)
> Logical Transport Type: 0x00
> Direction: Input (Host to Controller) (0x00)
>> HCI Event: Command Complete (0x0e) plen 12
> Read Local Supported Codec Capabilities (0x04|0x000e) ncmd 1
> Status: Success (0x00)
> Number of codec capabilities: 1
> Capabilities #0:
> 00 00 11 15 02 33
>
> Signed-off-by: Kiran K <[email protected]>
> Signed-off-by: Chethan T N <[email protected]>
> Signed-off-by: Srivatsa Ravishankar <[email protected]>
> ---
> * changes in v2
> add skb->len check before accessing event data
>
> include/net/bluetooth/hci.h | 7 ++++
> net/bluetooth/hci_event.c | 68 +++++++++++++++++++++++++++++++++++++
> 2 files changed, 75 insertions(+)
>
> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
> index ea4ae551c426..e3f7771fe84f 100644
> --- a/include/net/bluetooth/hci.h
> +++ b/include/net/bluetooth/hci.h
> @@ -1314,6 +1314,13 @@ struct hci_rp_read_local_pairing_opts {
> __u8 max_key_size;
> } __packed;
>
> +#define HCI_OP_READ_LOCAL_CODEC_CAPS 0x100e
> +struct hci_op_read_local_codec_caps {
> + __u8 codec_id[5];
> + __u8 transport;
> + __u8 direction;
> +} __packed;
> +
> #define HCI_OP_READ_PAGE_SCAN_ACTIVITY 0x0c1b
> struct hci_rp_read_page_scan_activity {
> __u8 status;
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index 5e99968939ce..a4b905a76c1b 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -887,6 +887,70 @@ static void hci_cc_read_data_block_size(struct hci_dev *hdev,
> hdev->block_cnt, hdev->block_len);
> }
>
> +static void hci_cc_read_local_codecs(struct hci_dev *hdev,
> + struct sk_buff *skb)
> +{
> + __u8 num_codecs;
> + struct hci_op_read_local_codec_caps caps;
> +
> + if (skb->len < sizeof(caps))
> + return;
> +
> + bt_dev_dbg(hdev, "status 0x%2.2x", skb->data[0]);
> +
> + if (skb->data[0])
> + return;
> +
> + /* enumerate standard codecs */
> + skb_pull(skb, 1);
> +
> + if (skb->len < 1)
> + return;
> +
> + num_codecs = skb->data[0];
> +
> + bt_dev_dbg(hdev, "Number of standard codecs: %u", num_codecs);
> +
> + skb_pull(skb, 1);
> +
> + if (skb->len < num_codecs)
> + return;
> +
> + while (num_codecs--) {
> + caps.codec_id[0] = skb->data[0];
> + caps.transport = 0x00;
> + caps.direction = 0x00;
> +
> + hci_send_cmd(hdev, HCI_OP_READ_LOCAL_CODEC_CAPS, sizeof(caps),
> + &caps);
> +
> + skb_pull(skb, 1);
> + }
> +
> + /* enumerate vendor specific codecs */
> + if (skb->len < 1)
> + return;
> +
> + num_codecs = skb->data[0];
> + skb_pull(skb, 1);
> +
> + bt_dev_dbg(hdev, "Number of vendor specific codecs: %u", num_codecs);
> +
> + if (skb->len < (num_codecs * 4))
> + return;
> +
> + while (num_codecs--) {
> + caps.codec_id[0] = 0xFF;
> + memcpy(&caps.codec_id[1], skb->data, 4);
> + caps.transport = 0x00;
> + caps.direction = 0x00;
> +
> + hci_send_cmd(hdev, HCI_OP_READ_LOCAL_CODEC_CAPS, sizeof(caps),
> + &caps);
> + skb_pull(skb, 4);
> + }

instead of sending hci_send_cmd here, I rather do this in a separate init stage. Since you want to cache the codec values anyway, start doing it now.

Regards

Marcel

2021-04-13 23:19:47

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCH v2 3/3] Bluetooth: cache local supported codec capabilities

Hi Kiran,

> Cache the codec information in the driver and this data can
> be exposed to user space audio modules via getsockopt
>
> Signed-off-by: Kiran K <[email protected]>
> Signed-off-by: Chethan T N <[email protected]>
> Signed-off-by: Srivatsa Ravishankar <[email protected]>
> ---
> * changes in v2
> add skb length check before accessing data
>
> include/net/bluetooth/hci.h | 11 +++++++++++
> include/net/bluetooth/hci_core.h | 13 ++++++++++++
> net/bluetooth/hci_core.c | 31 +++++++++++++++++++++++++++++
> net/bluetooth/hci_event.c | 34 ++++++++++++++++++++++++++++++++
> 4 files changed, 89 insertions(+)
>
> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
> index 34eb9f4b027f..6b4344639ff7 100644
> --- a/include/net/bluetooth/hci.h
> +++ b/include/net/bluetooth/hci.h
> @@ -1323,6 +1323,17 @@ struct hci_op_read_local_codec_caps {
> __u8 direction;
> } __packed;
>
> +struct hci_codec_caps {
> + __u8 len;
> + __u8 caps[];
> +} __packed;
> +
> +struct hci_rp_read_local_codec_caps {
> + __u8 status;
> + __u8 num_caps;
> + struct hci_codec_caps caps[];
> +} __packed;
> +
> #define HCI_OP_READ_PAGE_SCAN_ACTIVITY 0x0c1b
> struct hci_rp_read_page_scan_activity {
> __u8 status;
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index 2c19b02a805d..b40c7ed38d18 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -131,6 +131,14 @@ struct bdaddr_list {
> u8 bdaddr_type;
> };
>
> +struct codec_list {
> + struct list_head list;
> + u8 transport;
> + u8 codec_id[5];
> + u8 num_caps;
> + struct hci_codec_caps caps[];
> +};
> +
> struct bdaddr_list_with_irk {
> struct list_head list;
> bdaddr_t bdaddr;
> @@ -534,6 +542,7 @@ struct hci_dev {
> struct list_head pend_le_conns;
> struct list_head pend_le_reports;
> struct list_head blocked_keys;
> + struct list_head local_codecs;
>
> struct hci_dev_stats stat;
>
> @@ -1843,6 +1852,10 @@ void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand,
>
> void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
> u8 *bdaddr_type);
> +int hci_codec_list_add(struct list_head *list, struct hci_rp_read_local_codec_caps *rp,
> + __u32 len,
> + struct hci_op_read_local_codec_caps *sent);
> +void hci_codec_list_clear(struct list_head *codec_list);
>
> #define SCO_AIRMODE_MASK 0x0003
> #define SCO_AIRMODE_CVSD 0x0000
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index 230aeedd6d00..578f417d1904 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -3561,6 +3561,35 @@ void hci_conn_params_clear_disabled(struct hci_dev *hdev)
> BT_DBG("All LE disabled connection parameters were removed");
> }
>
> +int hci_codec_list_add(struct list_head *list, struct hci_rp_read_local_codec_caps *rp,
> + __u32 len,
> + struct hci_op_read_local_codec_caps *sent)
> +{
> + struct codec_list *entry;
> +
> + entry = kzalloc(sizeof(*entry) + len, GFP_KERNEL);
> + if (!entry)
> + return -ENOMEM;
> +
> + memcpy(entry->codec_id, sent->codec_id, 5);
> + entry->transport = sent->transport;
> + entry->num_caps = rp->num_caps;
> + if (rp->num_caps)
> + memcpy(entry->caps, rp->caps, len);
> + list_add(&entry->list, list);
> +
> + return 0;
> +}
> +
> +void hci_codec_list_clear(struct list_head *codec_list)
> +{
> + struct codec_list *c, *n;
> +
> + list_for_each_entry_safe(c, n, codec_list, list) {
> + list_del(&c->list);
> + kfree(c);
> + }
> +}
> /* This function requires the caller holds hdev->lock */
> static void hci_conn_params_clear_all(struct hci_dev *hdev)
> {
> @@ -3820,6 +3849,7 @@ struct hci_dev *hci_alloc_dev(void)
> INIT_LIST_HEAD(&hdev->conn_hash.list);
> INIT_LIST_HEAD(&hdev->adv_instances);
> INIT_LIST_HEAD(&hdev->blocked_keys);
> + INIT_LIST_HEAD(&hdev->local_codecs);
>
> INIT_WORK(&hdev->rx_work, hci_rx_work);
> INIT_WORK(&hdev->cmd_work, hci_cmd_work);
> @@ -4038,6 +4068,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
> hci_conn_params_clear_all(hdev);
> hci_discovery_filter_clear(hdev);
> hci_blocked_keys_clear(hdev);
> + hci_codec_list_clear(&hdev->local_codecs);
> hci_dev_unlock(hdev);
>
> hci_dev_put(hdev);
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index 7ca3535f30de..f9ea3109d620 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -1057,6 +1057,36 @@ static void hci_cc_read_local_codecs_v2(struct hci_dev *hdev,
> }
> }
>
> +static void hci_cc_read_local_codec_caps(struct hci_dev *hdev,
> + struct sk_buff *skb)
> +{
> + struct hci_op_read_local_codec_caps *sent;
> + struct hci_rp_read_local_codec_caps *rp;
> +
> + if (skb->len < sizeof(*rp))
> + return;
> +
> + rp = (void *)skb->data;
> +
> + bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
> +
> + if (rp->status)
> + return;
> +
> + sent = hci_sent_cmd_data(hdev, HCI_OP_READ_LOCAL_CODEC_CAPS);
> +
> + if (!sent)
> + return;
> +
> + hci_dev_lock(hdev);
> +
> + bt_dev_info(hdev, "Adding Codec. No of caps: %u", rp->num_caps);

This is a bit too verbose.

> +
> + hci_codec_list_add(&hdev->local_codecs, rp, skb->len - 2, sent);
> +
> + hci_dev_unlock(hdev);
> +}
> +
> static void hci_cc_read_clock(struct hci_dev *hdev, struct sk_buff *skb)
> {
> struct hci_rp_read_clock *rp = (void *) skb->data;
> @@ -3615,6 +3645,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb,
> hci_cc_read_local_codecs_v2(hdev, skb);
> break;
>
> + case HCI_OP_READ_LOCAL_CODEC_CAPS:
> + hci_cc_read_local_codec_caps(hdev, skb);
> + break;
> +
> case HCI_OP_READ_FLOW_CONTROL_MODE:
> hci_cc_read_flow_control_mode(hdev, skb);
> break;

Regards

Marcel

2021-04-22 14:10:59

by Kiran K

[permalink] [raw]
Subject: RE: [PATCH v2 1/3] Bluetooth: add support to enumerate codec capabilities

Hi Marcel,

Thanks for the comments. I will send out an updated version of patchset.

> -----Original Message-----
> From: Marcel Holtmann <[email protected]>
> Sent: Wednesday, April 14, 2021 12:45 AM
> To: K, Kiran <[email protected]>
> Cc: open list:BLUETOOTH DRIVERS <[email protected]>;
> Srivatsa, Ravishankar <[email protected]>; Tumkur Narayan,
> Chethan <[email protected]>; Von Dentz, Luiz
> <[email protected]>
> Subject: Re: [PATCH v2 1/3] Bluetooth: add support to enumerate codec
> capabilities
>
> Hi Kiran,
>
> > add support to enumerate local supported codec capabilities
> >
> > < HCI Command: Read Local Suppor.. (0x04|0x000e) plen 7
> > Codec: mSBC (0x05)
> > Logical Transport Type: 0x00
> > Direction: Input (Host to Controller) (0x00)
> >> HCI Event: Command Complete (0x0e) plen 12
> > Read Local Supported Codec Capabilities (0x04|0x000e) ncmd 1
> > Status: Success (0x00)
> > Number of codec capabilities: 1
> > Capabilities #0:
> > 00 00 11 15 02 33
> >
> > Signed-off-by: Kiran K <[email protected]>
> > Signed-off-by: Chethan T N <[email protected]>
> > Signed-off-by: Srivatsa Ravishankar <[email protected]>
> > ---
> > * changes in v2
> > add skb->len check before accessing event data
> >
> > include/net/bluetooth/hci.h | 7 ++++
> > net/bluetooth/hci_event.c | 68
> +++++++++++++++++++++++++++++++++++++
> > 2 files changed, 75 insertions(+)
> >
> > diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
> > index ea4ae551c426..e3f7771fe84f 100644
> > --- a/include/net/bluetooth/hci.h
> > +++ b/include/net/bluetooth/hci.h
> > @@ -1314,6 +1314,13 @@ struct hci_rp_read_local_pairing_opts {
> > __u8 max_key_size;
> > } __packed;
> >
> > +#define HCI_OP_READ_LOCAL_CODEC_CAPS 0x100e
> > +struct hci_op_read_local_codec_caps {
> > + __u8 codec_id[5];
> > + __u8 transport;
> > + __u8 direction;
> > +} __packed;
> > +
> > #define HCI_OP_READ_PAGE_SCAN_ACTIVITY 0x0c1b
> > struct hci_rp_read_page_scan_activity {
> > __u8 status;
> > diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> > index 5e99968939ce..a4b905a76c1b 100644
> > --- a/net/bluetooth/hci_event.c
> > +++ b/net/bluetooth/hci_event.c
> > @@ -887,6 +887,70 @@ static void hci_cc_read_data_block_size(struct
> hci_dev *hdev,
> > hdev->block_cnt, hdev->block_len); }
> >
> > +static void hci_cc_read_local_codecs(struct hci_dev *hdev,
> > + struct sk_buff *skb)
> > +{
> > + __u8 num_codecs;
> > + struct hci_op_read_local_codec_caps caps;
> > +
> > + if (skb->len < sizeof(caps))
> > + return;
> > +
> > + bt_dev_dbg(hdev, "status 0x%2.2x", skb->data[0]);
> > +
> > + if (skb->data[0])
> > + return;
> > +
> > + /* enumerate standard codecs */
> > + skb_pull(skb, 1);
> > +
> > + if (skb->len < 1)
> > + return;
> > +
> > + num_codecs = skb->data[0];
> > +
> > + bt_dev_dbg(hdev, "Number of standard codecs: %u", num_codecs);
> > +
> > + skb_pull(skb, 1);
> > +
> > + if (skb->len < num_codecs)
> > + return;
> > +
> > + while (num_codecs--) {
> > + caps.codec_id[0] = skb->data[0];
> > + caps.transport = 0x00;
> > + caps.direction = 0x00;
> > +
> > + hci_send_cmd(hdev, HCI_OP_READ_LOCAL_CODEC_CAPS,
> sizeof(caps),
> > + &caps);
> > +
> > + skb_pull(skb, 1);
> > + }
> > +
> > + /* enumerate vendor specific codecs */
> > + if (skb->len < 1)
> > + return;
> > +
> > + num_codecs = skb->data[0];
> > + skb_pull(skb, 1);
> > +
> > + bt_dev_dbg(hdev, "Number of vendor specific codecs: %u",
> > +num_codecs);
> > +
> > + if (skb->len < (num_codecs * 4))
> > + return;
> > +
> > + while (num_codecs--) {
> > + caps.codec_id[0] = 0xFF;
> > + memcpy(&caps.codec_id[1], skb->data, 4);
> > + caps.transport = 0x00;
> > + caps.direction = 0x00;
> > +
> > + hci_send_cmd(hdev, HCI_OP_READ_LOCAL_CODEC_CAPS,
> sizeof(caps),
> > + &caps);
> > + skb_pull(skb, 4);
> > + }
>
> instead of sending hci_send_cmd here, I rather do this in a separate init
> stage. Since you want to cache the codec values anyway, start doing it now.
>
> Regards
>
> Marcel

Regards,
Kiran