blob: 8eabf41b299394a85d8e020bb6b07415de9cf819 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth SCO sockets. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010028#include <linux/debugfs.h>
29#include <linux/seq_file.h>
Ingo Molnar174cd4b2017-02-02 19:15:33 +010030#include <linux/sched/signal.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031
32#include <net/bluetooth/bluetooth.h>
33#include <net/bluetooth/hci_core.h>
34#include <net/bluetooth/sco.h>
35
Rusty Russelleb939922011-12-19 14:08:01 +000036static bool disable_esco;
Linus Torvalds1da177e2005-04-16 15:20:36 -070037
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080038static const struct proto_ops sco_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070039
40static struct bt_sock_list sco_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070041 .lock = __RW_LOCK_UNLOCKED(sco_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070042};
43
Marcel Holtmannfc8f5252014-07-11 06:19:42 +020044/* ---- SCO connections ---- */
45struct sco_conn {
46 struct hci_conn *hcon;
47
48 spinlock_t lock;
49 struct sock *sk;
50
Desmond Cheong Zhi Xiba316be2021-08-10 12:14:05 +080051 struct delayed_work timeout_work;
52
Marcel Holtmannfc8f5252014-07-11 06:19:42 +020053 unsigned int mtu;
54};
55
Meng Yu0f90d322021-03-24 10:03:25 +080056#define sco_conn_lock(c) spin_lock(&c->lock)
57#define sco_conn_unlock(c) spin_unlock(&c->lock)
Marcel Holtmannfc8f5252014-07-11 06:19:42 +020058
Linus Torvalds1da177e2005-04-16 15:20:36 -070059static void sco_sock_close(struct sock *sk);
60static void sco_sock_kill(struct sock *sk);
61
Marcel Holtmann2a0dccb2014-07-11 06:19:41 +020062/* ----- SCO socket info ----- */
63#define sco_pi(sk) ((struct sco_pinfo *) sk)
64
65struct sco_pinfo {
66 struct bt_sock bt;
67 bdaddr_t src;
68 bdaddr_t dst;
69 __u32 flags;
70 __u16 setting;
Alain Michaud00398e12020-06-11 19:50:41 +000071 __u8 cmsg_mask;
Kiran Kf6873402021-09-07 15:42:42 +053072 struct bt_codec codec;
Marcel Holtmann2a0dccb2014-07-11 06:19:41 +020073 struct sco_conn *conn;
74};
75
Linus Torvalds1da177e2005-04-16 15:20:36 -070076/* ---- SCO timers ---- */
Marcel Holtmann068d69e2014-07-11 06:19:44 +020077#define SCO_CONN_TIMEOUT (HZ * 40)
78#define SCO_DISCONN_TIMEOUT (HZ * 2)
79
Desmond Cheong Zhi Xiba316be2021-08-10 12:14:05 +080080static void sco_sock_timeout(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -070081{
Desmond Cheong Zhi Xiba316be2021-08-10 12:14:05 +080082 struct sco_conn *conn = container_of(work, struct sco_conn,
83 timeout_work.work);
84 struct sock *sk;
85
86 sco_conn_lock(conn);
87 sk = conn->sk;
88 if (sk)
89 sock_hold(sk);
90 sco_conn_unlock(conn);
91
92 if (!sk)
93 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
95 BT_DBG("sock %p state %d", sk, sk->sk_state);
96
Desmond Cheong Zhi Xi27c24fd2021-08-10 12:14:07 +080097 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -070098 sk->sk_err = ETIMEDOUT;
99 sk->sk_state_change(sk);
Desmond Cheong Zhi Xi27c24fd2021-08-10 12:14:07 +0800100 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101 sock_put(sk);
102}
103
104static void sco_sock_set_timer(struct sock *sk, long timeout)
105{
Desmond Cheong Zhi Xiba316be2021-08-10 12:14:05 +0800106 if (!sco_pi(sk)->conn)
107 return;
108
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109 BT_DBG("sock %p state %d timeout %ld", sk, sk->sk_state, timeout);
Desmond Cheong Zhi Xiba316be2021-08-10 12:14:05 +0800110 cancel_delayed_work(&sco_pi(sk)->conn->timeout_work);
111 schedule_delayed_work(&sco_pi(sk)->conn->timeout_work, timeout);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112}
113
114static void sco_sock_clear_timer(struct sock *sk)
115{
Desmond Cheong Zhi Xiba316be2021-08-10 12:14:05 +0800116 if (!sco_pi(sk)->conn)
117 return;
118
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119 BT_DBG("sock %p state %d", sk, sk->sk_state);
Desmond Cheong Zhi Xiba316be2021-08-10 12:14:05 +0800120 cancel_delayed_work(&sco_pi(sk)->conn->timeout_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121}
122
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123/* ---- SCO connections ---- */
Lukasz Rymanowski519e42b2012-04-19 16:12:28 +0200124static struct sco_conn *sco_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125{
126 struct hci_dev *hdev = hcon->hdev;
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200127 struct sco_conn *conn = hcon->sco_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128
Lukasz Rymanowski519e42b2012-04-19 16:12:28 +0200129 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130 return conn;
131
Claudio Takahasic10cc5a2013-04-11 11:35:45 -0300132 conn = kzalloc(sizeof(struct sco_conn), GFP_KERNEL);
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200133 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135
136 spin_lock_init(&conn->lock);
Desmond Cheong Zhi Xi49d8a562021-09-02 23:13:06 -0400137 INIT_DELAYED_WORK(&conn->timeout_work, sco_sock_timeout);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138
139 hcon->sco_data = conn;
140 conn->hcon = hcon;
141
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142 if (hdev->sco_mtu > 0)
143 conn->mtu = hdev->sco_mtu;
144 else
145 conn->mtu = 60;
146
147 BT_DBG("hcon %p conn %p", hcon, conn);
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200148
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 return conn;
150}
151
Marcel Holtmanne03ab512014-07-13 19:54:49 +0200152/* Delete channel.
153 * Must be called on the locked socket. */
154static void sco_chan_del(struct sock *sk, int err)
155{
156 struct sco_conn *conn;
157
158 conn = sco_pi(sk)->conn;
159
160 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
161
162 if (conn) {
163 sco_conn_lock(conn);
164 conn->sk = NULL;
165 sco_pi(sk)->conn = NULL;
166 sco_conn_unlock(conn);
167
168 if (conn->hcon)
169 hci_conn_drop(conn->hcon);
170 }
171
172 sk->sk_state = BT_CLOSED;
173 sk->sk_err = err;
174 sk->sk_state_change(sk);
175
176 sock_set_flag(sk, SOCK_ZAPPED);
177}
178
Nicholas Krausedf945362015-08-18 21:23:01 -0400179static void sco_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180{
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200181 struct sco_conn *conn = hcon->sco_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 struct sock *sk;
183
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200184 if (!conn)
Nicholas Krausedf945362015-08-18 21:23:01 -0400185 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186
187 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
188
189 /* Kill socket */
Marcel Holtmanneb5a4de2014-07-14 01:30:15 +0200190 sco_conn_lock(conn);
191 sk = conn->sk;
Desmond Cheong Zhi Xif4712fa2021-09-02 23:13:05 -0400192 if (sk)
193 sock_hold(sk);
Marcel Holtmanneb5a4de2014-07-14 01:30:15 +0200194 sco_conn_unlock(conn);
195
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200196 if (sk) {
Desmond Cheong Zhi Xi27c24fd2021-08-10 12:14:07 +0800197 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198 sco_sock_clear_timer(sk);
199 sco_chan_del(sk, err);
Desmond Cheong Zhi Xi27c24fd2021-08-10 12:14:07 +0800200 release_sock(sk);
Kuba Pawlak75e34f52015-10-05 18:44:15 +0200201 sock_put(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202 }
203
Desmond Cheong Zhi Xi49d8a562021-09-02 23:13:06 -0400204 /* Ensure no more work items will run before freeing conn. */
205 cancel_delayed_work_sync(&conn->timeout_work);
206
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207 hcon->sco_data = NULL;
208 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209}
210
Marcel Holtmannc4297e82015-10-26 02:08:38 +0100211static void __sco_chan_add(struct sco_conn *conn, struct sock *sk,
212 struct sock *parent)
Marcel Holtmann015b01c2014-07-13 19:54:48 +0200213{
214 BT_DBG("conn %p", conn);
215
216 sco_pi(sk)->conn = conn;
217 conn->sk = sk;
218
219 if (parent)
Matthias Kaehlckec4f56272019-01-02 16:11:20 -0800220 bt_accept_enqueue(parent, sk, true);
Marcel Holtmann015b01c2014-07-13 19:54:48 +0200221}
222
Gustavo Padovan6039aa72012-05-23 04:04:18 -0300223static int sco_chan_add(struct sco_conn *conn, struct sock *sk,
224 struct sock *parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225{
226 int err = 0;
227
228 sco_conn_lock(conn);
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300229 if (conn->sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230 err = -EBUSY;
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300231 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232 __sco_chan_add(conn, sk, parent);
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300233
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234 sco_conn_unlock(conn);
235 return err;
236}
237
Desmond Cheong Zhi Xi734bc5f2021-08-10 12:14:06 +0800238static int sco_connect(struct hci_dev *hdev, struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240 struct sco_conn *conn;
241 struct hci_conn *hcon;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200242 int err, type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243
Marcel Holtmanneea96362013-10-13 10:34:01 -0700244 BT_DBG("%pMR -> %pMR", &sco_pi(sk)->src, &sco_pi(sk)->dst);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245
Marcel Holtmann7cb127d2008-07-14 20:13:53 +0200246 if (lmp_esco_capable(hdev) && !disable_esco)
247 type = ESCO_LINK;
248 else
249 type = SCO_LINK;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200250
Frédéric Dalleau79dc0082013-08-19 14:24:01 +0200251 if (sco_pi(sk)->setting == BT_VOICE_TRANSPARENT &&
Desmond Cheong Zhi Xi734bc5f2021-08-10 12:14:06 +0800252 (!lmp_transp_capable(hdev) || !lmp_esco_capable(hdev)))
253 return -EOPNOTSUPP;
Frédéric Dalleau79dc0082013-08-19 14:24:01 +0200254
Marcel Holtmanneea96362013-10-13 10:34:01 -0700255 hcon = hci_connect_sco(hdev, type, &sco_pi(sk)->dst,
Kiran Kb2af2642021-09-07 15:42:43 +0530256 sco_pi(sk)->setting, &sco_pi(sk)->codec);
Desmond Cheong Zhi Xi734bc5f2021-08-10 12:14:06 +0800257 if (IS_ERR(hcon))
258 return PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259
Lukasz Rymanowski519e42b2012-04-19 16:12:28 +0200260 conn = sco_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +0200262 hci_conn_drop(hcon);
Desmond Cheong Zhi Xi734bc5f2021-08-10 12:14:06 +0800263 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264 }
265
266 /* Update source addr of the socket */
Marcel Holtmanneea96362013-10-13 10:34:01 -0700267 bacpy(&sco_pi(sk)->src, &hcon->src);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268
269 err = sco_chan_add(conn, sk, NULL);
270 if (err)
Desmond Cheong Zhi Xi734bc5f2021-08-10 12:14:06 +0800271 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272
273 if (hcon->state == BT_CONNECTED) {
274 sco_sock_clear_timer(sk);
275 sk->sk_state = BT_CONNECTED;
276 } else {
277 sk->sk_state = BT_CONNECT;
278 sco_sock_set_timer(sk, sk->sk_sndtimeo);
279 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200280
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281 return err;
282}
283
Luiz Augusto von Dentz0771cbb2021-09-03 15:27:31 -0700284static int sco_send_frame(struct sock *sk, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285{
286 struct sco_conn *conn = sco_pi(sk)->conn;
Luiz Augusto von Dentz037ce002021-09-16 13:10:49 -0700287 int len = skb->len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288
289 /* Check outgoing MTU */
Luiz Augusto von Dentz037ce002021-09-16 13:10:49 -0700290 if (len > conn->mtu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 return -EINVAL;
292
Luiz Augusto von Dentz037ce002021-09-16 13:10:49 -0700293 BT_DBG("sk %p len %d", sk, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294
Gustavo F. Padovan0d861d82010-05-01 16:15:35 -0300295 hci_send_sco(conn->hcon, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296
Luiz Augusto von Dentz037ce002021-09-16 13:10:49 -0700297 return len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298}
299
Gustavo Padovan6039aa72012-05-23 04:04:18 -0300300static void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301{
Marcel Holtmanneb5a4de2014-07-14 01:30:15 +0200302 struct sock *sk;
303
304 sco_conn_lock(conn);
305 sk = conn->sk;
306 sco_conn_unlock(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307
308 if (!sk)
309 goto drop;
310
Kai Ye79dbeafe2021-06-03 15:41:04 +0800311 BT_DBG("sk %p len %u", sk, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312
313 if (sk->sk_state != BT_CONNECTED)
314 goto drop;
315
316 if (!sock_queue_rcv_skb(sk, skb))
317 return;
318
319drop:
320 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321}
322
323/* -------- Socket interface ---------- */
Marcel Holtmannfb334052012-04-19 14:37:58 +0200324static struct sock *__sco_get_sock_listen_by_addr(bdaddr_t *ba)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325{
Marcel Holtmannfb334052012-04-19 14:37:58 +0200326 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327
Sasha Levinb67bfe02013-02-27 17:06:00 -0800328 sk_for_each(sk, &sco_sk_list.head) {
Marcel Holtmannfb334052012-04-19 14:37:58 +0200329 if (sk->sk_state != BT_LISTEN)
330 continue;
331
Marcel Holtmanneea96362013-10-13 10:34:01 -0700332 if (!bacmp(&sco_pi(sk)->src, ba))
Marcel Holtmannfb334052012-04-19 14:37:58 +0200333 return sk;
334 }
335
336 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337}
338
339/* Find socket listening on source bdaddr.
340 * Returns closest match.
341 */
342static struct sock *sco_get_sock_listen(bdaddr_t *src)
343{
344 struct sock *sk = NULL, *sk1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345
346 read_lock(&sco_sk_list.lock);
347
Sasha Levinb67bfe02013-02-27 17:06:00 -0800348 sk_for_each(sk, &sco_sk_list.head) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349 if (sk->sk_state != BT_LISTEN)
350 continue;
351
352 /* Exact match. */
Marcel Holtmanneea96362013-10-13 10:34:01 -0700353 if (!bacmp(&sco_pi(sk)->src, src))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354 break;
355
356 /* Closest match */
Marcel Holtmanneea96362013-10-13 10:34:01 -0700357 if (!bacmp(&sco_pi(sk)->src, BDADDR_ANY))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358 sk1 = sk;
359 }
360
361 read_unlock(&sco_sk_list.lock);
362
Sasha Levinb67bfe02013-02-27 17:06:00 -0800363 return sk ? sk : sk1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364}
365
366static void sco_sock_destruct(struct sock *sk)
367{
368 BT_DBG("sk %p", sk);
369
370 skb_queue_purge(&sk->sk_receive_queue);
371 skb_queue_purge(&sk->sk_write_queue);
372}
373
374static void sco_sock_cleanup_listen(struct sock *parent)
375{
376 struct sock *sk;
377
378 BT_DBG("parent %p", parent);
379
380 /* Close not yet accepted channels */
381 while ((sk = bt_accept_dequeue(parent, NULL))) {
382 sco_sock_close(sk);
383 sco_sock_kill(sk);
384 }
385
386 parent->sk_state = BT_CLOSED;
387 sock_set_flag(parent, SOCK_ZAPPED);
388}
389
390/* Kill socket (only if zapped and orphan)
391 * Must be called on unlocked socket.
392 */
393static void sco_sock_kill(struct sock *sk)
394{
Desmond Cheong Zhi Xie1dee2c2021-08-10 12:14:10 +0800395 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396 return;
397
398 BT_DBG("sk %p state %d", sk, sk->sk_state);
399
400 /* Kill poor orphan */
401 bt_sock_unlink(&sco_sk_list, sk);
402 sock_set_flag(sk, SOCK_DEAD);
403 sock_put(sk);
404}
405
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200406static void __sco_sock_close(struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407{
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200408 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
410 switch (sk->sk_state) {
411 case BT_LISTEN:
412 sco_sock_cleanup_listen(sk);
413 break;
414
415 case BT_CONNECTED:
416 case BT_CONFIG:
Gustavo Padovanb7e98b52013-01-03 19:59:28 -0200417 if (sco_pi(sk)->conn->hcon) {
Luiz Augusto von Dentz4a777082011-05-12 11:13:15 +0300418 sk->sk_state = BT_DISCONN;
419 sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT);
Kuba Pawlak435c5132015-10-05 18:44:16 +0200420 sco_conn_lock(sco_pi(sk)->conn);
David Herrmann76a68ba2013-04-06 20:28:37 +0200421 hci_conn_drop(sco_pi(sk)->conn->hcon);
Luiz Augusto von Dentz4a777082011-05-12 11:13:15 +0300422 sco_pi(sk)->conn->hcon = NULL;
Kuba Pawlak435c5132015-10-05 18:44:16 +0200423 sco_conn_unlock(sco_pi(sk)->conn);
Luiz Augusto von Dentz4a777082011-05-12 11:13:15 +0300424 } else
425 sco_chan_del(sk, ECONNRESET);
426 break;
427
Vinicius Costa Gomeseb20ff92013-03-13 19:46:20 -0300428 case BT_CONNECT2:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429 case BT_CONNECT:
430 case BT_DISCONN:
431 sco_chan_del(sk, ECONNRESET);
432 break;
433
434 default:
435 sock_set_flag(sk, SOCK_ZAPPED);
436 break;
Stephen Hemminger3ff50b72007-04-20 17:09:22 -0700437 }
Kiran Kf6873402021-09-07 15:42:42 +0530438
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200439}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200441/* Must be called on unlocked socket. */
442static void sco_sock_close(struct sock *sk)
443{
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200444 lock_sock(sk);
Desmond Cheong Zhi Xi3f2c89f2021-08-10 12:14:08 +0800445 sco_sock_clear_timer(sk);
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200446 __sco_sock_close(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448}
449
Alain Michaud00398e12020-06-11 19:50:41 +0000450static void sco_skb_put_cmsg(struct sk_buff *skb, struct msghdr *msg,
451 struct sock *sk)
452{
453 if (sco_pi(sk)->cmsg_mask & SCO_CMSG_PKT_STATUS)
454 put_cmsg(msg, SOL_BLUETOOTH, BT_SCM_PKT_STATUS,
455 sizeof(bt_cb(skb)->sco.pkt_status),
456 &bt_cb(skb)->sco.pkt_status);
457}
458
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459static void sco_sock_init(struct sock *sk, struct sock *parent)
460{
461 BT_DBG("sk %p", sk);
462
Paul Moore6230c9b2011-10-07 09:40:59 +0000463 if (parent) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464 sk->sk_type = parent->sk_type;
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +0100465 bt_sk(sk)->flags = bt_sk(parent)->flags;
Paul Moore6230c9b2011-10-07 09:40:59 +0000466 security_sk_clone(parent, sk);
Alain Michaud00398e12020-06-11 19:50:41 +0000467 } else {
468 bt_sk(sk)->skb_put_cmsg = sco_skb_put_cmsg;
Paul Moore6230c9b2011-10-07 09:40:59 +0000469 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470}
471
472static struct proto sco_proto = {
473 .name = "SCO",
474 .owner = THIS_MODULE,
475 .obj_size = sizeof(struct sco_pinfo)
476};
477
Marcel Holtmannc4297e82015-10-26 02:08:38 +0100478static struct sock *sco_sock_alloc(struct net *net, struct socket *sock,
479 int proto, gfp_t prio, int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480{
481 struct sock *sk;
482
Eric W. Biederman11aa9c22015-05-08 21:09:13 -0500483 sk = sk_alloc(net, PF_BLUETOOTH, prio, &sco_proto, kern);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484 if (!sk)
485 return NULL;
486
487 sock_init_data(sock, sk);
488 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
489
490 sk->sk_destruct = sco_sock_destruct;
491 sk->sk_sndtimeo = SCO_CONN_TIMEOUT;
492
493 sock_reset_flag(sk, SOCK_ZAPPED);
494
495 sk->sk_protocol = proto;
496 sk->sk_state = BT_OPEN;
497
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +0200498 sco_pi(sk)->setting = BT_VOICE_CVSD_16BIT;
Kiran Kf6873402021-09-07 15:42:42 +0530499 sco_pi(sk)->codec.id = BT_CODEC_CVSD;
500 sco_pi(sk)->codec.cid = 0xffff;
501 sco_pi(sk)->codec.vid = 0xffff;
502 sco_pi(sk)->codec.data_path = 0x00;
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +0200503
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504 bt_sock_link(&sco_sk_list, sk);
505 return sk;
506}
507
Eric Paris3f378b62009-11-05 22:18:14 -0800508static int sco_sock_create(struct net *net, struct socket *sock, int protocol,
509 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510{
511 struct sock *sk;
512
513 BT_DBG("sock %p", sock);
514
515 sock->state = SS_UNCONNECTED;
516
517 if (sock->type != SOCK_SEQPACKET)
518 return -ESOCKTNOSUPPORT;
519
520 sock->ops = &sco_sock_ops;
521
Eric W. Biederman11aa9c22015-05-08 21:09:13 -0500522 sk = sco_sock_alloc(net, sock, protocol, GFP_ATOMIC, kern);
Marcel Holtmann74da6262006-10-15 17:31:14 +0200523 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524 return -ENOMEM;
525
526 sco_sock_init(sk, NULL);
527 return 0;
528}
529
Marcel Holtmannc4297e82015-10-26 02:08:38 +0100530static int sco_sock_bind(struct socket *sock, struct sockaddr *addr,
531 int addr_len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532{
533 struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
534 struct sock *sk = sock->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535 int err = 0;
536
Mateusz Jurczykd2ecfa72017-06-29 14:04:59 +0200537 if (!addr || addr_len < sizeof(struct sockaddr_sco) ||
538 addr->sa_family != AF_BLUETOOTH)
David S. Miller52332522015-12-15 15:39:08 -0500539 return -EINVAL;
540
Tetsuo Handabd7d46d2019-04-12 19:54:33 +0900541 BT_DBG("sk %p %pMR", sk, &sa->sco_bdaddr);
542
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 lock_sock(sk);
544
545 if (sk->sk_state != BT_OPEN) {
546 err = -EBADFD;
547 goto done;
548 }
549
Marcel Holtmann8ed21f72012-04-19 13:43:53 +0200550 if (sk->sk_type != SOCK_SEQPACKET) {
551 err = -EINVAL;
552 goto done;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553 }
554
Marcel Holtmanneea96362013-10-13 10:34:01 -0700555 bacpy(&sco_pi(sk)->src, &sa->sco_bdaddr);
Marcel Holtmann8ed21f72012-04-19 13:43:53 +0200556
557 sk->sk_state = BT_BOUND;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558
559done:
560 release_sock(sk);
561 return err;
562}
563
564static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
565{
566 struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
567 struct sock *sk = sock->sk;
Desmond Cheong Zhi Xi734bc5f2021-08-10 12:14:06 +0800568 struct hci_dev *hdev;
Claudio Takahasi92f185c2013-04-11 11:35:46 -0300569 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570
571 BT_DBG("sk %p", sk);
572
Changli Gao6503d962010-03-31 22:58:26 +0000573 if (alen < sizeof(struct sockaddr_sco) ||
574 addr->sa_family != AF_BLUETOOTH)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575 return -EINVAL;
576
577 if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)
578 return -EBADFD;
579
580 if (sk->sk_type != SOCK_SEQPACKET)
581 return -EINVAL;
582
Desmond Cheong Zhi Xi734bc5f2021-08-10 12:14:06 +0800583 hdev = hci_get_route(&sa->sco_bdaddr, &sco_pi(sk)->src, BDADDR_BREDR);
584 if (!hdev)
585 return -EHOSTUNREACH;
586 hci_dev_lock(hdev);
587
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 lock_sock(sk);
589
590 /* Set destination address and psm */
Marcel Holtmanneea96362013-10-13 10:34:01 -0700591 bacpy(&sco_pi(sk)->dst, &sa->sco_bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592
Desmond Cheong Zhi Xi734bc5f2021-08-10 12:14:06 +0800593 err = sco_connect(hdev, sk);
594 hci_dev_unlock(hdev);
595 hci_dev_put(hdev);
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200596 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597 goto done;
598
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900599 err = bt_sock_wait_state(sk, BT_CONNECTED,
Gustavo Padovanbe7c2b92012-05-17 00:36:21 -0300600 sock_sndtimeo(sk, flags & O_NONBLOCK));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601
602done:
603 release_sock(sk);
604 return err;
605}
606
607static int sco_sock_listen(struct socket *sock, int backlog)
608{
609 struct sock *sk = sock->sk;
Marcel Holtmanneea96362013-10-13 10:34:01 -0700610 bdaddr_t *src = &sco_pi(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611 int err = 0;
612
613 BT_DBG("sk %p backlog %d", sk, backlog);
614
615 lock_sock(sk);
616
Marcel Holtmann7d5d7752012-04-19 13:43:52 +0200617 if (sk->sk_state != BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 err = -EBADFD;
619 goto done;
620 }
621
Marcel Holtmann7d5d7752012-04-19 13:43:52 +0200622 if (sk->sk_type != SOCK_SEQPACKET) {
623 err = -EINVAL;
624 goto done;
625 }
626
Marcel Holtmannfb334052012-04-19 14:37:58 +0200627 write_lock(&sco_sk_list.lock);
628
629 if (__sco_get_sock_listen_by_addr(src)) {
630 err = -EADDRINUSE;
631 goto unlock;
632 }
633
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634 sk->sk_max_ack_backlog = backlog;
635 sk->sk_ack_backlog = 0;
Marcel Holtmannfb334052012-04-19 14:37:58 +0200636
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 sk->sk_state = BT_LISTEN;
638
Marcel Holtmannfb334052012-04-19 14:37:58 +0200639unlock:
640 write_unlock(&sco_sk_list.lock);
641
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642done:
643 release_sock(sk);
644 return err;
645}
646
Marcel Holtmannc4297e82015-10-26 02:08:38 +0100647static int sco_sock_accept(struct socket *sock, struct socket *newsock,
David Howellscdfbabf2017-03-09 08:09:05 +0000648 int flags, bool kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649{
Peter Hurleydfb2fae2015-01-23 12:16:53 -0500650 DEFINE_WAIT_FUNC(wait, woken_wake_function);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651 struct sock *sk = sock->sk, *ch;
652 long timeo;
653 int err = 0;
654
655 lock_sock(sk);
656
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
658
659 BT_DBG("sk %p timeo %ld", sk, timeo);
660
661 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +0000662 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Peter Hurley552b0d32011-07-24 00:11:01 -0400663 while (1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664 if (sk->sk_state != BT_LISTEN) {
665 err = -EBADFD;
666 break;
667 }
668
Peter Hurley552b0d32011-07-24 00:11:01 -0400669 ch = bt_accept_dequeue(sk, newsock);
670 if (ch)
671 break;
672
673 if (!timeo) {
674 err = -EAGAIN;
675 break;
676 }
677
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678 if (signal_pending(current)) {
679 err = sock_intr_errno(timeo);
680 break;
681 }
Peter Hurley552b0d32011-07-24 00:11:01 -0400682
683 release_sock(sk);
Peter Hurleydfb2fae2015-01-23 12:16:53 -0500684
685 timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, timeo);
Peter Hurley552b0d32011-07-24 00:11:01 -0400686 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687 }
Eric Dumazetaa395142010-04-20 13:03:51 +0000688 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689
690 if (err)
691 goto done;
692
693 newsock->state = SS_CONNECTED;
694
695 BT_DBG("new socket %p", ch);
696
697done:
698 release_sock(sk);
699 return err;
700}
701
Marcel Holtmannc4297e82015-10-26 02:08:38 +0100702static int sco_sock_getname(struct socket *sock, struct sockaddr *addr,
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +0100703 int peer)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704{
705 struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
706 struct sock *sk = sock->sk;
707
708 BT_DBG("sock %p, sk %p", sock, sk);
709
710 addr->sa_family = AF_BLUETOOTH;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711
712 if (peer)
Marcel Holtmanneea96362013-10-13 10:34:01 -0700713 bacpy(&sa->sco_bdaddr, &sco_pi(sk)->dst);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714 else
Marcel Holtmanneea96362013-10-13 10:34:01 -0700715 bacpy(&sa->sco_bdaddr, &sco_pi(sk)->src);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +0100717 return sizeof(struct sockaddr_sco);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718}
719
Ying Xue1b784142015-03-02 15:37:48 +0800720static int sco_sock_sendmsg(struct socket *sock, struct msghdr *msg,
721 size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722{
723 struct sock *sk = sock->sk;
Luiz Augusto von Dentz0771cbb2021-09-03 15:27:31 -0700724 struct sk_buff *skb;
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300725 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726
727 BT_DBG("sock %p, sk %p", sock, sk);
728
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -0800729 err = sock_error(sk);
730 if (err)
731 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732
733 if (msg->msg_flags & MSG_OOB)
734 return -EOPNOTSUPP;
735
Luiz Augusto von Dentz0771cbb2021-09-03 15:27:31 -0700736 skb = bt_skb_sendmsg(sk, msg, len, len, 0, 0);
Luiz Augusto von Dentz266191aa2021-09-16 13:10:48 -0700737 if (IS_ERR(skb))
Luiz Augusto von Dentz0771cbb2021-09-03 15:27:31 -0700738 return PTR_ERR(skb);
Takashi Iwai99c23da2021-08-28 18:18:18 +0200739
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740 lock_sock(sk);
741
742 if (sk->sk_state == BT_CONNECTED)
Luiz Augusto von Dentz0771cbb2021-09-03 15:27:31 -0700743 err = sco_send_frame(sk, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744 else
745 err = -ENOTCONN;
746
747 release_sock(sk);
Luiz Augusto von Dentz037ce002021-09-16 13:10:49 -0700748
749 if (err < 0)
Luiz Augusto von Dentz0771cbb2021-09-03 15:27:31 -0700750 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751 return err;
752}
753
Frédéric Dalleau2f69a822013-08-19 14:23:58 +0200754static void sco_conn_defer_accept(struct hci_conn *conn, u16 setting)
Frédéric Dalleaufa5513b2013-04-16 17:28:58 +0200755{
756 struct hci_dev *hdev = conn->hdev;
757
758 BT_DBG("conn %p", conn);
759
760 conn->state = BT_CONFIG;
761
762 if (!lmp_esco_capable(hdev)) {
763 struct hci_cp_accept_conn_req cp;
764
765 bacpy(&cp.bdaddr, &conn->dst);
Frédéric Dalleau33f24042013-08-19 14:23:55 +0200766 cp.role = 0x00; /* Ignored */
Frédéric Dalleaufa5513b2013-04-16 17:28:58 +0200767
768 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp);
769 } else {
770 struct hci_cp_accept_sync_conn_req cp;
771
772 bacpy(&cp.bdaddr, &conn->dst);
773 cp.pkt_type = cpu_to_le16(conn->pkt_type);
774
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700775 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
776 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
Frédéric Dalleau2f69a822013-08-19 14:23:58 +0200777 cp.content_format = cpu_to_le16(setting);
778
779 switch (setting & SCO_AIRMODE_MASK) {
780 case SCO_AIRMODE_TRANSP:
781 if (conn->pkt_type & ESCO_2EV3)
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700782 cp.max_latency = cpu_to_le16(0x0008);
Frédéric Dalleau2f69a822013-08-19 14:23:58 +0200783 else
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700784 cp.max_latency = cpu_to_le16(0x000D);
Frédéric Dalleau2f69a822013-08-19 14:23:58 +0200785 cp.retrans_effort = 0x02;
786 break;
787 case SCO_AIRMODE_CVSD:
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700788 cp.max_latency = cpu_to_le16(0xffff);
Frédéric Dalleau2f69a822013-08-19 14:23:58 +0200789 cp.retrans_effort = 0xff;
790 break;
Dan Carpenter59da0b32021-06-25 18:00:09 +0300791 default:
792 /* use CVSD settings as fallback */
793 cp.max_latency = cpu_to_le16(0xffff);
794 cp.retrans_effort = 0xff;
795 break;
Frédéric Dalleau2f69a822013-08-19 14:23:58 +0200796 }
Frédéric Dalleaufa5513b2013-04-16 17:28:58 +0200797
798 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
799 sizeof(cp), &cp);
800 }
801}
802
Ying Xue1b784142015-03-02 15:37:48 +0800803static int sco_sock_recvmsg(struct socket *sock, struct msghdr *msg,
804 size_t len, int flags)
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +0100805{
806 struct sock *sk = sock->sk;
807 struct sco_pinfo *pi = sco_pi(sk);
808
809 lock_sock(sk);
810
811 if (sk->sk_state == BT_CONNECT2 &&
812 test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Frédéric Dalleau2f69a822013-08-19 14:23:58 +0200813 sco_conn_defer_accept(pi->conn->hcon, pi->setting);
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +0100814 sk->sk_state = BT_CONFIG;
815
816 release_sock(sk);
817 return 0;
818 }
819
820 release_sock(sk);
821
Ying Xue1b784142015-03-02 15:37:48 +0800822 return bt_sock_recvmsg(sock, msg, len, flags);
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +0100823}
824
Marcel Holtmannc4297e82015-10-26 02:08:38 +0100825static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
Christoph Hellwiga7b75c52020-07-23 08:09:07 +0200826 sockptr_t optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827{
828 struct sock *sk = sock->sk;
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +0200829 int len, err = 0;
830 struct bt_voice voice;
Frédéric Dalleaub96e9c62012-11-21 10:51:11 +0100831 u32 opt;
Kiran Kf6873402021-09-07 15:42:42 +0530832 struct bt_codecs *codecs;
833 struct hci_dev *hdev;
834 __u8 buffer[255];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835
836 BT_DBG("sk %p", sk);
837
838 lock_sock(sk);
839
840 switch (optname) {
Frédéric Dalleaub96e9c62012-11-21 10:51:11 +0100841
842 case BT_DEFER_SETUP:
843 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
844 err = -EINVAL;
845 break;
846 }
847
Christoph Hellwiga7b75c52020-07-23 08:09:07 +0200848 if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
Frédéric Dalleaub96e9c62012-11-21 10:51:11 +0100849 err = -EFAULT;
850 break;
851 }
852
853 if (opt)
854 set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
855 else
856 clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
857 break;
858
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +0200859 case BT_VOICE:
860 if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND &&
861 sk->sk_state != BT_CONNECT2) {
862 err = -EINVAL;
863 break;
864 }
865
866 voice.setting = sco_pi(sk)->setting;
867
868 len = min_t(unsigned int, sizeof(voice), optlen);
Christoph Hellwiga7b75c52020-07-23 08:09:07 +0200869 if (copy_from_sockptr(&voice, optval, len)) {
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +0200870 err = -EFAULT;
871 break;
872 }
873
874 /* Explicitly check for these values */
875 if (voice.setting != BT_VOICE_TRANSPARENT &&
876 voice.setting != BT_VOICE_CVSD_16BIT) {
877 err = -EINVAL;
878 break;
879 }
880
881 sco_pi(sk)->setting = voice.setting;
Kiran Kb2af2642021-09-07 15:42:43 +0530882 hdev = hci_get_route(&sco_pi(sk)->dst, &sco_pi(sk)->src,
883 BDADDR_BREDR);
884 if (!hdev) {
885 err = -EBADFD;
886 break;
887 }
888 if (enhanced_sco_capable(hdev) &&
889 voice.setting == BT_VOICE_TRANSPARENT)
890 sco_pi(sk)->codec.id = BT_CODEC_TRANSPARENT;
891 hci_dev_put(hdev);
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +0200892 break;
893
Alain Michaud00398e12020-06-11 19:50:41 +0000894 case BT_PKT_STATUS:
David S. Miller83a33b22020-07-31 16:15:03 -0700895 if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
Alain Michaud00398e12020-06-11 19:50:41 +0000896 err = -EFAULT;
897 break;
898 }
899
900 if (opt)
901 sco_pi(sk)->cmsg_mask |= SCO_CMSG_PKT_STATUS;
902 else
903 sco_pi(sk)->cmsg_mask &= SCO_CMSG_PKT_STATUS;
904 break;
905
Kiran Kf6873402021-09-07 15:42:42 +0530906 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700957 default:
958 err = -ENOPROTOOPT;
959 break;
960 }
961
962 release_sock(sk);
963 return err;
964}
965
Marcel Holtmannc4297e82015-10-26 02:08:38 +0100966static int sco_sock_getsockopt_old(struct socket *sock, int optname,
967 char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700968{
969 struct sock *sk = sock->sk;
970 struct sco_options opts;
971 struct sco_conninfo cinfo;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900972 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973
974 BT_DBG("sk %p", sk);
975
976 if (get_user(len, optlen))
977 return -EFAULT;
978
979 lock_sock(sk);
980
981 switch (optname) {
982 case SCO_OPTIONS:
Johan Hedberg9d225d22013-08-08 14:53:56 +0300983 if (sk->sk_state != BT_CONNECTED &&
984 !(sk->sk_state == BT_CONNECT2 &&
985 test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986 err = -ENOTCONN;
987 break;
988 }
989
990 opts.mtu = sco_pi(sk)->conn->mtu;
991
Kai Ye79dbeafe2021-06-03 15:41:04 +0800992 BT_DBG("mtu %u", opts.mtu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993
994 len = min_t(unsigned int, len, sizeof(opts));
995 if (copy_to_user(optval, (char *)&opts, len))
996 err = -EFAULT;
997
998 break;
999
1000 case SCO_CONNINFO:
Johan Hedberg9d225d22013-08-08 14:53:56 +03001001 if (sk->sk_state != BT_CONNECTED &&
1002 !(sk->sk_state == BT_CONNECT2 &&
1003 test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004 err = -ENOTCONN;
1005 break;
1006 }
1007
Vasiliy Kulikovc4c896e2011-02-14 13:54:26 +03001008 memset(&cinfo, 0, sizeof(cinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009 cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle;
1010 memcpy(cinfo.dev_class, sco_pi(sk)->conn->hcon->dev_class, 3);
1011
1012 len = min_t(unsigned int, len, sizeof(cinfo));
1013 if (copy_to_user(optval, (char *)&cinfo, len))
1014 err = -EFAULT;
1015
1016 break;
1017
1018 default:
1019 err = -ENOPROTOOPT;
1020 break;
1021 }
1022
1023 release_sock(sk);
1024 return err;
1025}
1026
Marcel Holtmannc4297e82015-10-26 02:08:38 +01001027static int sco_sock_getsockopt(struct socket *sock, int level, int optname,
1028 char __user *optval, int __user *optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001029{
1030 struct sock *sk = sock->sk;
1031 int len, err = 0;
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +02001032 struct bt_voice voice;
Luiz Augusto von Dentzeab24042020-02-14 10:08:57 -08001033 u32 phys;
Alain Michaud00398e12020-06-11 19:50:41 +00001034 int pkt_status;
Kiran K248733e2021-09-07 15:42:40 +05301035 int buf_len;
1036 struct codec_list *c;
1037 u8 num_codecs, i, __user *ptr;
1038 struct hci_dev *hdev;
1039 struct hci_codec_caps *caps;
1040 struct bt_codec codec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001041
1042 BT_DBG("sk %p", sk);
1043
1044 if (level == SOL_SCO)
1045 return sco_sock_getsockopt_old(sock, optname, optval, optlen);
1046
1047 if (get_user(len, optlen))
1048 return -EFAULT;
1049
1050 lock_sock(sk);
1051
1052 switch (optname) {
Frédéric Dalleaub96e9c62012-11-21 10:51:11 +01001053
1054 case BT_DEFER_SETUP:
1055 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1056 err = -EINVAL;
1057 break;
1058 }
1059
1060 if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags),
Marcel Holtmannc4297e82015-10-26 02:08:38 +01001061 (u32 __user *)optval))
Frédéric Dalleaub96e9c62012-11-21 10:51:11 +01001062 err = -EFAULT;
1063
1064 break;
1065
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +02001066 case BT_VOICE:
1067 voice.setting = sco_pi(sk)->setting;
1068
1069 len = min_t(unsigned int, len, sizeof(voice));
1070 if (copy_to_user(optval, (char *)&voice, len))
1071 err = -EFAULT;
1072
1073 break;
1074
Luiz Augusto von Dentzeab24042020-02-14 10:08:57 -08001075 case BT_PHY:
Luiz Augusto von Dentza2a8b0b2020-02-18 10:33:20 -08001076 if (sk->sk_state != BT_CONNECTED) {
Luiz Augusto von Dentzeab24042020-02-14 10:08:57 -08001077 err = -ENOTCONN;
1078 break;
1079 }
1080
1081 phys = hci_conn_get_phy(sco_pi(sk)->conn->hcon);
1082
1083 if (put_user(phys, (u32 __user *) optval))
1084 err = -EFAULT;
1085 break;
1086
Alain Michaud00398e12020-06-11 19:50:41 +00001087 case BT_PKT_STATUS:
1088 pkt_status = (sco_pi(sk)->cmsg_mask & SCO_CMSG_PKT_STATUS);
1089
1090 if (put_user(pkt_status, (int __user *)optval))
1091 err = -EFAULT;
1092 break;
1093
Joseph Hwang0fc1a722020-09-10 14:04:02 +08001094 case BT_SNDMTU:
1095 case BT_RCVMTU:
Wei Yongjunf6b8c6b2020-11-16 21:24:21 +08001096 if (sk->sk_state != BT_CONNECTED) {
1097 err = -ENOTCONN;
1098 break;
1099 }
1100
Joseph Hwang0fc1a722020-09-10 14:04:02 +08001101 if (put_user(sco_pi(sk)->conn->mtu, (u32 __user *)optval))
1102 err = -EFAULT;
1103 break;
1104
Kiran K248733e2021-09-07 15:42:40 +05301105 case BT_CODEC:
1106 num_codecs = 0;
1107 buf_len = 0;
1108
1109 hdev = hci_get_route(&sco_pi(sk)->dst, &sco_pi(sk)->src, BDADDR_BREDR);
1110 if (!hdev) {
1111 err = -EBADFD;
1112 break;
1113 }
1114
1115 if (!hci_dev_test_flag(hdev, HCI_OFFLOAD_CODECS_ENABLED)) {
1116 hci_dev_put(hdev);
1117 err = -EOPNOTSUPP;
1118 break;
1119 }
1120
1121 if (!hdev->get_data_path_id) {
1122 hci_dev_put(hdev);
1123 err = -EOPNOTSUPP;
1124 break;
1125 }
1126
1127 /* find total buffer size required to copy codec + caps */
1128 hci_dev_lock(hdev);
1129 list_for_each_entry(c, &hdev->local_codecs, list) {
1130 if (c->transport != HCI_TRANSPORT_SCO_ESCO)
1131 continue;
1132 num_codecs++;
1133 for (i = 0, caps = c->caps; i < c->num_caps; i++) {
1134 buf_len += 1 + caps->len;
1135 caps = (void *)&caps->data[caps->len];
1136 }
1137 buf_len += sizeof(struct bt_codec);
1138 }
1139 hci_dev_unlock(hdev);
1140
1141 buf_len += sizeof(struct bt_codecs);
1142 if (buf_len > len) {
1143 hci_dev_put(hdev);
1144 err = -ENOBUFS;
1145 break;
1146 }
1147 ptr = optval;
1148
1149 if (put_user(num_codecs, ptr)) {
1150 hci_dev_put(hdev);
1151 err = -EFAULT;
1152 break;
1153 }
1154 ptr += sizeof(num_codecs);
1155
1156 /* Iterate all the codecs supported over SCO and populate
1157 * codec data
1158 */
1159 hci_dev_lock(hdev);
1160 list_for_each_entry(c, &hdev->local_codecs, list) {
1161 if (c->transport != HCI_TRANSPORT_SCO_ESCO)
1162 continue;
1163
1164 codec.id = c->id;
1165 codec.cid = c->cid;
1166 codec.vid = c->vid;
1167 err = hdev->get_data_path_id(hdev, &codec.data_path);
1168 if (err < 0)
1169 break;
1170 codec.num_caps = c->num_caps;
1171 if (copy_to_user(ptr, &codec, sizeof(codec))) {
1172 err = -EFAULT;
1173 break;
1174 }
1175 ptr += sizeof(codec);
1176
1177 /* find codec capabilities data length */
1178 len = 0;
1179 for (i = 0, caps = c->caps; i < c->num_caps; i++) {
1180 len += 1 + caps->len;
1181 caps = (void *)&caps->data[caps->len];
1182 }
1183
1184 /* copy codec capabilities data */
1185 if (len && copy_to_user(ptr, c->caps, len)) {
1186 err = -EFAULT;
1187 break;
1188 }
1189 ptr += len;
1190 }
1191
1192 if (!err && put_user(buf_len, optlen))
1193 err = -EFAULT;
1194
1195 hci_dev_unlock(hdev);
1196 hci_dev_put(hdev);
1197
1198 break;
1199
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001200 default:
1201 err = -ENOPROTOOPT;
1202 break;
1203 }
1204
1205 release_sock(sk);
1206 return err;
1207}
1208
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +02001209static int sco_sock_shutdown(struct socket *sock, int how)
1210{
1211 struct sock *sk = sock->sk;
1212 int err = 0;
1213
1214 BT_DBG("sock %p, sk %p", sock, sk);
1215
1216 if (!sk)
1217 return 0;
1218
Kuba Pawlak1da55372015-10-05 18:44:17 +02001219 sock_hold(sk);
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +02001220 lock_sock(sk);
Kuba Pawlak1da55372015-10-05 18:44:17 +02001221
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +02001222 if (!sk->sk_shutdown) {
1223 sk->sk_shutdown = SHUTDOWN_MASK;
1224 sco_sock_clear_timer(sk);
1225 __sco_sock_close(sk);
1226
Vladimir Davydov093facf2014-07-15 12:25:28 +04001227 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
1228 !(current->flags & PF_EXITING))
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +02001229 err = bt_sock_wait_state(sk, BT_CLOSED,
Gustavo Padovanbe7c2b92012-05-17 00:36:21 -03001230 sk->sk_lingertime);
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +02001231 }
Kuba Pawlak1da55372015-10-05 18:44:17 +02001232
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +02001233 release_sock(sk);
Kuba Pawlak1da55372015-10-05 18:44:17 +02001234 sock_put(sk);
1235
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +02001236 return err;
1237}
1238
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239static int sco_sock_release(struct socket *sock)
1240{
1241 struct sock *sk = sock->sk;
1242 int err = 0;
1243
1244 BT_DBG("sock %p, sk %p", sock, sk);
1245
1246 if (!sk)
1247 return 0;
1248
1249 sco_sock_close(sk);
1250
Vladimir Davydov093facf2014-07-15 12:25:28 +04001251 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
1252 !(current->flags & PF_EXITING)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253 lock_sock(sk);
1254 err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
1255 release_sock(sk);
1256 }
1257
1258 sock_orphan(sk);
1259 sco_sock_kill(sk);
1260 return err;
1261}
1262
Linus Torvalds1da177e2005-04-16 15:20:36 -07001263static void sco_conn_ready(struct sco_conn *conn)
1264{
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +02001265 struct sock *parent;
1266 struct sock *sk = conn->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001267
1268 BT_DBG("conn %p", conn);
1269
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +02001270 if (sk) {
Desmond Cheong Zhi Xi27c24fd2021-08-10 12:14:07 +08001271 lock_sock(sk);
Desmond Cheong Zhi Xi3f2c89f2021-08-10 12:14:08 +08001272 sco_sock_clear_timer(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001273 sk->sk_state = BT_CONNECTED;
1274 sk->sk_state_change(sk);
Desmond Cheong Zhi Xi27c24fd2021-08-10 12:14:07 +08001275 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001276 } else {
Andre Guedes40528082013-01-29 19:59:56 -03001277 sco_conn_lock(conn);
1278
Kuba Pawlak2c501cd2015-10-26 16:17:14 +00001279 if (!conn->hcon) {
1280 sco_conn_unlock(conn);
1281 return;
1282 }
1283
Marcel Holtmann041987c2013-10-13 10:15:22 -07001284 parent = sco_get_sock_listen(&conn->hcon->src);
Andre Guedes40528082013-01-29 19:59:56 -03001285 if (!parent) {
1286 sco_conn_unlock(conn);
1287 return;
1288 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001289
Desmond Cheong Zhi Xi27c24fd2021-08-10 12:14:07 +08001290 lock_sock(parent);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001291
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -03001292 sk = sco_sock_alloc(sock_net(parent), NULL,
Eric W. Biederman11aa9c22015-05-08 21:09:13 -05001293 BTPROTO_SCO, GFP_ATOMIC, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001294 if (!sk) {
Desmond Cheong Zhi Xi27c24fd2021-08-10 12:14:07 +08001295 release_sock(parent);
Andre Guedes40528082013-01-29 19:59:56 -03001296 sco_conn_unlock(conn);
1297 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001298 }
1299
1300 sco_sock_init(sk, parent);
1301
Marcel Holtmanneea96362013-10-13 10:34:01 -07001302 bacpy(&sco_pi(sk)->src, &conn->hcon->src);
1303 bacpy(&sco_pi(sk)->dst, &conn->hcon->dst);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304
1305 hci_conn_hold(conn->hcon);
1306 __sco_chan_add(conn, sk, parent);
1307
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001308 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags))
1309 sk->sk_state = BT_CONNECT2;
1310 else
1311 sk->sk_state = BT_CONNECTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312
1313 /* Wake up parent */
David S. Miller676d2362014-04-11 16:15:36 -04001314 parent->sk_data_ready(parent);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315
Desmond Cheong Zhi Xi27c24fd2021-08-10 12:14:07 +08001316 release_sock(parent);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001317
Andre Guedes40528082013-01-29 19:59:56 -03001318 sco_conn_unlock(conn);
1319 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320}
1321
1322/* ----- SCO interface with lower layer (HCI) ----- */
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001323int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001324{
Gustavo Padovanfc5fef62012-05-23 04:04:19 -03001325 struct sock *sk;
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +01001326 int lm = 0;
1327
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001328 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +01001330 /* Find listening sockets */
1331 read_lock(&sco_sk_list.lock);
Sasha Levinb67bfe02013-02-27 17:06:00 -08001332 sk_for_each(sk, &sco_sk_list.head) {
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +01001333 if (sk->sk_state != BT_LISTEN)
1334 continue;
1335
Marcel Holtmanneea96362013-10-13 10:34:01 -07001336 if (!bacmp(&sco_pi(sk)->src, &hdev->bdaddr) ||
1337 !bacmp(&sco_pi(sk)->src, BDADDR_ANY)) {
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +01001338 lm |= HCI_LM_ACCEPT;
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001339
1340 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
1341 *flags |= HCI_PROTO_DEFER;
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +01001342 break;
1343 }
1344 }
1345 read_unlock(&sco_sk_list.lock);
1346
1347 return lm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348}
1349
Johan Hedberg539c4962015-02-18 14:53:57 +02001350static void sco_connect_cfm(struct hci_conn *hcon, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351{
Johan Hedberg539c4962015-02-18 14:53:57 +02001352 if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
1353 return;
1354
Kai Ye79dbeafe2021-06-03 15:41:04 +08001355 BT_DBG("hcon %p bdaddr %pMR status %u", hcon, &hcon->dst, status);
Johan Hedberg539c4962015-02-18 14:53:57 +02001356
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357 if (!status) {
1358 struct sco_conn *conn;
1359
Lukasz Rymanowski519e42b2012-04-19 16:12:28 +02001360 conn = sco_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361 if (conn)
1362 sco_conn_ready(conn);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001363 } else
Joe Perchese1750722011-06-29 18:18:29 -07001364 sco_conn_del(hcon, bt_to_errno(status));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365}
1366
Johan Hedberg3a6d5762015-02-18 14:53:58 +02001367static void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001368{
Johan Hedberg3a6d5762015-02-18 14:53:58 +02001369 if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
1370 return;
1371
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372 BT_DBG("hcon %p reason %d", hcon, reason);
1373
Joe Perchese1750722011-06-29 18:18:29 -07001374 sco_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375}
1376
Arron Wang9b4c3332015-06-09 17:47:22 +08001377void sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378{
1379 struct sco_conn *conn = hcon->sco_data;
1380
1381 if (!conn)
1382 goto drop;
1383
Kai Ye79dbeafe2021-06-03 15:41:04 +08001384 BT_DBG("conn %p len %u", conn, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385
1386 if (skb->len) {
1387 sco_recv_frame(conn, skb);
Arron Wang9b4c3332015-06-09 17:47:22 +08001388 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389 }
1390
1391drop:
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001392 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393}
1394
Johan Hedberg539c4962015-02-18 14:53:57 +02001395static struct hci_cb sco_cb = {
1396 .name = "SCO",
1397 .connect_cfm = sco_connect_cfm,
Johan Hedberg3a6d5762015-02-18 14:53:58 +02001398 .disconn_cfm = sco_disconn_cfm,
Johan Hedberg539c4962015-02-18 14:53:57 +02001399};
1400
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001401static int sco_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402{
1403 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404
Gustavo F. Padovanee65d192011-12-27 15:28:46 -02001405 read_lock(&sco_sk_list.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406
Sasha Levinb67bfe02013-02-27 17:06:00 -08001407 sk_for_each(sk, &sco_sk_list.head) {
Marcel Holtmanneea96362013-10-13 10:34:01 -07001408 seq_printf(f, "%pMR %pMR %d\n", &sco_pi(sk)->src,
1409 &sco_pi(sk)->dst, sk->sk_state);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08001410 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411
Gustavo F. Padovanee65d192011-12-27 15:28:46 -02001412 read_unlock(&sco_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08001413
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001414 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415}
1416
Yangtao Li8e2924e2018-11-05 09:56:19 -05001417DEFINE_SHOW_ATTRIBUTE(sco_debugfs);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001418
1419static struct dentry *sco_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08001421static const struct proto_ops sco_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001422 .family = PF_BLUETOOTH,
1423 .owner = THIS_MODULE,
1424 .release = sco_sock_release,
1425 .bind = sco_sock_bind,
1426 .connect = sco_sock_connect,
1427 .listen = sco_sock_listen,
1428 .accept = sco_sock_accept,
1429 .getname = sco_sock_getname,
1430 .sendmsg = sco_sock_sendmsg,
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001431 .recvmsg = sco_sock_recvmsg,
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07001432 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02001433 .ioctl = bt_sock_ioctl,
Arnd Bergmannc7cbdbf2019-04-17 22:51:48 +02001434 .gettstamp = sock_gettstamp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435 .mmap = sock_no_mmap,
1436 .socketpair = sock_no_socketpair,
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +02001437 .shutdown = sco_sock_shutdown,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001438 .setsockopt = sco_sock_setsockopt,
1439 .getsockopt = sco_sock_getsockopt
1440};
1441
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00001442static const struct net_proto_family sco_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443 .family = PF_BLUETOOTH,
1444 .owner = THIS_MODULE,
1445 .create = sco_sock_create,
1446};
1447
Gustavo F. Padovan64274512011-02-07 20:08:52 -02001448int __init sco_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001449{
1450 int err;
1451
Marcel Holtmann15762fa2015-01-11 15:21:06 -08001452 BUILD_BUG_ON(sizeof(struct sockaddr_sco) > sizeof(struct sockaddr));
1453
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454 err = proto_register(&sco_proto, 0);
1455 if (err < 0)
1456 return err;
1457
1458 err = bt_sock_register(BTPROTO_SCO, &sco_sock_family_ops);
1459 if (err < 0) {
1460 BT_ERR("SCO socket registration failed");
1461 goto error;
1462 }
1463
Al Virob0316612013-04-04 19:14:33 -04001464 err = bt_procfs_init(&init_net, "sco", &sco_sk_list, NULL);
Masatake YAMATOde9b9212012-07-26 01:30:12 +09001465 if (err < 0) {
1466 BT_ERR("Failed to create SCO proc file");
1467 bt_sock_unregister(BTPROTO_SCO);
1468 goto error;
1469 }
1470
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471 BT_INFO("SCO socket layer initialized");
1472
Johan Hedberg539c4962015-02-18 14:53:57 +02001473 hci_register_cb(&sco_cb);
1474
Marcel Holtmann1120e4b2013-10-17 17:24:16 -07001475 if (IS_ERR_OR_NULL(bt_debugfs))
1476 return 0;
1477
1478 sco_debugfs = debugfs_create_file("sco", 0444, bt_debugfs,
1479 NULL, &sco_debugfs_fops);
1480
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481 return 0;
1482
1483error:
1484 proto_unregister(&sco_proto);
1485 return err;
1486}
1487
Alexander Aring0402d9f22015-03-07 20:52:28 +01001488void sco_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489{
Masatake YAMATOde9b9212012-07-26 01:30:12 +09001490 bt_procfs_cleanup(&init_net, "sco");
1491
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001492 debugfs_remove(sco_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493
Johan Hedberg539c4962015-02-18 14:53:57 +02001494 hci_unregister_cb(&sco_cb);
1495
David Herrmann5e9d7f82013-02-24 19:36:51 +01001496 bt_sock_unregister(BTPROTO_SCO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498 proto_unregister(&sco_proto);
1499}
1500
Marcel Holtmann7cb127d2008-07-14 20:13:53 +02001501module_param(disable_esco, bool, 0644);
1502MODULE_PARM_DESC(disable_esco, "Disable eSCO connection creation");