Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Bluetooth: Add support for Read Local Supported Codecs V2

Use V2 version of read local supported command is controller
supports

snoop:
> HCI Event: Command Complete (0x0e) plen 20
Read Local Supported Codecs V2 (0x04|0x000d) ncmd 1
Status: Success (0x00)
Number of supported codecs: 7
Codec: u-law log (0x00)
Logical Transport Type: 0x02
Codec supported over BR/EDR SCO and eSCO
Codec: A-law log (0x01)
Logical Transport Type: 0x02
Codec supported over BR/EDR SCO and eSCO
Codec: CVSD (0x02)
Logical Transport Type: 0x02
Codec supported over BR/EDR SCO and eSCO
Codec: Transparent (0x03)
Logical Transport Type: 0x02
Codec supported over BR/EDR SCO and eSCO
Codec: Linear PCM (0x04)
Logical Transport Type: 0x02
Codec supported over BR/EDR SCO and eSCO
Codec: Reserved (0x08)
Logical Transport Type: 0x03
Codec supported over BR/EDR ACL
Codec supported over BR/EDR SCO and eSCO
Codec: mSBC (0x05)
Logical Transport Type: 0x03
Codec supported over BR/EDR ACL
Codec supported over BR/EDR SCO and eSCO
Number of vendor codecs: 0
......
< 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 <kiran.k@intel.com>
Signed-off-by: Chethan T N <chethan.tumkur.narayan@intel.com>
Signed-off-by: Srivatsa Ravishankar <ravishankar.srivatsa@intel.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

authored by

Kiran K and committed by
Luiz Augusto von Dentz
9ae66402 8961987f

+99 -1
+29
include/net/bluetooth/hci.h
··· 1338 1338 __u8 max_key_size; 1339 1339 } __packed; 1340 1340 1341 + #define HCI_OP_READ_LOCAL_CODECS_V2 0x100d 1342 + struct hci_std_codec_v2 { 1343 + __u8 id; 1344 + __u8 transport; 1345 + } __packed; 1346 + 1347 + struct hci_std_codecs_v2 { 1348 + __u8 num; 1349 + struct hci_std_codec_v2 codec[]; 1350 + } __packed; 1351 + 1352 + struct hci_vnd_codec_v2 { 1353 + __u8 id; 1354 + __le16 cid; 1355 + __le16 vid; 1356 + __u8 transport; 1357 + } __packed; 1358 + 1359 + struct hci_vnd_codecs_v2 { 1360 + __u8 num; 1361 + struct hci_vnd_codec_v2 codec[]; 1362 + } __packed; 1363 + 1364 + struct hci_rp_read_local_supported_codecs_v2 { 1365 + __u8 status; 1366 + struct hci_std_codecs_v2 std_codecs; 1367 + struct hci_vnd_codecs_v2 vendor_codecs; 1368 + } __packed; 1369 + 1341 1370 #define HCI_OP_READ_LOCAL_CODEC_CAPS 0x100e 1342 1371 struct hci_op_read_local_codec_caps { 1343 1372 __u8 id;
+66
net/bluetooth/hci_codec.c
··· 170 170 error: 171 171 kfree_skb(skb); 172 172 } 173 + 174 + void hci_read_supported_codecs_v2(struct hci_dev *hdev) 175 + { 176 + struct sk_buff *skb; 177 + struct hci_rp_read_local_supported_codecs_v2 *rp; 178 + struct hci_std_codecs_v2 *std_codecs; 179 + struct hci_vnd_codecs_v2 *vnd_codecs; 180 + struct hci_op_read_local_codec_caps caps; 181 + __u8 i; 182 + 183 + skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_CODECS_V2, 0, NULL, 184 + HCI_CMD_TIMEOUT); 185 + 186 + if (IS_ERR(skb)) { 187 + bt_dev_err(hdev, "Failed to read local supported codecs (%ld)", 188 + PTR_ERR(skb)); 189 + return; 190 + } 191 + 192 + if (skb->len < sizeof(*rp)) 193 + goto error; 194 + 195 + rp = (void *)skb->data; 196 + 197 + if (rp->status) 198 + goto error; 199 + 200 + skb_pull(skb, sizeof(rp->status)); 201 + 202 + std_codecs = (void *)skb->data; 203 + 204 + /* check for payload data length before accessing */ 205 + if (skb->len < flex_array_size(std_codecs, codec, std_codecs->num) 206 + + sizeof(std_codecs->num)) 207 + goto error; 208 + 209 + memset(&caps, 0, sizeof(caps)); 210 + 211 + for (i = 0; i < std_codecs->num; i++) { 212 + caps.id = std_codecs->codec[i].id; 213 + hci_read_codec_capabilities(hdev, std_codecs->codec[i].transport, 214 + &caps); 215 + } 216 + 217 + skb_pull(skb, flex_array_size(std_codecs, codec, std_codecs->num) 218 + + sizeof(std_codecs->num)); 219 + 220 + vnd_codecs = (void *)skb->data; 221 + 222 + /* check for payload data length before accessing */ 223 + if (skb->len < 224 + flex_array_size(vnd_codecs, codec, vnd_codecs->num) 225 + + sizeof(vnd_codecs->num)) 226 + goto error; 227 + 228 + for (i = 0; i < vnd_codecs->num; i++) { 229 + caps.id = 0xFF; 230 + caps.cid = vnd_codecs->codec[i].cid; 231 + caps.vid = vnd_codecs->codec[i].vid; 232 + hci_read_codec_capabilities(hdev, vnd_codecs->codec[i].transport, 233 + &caps); 234 + } 235 + 236 + error: 237 + kfree_skb(skb); 238 + }
+1
net/bluetooth/hci_codec.h
··· 3 3 /* Copyright (C) 2014 Intel Corporation */ 4 4 5 5 void hci_read_supported_codecs(struct hci_dev *hdev); 6 + void hci_read_supported_codecs_v2(struct hci_dev *hdev); 6 7 void hci_codec_list_clear(struct list_head *codec_list);
+3 -1
net/bluetooth/hci_core.c
··· 935 935 return err; 936 936 937 937 /* Read local codec list if the HCI command is supported */ 938 - if (hdev->commands[29] & 0x20) 938 + if (hdev->commands[45] & 0x04) 939 + hci_read_supported_codecs_v2(hdev); 940 + else if (hdev->commands[29] & 0x20) 939 941 hci_read_supported_codecs(hdev); 940 942 941 943 /* This function is only called when the controller is actually in