From: "K, Kiran" <kiran.k@intel.com>
To: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
Cc: "linux-bluetooth@vger.kernel.org"
<linux-bluetooth@vger.kernel.org>,
"Tumkur Narayan, Chethan" <chethan.tumkur.narayan@intel.com>,
"Srivatsa, Ravishankar" <ravishankar.srivatsa@intel.com>
Subject: RE: [PATCH v10 01/10] Bluetooth: Enumerate local supported codec and cache details
Date: Tue, 27 Jul 2021 06:56:19 +0000 [thread overview]
Message-ID: <DM8PR11MB55738B99F01D5BCFD37AEE49F5E99@DM8PR11MB5573.namprd11.prod.outlook.com> (raw)
In-Reply-To: <CABBYNZJ3Gy7u0Erqmbn=8X6Rko=4kmmjx_Cg9c-U=CVYsyJ-bA@mail.gmail.com>
Hi Luiz,
> > #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 a53e94459ecd..7b8d603358b9 100644
> > --- a/include/net/bluetooth/hci_core.h
> > +++ b/include/net/bluetooth/hci_core.h
> > @@ -131,6 +131,19 @@ struct bdaddr_list {
> > u8 bdaddr_type;
> > };
> >
> > +#if IS_ENABLED(CONFIG_BT_OFFLOAD_CODECS)
> > +struct codec_list {
> > + struct list_head list;
> > + u8 id;
> > + __le16 cid;
> > + __le16 vid;
>
> I wonder why you are not storing these fields in host byte order?
> Looks odd since everything else is using host order.
Ack. I will change this to host order.
>
> > + u8 transport;
> > + u8 num_caps;
> > + u32 len;
> > + struct hci_codec_caps caps[];
> > +};
> > +#endif
> > +
> > struct bdaddr_list_with_irk {
> > struct list_head list;
> > bdaddr_t bdaddr;
> > @@ -535,6 +548,9 @@ struct hci_dev {
> > struct list_head pend_le_conns;
> > struct list_head pend_le_reports;
> > struct list_head blocked_keys;
> > +#if IS_ENABLED(CONFIG_BT_OFFLOAD_CODECS)
> > + struct list_head local_codecs;
> > +#endif
>
> I wonder if this is preferable over just leaving the local_codecs empty as we
> would probably just save a couple of bytes here but when using
> preprocessor #if that means we can no longer use IS_ENABLED directly inside
> the C statements.
Ack.
>
> >
> > struct hci_dev_stats stat;
> >
> > @@ -1849,4 +1865,11 @@ void hci_copy_identity_address(struct hci_dev
> *hdev, bdaddr_t *bdaddr,
> > #define SCO_AIRMODE_CVSD 0x0000
> > #define SCO_AIRMODE_TRANSP 0x0003
> >
> > +#if IS_ENABLED(CONFIG_BT_OFFLOAD_CODECS)
> > +#define LOCAL_CODEC_ACL_MASK BIT(0)
> > +#define LOCAL_CODEC_SCO_MASK BIT(1)
> > +
> > +#define TRANSPORT_TYPE_MAX 0x04
>
> Ditto, Id just have these defines all the time.
Ack
>
> > +#endif
> > +
> > #endif /* __HCI_CORE_H */
> > diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index
> > e0ab4cd7afc3..1069623f36c4 100644
> > --- a/net/bluetooth/Kconfig
> > +++ b/net/bluetooth/Kconfig
> > @@ -92,6 +92,17 @@ config BT_LEDS
> > This option selects a few LED triggers for different
> > Bluetooth events.
> >
> > +config BT_OFFLOAD_CODECS
> > + bool "Enable offload codecs"
> > + depends on BT && BT_BREDR
> > + default n
> > + help
> > + This option enables offload codecs if controller supports.
> > + When this option is enabled, user space audio modules can
> > + query offload codecs and can set the codec to be used for
> > + specific use case.
>
> I would have named this BT_HCI_CODECS.
I believe in 10/10 patch, Marcel and you agreed to not to have Kconfig altogether.
>
> > +
> > config BT_MSFTEXT
> > bool "Enable Microsoft extensions"
> > depends on BT
> > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index
> > 2560ed2f144d..2657d84e8240 100644
> > --- a/net/bluetooth/hci_core.c
> > +++ b/net/bluetooth/hci_core.c
> > @@ -838,10 +838,6 @@ static int hci_init4_req(struct hci_request *req,
> unsigned long opt)
> > if (hdev->commands[22] & 0x04)
> > hci_set_event_mask_page_2(req);
> >
> > - /* Read local codec list if the HCI command is supported */
> > - if (hdev->commands[29] & 0x20)
> > - hci_req_add(req, HCI_OP_READ_LOCAL_CODECS, 0, NULL);
> > -
> > /* Read local pairing options if the HCI command is supported */
> > if (hdev->commands[41] & 0x08)
> > hci_req_add(req, HCI_OP_READ_LOCAL_PAIRING_OPTS, 0,
> > NULL); @@ -907,6 +903,197 @@ static int hci_init4_req(struct hci_request
> *req, unsigned long opt)
> > return 0;
> > }
> >
> > +#if IS_ENABLED(CONFIG_BT_OFFLOAD_CODECS)
> > +static int hci_codec_list_add(struct list_head *list,
> > + struct hci_op_read_local_codec_caps *sent,
> > + struct hci_rp_read_local_codec_caps *rp,
> > + void *caps,
> > + __u32 len) {
> > + struct codec_list *entry;
> > +
> > + entry = kzalloc(sizeof(*entry) + len, GFP_KERNEL);
> > + if (!entry)
> > + return -ENOMEM;
> > +
> > + entry->id = sent->id;
> > + if (sent->id == 0xFF) {
> > + entry->cid = __le16_to_cpu(sent->cid);
> > + entry->vid = __le16_to_cpu(sent->vid);
> > + }
> > + entry->transport = sent->transport;
> > + entry->len = len;
> > + entry->num_caps = rp->num_caps;
> > + if (rp->num_caps)
> > + memcpy(entry->caps, caps, len);
> > + list_add(&entry->list, list);
> > +
> > + return 0;
> > +}
> > +
> > +static 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);
> > + }
> > +}
> > +
> > +static void hci_read_codec_capabilities(struct hci_dev *hdev, void
> *codec_id,
> > + __u8 transport, bool
> > +is_vnd_codec) {
> > + struct hci_op_read_local_codec_caps cmd;
> > + __u8 i;
> > +
> > + memset(&cmd, 0, sizeof(cmd));
> > +
> > + if (is_vnd_codec) {
> > + struct hci_vnd_codec *vnd_codec;
> > +
> > + vnd_codec = codec_id;
> > + cmd.id = 0xFF;
> > + cmd.cid = vnd_codec->cid;
> > + cmd.vid = vnd_codec->vid;
> > + } else {
> > + cmd.id = *(__u8 *)codec_id;
> > + }
> > +
> > + cmd.direction = 0x00;
> > +
> > + for (i = 0; i < TRANSPORT_TYPE_MAX; i++) {
> > + if (transport & BIT(i)) {
> > + struct hci_rp_read_local_codec_caps *rp;
> > + struct hci_codec_caps *caps;
> > + struct sk_buff *skb;
> > + __u8 j;
> > + __u32 len;
> > +
> > + cmd.transport = i;
> > + skb = __hci_cmd_sync(hdev,
> HCI_OP_READ_LOCAL_CODEC_CAPS,
> > + sizeof(cmd), &cmd,
> > + HCI_CMD_TIMEOUT);
> > + if (IS_ERR(skb)) {
> > + bt_dev_err(hdev, "Failed to read codec capabilities
> (%ld)",
> > + PTR_ERR(skb));
> > + continue;
> > + }
> > +
> > + if (skb->len < sizeof(*rp))
> > + goto error;
> > +
> > + rp = (void *)skb->data;
> > +
> > + if (rp->status)
> > + goto error;
> > +
> > + if (!rp->num_caps) {
> > + len = 0;
> > + /* this codec doesn't have capabilities */
> > + goto skip_caps_parse;
> > + }
> > +
> > + skb_pull(skb, sizeof(*rp));
> > +
> > + for (j = 0, len = 0; j < rp->num_caps; j++) {
> > + caps = (void *)skb->data;
> > + if (skb->len < sizeof(*caps))
> > + goto error;
> > + if (skb->len < caps->len)
> > + goto error;
> > + len += sizeof(caps->len) + caps->len;
> > + skb_pull(skb, sizeof(caps->len) + caps->len);
> > + }
> > +
> > +skip_caps_parse:
> > + hci_dev_lock(hdev);
> > + hci_codec_list_add(&hdev->local_codecs, &cmd, rp,
> > + (__u8 *)rp + sizeof(*rp), len);
> > + hci_dev_unlock(hdev);
> > +error:
> > + kfree_skb(skb);
> > + }
> > + }
> > +}
> > +
> > +static void hci_codec_list_parse(struct hci_dev *hdev, __u8 num_codecs,
> > + void *codec_list, bool is_vnd_codec)
> > +{
> > + __u8 i;
> > +
> > + for (i = 0; i < num_codecs; i++) {
> > + if (!is_vnd_codec) {
> > + struct hci_std_codecs *codecs = codec_list;
> > +
> > + hci_read_codec_capabilities(hdev, &codecs->codec[i],
> > + LOCAL_CODEC_ACL_MASK,
> > + is_vnd_codec);
> > + } else {
> > + struct hci_vnd_codecs *codecs = codec_list;
> > +
> > + hci_read_codec_capabilities(hdev, &codecs->codec[i],
> > + LOCAL_CODEC_ACL_MASK,
> > + is_vnd_codec);
> > + }
> > + }
> > +}
> > +
> > +static void hci_read_supported_codecs(struct hci_dev *hdev) {
> > + struct sk_buff *skb;
> > + struct hci_rp_read_local_supported_codecs *rp;
> > + struct hci_std_codecs *std_codecs;
> > + struct hci_vnd_codecs *vnd_codecs;
> > +
> > + skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_CODECS, 0, NULL,
> > + HCI_CMD_TIMEOUT);
> > +
> > + if (IS_ERR(skb)) {
> > + bt_dev_err(hdev, "Failed to read local supported codecs (%ld)",
> > + PTR_ERR(skb));
> > + return;
> > + }
> > +
> > + if (skb->len < sizeof(*rp))
> > + goto error;
> > +
> > + rp = (void *)skb->data;
> > +
> > + if (rp->status)
> > + goto error;
> > +
> > + skb_pull(skb, sizeof(rp->status));
> > +
> > + std_codecs = (void *)skb->data;
> > +
> > + /* validate codecs length before accessing */
> > + if (skb->len < flex_array_size(std_codecs, codec, std_codecs->num)
> > + + sizeof(std_codecs->num))
> > + goto error;
> > +
> > + /* enumerate codec capabilities of standard codecs */
> > + hci_codec_list_parse(hdev, std_codecs->num, std_codecs,
> > + false);
> > +
> > + skb_pull(skb, flex_array_size(std_codecs, codec, std_codecs->num)
> > + + sizeof(std_codecs->num));
> > +
> > + vnd_codecs = (void *)skb->data;
> > +
> > + /* validate vendor codecs length before accessing */
> > + if (skb->len <
> > + flex_array_size(vnd_codecs, codec, vnd_codecs->num)
> > + + sizeof(vnd_codecs->num))
> > + goto error;
> > +
> > + /* enumerate vendor codec capabilities */
> > + hci_codec_list_parse(hdev, vnd_codecs->num, vnd_codecs, true);
> > +
> > +error:
> > + kfree_skb(skb);
> > +}
> > +#endif
>
> We might as well move these to hci_codec.c so we just enable/disable via
> Makefile, hci_core.c is getting a little too convoluted handling so many things.
>
> > static int __hci_init(struct hci_dev *hdev) {
> > int err;
> > @@ -937,6 +1124,12 @@ static int __hci_init(struct hci_dev *hdev)
> > if (err < 0)
> > return err;
> >
> > +#if IS_ENABLED(CONFIG_BT_OFFLOAD_CODECS)
> > + /* Read local codec list if the HCI command is supported */
> > + if (hdev->commands[29] & 0x20)
> > + hci_read_supported_codecs(hdev); #endif
> > +
> > /* This function is only called when the controller is actually in
> > * configured state. When the controller is marked as unconfigured,
> > * this initialization procedure is not run.
> > @@ -1841,6 +2034,9 @@ int hci_dev_do_close(struct hci_dev *hdev)
> > memset(hdev->eir, 0, sizeof(hdev->eir));
> > memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
> > bacpy(&hdev->random_addr, BDADDR_ANY);
> > +#if IS_ENABLED(CONFIG_BT_OFFLOAD_CODECS)
> > + hci_codec_list_clear(&hdev->local_codecs);
> > +#endif
> >
> > hci_req_sync_unlock(hdev);
> >
> > @@ -3843,6 +4039,9 @@ struct hci_dev *hci_alloc_dev(void)
> > INIT_LIST_HEAD(&hdev->adv_instances);
> > INIT_LIST_HEAD(&hdev->blocked_keys);
> >
> > +#if IS_ENABLED(CONFIG_BT_OFFLOAD_CODECS)
> > + INIT_LIST_HEAD(&hdev->local_codecs);
> > +#endif
> > INIT_WORK(&hdev->rx_work, hci_rx_work);
> > INIT_WORK(&hdev->cmd_work, hci_cmd_work);
> > INIT_WORK(&hdev->tx_work, hci_tx_work);
> > --
> > 2.17.1
> >
>
>
> --
> Luiz Augusto von Dentz
Thanks,
Kiran
prev parent reply other threads:[~2021-07-27 6:56 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-30 8:07 [PATCH v10 01/10] Bluetooth: Enumerate local supported codec and cache details Kiran K
2021-06-30 8:07 ` [PATCH v10 02/10] Bluetooth: Add support for Read Local Supported Codecs V2 Kiran K
2021-06-30 8:08 ` [PATCH v10 03/10] Bluetooth: btintel: Read supported offload usecases Kiran K
2021-06-30 8:08 ` [PATCH v10 04/10] Bluetooth: Allow querying of supported offload codecs over SCO socket Kiran K
2021-06-30 8:08 ` [PATCH v10 05/10] Bluetooth: btintel: Define callback to fetch data_path_id Kiran K
2021-06-30 8:08 ` [PATCH v10 06/10] Bluetooth: Allow setting of codec for HFP offload usecase Kiran K
2021-06-30 8:08 ` [PATCH v10 07/10] Bluetooth: btintel: Define a callback to fetch codec config data Kiran K
2021-06-30 8:08 ` [PATCH v10 08/10] Bluetooth: Add support for HCI_Enhanced_Setup_Synchronous_Connection command Kiran K
2021-06-30 20:39 ` Luiz Augusto von Dentz
2021-07-27 7:19 ` K, Kiran
2021-06-30 8:08 ` [PATCH v10 09/10] Bluetooth: Add support for msbc coding format Kiran K
2021-06-30 8:08 ` [PATCH v10 10/10] Bluetooth: Add offload feature under experimental flag Kiran K
2021-06-30 19:56 ` Luiz Augusto von Dentz
2021-07-22 14:01 ` Marcel Holtmann
2021-07-22 17:42 ` Luiz Augusto von Dentz
2021-07-22 17:59 ` Marcel Holtmann
2021-07-22 18:07 ` Luiz Augusto von Dentz
2021-07-22 18:50 ` Marcel Holtmann
2021-07-27 7:21 ` K, Kiran
2021-06-30 9:12 ` [v10,01/10] Bluetooth: Enumerate local supported codec and cache details bluez.test.bot
2021-06-30 20:15 ` [PATCH v10 01/10] " Luiz Augusto von Dentz
2021-07-27 6:56 ` K, Kiran [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=DM8PR11MB55738B99F01D5BCFD37AEE49F5E99@DM8PR11MB5573.namprd11.prod.outlook.com \
--to=kiran.k@intel.com \
--cc=chethan.tumkur.narayan@intel.com \
--cc=linux-bluetooth@vger.kernel.org \
--cc=luiz.dentz@gmail.com \
--cc=ravishankar.srivatsa@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).