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