blob: 24fa3964b3c84da299287d6c913771c579d6a9a5 [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;
714
715 release_sock(sk);
716 return 0;
717 }
718
719 release_sock(sk);
720
721 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
722}
723
David S. Millerb7058842009-09-30 16:12:20 -0700724static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725{
726 struct sock *sk = sock->sk;
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +0200727 int len, err = 0;
728 struct bt_voice voice;
Frédéric Dalleaub96e9c62012-11-21 10:51:11 +0100729 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730
731 BT_DBG("sk %p", sk);
732
733 lock_sock(sk);
734
735 switch (optname) {
Frédéric Dalleaub96e9c62012-11-21 10:51:11 +0100736
737 case BT_DEFER_SETUP:
738 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
739 err = -EINVAL;
740 break;
741 }
742
743 if (get_user(opt, (u32 __user *) optval)) {
744 err = -EFAULT;
745 break;
746 }
747
748 if (opt)
749 set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
750 else
751 clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
752 break;
753
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +0200754 case BT_VOICE:
755 if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND &&
756 sk->sk_state != BT_CONNECT2) {
757 err = -EINVAL;
758 break;
759 }
760
761 voice.setting = sco_pi(sk)->setting;
762
763 len = min_t(unsigned int, sizeof(voice), optlen);
764 if (copy_from_user((char *) &voice, optval, len)) {
765 err = -EFAULT;
766 break;
767 }
768
769 /* Explicitly check for these values */
770 if (voice.setting != BT_VOICE_TRANSPARENT &&
771 voice.setting != BT_VOICE_CVSD_16BIT) {
772 err = -EINVAL;
773 break;
774 }
775
776 sco_pi(sk)->setting = voice.setting;
777 break;
778
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779 default:
780 err = -ENOPROTOOPT;
781 break;
782 }
783
784 release_sock(sk);
785 return err;
786}
787
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100788static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789{
790 struct sock *sk = sock->sk;
791 struct sco_options opts;
792 struct sco_conninfo cinfo;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900793 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794
795 BT_DBG("sk %p", sk);
796
797 if (get_user(len, optlen))
798 return -EFAULT;
799
800 lock_sock(sk);
801
802 switch (optname) {
803 case SCO_OPTIONS:
Johan Hedberg9d225d22013-08-08 14:53:56 +0300804 if (sk->sk_state != BT_CONNECTED &&
805 !(sk->sk_state == BT_CONNECT2 &&
806 test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807 err = -ENOTCONN;
808 break;
809 }
810
811 opts.mtu = sco_pi(sk)->conn->mtu;
812
813 BT_DBG("mtu %d", opts.mtu);
814
815 len = min_t(unsigned int, len, sizeof(opts));
816 if (copy_to_user(optval, (char *)&opts, len))
817 err = -EFAULT;
818
819 break;
820
821 case SCO_CONNINFO:
Johan Hedberg9d225d22013-08-08 14:53:56 +0300822 if (sk->sk_state != BT_CONNECTED &&
823 !(sk->sk_state == BT_CONNECT2 &&
824 test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825 err = -ENOTCONN;
826 break;
827 }
828
Vasiliy Kulikovc4c896e2011-02-14 13:54:26 +0300829 memset(&cinfo, 0, sizeof(cinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830 cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle;
831 memcpy(cinfo.dev_class, sco_pi(sk)->conn->hcon->dev_class, 3);
832
833 len = min_t(unsigned int, len, sizeof(cinfo));
834 if (copy_to_user(optval, (char *)&cinfo, len))
835 err = -EFAULT;
836
837 break;
838
839 default:
840 err = -ENOPROTOOPT;
841 break;
842 }
843
844 release_sock(sk);
845 return err;
846}
847
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100848static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
849{
850 struct sock *sk = sock->sk;
851 int len, err = 0;
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +0200852 struct bt_voice voice;
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100853
854 BT_DBG("sk %p", sk);
855
856 if (level == SOL_SCO)
857 return sco_sock_getsockopt_old(sock, optname, optval, optlen);
858
859 if (get_user(len, optlen))
860 return -EFAULT;
861
862 lock_sock(sk);
863
864 switch (optname) {
Frédéric Dalleaub96e9c62012-11-21 10:51:11 +0100865
866 case BT_DEFER_SETUP:
867 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
868 err = -EINVAL;
869 break;
870 }
871
872 if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags),
873 (u32 __user *) optval))
874 err = -EFAULT;
875
876 break;
877
Frédéric Dalleauad10b1a2013-08-19 14:23:56 +0200878 case BT_VOICE:
879 voice.setting = sco_pi(sk)->setting;
880
881 len = min_t(unsigned int, len, sizeof(voice));
882 if (copy_to_user(optval, (char *)&voice, len))
883 err = -EFAULT;
884
885 break;
886
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100887 default:
888 err = -ENOPROTOOPT;
889 break;
890 }
891
892 release_sock(sk);
893 return err;
894}
895
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200896static int sco_sock_shutdown(struct socket *sock, int how)
897{
898 struct sock *sk = sock->sk;
899 int err = 0;
900
901 BT_DBG("sock %p, sk %p", sock, sk);
902
903 if (!sk)
904 return 0;
905
906 lock_sock(sk);
907 if (!sk->sk_shutdown) {
908 sk->sk_shutdown = SHUTDOWN_MASK;
909 sco_sock_clear_timer(sk);
910 __sco_sock_close(sk);
911
912 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
913 err = bt_sock_wait_state(sk, BT_CLOSED,
Gustavo Padovanbe7c2b92012-05-17 00:36:21 -0300914 sk->sk_lingertime);
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200915 }
916 release_sock(sk);
917 return err;
918}
919
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920static int sco_sock_release(struct socket *sock)
921{
922 struct sock *sk = sock->sk;
923 int err = 0;
924
925 BT_DBG("sock %p, sk %p", sock, sk);
926
927 if (!sk)
928 return 0;
929
930 sco_sock_close(sk);
931
932 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) {
933 lock_sock(sk);
934 err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
935 release_sock(sk);
936 }
937
938 sock_orphan(sk);
939 sco_sock_kill(sk);
940 return err;
941}
942
943static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
944{
945 BT_DBG("conn %p", conn);
946
947 sco_pi(sk)->conn = conn;
948 conn->sk = sk;
949
950 if (parent)
951 bt_accept_enqueue(parent, sk);
952}
953
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900954/* Delete channel.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 * Must be called on the locked socket. */
956static void sco_chan_del(struct sock *sk, int err)
957{
958 struct sco_conn *conn;
959
960 conn = sco_pi(sk)->conn;
961
962 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
963
Gustavo Padovan0b27a4b2012-12-03 15:36:51 -0200964 if (conn) {
965 sco_conn_lock(conn);
966 conn->sk = NULL;
967 sco_pi(sk)->conn = NULL;
968 sco_conn_unlock(conn);
969
970 if (conn->hcon)
David Herrmann76a68ba2013-04-06 20:28:37 +0200971 hci_conn_drop(conn->hcon);
Gustavo Padovan0b27a4b2012-12-03 15:36:51 -0200972 }
973
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974 sk->sk_state = BT_CLOSED;
975 sk->sk_err = err;
976 sk->sk_state_change(sk);
977
978 sock_set_flag(sk, SOCK_ZAPPED);
979}
980
981static void sco_conn_ready(struct sco_conn *conn)
982{
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200983 struct sock *parent;
984 struct sock *sk = conn->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985
986 BT_DBG("conn %p", conn);
987
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200988 if (sk) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700989 sco_sock_clear_timer(sk);
990 bh_lock_sock(sk);
991 sk->sk_state = BT_CONNECTED;
992 sk->sk_state_change(sk);
993 bh_unlock_sock(sk);
994 } else {
Andre Guedes40528082013-01-29 19:59:56 -0300995 sco_conn_lock(conn);
996
Marcel Holtmann041987c2013-10-13 10:15:22 -0700997 parent = sco_get_sock_listen(&conn->hcon->src);
Andre Guedes40528082013-01-29 19:59:56 -0300998 if (!parent) {
999 sco_conn_unlock(conn);
1000 return;
1001 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002
1003 bh_lock_sock(parent);
1004
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -03001005 sk = sco_sock_alloc(sock_net(parent), NULL,
Gustavo Padovanbe7c2b92012-05-17 00:36:21 -03001006 BTPROTO_SCO, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007 if (!sk) {
1008 bh_unlock_sock(parent);
Andre Guedes40528082013-01-29 19:59:56 -03001009 sco_conn_unlock(conn);
1010 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011 }
1012
1013 sco_sock_init(sk, parent);
1014
Marcel Holtmanneea96362013-10-13 10:34:01 -07001015 bacpy(&sco_pi(sk)->src, &conn->hcon->src);
1016 bacpy(&sco_pi(sk)->dst, &conn->hcon->dst);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017
1018 hci_conn_hold(conn->hcon);
1019 __sco_chan_add(conn, sk, parent);
1020
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001021 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags))
1022 sk->sk_state = BT_CONNECT2;
1023 else
1024 sk->sk_state = BT_CONNECTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025
1026 /* Wake up parent */
1027 parent->sk_data_ready(parent, 1);
1028
1029 bh_unlock_sock(parent);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030
Andre Guedes40528082013-01-29 19:59:56 -03001031 sco_conn_unlock(conn);
1032 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033}
1034
1035/* ----- SCO interface with lower layer (HCI) ----- */
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001036int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037{
Gustavo Padovanfc5fef62012-05-23 04:04:19 -03001038 struct sock *sk;
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +01001039 int lm = 0;
1040
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001041 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +01001043 /* Find listening sockets */
1044 read_lock(&sco_sk_list.lock);
Sasha Levinb67bfe02013-02-27 17:06:00 -08001045 sk_for_each(sk, &sco_sk_list.head) {
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +01001046 if (sk->sk_state != BT_LISTEN)
1047 continue;
1048
Marcel Holtmanneea96362013-10-13 10:34:01 -07001049 if (!bacmp(&sco_pi(sk)->src, &hdev->bdaddr) ||
1050 !bacmp(&sco_pi(sk)->src, BDADDR_ANY)) {
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +01001051 lm |= HCI_LM_ACCEPT;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001052
1053 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
1054 *flags |= HCI_PROTO_DEFER;
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +01001055 break;
1056 }
1057 }
1058 read_unlock(&sco_sk_list.lock);
1059
1060 return lm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061}
1062
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03001063void sco_connect_cfm(struct hci_conn *hcon, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064{
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001065 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066 if (!status) {
1067 struct sco_conn *conn;
1068
Lukasz Rymanowski519e42b2012-04-19 16:12:28 +02001069 conn = sco_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 if (conn)
1071 sco_conn_ready(conn);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001072 } else
Joe Perchese1750722011-06-29 18:18:29 -07001073 sco_conn_del(hcon, bt_to_errno(status));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074}
1075
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03001076void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077{
1078 BT_DBG("hcon %p reason %d", hcon, reason);
1079
Joe Perchese1750722011-06-29 18:18:29 -07001080 sco_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081}
1082
Ulisses Furquim686ebf22011-12-21 10:11:33 -02001083int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084{
1085 struct sco_conn *conn = hcon->sco_data;
1086
1087 if (!conn)
1088 goto drop;
1089
1090 BT_DBG("conn %p len %d", conn, skb->len);
1091
1092 if (skb->len) {
1093 sco_recv_frame(conn, skb);
1094 return 0;
1095 }
1096
1097drop:
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001098 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099 return 0;
1100}
1101
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001102static int sco_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103{
1104 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105
Gustavo F. Padovanee65d192011-12-27 15:28:46 -02001106 read_lock(&sco_sk_list.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107
Sasha Levinb67bfe02013-02-27 17:06:00 -08001108 sk_for_each(sk, &sco_sk_list.head) {
Marcel Holtmanneea96362013-10-13 10:34:01 -07001109 seq_printf(f, "%pMR %pMR %d\n", &sco_pi(sk)->src,
1110 &sco_pi(sk)->dst, sk->sk_state);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08001111 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112
Gustavo F. Padovanee65d192011-12-27 15:28:46 -02001113 read_unlock(&sco_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08001114
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001115 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116}
1117
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001118static int sco_debugfs_open(struct inode *inode, struct file *file)
1119{
1120 return single_open(file, sco_debugfs_show, inode->i_private);
1121}
1122
1123static const struct file_operations sco_debugfs_fops = {
1124 .open = sco_debugfs_open,
1125 .read = seq_read,
1126 .llseek = seq_lseek,
1127 .release = single_release,
1128};
1129
1130static struct dentry *sco_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08001132static const struct proto_ops sco_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133 .family = PF_BLUETOOTH,
1134 .owner = THIS_MODULE,
1135 .release = sco_sock_release,
1136 .bind = sco_sock_bind,
1137 .connect = sco_sock_connect,
1138 .listen = sco_sock_listen,
1139 .accept = sco_sock_accept,
1140 .getname = sco_sock_getname,
1141 .sendmsg = sco_sock_sendmsg,
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001142 .recvmsg = sco_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001143 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02001144 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145 .mmap = sock_no_mmap,
1146 .socketpair = sock_no_socketpair,
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +02001147 .shutdown = sco_sock_shutdown,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148 .setsockopt = sco_sock_setsockopt,
1149 .getsockopt = sco_sock_getsockopt
1150};
1151
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00001152static const struct net_proto_family sco_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153 .family = PF_BLUETOOTH,
1154 .owner = THIS_MODULE,
1155 .create = sco_sock_create,
1156};
1157
Gustavo F. Padovan64274512011-02-07 20:08:52 -02001158int __init sco_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001159{
1160 int err;
1161
1162 err = proto_register(&sco_proto, 0);
1163 if (err < 0)
1164 return err;
1165
1166 err = bt_sock_register(BTPROTO_SCO, &sco_sock_family_ops);
1167 if (err < 0) {
1168 BT_ERR("SCO socket registration failed");
1169 goto error;
1170 }
1171
Al Virob0316612013-04-04 19:14:33 -04001172 err = bt_procfs_init(&init_net, "sco", &sco_sk_list, NULL);
Masatake YAMATOde9b9212012-07-26 01:30:12 +09001173 if (err < 0) {
1174 BT_ERR("Failed to create SCO proc file");
1175 bt_sock_unregister(BTPROTO_SCO);
1176 goto error;
1177 }
1178
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179 BT_INFO("SCO socket layer initialized");
1180
Marcel Holtmann1120e4b2013-10-17 17:24:16 -07001181 if (IS_ERR_OR_NULL(bt_debugfs))
1182 return 0;
1183
1184 sco_debugfs = debugfs_create_file("sco", 0444, bt_debugfs,
1185 NULL, &sco_debugfs_fops);
1186
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187 return 0;
1188
1189error:
1190 proto_unregister(&sco_proto);
1191 return err;
1192}
1193
Gustavo F. Padovan64274512011-02-07 20:08:52 -02001194void __exit sco_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195{
Masatake YAMATOde9b9212012-07-26 01:30:12 +09001196 bt_procfs_cleanup(&init_net, "sco");
1197
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001198 debugfs_remove(sco_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199
David Herrmann5e9d7f82013-02-24 19:36:51 +01001200 bt_sock_unregister(BTPROTO_SCO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202 proto_unregister(&sco_proto);
1203}
1204
Marcel Holtmann7cb127d2008-07-14 20:13:53 +02001205module_param(disable_esco, bool, 0644);
1206MODULE_PARM_DESC(disable_esco, "Disable eSCO connection creation");