blob: a92aebac56caf631eb8ebe9ade6dc462c3988a16 [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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070030
31#include <net/bluetooth/bluetooth.h>
32#include <net/bluetooth/hci_core.h>
33#include <net/bluetooth/sco.h>
34
Rusty Russelleb939922011-12-19 14:08:01 +000035static bool disable_esco;
Linus Torvalds1da177e2005-04-16 15:20:36 -070036
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080037static const struct proto_ops sco_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070038
39static struct bt_sock_list sco_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070040 .lock = __RW_LOCK_UNLOCKED(sco_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070041};
42
43static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent);
44static void sco_chan_del(struct sock *sk, int err);
45
Linus Torvalds1da177e2005-04-16 15:20:36 -070046static void sco_sock_close(struct sock *sk);
47static void sco_sock_kill(struct sock *sk);
48
49/* ---- SCO timers ---- */
50static void sco_sock_timeout(unsigned long arg)
51{
52 struct sock *sk = (struct sock *) arg;
53
54 BT_DBG("sock %p state %d", sk, sk->sk_state);
55
56 bh_lock_sock(sk);
57 sk->sk_err = ETIMEDOUT;
58 sk->sk_state_change(sk);
59 bh_unlock_sock(sk);
60
61 sco_sock_kill(sk);
62 sock_put(sk);
63}
64
65static void sco_sock_set_timer(struct sock *sk, long timeout)
66{
67 BT_DBG("sock %p state %d timeout %ld", sk, sk->sk_state, timeout);
68 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
69}
70
71static void sco_sock_clear_timer(struct sock *sk)
72{
73 BT_DBG("sock %p state %d", sk, sk->sk_state);
74 sk_stop_timer(sk, &sk->sk_timer);
75}
76
Linus Torvalds1da177e2005-04-16 15:20:36 -070077/* ---- SCO connections ---- */
Lukasz Rymanowski519e42b2012-04-19 16:12:28 +020078static struct sco_conn *sco_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -070079{
80 struct hci_dev *hdev = hcon->hdev;
Marcel Holtmann25ea6db2006-07-06 15:40:09 +020081 struct sco_conn *conn = hcon->sco_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070082
Lukasz Rymanowski519e42b2012-04-19 16:12:28 +020083 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -070084 return conn;
85
Claudio Takahasic10cc5a2013-04-11 11:35:45 -030086 conn = kzalloc(sizeof(struct sco_conn), GFP_KERNEL);
Marcel Holtmann25ea6db2006-07-06 15:40:09 +020087 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089
90 spin_lock_init(&conn->lock);
91
92 hcon->sco_data = conn;
93 conn->hcon = hcon;
94
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 if (hdev->sco_mtu > 0)
96 conn->mtu = hdev->sco_mtu;
97 else
98 conn->mtu = 60;
99
100 BT_DBG("hcon %p conn %p", hcon, conn);
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200101
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102 return conn;
103}
104
Gustavo Padovan6039aa732012-05-23 04:04:18 -0300105static struct sock *sco_chan_get(struct sco_conn *conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106{
107 struct sock *sk = NULL;
108 sco_conn_lock(conn);
109 sk = conn->sk;
110 sco_conn_unlock(conn);
111 return sk;
112}
113
114static int sco_conn_del(struct hci_conn *hcon, int err)
115{
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200116 struct sco_conn *conn = hcon->sco_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117 struct sock *sk;
118
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200119 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120 return 0;
121
122 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
123
124 /* Kill socket */
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200125 sk = sco_chan_get(conn);
126 if (sk) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127 bh_lock_sock(sk);
128 sco_sock_clear_timer(sk);
129 sco_chan_del(sk, err);
130 bh_unlock_sock(sk);
131 sco_sock_kill(sk);
132 }
133
134 hcon->sco_data = NULL;
135 kfree(conn);
136 return 0;
137}
138
Gustavo Padovan6039aa732012-05-23 04:04:18 -0300139static int sco_chan_add(struct sco_conn *conn, struct sock *sk,
140 struct sock *parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141{
142 int err = 0;
143
144 sco_conn_lock(conn);
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300145 if (conn->sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 err = -EBUSY;
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300147 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148 __sco_chan_add(conn, sk, parent);
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300149
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150 sco_conn_unlock(conn);
151 return err;
152}
153
154static int sco_connect(struct sock *sk)
155{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156 struct sco_conn *conn;
157 struct hci_conn *hcon;
158 struct hci_dev *hdev;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200159 int err, type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160
Marcel Holtmanneea96362013-10-13 10:34:01 -0700161 BT_DBG("%pMR -> %pMR", &sco_pi(sk)->src, &sco_pi(sk)->dst);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162
Marcel Holtmanneea96362013-10-13 10:34:01 -0700163 hdev = hci_get_route(&sco_pi(sk)->dst, &sco_pi(sk)->src);
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200164 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165 return -EHOSTUNREACH;
166
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300167 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168
Marcel Holtmann7cb127d2008-07-14 20:13:53 +0200169 if (lmp_esco_capable(hdev) && !disable_esco)
170 type = ESCO_LINK;
171 else
172 type = SCO_LINK;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200173
Frédéric Dalleau79dc0082013-08-19 14:24:01 +0200174 if (sco_pi(sk)->setting == BT_VOICE_TRANSPARENT &&
175 (!lmp_transp_capable(hdev) || !lmp_esco_capable(hdev))) {
176 err = -EOPNOTSUPP;
177 goto done;
178 }
179
Marcel Holtmanneea96362013-10-13 10:34:01 -0700180 hcon = hci_connect_sco(hdev, type, &sco_pi(sk)->dst,
Marcel Holtmann041987c2013-10-13 10:15:22 -0700181 sco_pi(sk)->setting);
Ville Tervo30e76272011-02-22 16:10:53 -0300182 if (IS_ERR(hcon)) {
183 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -0300185 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186
Lukasz Rymanowski519e42b2012-04-19 16:12:28 +0200187 conn = sco_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +0200189 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -0300190 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191 goto done;
192 }
193
194 /* Update source addr of the socket */
Marcel Holtmanneea96362013-10-13 10:34:01 -0700195 bacpy(&sco_pi(sk)->src, &hcon->src);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196
197 err = sco_chan_add(conn, sk, NULL);
198 if (err)
199 goto done;
200
201 if (hcon->state == BT_CONNECTED) {
202 sco_sock_clear_timer(sk);
203 sk->sk_state = BT_CONNECTED;
204 } else {
205 sk->sk_state = BT_CONNECT;
206 sco_sock_set_timer(sk, sk->sk_sndtimeo);
207 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200208
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209done:
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300210 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211 hci_dev_put(hdev);
212 return err;
213}
214
Gustavo Padovan6039aa732012-05-23 04:04:18 -0300215static int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216{
217 struct sco_conn *conn = sco_pi(sk)->conn;
218 struct sk_buff *skb;
Mikel Astiz088ce082012-04-11 08:48:48 +0200219 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220
221 /* Check outgoing MTU */
222 if (len > conn->mtu)
223 return -EINVAL;
224
225 BT_DBG("sk %p len %d", sk, len);
226
Mikel Astiz088ce082012-04-11 08:48:48 +0200227 skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300228 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229 return err;
230
Mikel Astiz088ce082012-04-11 08:48:48 +0200231 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300232 kfree_skb(skb);
233 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234 }
235
Gustavo F. Padovan0d861d82010-05-01 16:15:35 -0300236 hci_send_sco(conn->hcon, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237
Mikel Astiz088ce082012-04-11 08:48:48 +0200238 return len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239}
240
Gustavo Padovan6039aa732012-05-23 04:04:18 -0300241static void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242{
243 struct sock *sk = sco_chan_get(conn);
244
245 if (!sk)
246 goto drop;
247
248 BT_DBG("sk %p len %d", sk, skb->len);
249
250 if (sk->sk_state != BT_CONNECTED)
251 goto drop;
252
253 if (!sock_queue_rcv_skb(sk, skb))
254 return;
255
256drop:
257 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258}
259
260/* -------- Socket interface ---------- */
Marcel Holtmannfb334052012-04-19 14:37:58 +0200261static struct sock *__sco_get_sock_listen_by_addr(bdaddr_t *ba)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262{
Marcel Holtmannfb334052012-04-19 14:37:58 +0200263 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264
Sasha Levinb67bfe02013-02-27 17:06:00 -0800265 sk_for_each(sk, &sco_sk_list.head) {
Marcel Holtmannfb334052012-04-19 14:37:58 +0200266 if (sk->sk_state != BT_LISTEN)
267 continue;
268
Marcel Holtmanneea96362013-10-13 10:34:01 -0700269 if (!bacmp(&sco_pi(sk)->src, ba))
Marcel Holtmannfb334052012-04-19 14:37:58 +0200270 return sk;
271 }
272
273 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274}
275
276/* Find socket listening on source bdaddr.
277 * Returns closest match.
278 */
279static struct sock *sco_get_sock_listen(bdaddr_t *src)
280{
281 struct sock *sk = NULL, *sk1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282
283 read_lock(&sco_sk_list.lock);
284
Sasha Levinb67bfe02013-02-27 17:06:00 -0800285 sk_for_each(sk, &sco_sk_list.head) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286 if (sk->sk_state != BT_LISTEN)
287 continue;
288
289 /* Exact match. */
Marcel Holtmanneea96362013-10-13 10:34:01 -0700290 if (!bacmp(&sco_pi(sk)->src, src))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 break;
292
293 /* Closest match */
Marcel Holtmanneea96362013-10-13 10:34:01 -0700294 if (!bacmp(&sco_pi(sk)->src, BDADDR_ANY))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295 sk1 = sk;
296 }
297
298 read_unlock(&sco_sk_list.lock);
299
Sasha Levinb67bfe02013-02-27 17:06:00 -0800300 return sk ? sk : sk1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301}
302
303static void sco_sock_destruct(struct sock *sk)
304{
305 BT_DBG("sk %p", sk);
306
307 skb_queue_purge(&sk->sk_receive_queue);
308 skb_queue_purge(&sk->sk_write_queue);
309}
310
311static void sco_sock_cleanup_listen(struct sock *parent)
312{
313 struct sock *sk;
314
315 BT_DBG("parent %p", parent);
316
317 /* Close not yet accepted channels */
318 while ((sk = bt_accept_dequeue(parent, NULL))) {
319 sco_sock_close(sk);
320 sco_sock_kill(sk);
321 }
322
323 parent->sk_state = BT_CLOSED;
324 sock_set_flag(parent, SOCK_ZAPPED);
325}
326
327/* Kill socket (only if zapped and orphan)
328 * Must be called on unlocked socket.
329 */
330static void sco_sock_kill(struct sock *sk)
331{
332 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
333 return;
334
335 BT_DBG("sk %p state %d", sk, sk->sk_state);
336
337 /* Kill poor orphan */
338 bt_sock_unlink(&sco_sk_list, sk);
339 sock_set_flag(sk, SOCK_DEAD);
340 sock_put(sk);
341}
342
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200343static void __sco_sock_close(struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344{
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200345 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346
347 switch (sk->sk_state) {
348 case BT_LISTEN:
349 sco_sock_cleanup_listen(sk);
350 break;
351
352 case BT_CONNECTED:
353 case BT_CONFIG:
Gustavo Padovanb7e98b52013-01-03 19:59:28 -0200354 if (sco_pi(sk)->conn->hcon) {
Luiz Augusto von Dentz4a777082011-05-12 11:13:15 +0300355 sk->sk_state = BT_DISCONN;
356 sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT);
David Herrmann76a68ba2013-04-06 20:28:37 +0200357 hci_conn_drop(sco_pi(sk)->conn->hcon);
Luiz Augusto von Dentz4a777082011-05-12 11:13:15 +0300358 sco_pi(sk)->conn->hcon = NULL;
359 } else
360 sco_chan_del(sk, ECONNRESET);
361 break;
362
Vinicius Costa Gomeseb20ff92013-03-13 19:46:20 -0300363 case BT_CONNECT2:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364 case BT_CONNECT:
365 case BT_DISCONN:
366 sco_chan_del(sk, ECONNRESET);
367 break;
368
369 default:
370 sock_set_flag(sk, SOCK_ZAPPED);
371 break;
Stephen Hemminger3ff50b72007-04-20 17:09:22 -0700372 }
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200373}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200375/* Must be called on unlocked socket. */
376static void sco_sock_close(struct sock *sk)
377{
378 sco_sock_clear_timer(sk);
379 lock_sock(sk);
380 __sco_sock_close(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382 sco_sock_kill(sk);
383}
384
385static void sco_sock_init(struct sock *sk, struct sock *parent)
386{
387 BT_DBG("sk %p", sk);
388
Paul Moore6230c9b2011-10-07 09:40:59 +0000389 if (parent) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390 sk->sk_type = parent->sk_type;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +0100391 bt_sk(sk)->flags = bt_sk(parent)->flags;
Paul Moore6230c9b2011-10-07 09:40:59 +0000392 security_sk_clone(parent, sk);
393 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394}
395
396static struct proto sco_proto = {
397 .name = "SCO",
398 .owner = THIS_MODULE,
399 .obj_size = sizeof(struct sco_pinfo)
400};
401
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700402static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403{
404 struct sock *sk;
405
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700406 sk = sk_alloc(net, PF_BLUETOOTH, prio, &sco_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407 if (!sk)
408 return NULL;
409
410 sock_init_data(sock, sk);
411 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
412
413 sk->sk_destruct = sco_sock_destruct;
414 sk->sk_sndtimeo = SCO_CONN_TIMEOUT;
415
416 sock_reset_flag(sk, SOCK_ZAPPED);
417
418 sk->sk_protocol = proto;
419 sk->sk_state = BT_OPEN;
420
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +0200421 sco_pi(sk)->setting = BT_VOICE_CVSD_16BIT;
422
Pavel Emelyanovb24b8a22008-01-23 21:20:07 -0800423 setup_timer(&sk->sk_timer, sco_sock_timeout, (unsigned long)sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424
425 bt_sock_link(&sco_sk_list, sk);
426 return sk;
427}
428
Eric Paris3f378b62009-11-05 22:18:14 -0800429static int sco_sock_create(struct net *net, struct socket *sock, int protocol,
430 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431{
432 struct sock *sk;
433
434 BT_DBG("sock %p", sock);
435
436 sock->state = SS_UNCONNECTED;
437
438 if (sock->type != SOCK_SEQPACKET)
439 return -ESOCKTNOSUPPORT;
440
441 sock->ops = &sco_sock_ops;
442
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700443 sk = sco_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Marcel Holtmann74da6262006-10-15 17:31:14 +0200444 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 return -ENOMEM;
446
447 sco_sock_init(sk, NULL);
448 return 0;
449}
450
451static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
452{
453 struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
454 struct sock *sk = sock->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 int err = 0;
456
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +0300457 BT_DBG("sk %p %pMR", sk, &sa->sco_bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458
459 if (!addr || addr->sa_family != AF_BLUETOOTH)
460 return -EINVAL;
461
462 lock_sock(sk);
463
464 if (sk->sk_state != BT_OPEN) {
465 err = -EBADFD;
466 goto done;
467 }
468
Marcel Holtmann8ed21f72012-04-19 13:43:53 +0200469 if (sk->sk_type != SOCK_SEQPACKET) {
470 err = -EINVAL;
471 goto done;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 }
473
Marcel Holtmanneea96362013-10-13 10:34:01 -0700474 bacpy(&sco_pi(sk)->src, &sa->sco_bdaddr);
Marcel Holtmann8ed21f72012-04-19 13:43:53 +0200475
476 sk->sk_state = BT_BOUND;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477
478done:
479 release_sock(sk);
480 return err;
481}
482
483static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
484{
485 struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
486 struct sock *sk = sock->sk;
Claudio Takahasi92f185c2013-04-11 11:35:46 -0300487 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488
489 BT_DBG("sk %p", sk);
490
Changli Gao6503d962010-03-31 22:58:26 +0000491 if (alen < sizeof(struct sockaddr_sco) ||
492 addr->sa_family != AF_BLUETOOTH)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493 return -EINVAL;
494
495 if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)
496 return -EBADFD;
497
498 if (sk->sk_type != SOCK_SEQPACKET)
499 return -EINVAL;
500
501 lock_sock(sk);
502
503 /* Set destination address and psm */
Marcel Holtmanneea96362013-10-13 10:34:01 -0700504 bacpy(&sco_pi(sk)->dst, &sa->sco_bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200506 err = sco_connect(sk);
507 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508 goto done;
509
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900510 err = bt_sock_wait_state(sk, BT_CONNECTED,
Gustavo Padovanbe7c2b92012-05-17 00:36:21 -0300511 sock_sndtimeo(sk, flags & O_NONBLOCK));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512
513done:
514 release_sock(sk);
515 return err;
516}
517
518static int sco_sock_listen(struct socket *sock, int backlog)
519{
520 struct sock *sk = sock->sk;
Marcel Holtmanneea96362013-10-13 10:34:01 -0700521 bdaddr_t *src = &sco_pi(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522 int err = 0;
523
524 BT_DBG("sk %p backlog %d", sk, backlog);
525
526 lock_sock(sk);
527
Marcel Holtmann7d5d7752012-04-19 13:43:52 +0200528 if (sk->sk_state != BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 err = -EBADFD;
530 goto done;
531 }
532
Marcel Holtmann7d5d7752012-04-19 13:43:52 +0200533 if (sk->sk_type != SOCK_SEQPACKET) {
534 err = -EINVAL;
535 goto done;
536 }
537
Marcel Holtmannfb334052012-04-19 14:37:58 +0200538 write_lock(&sco_sk_list.lock);
539
540 if (__sco_get_sock_listen_by_addr(src)) {
541 err = -EADDRINUSE;
542 goto unlock;
543 }
544
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545 sk->sk_max_ack_backlog = backlog;
546 sk->sk_ack_backlog = 0;
Marcel Holtmannfb334052012-04-19 14:37:58 +0200547
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548 sk->sk_state = BT_LISTEN;
549
Marcel Holtmannfb334052012-04-19 14:37:58 +0200550unlock:
551 write_unlock(&sco_sk_list.lock);
552
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553done:
554 release_sock(sk);
555 return err;
556}
557
558static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flags)
559{
560 DECLARE_WAITQUEUE(wait, current);
561 struct sock *sk = sock->sk, *ch;
562 long timeo;
563 int err = 0;
564
565 lock_sock(sk);
566
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
568
569 BT_DBG("sk %p timeo %ld", sk, timeo);
570
571 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +0000572 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Peter Hurley552b0d32011-07-24 00:11:01 -0400573 while (1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 set_current_state(TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575
576 if (sk->sk_state != BT_LISTEN) {
577 err = -EBADFD;
578 break;
579 }
580
Peter Hurley552b0d32011-07-24 00:11:01 -0400581 ch = bt_accept_dequeue(sk, newsock);
582 if (ch)
583 break;
584
585 if (!timeo) {
586 err = -EAGAIN;
587 break;
588 }
589
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590 if (signal_pending(current)) {
591 err = sock_intr_errno(timeo);
592 break;
593 }
Peter Hurley552b0d32011-07-24 00:11:01 -0400594
595 release_sock(sk);
596 timeo = schedule_timeout(timeo);
597 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 }
Peter Hurley552b0d32011-07-24 00:11:01 -0400599 __set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +0000600 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601
602 if (err)
603 goto done;
604
605 newsock->state = SS_CONNECTED;
606
607 BT_DBG("new socket %p", ch);
608
609done:
610 release_sock(sk);
611 return err;
612}
613
614static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
615{
616 struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
617 struct sock *sk = sock->sk;
618
619 BT_DBG("sock %p, sk %p", sock, sk);
620
621 addr->sa_family = AF_BLUETOOTH;
622 *len = sizeof(struct sockaddr_sco);
623
624 if (peer)
Marcel Holtmanneea96362013-10-13 10:34:01 -0700625 bacpy(&sa->sco_bdaddr, &sco_pi(sk)->dst);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626 else
Marcel Holtmanneea96362013-10-13 10:34:01 -0700627 bacpy(&sa->sco_bdaddr, &sco_pi(sk)->src);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628
629 return 0;
630}
631
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900632static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633 struct msghdr *msg, size_t len)
634{
635 struct sock *sk = sock->sk;
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300636 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637
638 BT_DBG("sock %p, sk %p", sock, sk);
639
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -0800640 err = sock_error(sk);
641 if (err)
642 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643
644 if (msg->msg_flags & MSG_OOB)
645 return -EOPNOTSUPP;
646
647 lock_sock(sk);
648
649 if (sk->sk_state == BT_CONNECTED)
650 err = sco_send_frame(sk, msg, len);
651 else
652 err = -ENOTCONN;
653
654 release_sock(sk);
655 return err;
656}
657
Frédéric Dalleau2f69a822013-08-19 14:23:58 +0200658static void sco_conn_defer_accept(struct hci_conn *conn, u16 setting)
Frédéric Dalleaufa5513b2013-04-16 17:28:58 +0200659{
660 struct hci_dev *hdev = conn->hdev;
661
662 BT_DBG("conn %p", conn);
663
664 conn->state = BT_CONFIG;
665
666 if (!lmp_esco_capable(hdev)) {
667 struct hci_cp_accept_conn_req cp;
668
669 bacpy(&cp.bdaddr, &conn->dst);
Frédéric Dalleau33f24042013-08-19 14:23:55 +0200670 cp.role = 0x00; /* Ignored */
Frédéric Dalleaufa5513b2013-04-16 17:28:58 +0200671
672 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp);
673 } else {
674 struct hci_cp_accept_sync_conn_req cp;
675
676 bacpy(&cp.bdaddr, &conn->dst);
677 cp.pkt_type = cpu_to_le16(conn->pkt_type);
678
679 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
680 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
Frédéric Dalleau2f69a822013-08-19 14:23:58 +0200681 cp.content_format = cpu_to_le16(setting);
682
683 switch (setting & SCO_AIRMODE_MASK) {
684 case SCO_AIRMODE_TRANSP:
685 if (conn->pkt_type & ESCO_2EV3)
686 cp.max_latency = __constant_cpu_to_le16(0x0008);
687 else
688 cp.max_latency = __constant_cpu_to_le16(0x000D);
689 cp.retrans_effort = 0x02;
690 break;
691 case SCO_AIRMODE_CVSD:
692 cp.max_latency = __constant_cpu_to_le16(0xffff);
693 cp.retrans_effort = 0xff;
694 break;
695 }
Frédéric Dalleaufa5513b2013-04-16 17:28:58 +0200696
697 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
698 sizeof(cp), &cp);
699 }
700}
701
Frédéric Dalleau20714bf2012-11-21 10:51:12 +0100702static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
703 struct msghdr *msg, size_t len, int flags)
704{
705 struct sock *sk = sock->sk;
706 struct sco_pinfo *pi = sco_pi(sk);
707
708 lock_sock(sk);
709
710 if (sk->sk_state == BT_CONNECT2 &&
711 test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Frédéric Dalleau2f69a822013-08-19 14:23:58 +0200712 sco_conn_defer_accept(pi->conn->hcon, pi->setting);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +0100713 sk->sk_state = BT_CONFIG;
Mathias Krausec8c49912013-04-07 01:51:51 +0000714 msg->msg_namelen = 0;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +0100715
716 release_sock(sk);
717 return 0;
718 }
719
720 release_sock(sk);
721
722 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
723}
724
David S. Millerb7058842009-09-30 16:12:20 -0700725static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726{
727 struct sock *sk = sock->sk;
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +0200728 int len, err = 0;
729 struct bt_voice voice;
Frédéric Dalleaub96e9c62012-11-21 10:51:11 +0100730 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731
732 BT_DBG("sk %p", sk);
733
734 lock_sock(sk);
735
736 switch (optname) {
Frédéric Dalleaub96e9c62012-11-21 10:51:11 +0100737
738 case BT_DEFER_SETUP:
739 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
740 err = -EINVAL;
741 break;
742 }
743
744 if (get_user(opt, (u32 __user *) optval)) {
745 err = -EFAULT;
746 break;
747 }
748
749 if (opt)
750 set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
751 else
752 clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
753 break;
754
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +0200755 case BT_VOICE:
756 if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND &&
757 sk->sk_state != BT_CONNECT2) {
758 err = -EINVAL;
759 break;
760 }
761
762 voice.setting = sco_pi(sk)->setting;
763
764 len = min_t(unsigned int, sizeof(voice), optlen);
765 if (copy_from_user((char *) &voice, optval, len)) {
766 err = -EFAULT;
767 break;
768 }
769
770 /* Explicitly check for these values */
771 if (voice.setting != BT_VOICE_TRANSPARENT &&
772 voice.setting != BT_VOICE_CVSD_16BIT) {
773 err = -EINVAL;
774 break;
775 }
776
777 sco_pi(sk)->setting = voice.setting;
778 break;
779
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 default:
781 err = -ENOPROTOOPT;
782 break;
783 }
784
785 release_sock(sk);
786 return err;
787}
788
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100789static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790{
791 struct sock *sk = sock->sk;
792 struct sco_options opts;
793 struct sco_conninfo cinfo;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900794 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795
796 BT_DBG("sk %p", sk);
797
798 if (get_user(len, optlen))
799 return -EFAULT;
800
801 lock_sock(sk);
802
803 switch (optname) {
804 case SCO_OPTIONS:
Johan Hedberg9d225d22013-08-08 14:53:56 +0300805 if (sk->sk_state != BT_CONNECTED &&
806 !(sk->sk_state == BT_CONNECT2 &&
807 test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808 err = -ENOTCONN;
809 break;
810 }
811
812 opts.mtu = sco_pi(sk)->conn->mtu;
813
814 BT_DBG("mtu %d", opts.mtu);
815
816 len = min_t(unsigned int, len, sizeof(opts));
817 if (copy_to_user(optval, (char *)&opts, len))
818 err = -EFAULT;
819
820 break;
821
822 case SCO_CONNINFO:
Johan Hedberg9d225d22013-08-08 14:53:56 +0300823 if (sk->sk_state != BT_CONNECTED &&
824 !(sk->sk_state == BT_CONNECT2 &&
825 test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826 err = -ENOTCONN;
827 break;
828 }
829
Vasiliy Kulikovc4c896e2011-02-14 13:54:26 +0300830 memset(&cinfo, 0, sizeof(cinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle;
832 memcpy(cinfo.dev_class, sco_pi(sk)->conn->hcon->dev_class, 3);
833
834 len = min_t(unsigned int, len, sizeof(cinfo));
835 if (copy_to_user(optval, (char *)&cinfo, len))
836 err = -EFAULT;
837
838 break;
839
840 default:
841 err = -ENOPROTOOPT;
842 break;
843 }
844
845 release_sock(sk);
846 return err;
847}
848
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100849static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
850{
851 struct sock *sk = sock->sk;
852 int len, err = 0;
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +0200853 struct bt_voice voice;
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100854
855 BT_DBG("sk %p", sk);
856
857 if (level == SOL_SCO)
858 return sco_sock_getsockopt_old(sock, optname, optval, optlen);
859
860 if (get_user(len, optlen))
861 return -EFAULT;
862
863 lock_sock(sk);
864
865 switch (optname) {
Frédéric Dalleaub96e9c62012-11-21 10:51:11 +0100866
867 case BT_DEFER_SETUP:
868 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
869 err = -EINVAL;
870 break;
871 }
872
873 if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags),
874 (u32 __user *) optval))
875 err = -EFAULT;
876
877 break;
878
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +0200879 case BT_VOICE:
880 voice.setting = sco_pi(sk)->setting;
881
882 len = min_t(unsigned int, len, sizeof(voice));
883 if (copy_to_user(optval, (char *)&voice, len))
884 err = -EFAULT;
885
886 break;
887
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100888 default:
889 err = -ENOPROTOOPT;
890 break;
891 }
892
893 release_sock(sk);
894 return err;
895}
896
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200897static int sco_sock_shutdown(struct socket *sock, int how)
898{
899 struct sock *sk = sock->sk;
900 int err = 0;
901
902 BT_DBG("sock %p, sk %p", sock, sk);
903
904 if (!sk)
905 return 0;
906
907 lock_sock(sk);
908 if (!sk->sk_shutdown) {
909 sk->sk_shutdown = SHUTDOWN_MASK;
910 sco_sock_clear_timer(sk);
911 __sco_sock_close(sk);
912
913 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
914 err = bt_sock_wait_state(sk, BT_CLOSED,
Gustavo Padovanbe7c2b92012-05-17 00:36:21 -0300915 sk->sk_lingertime);
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200916 }
917 release_sock(sk);
918 return err;
919}
920
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921static int sco_sock_release(struct socket *sock)
922{
923 struct sock *sk = sock->sk;
924 int err = 0;
925
926 BT_DBG("sock %p, sk %p", sock, sk);
927
928 if (!sk)
929 return 0;
930
931 sco_sock_close(sk);
932
933 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) {
934 lock_sock(sk);
935 err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
936 release_sock(sk);
937 }
938
939 sock_orphan(sk);
940 sco_sock_kill(sk);
941 return err;
942}
943
944static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
945{
946 BT_DBG("conn %p", conn);
947
948 sco_pi(sk)->conn = conn;
949 conn->sk = sk;
950
951 if (parent)
952 bt_accept_enqueue(parent, sk);
953}
954
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900955/* Delete channel.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956 * Must be called on the locked socket. */
957static void sco_chan_del(struct sock *sk, int err)
958{
959 struct sco_conn *conn;
960
961 conn = sco_pi(sk)->conn;
962
963 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
964
Gustavo Padovan0b27a4b2012-12-03 15:36:51 -0200965 if (conn) {
966 sco_conn_lock(conn);
967 conn->sk = NULL;
968 sco_pi(sk)->conn = NULL;
969 sco_conn_unlock(conn);
970
971 if (conn->hcon)
David Herrmann76a68ba2013-04-06 20:28:37 +0200972 hci_conn_drop(conn->hcon);
Gustavo Padovan0b27a4b2012-12-03 15:36:51 -0200973 }
974
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975 sk->sk_state = BT_CLOSED;
976 sk->sk_err = err;
977 sk->sk_state_change(sk);
978
979 sock_set_flag(sk, SOCK_ZAPPED);
980}
981
982static void sco_conn_ready(struct sco_conn *conn)
983{
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200984 struct sock *parent;
985 struct sock *sk = conn->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986
987 BT_DBG("conn %p", conn);
988
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200989 if (sk) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990 sco_sock_clear_timer(sk);
991 bh_lock_sock(sk);
992 sk->sk_state = BT_CONNECTED;
993 sk->sk_state_change(sk);
994 bh_unlock_sock(sk);
995 } else {
Andre Guedes40528082013-01-29 19:59:56 -0300996 sco_conn_lock(conn);
997
Marcel Holtmann041987c2013-10-13 10:15:22 -0700998 parent = sco_get_sock_listen(&conn->hcon->src);
Andre Guedes40528082013-01-29 19:59:56 -0300999 if (!parent) {
1000 sco_conn_unlock(conn);
1001 return;
1002 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003
1004 bh_lock_sock(parent);
1005
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -03001006 sk = sco_sock_alloc(sock_net(parent), NULL,
Gustavo Padovanbe7c2b92012-05-17 00:36:21 -03001007 BTPROTO_SCO, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008 if (!sk) {
1009 bh_unlock_sock(parent);
Andre Guedes40528082013-01-29 19:59:56 -03001010 sco_conn_unlock(conn);
1011 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012 }
1013
1014 sco_sock_init(sk, parent);
1015
Marcel Holtmanneea96362013-10-13 10:34:01 -07001016 bacpy(&sco_pi(sk)->src, &conn->hcon->src);
1017 bacpy(&sco_pi(sk)->dst, &conn->hcon->dst);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018
1019 hci_conn_hold(conn->hcon);
1020 __sco_chan_add(conn, sk, parent);
1021
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001022 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags))
1023 sk->sk_state = BT_CONNECT2;
1024 else
1025 sk->sk_state = BT_CONNECTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001026
1027 /* Wake up parent */
1028 parent->sk_data_ready(parent, 1);
1029
1030 bh_unlock_sock(parent);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031
Andre Guedes40528082013-01-29 19:59:56 -03001032 sco_conn_unlock(conn);
1033 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034}
1035
1036/* ----- SCO interface with lower layer (HCI) ----- */
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001037int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038{
Gustavo Padovanfc5fef62012-05-23 04:04:19 -03001039 struct sock *sk;
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +01001040 int lm = 0;
1041
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001042 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001043
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +01001044 /* Find listening sockets */
1045 read_lock(&sco_sk_list.lock);
Sasha Levinb67bfe02013-02-27 17:06:00 -08001046 sk_for_each(sk, &sco_sk_list.head) {
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +01001047 if (sk->sk_state != BT_LISTEN)
1048 continue;
1049
Marcel Holtmanneea96362013-10-13 10:34:01 -07001050 if (!bacmp(&sco_pi(sk)->src, &hdev->bdaddr) ||
1051 !bacmp(&sco_pi(sk)->src, BDADDR_ANY)) {
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +01001052 lm |= HCI_LM_ACCEPT;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001053
1054 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
1055 *flags |= HCI_PROTO_DEFER;
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +01001056 break;
1057 }
1058 }
1059 read_unlock(&sco_sk_list.lock);
1060
1061 return lm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062}
1063
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03001064void sco_connect_cfm(struct hci_conn *hcon, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065{
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001066 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067 if (!status) {
1068 struct sco_conn *conn;
1069
Lukasz Rymanowski519e42b2012-04-19 16:12:28 +02001070 conn = sco_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071 if (conn)
1072 sco_conn_ready(conn);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001073 } else
Joe Perchese1750722011-06-29 18:18:29 -07001074 sco_conn_del(hcon, bt_to_errno(status));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075}
1076
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03001077void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078{
1079 BT_DBG("hcon %p reason %d", hcon, reason);
1080
Joe Perchese1750722011-06-29 18:18:29 -07001081 sco_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082}
1083
Ulisses Furquim686ebf22011-12-21 10:11:33 -02001084int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085{
1086 struct sco_conn *conn = hcon->sco_data;
1087
1088 if (!conn)
1089 goto drop;
1090
1091 BT_DBG("conn %p len %d", conn, skb->len);
1092
1093 if (skb->len) {
1094 sco_recv_frame(conn, skb);
1095 return 0;
1096 }
1097
1098drop:
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001099 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100 return 0;
1101}
1102
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001103static int sco_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104{
1105 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106
Gustavo F. Padovanee65d192011-12-27 15:28:46 -02001107 read_lock(&sco_sk_list.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108
Sasha Levinb67bfe02013-02-27 17:06:00 -08001109 sk_for_each(sk, &sco_sk_list.head) {
Marcel Holtmanneea96362013-10-13 10:34:01 -07001110 seq_printf(f, "%pMR %pMR %d\n", &sco_pi(sk)->src,
1111 &sco_pi(sk)->dst, sk->sk_state);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08001112 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113
Gustavo F. Padovanee65d192011-12-27 15:28:46 -02001114 read_unlock(&sco_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08001115
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001116 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117}
1118
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001119static int sco_debugfs_open(struct inode *inode, struct file *file)
1120{
1121 return single_open(file, sco_debugfs_show, inode->i_private);
1122}
1123
1124static const struct file_operations sco_debugfs_fops = {
1125 .open = sco_debugfs_open,
1126 .read = seq_read,
1127 .llseek = seq_lseek,
1128 .release = single_release,
1129};
1130
1131static struct dentry *sco_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08001133static const struct proto_ops sco_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134 .family = PF_BLUETOOTH,
1135 .owner = THIS_MODULE,
1136 .release = sco_sock_release,
1137 .bind = sco_sock_bind,
1138 .connect = sco_sock_connect,
1139 .listen = sco_sock_listen,
1140 .accept = sco_sock_accept,
1141 .getname = sco_sock_getname,
1142 .sendmsg = sco_sock_sendmsg,
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001143 .recvmsg = sco_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02001145 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146 .mmap = sock_no_mmap,
1147 .socketpair = sock_no_socketpair,
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +02001148 .shutdown = sco_sock_shutdown,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149 .setsockopt = sco_sock_setsockopt,
1150 .getsockopt = sco_sock_getsockopt
1151};
1152
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00001153static const struct net_proto_family sco_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001154 .family = PF_BLUETOOTH,
1155 .owner = THIS_MODULE,
1156 .create = sco_sock_create,
1157};
1158
Gustavo F. Padovan64274512011-02-07 20:08:52 -02001159int __init sco_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160{
1161 int err;
1162
1163 err = proto_register(&sco_proto, 0);
1164 if (err < 0)
1165 return err;
1166
1167 err = bt_sock_register(BTPROTO_SCO, &sco_sock_family_ops);
1168 if (err < 0) {
1169 BT_ERR("SCO socket registration failed");
1170 goto error;
1171 }
1172
Al Virob0316612013-04-04 19:14:33 -04001173 err = bt_procfs_init(&init_net, "sco", &sco_sk_list, NULL);
Masatake YAMATOde9b9212012-07-26 01:30:12 +09001174 if (err < 0) {
1175 BT_ERR("Failed to create SCO proc file");
1176 bt_sock_unregister(BTPROTO_SCO);
1177 goto error;
1178 }
1179
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001180 if (bt_debugfs) {
Gustavo Padovanbe7c2b92012-05-17 00:36:21 -03001181 sco_debugfs = debugfs_create_file("sco", 0444, bt_debugfs,
1182 NULL, &sco_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001183 if (!sco_debugfs)
1184 BT_ERR("Failed to create SCO debug file");
1185 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187 BT_INFO("SCO socket layer initialized");
1188
1189 return 0;
1190
1191error:
1192 proto_unregister(&sco_proto);
1193 return err;
1194}
1195
Gustavo F. Padovan64274512011-02-07 20:08:52 -02001196void __exit sco_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197{
Masatake YAMATOde9b9212012-07-26 01:30:12 +09001198 bt_procfs_cleanup(&init_net, "sco");
1199
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001200 debugfs_remove(sco_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201
David Herrmann5e9d7f82013-02-24 19:36:51 +01001202 bt_sock_unregister(BTPROTO_SCO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204 proto_unregister(&sco_proto);
1205}
1206
Marcel Holtmann7cb127d2008-07-14 20:13:53 +02001207module_param(disable_esco, bool, 0644);
1208MODULE_PARM_DESC(disable_esco, "Disable eSCO connection creation");