blob: 96bd388d93a4aae145bfb207d26fbc3a90b9e0a8 [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
95 conn->src = &hdev->bdaddr;
96 conn->dst = &hcon->dst;
97
98 if (hdev->sco_mtu > 0)
99 conn->mtu = hdev->sco_mtu;
100 else
101 conn->mtu = 60;
102
103 BT_DBG("hcon %p conn %p", hcon, conn);
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200104
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105 return conn;
106}
107
Gustavo Padovan6039aa732012-05-23 04:04:18 -0300108static struct sock *sco_chan_get(struct sco_conn *conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109{
110 struct sock *sk = NULL;
111 sco_conn_lock(conn);
112 sk = conn->sk;
113 sco_conn_unlock(conn);
114 return sk;
115}
116
117static int sco_conn_del(struct hci_conn *hcon, int err)
118{
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200119 struct sco_conn *conn = hcon->sco_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120 struct sock *sk;
121
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200122 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123 return 0;
124
125 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
126
127 /* Kill socket */
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200128 sk = sco_chan_get(conn);
129 if (sk) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130 bh_lock_sock(sk);
131 sco_sock_clear_timer(sk);
132 sco_chan_del(sk, err);
133 bh_unlock_sock(sk);
134 sco_sock_kill(sk);
135 }
136
137 hcon->sco_data = NULL;
138 kfree(conn);
139 return 0;
140}
141
Gustavo Padovan6039aa732012-05-23 04:04:18 -0300142static int sco_chan_add(struct sco_conn *conn, struct sock *sk,
143 struct sock *parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144{
145 int err = 0;
146
147 sco_conn_lock(conn);
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300148 if (conn->sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 err = -EBUSY;
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300150 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151 __sco_chan_add(conn, sk, parent);
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300152
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153 sco_conn_unlock(conn);
154 return err;
155}
156
157static int sco_connect(struct sock *sk)
158{
159 bdaddr_t *src = &bt_sk(sk)->src;
160 bdaddr_t *dst = &bt_sk(sk)->dst;
161 struct sco_conn *conn;
162 struct hci_conn *hcon;
163 struct hci_dev *hdev;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200164 int err, type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +0300166 BT_DBG("%pMR -> %pMR", src, dst);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200168 hdev = hci_get_route(dst, src);
169 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 return -EHOSTUNREACH;
171
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300172 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173
Marcel Holtmann7cb127d2008-07-14 20:13:53 +0200174 if (lmp_esco_capable(hdev) && !disable_esco)
175 type = ESCO_LINK;
176 else
177 type = SCO_LINK;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200178
Frédéric Dalleau79dc0082013-08-19 14:24:01 +0200179 if (sco_pi(sk)->setting == BT_VOICE_TRANSPARENT &&
180 (!lmp_transp_capable(hdev) || !lmp_esco_capable(hdev))) {
181 err = -EOPNOTSUPP;
182 goto done;
183 }
184
Frédéric Dalleau10c62dd2013-08-19 14:23:59 +0200185 hcon = hci_connect_sco(hdev, type, dst, sco_pi(sk)->setting);
Ville Tervo30e76272011-02-22 16:10:53 -0300186 if (IS_ERR(hcon)) {
187 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -0300189 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190
Lukasz Rymanowski519e42b2012-04-19 16:12:28 +0200191 conn = sco_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +0200193 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -0300194 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195 goto done;
196 }
197
198 /* Update source addr of the socket */
199 bacpy(src, conn->src);
200
201 err = sco_chan_add(conn, sk, NULL);
202 if (err)
203 goto done;
204
205 if (hcon->state == BT_CONNECTED) {
206 sco_sock_clear_timer(sk);
207 sk->sk_state = BT_CONNECTED;
208 } else {
209 sk->sk_state = BT_CONNECT;
210 sco_sock_set_timer(sk, sk->sk_sndtimeo);
211 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200212
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213done:
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300214 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215 hci_dev_put(hdev);
216 return err;
217}
218
Gustavo Padovan6039aa732012-05-23 04:04:18 -0300219static int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220{
221 struct sco_conn *conn = sco_pi(sk)->conn;
222 struct sk_buff *skb;
Mikel Astiz088ce082012-04-11 08:48:48 +0200223 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224
225 /* Check outgoing MTU */
226 if (len > conn->mtu)
227 return -EINVAL;
228
229 BT_DBG("sk %p len %d", sk, len);
230
Mikel Astiz088ce082012-04-11 08:48:48 +0200231 skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300232 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233 return err;
234
Mikel Astiz088ce082012-04-11 08:48:48 +0200235 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300236 kfree_skb(skb);
237 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238 }
239
Gustavo F. Padovan0d861d82010-05-01 16:15:35 -0300240 hci_send_sco(conn->hcon, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241
Mikel Astiz088ce082012-04-11 08:48:48 +0200242 return len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243}
244
Gustavo Padovan6039aa732012-05-23 04:04:18 -0300245static void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246{
247 struct sock *sk = sco_chan_get(conn);
248
249 if (!sk)
250 goto drop;
251
252 BT_DBG("sk %p len %d", sk, skb->len);
253
254 if (sk->sk_state != BT_CONNECTED)
255 goto drop;
256
257 if (!sock_queue_rcv_skb(sk, skb))
258 return;
259
260drop:
261 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262}
263
264/* -------- Socket interface ---------- */
Marcel Holtmannfb334052012-04-19 14:37:58 +0200265static struct sock *__sco_get_sock_listen_by_addr(bdaddr_t *ba)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266{
Marcel Holtmannfb334052012-04-19 14:37:58 +0200267 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268
Sasha Levinb67bfe02013-02-27 17:06:00 -0800269 sk_for_each(sk, &sco_sk_list.head) {
Marcel Holtmannfb334052012-04-19 14:37:58 +0200270 if (sk->sk_state != BT_LISTEN)
271 continue;
272
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273 if (!bacmp(&bt_sk(sk)->src, ba))
Marcel Holtmannfb334052012-04-19 14:37:58 +0200274 return sk;
275 }
276
277 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278}
279
280/* Find socket listening on source bdaddr.
281 * Returns closest match.
282 */
283static struct sock *sco_get_sock_listen(bdaddr_t *src)
284{
285 struct sock *sk = NULL, *sk1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286
287 read_lock(&sco_sk_list.lock);
288
Sasha Levinb67bfe02013-02-27 17:06:00 -0800289 sk_for_each(sk, &sco_sk_list.head) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290 if (sk->sk_state != BT_LISTEN)
291 continue;
292
293 /* Exact match. */
294 if (!bacmp(&bt_sk(sk)->src, src))
295 break;
296
297 /* Closest match */
298 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
299 sk1 = sk;
300 }
301
302 read_unlock(&sco_sk_list.lock);
303
Sasha Levinb67bfe02013-02-27 17:06:00 -0800304 return sk ? sk : sk1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305}
306
307static void sco_sock_destruct(struct sock *sk)
308{
309 BT_DBG("sk %p", sk);
310
311 skb_queue_purge(&sk->sk_receive_queue);
312 skb_queue_purge(&sk->sk_write_queue);
313}
314
315static void sco_sock_cleanup_listen(struct sock *parent)
316{
317 struct sock *sk;
318
319 BT_DBG("parent %p", parent);
320
321 /* Close not yet accepted channels */
322 while ((sk = bt_accept_dequeue(parent, NULL))) {
323 sco_sock_close(sk);
324 sco_sock_kill(sk);
325 }
326
327 parent->sk_state = BT_CLOSED;
328 sock_set_flag(parent, SOCK_ZAPPED);
329}
330
331/* Kill socket (only if zapped and orphan)
332 * Must be called on unlocked socket.
333 */
334static void sco_sock_kill(struct sock *sk)
335{
336 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
337 return;
338
339 BT_DBG("sk %p state %d", sk, sk->sk_state);
340
341 /* Kill poor orphan */
342 bt_sock_unlink(&sco_sk_list, sk);
343 sock_set_flag(sk, SOCK_DEAD);
344 sock_put(sk);
345}
346
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200347static void __sco_sock_close(struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348{
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200349 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350
351 switch (sk->sk_state) {
352 case BT_LISTEN:
353 sco_sock_cleanup_listen(sk);
354 break;
355
356 case BT_CONNECTED:
357 case BT_CONFIG:
Gustavo Padovanb7e98b52013-01-03 19:59:28 -0200358 if (sco_pi(sk)->conn->hcon) {
Luiz Augusto von Dentz4a777082011-05-12 11:13:15 +0300359 sk->sk_state = BT_DISCONN;
360 sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT);
David Herrmann76a68ba2013-04-06 20:28:37 +0200361 hci_conn_drop(sco_pi(sk)->conn->hcon);
Luiz Augusto von Dentz4a777082011-05-12 11:13:15 +0300362 sco_pi(sk)->conn->hcon = NULL;
363 } else
364 sco_chan_del(sk, ECONNRESET);
365 break;
366
Vinicius Costa Gomeseb20ff92013-03-13 19:46:20 -0300367 case BT_CONNECT2:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368 case BT_CONNECT:
369 case BT_DISCONN:
370 sco_chan_del(sk, ECONNRESET);
371 break;
372
373 default:
374 sock_set_flag(sk, SOCK_ZAPPED);
375 break;
Stephen Hemminger3ff50b72007-04-20 17:09:22 -0700376 }
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200377}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200379/* Must be called on unlocked socket. */
380static void sco_sock_close(struct sock *sk)
381{
382 sco_sock_clear_timer(sk);
383 lock_sock(sk);
384 __sco_sock_close(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 sco_sock_kill(sk);
387}
388
389static void sco_sock_init(struct sock *sk, struct sock *parent)
390{
391 BT_DBG("sk %p", sk);
392
Paul Moore6230c9b2011-10-07 09:40:59 +0000393 if (parent) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394 sk->sk_type = parent->sk_type;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +0100395 bt_sk(sk)->flags = bt_sk(parent)->flags;
Paul Moore6230c9b2011-10-07 09:40:59 +0000396 security_sk_clone(parent, sk);
397 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398}
399
400static struct proto sco_proto = {
401 .name = "SCO",
402 .owner = THIS_MODULE,
403 .obj_size = sizeof(struct sco_pinfo)
404};
405
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700406static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407{
408 struct sock *sk;
409
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700410 sk = sk_alloc(net, PF_BLUETOOTH, prio, &sco_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411 if (!sk)
412 return NULL;
413
414 sock_init_data(sock, sk);
415 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
416
417 sk->sk_destruct = sco_sock_destruct;
418 sk->sk_sndtimeo = SCO_CONN_TIMEOUT;
419
420 sock_reset_flag(sk, SOCK_ZAPPED);
421
422 sk->sk_protocol = proto;
423 sk->sk_state = BT_OPEN;
424
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +0200425 sco_pi(sk)->setting = BT_VOICE_CVSD_16BIT;
426
Pavel Emelyanovb24b8a22008-01-23 21:20:07 -0800427 setup_timer(&sk->sk_timer, sco_sock_timeout, (unsigned long)sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428
429 bt_sock_link(&sco_sk_list, sk);
430 return sk;
431}
432
Eric Paris3f378b62009-11-05 22:18:14 -0800433static int sco_sock_create(struct net *net, struct socket *sock, int protocol,
434 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435{
436 struct sock *sk;
437
438 BT_DBG("sock %p", sock);
439
440 sock->state = SS_UNCONNECTED;
441
442 if (sock->type != SOCK_SEQPACKET)
443 return -ESOCKTNOSUPPORT;
444
445 sock->ops = &sco_sock_ops;
446
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700447 sk = sco_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Marcel Holtmann74da6262006-10-15 17:31:14 +0200448 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 return -ENOMEM;
450
451 sco_sock_init(sk, NULL);
452 return 0;
453}
454
455static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
456{
457 struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
458 struct sock *sk = sock->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459 int err = 0;
460
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +0300461 BT_DBG("sk %p %pMR", sk, &sa->sco_bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462
463 if (!addr || addr->sa_family != AF_BLUETOOTH)
464 return -EINVAL;
465
466 lock_sock(sk);
467
468 if (sk->sk_state != BT_OPEN) {
469 err = -EBADFD;
470 goto done;
471 }
472
Marcel Holtmann8ed21f72012-04-19 13:43:53 +0200473 if (sk->sk_type != SOCK_SEQPACKET) {
474 err = -EINVAL;
475 goto done;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 }
477
Marcel Holtmann8ed21f72012-04-19 13:43:53 +0200478 bacpy(&bt_sk(sk)->src, &sa->sco_bdaddr);
479
480 sk->sk_state = BT_BOUND;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481
482done:
483 release_sock(sk);
484 return err;
485}
486
487static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
488{
489 struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
490 struct sock *sk = sock->sk;
Claudio Takahasi92f185c2013-04-11 11:35:46 -0300491 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492
493 BT_DBG("sk %p", sk);
494
Changli Gao6503d962010-03-31 22:58:26 +0000495 if (alen < sizeof(struct sockaddr_sco) ||
496 addr->sa_family != AF_BLUETOOTH)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497 return -EINVAL;
498
499 if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)
500 return -EBADFD;
501
502 if (sk->sk_type != SOCK_SEQPACKET)
503 return -EINVAL;
504
505 lock_sock(sk);
506
507 /* Set destination address and psm */
508 bacpy(&bt_sk(sk)->dst, &sa->sco_bdaddr);
509
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200510 err = sco_connect(sk);
511 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512 goto done;
513
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900514 err = bt_sock_wait_state(sk, BT_CONNECTED,
Gustavo Padovanbe7c2b92012-05-17 00:36:21 -0300515 sock_sndtimeo(sk, flags & O_NONBLOCK));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516
517done:
518 release_sock(sk);
519 return err;
520}
521
522static int sco_sock_listen(struct socket *sock, int backlog)
523{
524 struct sock *sk = sock->sk;
Marcel Holtmannfb334052012-04-19 14:37:58 +0200525 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526 int err = 0;
527
528 BT_DBG("sk %p backlog %d", sk, backlog);
529
530 lock_sock(sk);
531
Marcel Holtmann7d5d7752012-04-19 13:43:52 +0200532 if (sk->sk_state != BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533 err = -EBADFD;
534 goto done;
535 }
536
Marcel Holtmann7d5d7752012-04-19 13:43:52 +0200537 if (sk->sk_type != SOCK_SEQPACKET) {
538 err = -EINVAL;
539 goto done;
540 }
541
Marcel Holtmannfb334052012-04-19 14:37:58 +0200542 write_lock(&sco_sk_list.lock);
543
544 if (__sco_get_sock_listen_by_addr(src)) {
545 err = -EADDRINUSE;
546 goto unlock;
547 }
548
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549 sk->sk_max_ack_backlog = backlog;
550 sk->sk_ack_backlog = 0;
Marcel Holtmannfb334052012-04-19 14:37:58 +0200551
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552 sk->sk_state = BT_LISTEN;
553
Marcel Holtmannfb334052012-04-19 14:37:58 +0200554unlock:
555 write_unlock(&sco_sk_list.lock);
556
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557done:
558 release_sock(sk);
559 return err;
560}
561
562static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flags)
563{
564 DECLARE_WAITQUEUE(wait, current);
565 struct sock *sk = sock->sk, *ch;
566 long timeo;
567 int err = 0;
568
569 lock_sock(sk);
570
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
572
573 BT_DBG("sk %p timeo %ld", sk, timeo);
574
575 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +0000576 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Peter Hurley552b0d32011-07-24 00:11:01 -0400577 while (1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578 set_current_state(TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579
580 if (sk->sk_state != BT_LISTEN) {
581 err = -EBADFD;
582 break;
583 }
584
Peter Hurley552b0d32011-07-24 00:11:01 -0400585 ch = bt_accept_dequeue(sk, newsock);
586 if (ch)
587 break;
588
589 if (!timeo) {
590 err = -EAGAIN;
591 break;
592 }
593
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594 if (signal_pending(current)) {
595 err = sock_intr_errno(timeo);
596 break;
597 }
Peter Hurley552b0d32011-07-24 00:11:01 -0400598
599 release_sock(sk);
600 timeo = schedule_timeout(timeo);
601 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602 }
Peter Hurley552b0d32011-07-24 00:11:01 -0400603 __set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +0000604 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605
606 if (err)
607 goto done;
608
609 newsock->state = SS_CONNECTED;
610
611 BT_DBG("new socket %p", ch);
612
613done:
614 release_sock(sk);
615 return err;
616}
617
618static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
619{
620 struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
621 struct sock *sk = sock->sk;
622
623 BT_DBG("sock %p, sk %p", sock, sk);
624
625 addr->sa_family = AF_BLUETOOTH;
626 *len = sizeof(struct sockaddr_sco);
627
628 if (peer)
629 bacpy(&sa->sco_bdaddr, &bt_sk(sk)->dst);
630 else
631 bacpy(&sa->sco_bdaddr, &bt_sk(sk)->src);
632
633 return 0;
634}
635
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900636static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 struct msghdr *msg, size_t len)
638{
639 struct sock *sk = sock->sk;
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300640 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641
642 BT_DBG("sock %p, sk %p", sock, sk);
643
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -0800644 err = sock_error(sk);
645 if (err)
646 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647
648 if (msg->msg_flags & MSG_OOB)
649 return -EOPNOTSUPP;
650
651 lock_sock(sk);
652
653 if (sk->sk_state == BT_CONNECTED)
654 err = sco_send_frame(sk, msg, len);
655 else
656 err = -ENOTCONN;
657
658 release_sock(sk);
659 return err;
660}
661
Frédéric Dalleau2f69a822013-08-19 14:23:58 +0200662static void sco_conn_defer_accept(struct hci_conn *conn, u16 setting)
Frédéric Dalleaufa5513b2013-04-16 17:28:58 +0200663{
664 struct hci_dev *hdev = conn->hdev;
665
666 BT_DBG("conn %p", conn);
667
668 conn->state = BT_CONFIG;
669
670 if (!lmp_esco_capable(hdev)) {
671 struct hci_cp_accept_conn_req cp;
672
673 bacpy(&cp.bdaddr, &conn->dst);
Frédéric Dalleau33f24042013-08-19 14:23:55 +0200674 cp.role = 0x00; /* Ignored */
Frédéric Dalleaufa5513b2013-04-16 17:28:58 +0200675
676 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp);
677 } else {
678 struct hci_cp_accept_sync_conn_req cp;
679
680 bacpy(&cp.bdaddr, &conn->dst);
681 cp.pkt_type = cpu_to_le16(conn->pkt_type);
682
683 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
684 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
Frédéric Dalleau2f69a822013-08-19 14:23:58 +0200685 cp.content_format = cpu_to_le16(setting);
686
687 switch (setting & SCO_AIRMODE_MASK) {
688 case SCO_AIRMODE_TRANSP:
689 if (conn->pkt_type & ESCO_2EV3)
690 cp.max_latency = __constant_cpu_to_le16(0x0008);
691 else
692 cp.max_latency = __constant_cpu_to_le16(0x000D);
693 cp.retrans_effort = 0x02;
694 break;
695 case SCO_AIRMODE_CVSD:
696 cp.max_latency = __constant_cpu_to_le16(0xffff);
697 cp.retrans_effort = 0xff;
698 break;
699 }
Frédéric Dalleaufa5513b2013-04-16 17:28:58 +0200700
701 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
702 sizeof(cp), &cp);
703 }
704}
705
Frédéric Dalleau20714bf2012-11-21 10:51:12 +0100706static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
707 struct msghdr *msg, size_t len, int flags)
708{
709 struct sock *sk = sock->sk;
710 struct sco_pinfo *pi = sco_pi(sk);
711
712 lock_sock(sk);
713
714 if (sk->sk_state == BT_CONNECT2 &&
715 test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Frédéric Dalleau2f69a822013-08-19 14:23:58 +0200716 sco_conn_defer_accept(pi->conn->hcon, pi->setting);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +0100717 sk->sk_state = BT_CONFIG;
Mathias Krausec8c49912013-04-07 01:51:51 +0000718 msg->msg_namelen = 0;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +0100719
720 release_sock(sk);
721 return 0;
722 }
723
724 release_sock(sk);
725
726 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
727}
728
David S. Millerb7058842009-09-30 16:12:20 -0700729static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730{
731 struct sock *sk = sock->sk;
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +0200732 int len, err = 0;
733 struct bt_voice voice;
Frédéric Dalleaub96e9c62012-11-21 10:51:11 +0100734 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735
736 BT_DBG("sk %p", sk);
737
738 lock_sock(sk);
739
740 switch (optname) {
Frédéric Dalleaub96e9c62012-11-21 10:51:11 +0100741
742 case BT_DEFER_SETUP:
743 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
744 err = -EINVAL;
745 break;
746 }
747
748 if (get_user(opt, (u32 __user *) optval)) {
749 err = -EFAULT;
750 break;
751 }
752
753 if (opt)
754 set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
755 else
756 clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
757 break;
758
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +0200759 case BT_VOICE:
760 if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND &&
761 sk->sk_state != BT_CONNECT2) {
762 err = -EINVAL;
763 break;
764 }
765
766 voice.setting = sco_pi(sk)->setting;
767
768 len = min_t(unsigned int, sizeof(voice), optlen);
769 if (copy_from_user((char *) &voice, optval, len)) {
770 err = -EFAULT;
771 break;
772 }
773
774 /* Explicitly check for these values */
775 if (voice.setting != BT_VOICE_TRANSPARENT &&
776 voice.setting != BT_VOICE_CVSD_16BIT) {
777 err = -EINVAL;
778 break;
779 }
780
781 sco_pi(sk)->setting = voice.setting;
782 break;
783
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784 default:
785 err = -ENOPROTOOPT;
786 break;
787 }
788
789 release_sock(sk);
790 return err;
791}
792
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100793static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794{
795 struct sock *sk = sock->sk;
796 struct sco_options opts;
797 struct sco_conninfo cinfo;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900798 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799
800 BT_DBG("sk %p", sk);
801
802 if (get_user(len, optlen))
803 return -EFAULT;
804
805 lock_sock(sk);
806
807 switch (optname) {
808 case SCO_OPTIONS:
Johan Hedberg9d225d22013-08-08 14:53:56 +0300809 if (sk->sk_state != BT_CONNECTED &&
810 !(sk->sk_state == BT_CONNECT2 &&
811 test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812 err = -ENOTCONN;
813 break;
814 }
815
816 opts.mtu = sco_pi(sk)->conn->mtu;
817
818 BT_DBG("mtu %d", opts.mtu);
819
820 len = min_t(unsigned int, len, sizeof(opts));
821 if (copy_to_user(optval, (char *)&opts, len))
822 err = -EFAULT;
823
824 break;
825
826 case SCO_CONNINFO:
Johan Hedberg9d225d22013-08-08 14:53:56 +0300827 if (sk->sk_state != BT_CONNECTED &&
828 !(sk->sk_state == BT_CONNECT2 &&
829 test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830 err = -ENOTCONN;
831 break;
832 }
833
Vasiliy Kulikovc4c896e2011-02-14 13:54:26 +0300834 memset(&cinfo, 0, sizeof(cinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835 cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle;
836 memcpy(cinfo.dev_class, sco_pi(sk)->conn->hcon->dev_class, 3);
837
838 len = min_t(unsigned int, len, sizeof(cinfo));
839 if (copy_to_user(optval, (char *)&cinfo, len))
840 err = -EFAULT;
841
842 break;
843
844 default:
845 err = -ENOPROTOOPT;
846 break;
847 }
848
849 release_sock(sk);
850 return err;
851}
852
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100853static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
854{
855 struct sock *sk = sock->sk;
856 int len, err = 0;
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +0200857 struct bt_voice voice;
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100858
859 BT_DBG("sk %p", sk);
860
861 if (level == SOL_SCO)
862 return sco_sock_getsockopt_old(sock, optname, optval, optlen);
863
864 if (get_user(len, optlen))
865 return -EFAULT;
866
867 lock_sock(sk);
868
869 switch (optname) {
Frédéric Dalleaub96e9c62012-11-21 10:51:11 +0100870
871 case BT_DEFER_SETUP:
872 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
873 err = -EINVAL;
874 break;
875 }
876
877 if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags),
878 (u32 __user *) optval))
879 err = -EFAULT;
880
881 break;
882
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +0200883 case BT_VOICE:
884 voice.setting = sco_pi(sk)->setting;
885
886 len = min_t(unsigned int, len, sizeof(voice));
887 if (copy_to_user(optval, (char *)&voice, len))
888 err = -EFAULT;
889
890 break;
891
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100892 default:
893 err = -ENOPROTOOPT;
894 break;
895 }
896
897 release_sock(sk);
898 return err;
899}
900
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200901static int sco_sock_shutdown(struct socket *sock, int how)
902{
903 struct sock *sk = sock->sk;
904 int err = 0;
905
906 BT_DBG("sock %p, sk %p", sock, sk);
907
908 if (!sk)
909 return 0;
910
911 lock_sock(sk);
912 if (!sk->sk_shutdown) {
913 sk->sk_shutdown = SHUTDOWN_MASK;
914 sco_sock_clear_timer(sk);
915 __sco_sock_close(sk);
916
917 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
918 err = bt_sock_wait_state(sk, BT_CLOSED,
Gustavo Padovanbe7c2b92012-05-17 00:36:21 -0300919 sk->sk_lingertime);
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200920 }
921 release_sock(sk);
922 return err;
923}
924
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925static int sco_sock_release(struct socket *sock)
926{
927 struct sock *sk = sock->sk;
928 int err = 0;
929
930 BT_DBG("sock %p, sk %p", sock, sk);
931
932 if (!sk)
933 return 0;
934
935 sco_sock_close(sk);
936
937 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) {
938 lock_sock(sk);
939 err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
940 release_sock(sk);
941 }
942
943 sock_orphan(sk);
944 sco_sock_kill(sk);
945 return err;
946}
947
948static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
949{
950 BT_DBG("conn %p", conn);
951
952 sco_pi(sk)->conn = conn;
953 conn->sk = sk;
954
955 if (parent)
956 bt_accept_enqueue(parent, sk);
957}
958
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900959/* Delete channel.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960 * Must be called on the locked socket. */
961static void sco_chan_del(struct sock *sk, int err)
962{
963 struct sco_conn *conn;
964
965 conn = sco_pi(sk)->conn;
966
967 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
968
Gustavo Padovan0b27a4b2012-12-03 15:36:51 -0200969 if (conn) {
970 sco_conn_lock(conn);
971 conn->sk = NULL;
972 sco_pi(sk)->conn = NULL;
973 sco_conn_unlock(conn);
974
975 if (conn->hcon)
David Herrmann76a68ba2013-04-06 20:28:37 +0200976 hci_conn_drop(conn->hcon);
Gustavo Padovan0b27a4b2012-12-03 15:36:51 -0200977 }
978
Linus Torvalds1da177e2005-04-16 15:20:36 -0700979 sk->sk_state = BT_CLOSED;
980 sk->sk_err = err;
981 sk->sk_state_change(sk);
982
983 sock_set_flag(sk, SOCK_ZAPPED);
984}
985
986static void sco_conn_ready(struct sco_conn *conn)
987{
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200988 struct sock *parent;
989 struct sock *sk = conn->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990
991 BT_DBG("conn %p", conn);
992
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200993 if (sk) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700994 sco_sock_clear_timer(sk);
995 bh_lock_sock(sk);
996 sk->sk_state = BT_CONNECTED;
997 sk->sk_state_change(sk);
998 bh_unlock_sock(sk);
999 } else {
Andre Guedes40528082013-01-29 19:59:56 -03001000 sco_conn_lock(conn);
1001
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002 parent = sco_get_sock_listen(conn->src);
Andre Guedes40528082013-01-29 19:59:56 -03001003 if (!parent) {
1004 sco_conn_unlock(conn);
1005 return;
1006 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007
1008 bh_lock_sock(parent);
1009
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -03001010 sk = sco_sock_alloc(sock_net(parent), NULL,
Gustavo Padovanbe7c2b92012-05-17 00:36:21 -03001011 BTPROTO_SCO, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012 if (!sk) {
1013 bh_unlock_sock(parent);
Andre Guedes40528082013-01-29 19:59:56 -03001014 sco_conn_unlock(conn);
1015 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 }
1017
1018 sco_sock_init(sk, parent);
1019
1020 bacpy(&bt_sk(sk)->src, conn->src);
1021 bacpy(&bt_sk(sk)->dst, conn->dst);
1022
1023 hci_conn_hold(conn->hcon);
1024 __sco_chan_add(conn, sk, parent);
1025
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001026 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags))
1027 sk->sk_state = BT_CONNECT2;
1028 else
1029 sk->sk_state = BT_CONNECTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030
1031 /* Wake up parent */
1032 parent->sk_data_ready(parent, 1);
1033
1034 bh_unlock_sock(parent);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035
Andre Guedes40528082013-01-29 19:59:56 -03001036 sco_conn_unlock(conn);
1037 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038}
1039
1040/* ----- SCO interface with lower layer (HCI) ----- */
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001041int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042{
Gustavo Padovanfc5fef62012-05-23 04:04:19 -03001043 struct sock *sk;
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +01001044 int lm = 0;
1045
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001046 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +01001048 /* Find listening sockets */
1049 read_lock(&sco_sk_list.lock);
Sasha Levinb67bfe02013-02-27 17:06:00 -08001050 sk_for_each(sk, &sco_sk_list.head) {
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +01001051 if (sk->sk_state != BT_LISTEN)
1052 continue;
1053
1054 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr) ||
Gustavo Padovanbe7c2b92012-05-17 00:36:21 -03001055 !bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +01001056 lm |= HCI_LM_ACCEPT;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001057
1058 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
1059 *flags |= HCI_PROTO_DEFER;
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +01001060 break;
1061 }
1062 }
1063 read_unlock(&sco_sk_list.lock);
1064
1065 return lm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066}
1067
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03001068void sco_connect_cfm(struct hci_conn *hcon, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001069{
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001070 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071 if (!status) {
1072 struct sco_conn *conn;
1073
Lukasz Rymanowski519e42b2012-04-19 16:12:28 +02001074 conn = sco_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 if (conn)
1076 sco_conn_ready(conn);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001077 } else
Joe Perchese1750722011-06-29 18:18:29 -07001078 sco_conn_del(hcon, bt_to_errno(status));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079}
1080
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03001081void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082{
1083 BT_DBG("hcon %p reason %d", hcon, reason);
1084
Joe Perchese1750722011-06-29 18:18:29 -07001085 sco_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001086}
1087
Ulisses Furquim686ebf22011-12-21 10:11:33 -02001088int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089{
1090 struct sco_conn *conn = hcon->sco_data;
1091
1092 if (!conn)
1093 goto drop;
1094
1095 BT_DBG("conn %p len %d", conn, skb->len);
1096
1097 if (skb->len) {
1098 sco_recv_frame(conn, skb);
1099 return 0;
1100 }
1101
1102drop:
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001103 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104 return 0;
1105}
1106
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001107static int sco_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108{
1109 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110
Gustavo F. Padovanee65d192011-12-27 15:28:46 -02001111 read_lock(&sco_sk_list.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112
Sasha Levinb67bfe02013-02-27 17:06:00 -08001113 sk_for_each(sk, &sco_sk_list.head) {
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03001114 seq_printf(f, "%pMR %pMR %d\n", &bt_sk(sk)->src,
1115 &bt_sk(sk)->dst, sk->sk_state);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08001116 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117
Gustavo F. Padovanee65d192011-12-27 15:28:46 -02001118 read_unlock(&sco_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08001119
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001120 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121}
1122
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001123static int sco_debugfs_open(struct inode *inode, struct file *file)
1124{
1125 return single_open(file, sco_debugfs_show, inode->i_private);
1126}
1127
1128static const struct file_operations sco_debugfs_fops = {
1129 .open = sco_debugfs_open,
1130 .read = seq_read,
1131 .llseek = seq_lseek,
1132 .release = single_release,
1133};
1134
1135static struct dentry *sco_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08001137static const struct proto_ops sco_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138 .family = PF_BLUETOOTH,
1139 .owner = THIS_MODULE,
1140 .release = sco_sock_release,
1141 .bind = sco_sock_bind,
1142 .connect = sco_sock_connect,
1143 .listen = sco_sock_listen,
1144 .accept = sco_sock_accept,
1145 .getname = sco_sock_getname,
1146 .sendmsg = sco_sock_sendmsg,
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001147 .recvmsg = sco_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02001149 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001150 .mmap = sock_no_mmap,
1151 .socketpair = sock_no_socketpair,
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +02001152 .shutdown = sco_sock_shutdown,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153 .setsockopt = sco_sock_setsockopt,
1154 .getsockopt = sco_sock_getsockopt
1155};
1156
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00001157static const struct net_proto_family sco_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158 .family = PF_BLUETOOTH,
1159 .owner = THIS_MODULE,
1160 .create = sco_sock_create,
1161};
1162
Gustavo F. Padovan64274512011-02-07 20:08:52 -02001163int __init sco_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164{
1165 int err;
1166
1167 err = proto_register(&sco_proto, 0);
1168 if (err < 0)
1169 return err;
1170
1171 err = bt_sock_register(BTPROTO_SCO, &sco_sock_family_ops);
1172 if (err < 0) {
1173 BT_ERR("SCO socket registration failed");
1174 goto error;
1175 }
1176
Al Virob0316612013-04-04 19:14:33 -04001177 err = bt_procfs_init(&init_net, "sco", &sco_sk_list, NULL);
Masatake YAMATOde9b9212012-07-26 01:30:12 +09001178 if (err < 0) {
1179 BT_ERR("Failed to create SCO proc file");
1180 bt_sock_unregister(BTPROTO_SCO);
1181 goto error;
1182 }
1183
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001184 if (bt_debugfs) {
Gustavo Padovanbe7c2b92012-05-17 00:36:21 -03001185 sco_debugfs = debugfs_create_file("sco", 0444, bt_debugfs,
1186 NULL, &sco_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001187 if (!sco_debugfs)
1188 BT_ERR("Failed to create SCO debug file");
1189 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191 BT_INFO("SCO socket layer initialized");
1192
1193 return 0;
1194
1195error:
1196 proto_unregister(&sco_proto);
1197 return err;
1198}
1199
Gustavo F. Padovan64274512011-02-07 20:08:52 -02001200void __exit sco_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201{
Masatake YAMATOde9b9212012-07-26 01:30:12 +09001202 bt_procfs_cleanup(&init_net, "sco");
1203
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001204 debugfs_remove(sco_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205
David Herrmann5e9d7f82013-02-24 19:36:51 +01001206 bt_sock_unregister(BTPROTO_SCO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208 proto_unregister(&sco_proto);
1209}
1210
Marcel Holtmann7cb127d2008-07-14 20:13:53 +02001211module_param(disable_esco, bool, 0644);
1212MODULE_PARM_DESC(disable_esco, "Disable eSCO connection creation");