Hi Luiz, > > Hi Kiran, > > On Sun, Nov 14, 2021 at 10:44 PM Kiran K <kiran.k@xxxxxxxxx> wrote: > > > > In A2DP offload use case, controller needs to configured with selected > > codec capabilities, dcid of media transport channel and ACL connection > > handle. > > > > Controller responds with avdtp handle which needs to be sent in other > > avdtp commands like start, suspend and close. > > > > Signed-off-by: Kiran K <kiran.k@xxxxxxxxx> > > Reviewed-by: Chethan T N <chethan.tumkur.narayan@xxxxxxxxx> > > Reviewed-by: Srivatsa Ravishankar <ravishankar.srivatsa@xxxxxxxxx> > > --- > > include/net/bluetooth/bluetooth.h | 2 ++ > > include/net/bluetooth/hci.h | 16 ++++++++++++ > > net/bluetooth/hci_codec.c | 43 +++++++++++++++++++++++++++++++ > > net/bluetooth/hci_codec.h | 4 +++ > > net/bluetooth/l2cap_sock.c | 24 +++++++++++++++++ > > 5 files changed, 89 insertions(+) > > > > diff --git a/include/net/bluetooth/bluetooth.h > > b/include/net/bluetooth/bluetooth.h > > index 2f31e571f34c..5e07cfed941d 100644 > > --- a/include/net/bluetooth/bluetooth.h > > +++ b/include/net/bluetooth/bluetooth.h > > @@ -177,6 +177,8 @@ struct bt_codecs { > > #define BT_CODEC_TRANSPARENT 0x03 > > #define BT_CODEC_MSBC 0x05 > > > > +#define BT_MSFT_OPEN 20 > > I rather not have each command as a different sockopt, instead I would > suggest just one opcode and a internal header for each command so we > don't pollute too much our sockopt space since this only really apply to MSFT > I guess calling it BT_MSFT should be fine, also Id make it extensible so we > have a header and a flexible payload in case more commands needs to be > added. Agree. I will send an updated patch. > > > __printf(1, 2) > > void bt_info(const char *fmt, ...); > > __printf(1, 2) > > diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h > > index 7ea1bfce204f..a7dad0125c10 100644 > > --- a/include/net/bluetooth/hci.h > > +++ b/include/net/bluetooth/hci.h > > @@ -2009,6 +2009,22 @@ struct hci_cp_le_reject_cis { > > __u8 reason; > > } __packed; > > > > +#define HCI_MSFT_AVDTP_CMD 0xfc1e > > + > > +#define HCI_MSFT_AVDTP_OPEN 0x08 > > +struct hci_media_service_caps { > > + __u8 category; > > + __u8 len; > > + __u8 data[0]; > > +} __packed; > > + > > +struct msft_cp_avdtp_open { > > + __u8 sub_opcode; > > + __le16 handle; > > + __le16 dcid; > > + __le16 omtu; > > +} __packed; > > + > > /* ---- HCI Events ---- */ > > #define HCI_EV_INQUIRY_COMPLETE 0x01 > > > > diff --git a/net/bluetooth/hci_codec.c b/net/bluetooth/hci_codec.c > > index c6bd934dcf36..e179f3bfb494 100644 > > --- a/net/bluetooth/hci_codec.c > > +++ b/net/bluetooth/hci_codec.c > > @@ -355,3 +355,46 @@ int hci_get_supported_codecs(struct hci_dev > > *hdev, u8 type, char __user *optval, > > error: > > return err; > > } > > + > > +int hci_configure_msft_avdtp_open(struct hci_dev *hdev, struct > l2cap_chan *chan, > > + sockptr_t optval, int optlen) { > > + struct msft_cp_avdtp_open *cmd = NULL; > > + struct hci_media_service_caps *caps; > > + int err; > > + > > + if (!optlen || optlen < sizeof(*caps)) { > > + err = -EINVAL; > > + goto fail; > > + } > > + > > + cmd = kzalloc(sizeof(*cmd) + optlen, GFP_KERNEL); > > + if (!cmd) { > > + err = -ENOMEM; > > + goto fail; > > + } > > + > > + cmd->sub_opcode = HCI_MSFT_AVDTP_OPEN; > > + cmd->handle = __cpu_to_le16(chan->conn->hcon->handle); > > + cmd->dcid = cpu_to_le16(chan->dcid); > > + cmd->omtu = cpu_to_le16(chan->omtu); > > + caps = (void *)(cmd + 1); > > + > > + if (copy_from_sockptr(caps, optval, optlen)) { > > + err = -EFAULT; > > + goto fail; > > + } > > + > > + if (caps->category != 0x07) { > > + err = -EINVAL; > > + goto fail; > > + } > > + > > + hci_send_cmd(hdev, HCI_MSFT_AVDTP_CMD, sizeof(*cmd) + optlen, > > + cmd); > > + > > + /* wait until we get avdtp handle or timeout */ > > + > > +fail: > > + kfree(cmd); > > + return err; > > +} > > diff --git a/net/bluetooth/hci_codec.h b/net/bluetooth/hci_codec.h > > index 6e849c7d75b9..123b46a6a8ce 100644 > > --- a/net/bluetooth/hci_codec.h > > +++ b/net/bluetooth/hci_codec.h > > @@ -2,8 +2,12 @@ > > > > /* Copyright (C) 2014 Intel Corporation */ > > > > +#include <net/bluetooth/l2cap.h> > > + > > void hci_read_supported_codecs(struct hci_dev *hdev); void > > hci_read_supported_codecs_v2(struct hci_dev *hdev); void > > hci_codec_list_clear(struct list_head *codec_list); int > > hci_get_supported_codecs(struct hci_dev *hdev, u8 type, char __user > *optval, > > int __user *optlen, int len); > > +int hci_configure_msft_avdtp_open(struct hci_dev *hdev, struct > l2cap_chan *chan, > > + sockptr_t optval, int optlen); > > Id place this function inside msft.h/msft.c since this is a MSFT extension. > > > diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c > > index a883acf33e3c..fa689e576576 100644 > > --- a/net/bluetooth/l2cap_sock.c > > +++ b/net/bluetooth/l2cap_sock.c > > @@ -909,6 +909,7 @@ static int l2cap_sock_setsockopt(struct socket > *sock, int level, int optname, > > struct l2cap_conn *conn; > > int len, err = 0; > > u32 opt; > > + struct hci_dev *hdev; > > > > BT_DBG("sk %p", sk); > > > > @@ -1137,6 +1138,29 @@ static int l2cap_sock_setsockopt(struct socket > > *sock, int level, int optname, > > > > break; > > > > + case BT_MSFT_OPEN: > > + if (sk->sk_state != BT_CONNECTED) { > > + err = -ENOTCONN; > > + break; > > + } > > + > > + hdev = hci_get_route(BDADDR_ANY, &chan->src, > BDADDR_BREDR); > > + if (!hdev) { > > + err = -EBADFD; > > + break; > > + } > > + > > + if (!hci_dev_test_flag(hdev, HCI_OFFLOAD_CODECS_ENABLED) || > > + !hdev->get_data_path_id) { > > + err = -EOPNOTSUPP; > > + hci_dev_put(hdev); > > + break; > > + } > > + > > + err = hci_configure_msft_avdtp_open(hdev, chan, optval, optlen); > > + hci_dev_put(hdev); > > + break; > > + > > default: > > err = -ENOPROTOOPT; > > break; > > -- > > 2.17.1 > > > > > -- > Luiz Augusto von Dentz Thanks, Kiran