Skip to content

Commit f687340

Browse files
kirankrishnappa-intelVudentz
authored andcommitted
Bluetooth: Allow setting of codec for HFP offload use case
This patch allows user space to set the codec that needs to be used for HFP offload use case. The codec details are cached and the controller is configured before opening the SCO connection. Signed-off-by: Kiran K <[email protected]> Reviewed-by: Chethan T N <[email protected]> Reviewed-by: Srivatsa Ravishankar <[email protected]> Signed-off-by: Luiz Augusto von Dentz <[email protected]>
1 parent d586029 commit f687340

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

include/net/bluetooth/bluetooth.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ struct bt_codecs {
173173
struct bt_codec codecs[];
174174
} __packed;
175175

176+
#define BT_CODEC_CVSD 0x02
177+
176178
__printf(1, 2)
177179
void bt_info(const char *fmt, ...);
178180
__printf(1, 2)

net/bluetooth/sco.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ struct sco_pinfo {
6969
__u32 flags;
7070
__u16 setting;
7171
__u8 cmsg_mask;
72+
struct bt_codec codec;
7273
struct sco_conn *conn;
7374
};
7475

@@ -441,6 +442,7 @@ static void __sco_sock_close(struct sock *sk)
441442
sock_set_flag(sk, SOCK_ZAPPED);
442443
break;
443444
}
445+
444446
}
445447

446448
/* Must be called on unlocked socket. */
@@ -501,6 +503,10 @@ static struct sock *sco_sock_alloc(struct net *net, struct socket *sock,
501503
sk->sk_state = BT_OPEN;
502504

503505
sco_pi(sk)->setting = BT_VOICE_CVSD_16BIT;
506+
sco_pi(sk)->codec.id = BT_CODEC_CVSD;
507+
sco_pi(sk)->codec.cid = 0xffff;
508+
sco_pi(sk)->codec.vid = 0xffff;
509+
sco_pi(sk)->codec.data_path = 0x00;
504510

505511
bt_sock_link(&sco_sk_list, sk);
506512
return sk;
@@ -833,6 +839,9 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
833839
int len, err = 0;
834840
struct bt_voice voice;
835841
u32 opt;
842+
struct bt_codecs *codecs;
843+
struct hci_dev *hdev;
844+
__u8 buffer[255];
836845

837846
BT_DBG("sk %p", sk);
838847

@@ -894,6 +903,57 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
894903
sco_pi(sk)->cmsg_mask &= SCO_CMSG_PKT_STATUS;
895904
break;
896905

906+
case BT_CODEC:
907+
if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND &&
908+
sk->sk_state != BT_CONNECT2) {
909+
err = -EINVAL;
910+
break;
911+
}
912+
913+
hdev = hci_get_route(&sco_pi(sk)->dst, &sco_pi(sk)->src,
914+
BDADDR_BREDR);
915+
if (!hdev) {
916+
err = -EBADFD;
917+
break;
918+
}
919+
920+
if (!hci_dev_test_flag(hdev, HCI_OFFLOAD_CODECS_ENABLED)) {
921+
hci_dev_put(hdev);
922+
err = -EOPNOTSUPP;
923+
break;
924+
}
925+
926+
if (!hdev->get_data_path_id) {
927+
hci_dev_put(hdev);
928+
err = -EOPNOTSUPP;
929+
break;
930+
}
931+
932+
if (optlen < sizeof(struct bt_codecs) ||
933+
optlen > sizeof(buffer)) {
934+
hci_dev_put(hdev);
935+
err = -EINVAL;
936+
break;
937+
}
938+
939+
if (copy_from_sockptr(buffer, optval, optlen)) {
940+
hci_dev_put(hdev);
941+
err = -EFAULT;
942+
break;
943+
}
944+
945+
codecs = (void *)buffer;
946+
947+
if (codecs->num_codecs > 1) {
948+
hci_dev_put(hdev);
949+
err = -EINVAL;
950+
break;
951+
}
952+
953+
sco_pi(sk)->codec = codecs->codecs[0];
954+
hci_dev_put(hdev);
955+
break;
956+
897957
default:
898958
err = -ENOPROTOOPT;
899959
break;

0 commit comments

Comments
 (0)