blob: 3e1c6b1910381dea4973269bd0a9e5fcf2a453cb [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>
28
29#include <linux/types.h>
30#include <linux/errno.h>
31#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/sched.h>
33#include <linux/slab.h>
34#include <linux/poll.h>
35#include <linux/fcntl.h>
36#include <linux/init.h>
37#include <linux/interrupt.h>
38#include <linux/socket.h>
39#include <linux/skbuff.h>
Marcel Holtmannbe9d1222005-11-08 09:57:38 -080040#include <linux/device.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010041#include <linux/debugfs.h>
42#include <linux/seq_file.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#include <linux/list.h>
44#include <net/sock.h>
45
46#include <asm/system.h>
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +020047#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
49#include <net/bluetooth/bluetooth.h>
50#include <net/bluetooth/hci_core.h>
51#include <net/bluetooth/sco.h>
52
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +020053static int disable_esco;
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080055static const struct proto_ops sco_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070056
57static struct bt_sock_list sco_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070058 .lock = __RW_LOCK_UNLOCKED(sco_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070059};
60
61static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent);
62static void sco_chan_del(struct sock *sk, int err);
63
64static int sco_conn_del(struct hci_conn *conn, int err);
65
66static void sco_sock_close(struct sock *sk);
67static void sco_sock_kill(struct sock *sk);
68
69/* ---- SCO timers ---- */
70static void sco_sock_timeout(unsigned long arg)
71{
72 struct sock *sk = (struct sock *) arg;
73
74 BT_DBG("sock %p state %d", sk, sk->sk_state);
75
76 bh_lock_sock(sk);
77 sk->sk_err = ETIMEDOUT;
78 sk->sk_state_change(sk);
79 bh_unlock_sock(sk);
80
81 sco_sock_kill(sk);
82 sock_put(sk);
83}
84
85static void sco_sock_set_timer(struct sock *sk, long timeout)
86{
87 BT_DBG("sock %p state %d timeout %ld", sk, sk->sk_state, timeout);
88 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
89}
90
91static void sco_sock_clear_timer(struct sock *sk)
92{
93 BT_DBG("sock %p state %d", sk, sk->sk_state);
94 sk_stop_timer(sk, &sk->sk_timer);
95}
96
Linus Torvalds1da177e2005-04-16 15:20:36 -070097/* ---- SCO connections ---- */
98static struct sco_conn *sco_conn_add(struct hci_conn *hcon, __u8 status)
99{
100 struct hci_dev *hdev = hcon->hdev;
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200101 struct sco_conn *conn = hcon->sco_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200103 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104 return conn;
105
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200106 conn = kzalloc(sizeof(struct sco_conn), GFP_ATOMIC);
107 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109
110 spin_lock_init(&conn->lock);
111
112 hcon->sco_data = conn;
113 conn->hcon = hcon;
114
115 conn->src = &hdev->bdaddr;
116 conn->dst = &hcon->dst;
117
118 if (hdev->sco_mtu > 0)
119 conn->mtu = hdev->sco_mtu;
120 else
121 conn->mtu = 60;
122
123 BT_DBG("hcon %p conn %p", hcon, conn);
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200124
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125 return conn;
126}
127
128static inline struct sock *sco_chan_get(struct sco_conn *conn)
129{
130 struct sock *sk = NULL;
131 sco_conn_lock(conn);
132 sk = conn->sk;
133 sco_conn_unlock(conn);
134 return sk;
135}
136
137static int sco_conn_del(struct hci_conn *hcon, int err)
138{
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200139 struct sco_conn *conn = hcon->sco_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140 struct sock *sk;
141
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200142 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143 return 0;
144
145 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
146
147 /* Kill socket */
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200148 sk = sco_chan_get(conn);
149 if (sk) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150 bh_lock_sock(sk);
151 sco_sock_clear_timer(sk);
152 sco_chan_del(sk, err);
153 bh_unlock_sock(sk);
154 sco_sock_kill(sk);
155 }
156
157 hcon->sco_data = NULL;
158 kfree(conn);
159 return 0;
160}
161
162static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
163{
164 int err = 0;
165
166 sco_conn_lock(conn);
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300167 if (conn->sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168 err = -EBUSY;
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300169 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 __sco_chan_add(conn, sk, parent);
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300171
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 sco_conn_unlock(conn);
173 return err;
174}
175
176static int sco_connect(struct sock *sk)
177{
178 bdaddr_t *src = &bt_sk(sk)->src;
179 bdaddr_t *dst = &bt_sk(sk)->dst;
Nick Pellybbcda3b2010-02-11 11:54:28 -0800180 __u16 pkt_type = sco_pi(sk)->pkt_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181 struct sco_conn *conn;
182 struct hci_conn *hcon;
183 struct hci_dev *hdev;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200184 int err, type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185
186 BT_DBG("%s -> %s", batostr(src), batostr(dst));
187
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200188 hdev = hci_get_route(dst, src);
189 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190 return -EHOSTUNREACH;
191
192 hci_dev_lock_bh(hdev);
193
Marcel Holtmann7cb127d2008-07-14 20:13:53 +0200194 if (lmp_esco_capable(hdev) && !disable_esco)
195 type = ESCO_LINK;
Nick Pellybbcda3b2010-02-11 11:54:28 -0800196 else {
Marcel Holtmann7cb127d2008-07-14 20:13:53 +0200197 type = SCO_LINK;
Nick Pellybbcda3b2010-02-11 11:54:28 -0800198 pkt_type &= SCO_ESCO_MASK;
199 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200200
Nick Pellybbcda3b2010-02-11 11:54:28 -0800201 hcon = hci_connect(hdev, type, pkt_type, dst, BT_SECURITY_LOW, HCI_AT_NO_BONDING);
Ville Tervo30e76272011-02-22 16:10:53 -0300202 if (IS_ERR(hcon)) {
203 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -0300205 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206
207 conn = sco_conn_add(hcon, 0);
208 if (!conn) {
209 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -0300210 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211 goto done;
212 }
213
214 /* Update source addr of the socket */
215 bacpy(src, conn->src);
216
217 err = sco_chan_add(conn, sk, NULL);
218 if (err)
219 goto done;
220
221 if (hcon->state == BT_CONNECTED) {
222 sco_sock_clear_timer(sk);
223 sk->sk_state = BT_CONNECTED;
224 } else {
225 sk->sk_state = BT_CONNECT;
226 sco_sock_set_timer(sk, sk->sk_sndtimeo);
227 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200228
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229done:
230 hci_dev_unlock_bh(hdev);
231 hci_dev_put(hdev);
232 return err;
233}
234
235static inline int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
236{
237 struct sco_conn *conn = sco_pi(sk)->conn;
238 struct sk_buff *skb;
239 int err, count;
240
241 /* Check outgoing MTU */
242 if (len > conn->mtu)
243 return -EINVAL;
244
245 BT_DBG("sk %p len %d", sk, len);
246
247 count = min_t(unsigned int, conn->mtu, len);
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300248 skb = bt_skb_send_alloc(sk, count,
249 msg->msg_flags & MSG_DONTWAIT, &err);
250 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251 return err;
252
253 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300254 kfree_skb(skb);
255 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256 }
257
Gustavo F. Padovan0d861d82010-05-01 16:15:35 -0300258 hci_send_sco(conn->hcon, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259
260 return count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261}
262
263static inline void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
264{
265 struct sock *sk = sco_chan_get(conn);
266
267 if (!sk)
268 goto drop;
269
270 BT_DBG("sk %p len %d", sk, skb->len);
271
272 if (sk->sk_state != BT_CONNECTED)
273 goto drop;
274
275 if (!sock_queue_rcv_skb(sk, skb))
276 return;
277
278drop:
279 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280}
281
282/* -------- Socket interface ---------- */
283static struct sock *__sco_get_sock_by_addr(bdaddr_t *ba)
284{
285 struct sock *sk;
286 struct hlist_node *node;
287
288 sk_for_each(sk, node, &sco_sk_list.head)
289 if (!bacmp(&bt_sk(sk)->src, ba))
290 goto found;
291 sk = NULL;
292found:
293 return sk;
294}
295
296/* Find socket listening on source bdaddr.
297 * Returns closest match.
298 */
299static struct sock *sco_get_sock_listen(bdaddr_t *src)
300{
301 struct sock *sk = NULL, *sk1 = NULL;
302 struct hlist_node *node;
303
304 read_lock(&sco_sk_list.lock);
305
306 sk_for_each(sk, node, &sco_sk_list.head) {
307 if (sk->sk_state != BT_LISTEN)
308 continue;
309
310 /* Exact match. */
311 if (!bacmp(&bt_sk(sk)->src, src))
312 break;
313
314 /* Closest match */
315 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
316 sk1 = sk;
317 }
318
319 read_unlock(&sco_sk_list.lock);
320
321 return node ? sk : sk1;
322}
323
324static void sco_sock_destruct(struct sock *sk)
325{
326 BT_DBG("sk %p", sk);
327
328 skb_queue_purge(&sk->sk_receive_queue);
329 skb_queue_purge(&sk->sk_write_queue);
330}
331
332static void sco_sock_cleanup_listen(struct sock *parent)
333{
334 struct sock *sk;
335
336 BT_DBG("parent %p", parent);
337
338 /* Close not yet accepted channels */
339 while ((sk = bt_accept_dequeue(parent, NULL))) {
340 sco_sock_close(sk);
341 sco_sock_kill(sk);
342 }
343
344 parent->sk_state = BT_CLOSED;
345 sock_set_flag(parent, SOCK_ZAPPED);
346}
347
348/* Kill socket (only if zapped and orphan)
349 * Must be called on unlocked socket.
350 */
351static void sco_sock_kill(struct sock *sk)
352{
353 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
354 return;
355
356 BT_DBG("sk %p state %d", sk, sk->sk_state);
357
358 /* Kill poor orphan */
359 bt_sock_unlink(&sco_sk_list, sk);
360 sock_set_flag(sk, SOCK_DEAD);
361 sock_put(sk);
362}
363
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200364static void __sco_sock_close(struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365{
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200366 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367
368 switch (sk->sk_state) {
369 case BT_LISTEN:
370 sco_sock_cleanup_listen(sk);
371 break;
372
373 case BT_CONNECTED:
374 case BT_CONFIG:
375 case BT_CONNECT:
376 case BT_DISCONN:
377 sco_chan_del(sk, ECONNRESET);
378 break;
379
380 default:
381 sock_set_flag(sk, SOCK_ZAPPED);
382 break;
Stephen Hemminger3ff50b72007-04-20 17:09:22 -0700383 }
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200384}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200386/* Must be called on unlocked socket. */
387static void sco_sock_close(struct sock *sk)
388{
389 sco_sock_clear_timer(sk);
390 lock_sock(sk);
391 __sco_sock_close(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393 sco_sock_kill(sk);
394}
395
396static void sco_sock_init(struct sock *sk, struct sock *parent)
397{
398 BT_DBG("sk %p", sk);
399
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900400 if (parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401 sk->sk_type = parent->sk_type;
402}
403
404static struct proto sco_proto = {
405 .name = "SCO",
406 .owner = THIS_MODULE,
407 .obj_size = sizeof(struct sco_pinfo)
408};
409
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700410static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411{
412 struct sock *sk;
413
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700414 sk = sk_alloc(net, PF_BLUETOOTH, prio, &sco_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 if (!sk)
416 return NULL;
417
418 sock_init_data(sock, sk);
419 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
420
421 sk->sk_destruct = sco_sock_destruct;
422 sk->sk_sndtimeo = SCO_CONN_TIMEOUT;
423
424 sock_reset_flag(sk, SOCK_ZAPPED);
425
426 sk->sk_protocol = proto;
427 sk->sk_state = BT_OPEN;
428
Pavel Emelyanovb24b8a22008-01-23 21:20:07 -0800429 setup_timer(&sk->sk_timer, sco_sock_timeout, (unsigned long)sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430
431 bt_sock_link(&sco_sk_list, sk);
432 return sk;
433}
434
Eric Paris3f378b62009-11-05 22:18:14 -0800435static int sco_sock_create(struct net *net, struct socket *sock, int protocol,
436 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437{
438 struct sock *sk;
439
440 BT_DBG("sock %p", sock);
441
442 sock->state = SS_UNCONNECTED;
443
444 if (sock->type != SOCK_SEQPACKET)
445 return -ESOCKTNOSUPPORT;
446
447 sock->ops = &sco_sock_ops;
448
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700449 sk = sco_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Marcel Holtmann74da6262006-10-15 17:31:14 +0200450 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 return -ENOMEM;
452
453 sco_sock_init(sk, NULL);
454 return 0;
455}
456
Nick Pellybbcda3b2010-02-11 11:54:28 -0800457static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458{
Nick Pellybbcda3b2010-02-11 11:54:28 -0800459 struct sockaddr_sco sa;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460 struct sock *sk = sock->sk;
Nick Pellybbcda3b2010-02-11 11:54:28 -0800461 bdaddr_t *src = &sa.sco_bdaddr;
462 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463
Nick Pellybbcda3b2010-02-11 11:54:28 -0800464 BT_DBG("sk %p %s", sk, batostr(&sa.sco_bdaddr));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465
466 if (!addr || addr->sa_family != AF_BLUETOOTH)
467 return -EINVAL;
468
Nick Pellybbcda3b2010-02-11 11:54:28 -0800469 memset(&sa, 0, sizeof(sa));
470 len = min_t(unsigned int, sizeof(sa), alen);
471 memcpy(&sa, addr, len);
472
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 lock_sock(sk);
474
475 if (sk->sk_state != BT_OPEN) {
476 err = -EBADFD;
477 goto done;
478 }
479
480 write_lock_bh(&sco_sk_list.lock);
481
482 if (bacmp(src, BDADDR_ANY) && __sco_get_sock_by_addr(src)) {
483 err = -EADDRINUSE;
484 } else {
485 /* Save source address */
Nick Pellybbcda3b2010-02-11 11:54:28 -0800486 bacpy(&bt_sk(sk)->src, &sa.sco_bdaddr);
487 sco_pi(sk)->pkt_type = sa.sco_pkt_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488 sk->sk_state = BT_BOUND;
489 }
490
491 write_unlock_bh(&sco_sk_list.lock);
492
493done:
494 release_sock(sk);
495 return err;
496}
497
498static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
499{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 struct sock *sk = sock->sk;
Nick Pellybbcda3b2010-02-11 11:54:28 -0800501 struct sockaddr_sco sa;
502 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503
504 BT_DBG("sk %p", sk);
505
Nick Pellybbcda3b2010-02-11 11:54:28 -0800506 if (!addr || addr->sa_family != AF_BLUETOOTH)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 return -EINVAL;
508
Nick Pellybbcda3b2010-02-11 11:54:28 -0800509 memset(&sa, 0, sizeof(sa));
510 len = min_t(unsigned int, sizeof(sa), alen);
511 memcpy(&sa, addr, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512
513 lock_sock(sk);
514
Nick Pellybbcda3b2010-02-11 11:54:28 -0800515 if (sk->sk_type != SOCK_SEQPACKET) {
516 err = -EINVAL;
517 goto done;
518 }
519
520 if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) {
521 err = -EBADFD;
522 goto done;
523 }
524
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525 /* Set destination address and psm */
Nick Pellybbcda3b2010-02-11 11:54:28 -0800526 bacpy(&bt_sk(sk)->dst, &sa.sco_bdaddr);
527 sco_pi(sk)->pkt_type = sa.sco_pkt_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200529 err = sco_connect(sk);
530 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531 goto done;
532
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900533 err = bt_sock_wait_state(sk, BT_CONNECTED,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534 sock_sndtimeo(sk, flags & O_NONBLOCK));
535
536done:
537 release_sock(sk);
538 return err;
539}
540
541static int sco_sock_listen(struct socket *sock, int backlog)
542{
543 struct sock *sk = sock->sk;
544 int err = 0;
545
546 BT_DBG("sk %p backlog %d", sk, backlog);
547
548 lock_sock(sk);
549
550 if (sk->sk_state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
551 err = -EBADFD;
552 goto done;
553 }
554
555 sk->sk_max_ack_backlog = backlog;
556 sk->sk_ack_backlog = 0;
557 sk->sk_state = BT_LISTEN;
558
559done:
560 release_sock(sk);
561 return err;
562}
563
564static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flags)
565{
566 DECLARE_WAITQUEUE(wait, current);
567 struct sock *sk = sock->sk, *ch;
568 long timeo;
569 int err = 0;
570
571 lock_sock(sk);
572
573 if (sk->sk_state != BT_LISTEN) {
574 err = -EBADFD;
575 goto done;
576 }
577
578 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
579
580 BT_DBG("sk %p timeo %ld", sk, timeo);
581
582 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +0000583 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 while (!(ch = bt_accept_dequeue(sk, newsock))) {
585 set_current_state(TASK_INTERRUPTIBLE);
586 if (!timeo) {
587 err = -EAGAIN;
588 break;
589 }
590
591 release_sock(sk);
592 timeo = schedule_timeout(timeo);
593 lock_sock(sk);
594
595 if (sk->sk_state != BT_LISTEN) {
596 err = -EBADFD;
597 break;
598 }
599
600 if (signal_pending(current)) {
601 err = sock_intr_errno(timeo);
602 break;
603 }
604 }
605 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +0000606 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607
608 if (err)
609 goto done;
610
611 newsock->state = SS_CONNECTED;
612
613 BT_DBG("new socket %p", ch);
614
615done:
616 release_sock(sk);
617 return err;
618}
619
620static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
621{
622 struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
623 struct sock *sk = sock->sk;
624
625 BT_DBG("sock %p, sk %p", sock, sk);
626
627 addr->sa_family = AF_BLUETOOTH;
628 *len = sizeof(struct sockaddr_sco);
629
630 if (peer)
631 bacpy(&sa->sco_bdaddr, &bt_sk(sk)->dst);
632 else
633 bacpy(&sa->sco_bdaddr, &bt_sk(sk)->src);
Nick Pellybbcda3b2010-02-11 11:54:28 -0800634 sa->sco_pkt_type = sco_pi(sk)->pkt_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635
636 return 0;
637}
638
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900639static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640 struct msghdr *msg, size_t len)
641{
642 struct sock *sk = sock->sk;
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300643 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644
645 BT_DBG("sock %p, sk %p", sock, sk);
646
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -0800647 err = sock_error(sk);
648 if (err)
649 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650
651 if (msg->msg_flags & MSG_OOB)
652 return -EOPNOTSUPP;
653
654 lock_sock(sk);
655
656 if (sk->sk_state == BT_CONNECTED)
657 err = sco_send_frame(sk, msg, len);
658 else
659 err = -ENOTCONN;
660
661 release_sock(sk);
662 return err;
663}
664
David S. Millerb7058842009-09-30 16:12:20 -0700665static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666{
667 struct sock *sk = sock->sk;
668 int err = 0;
669
670 BT_DBG("sk %p", sk);
671
672 lock_sock(sk);
673
674 switch (optname) {
675 default:
676 err = -ENOPROTOOPT;
677 break;
678 }
679
680 release_sock(sk);
681 return err;
682}
683
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100684static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685{
686 struct sock *sk = sock->sk;
687 struct sco_options opts;
688 struct sco_conninfo cinfo;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900689 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690
691 BT_DBG("sk %p", sk);
692
693 if (get_user(len, optlen))
694 return -EFAULT;
695
696 lock_sock(sk);
697
698 switch (optname) {
699 case SCO_OPTIONS:
700 if (sk->sk_state != BT_CONNECTED) {
701 err = -ENOTCONN;
702 break;
703 }
704
705 opts.mtu = sco_pi(sk)->conn->mtu;
706
707 BT_DBG("mtu %d", opts.mtu);
708
709 len = min_t(unsigned int, len, sizeof(opts));
710 if (copy_to_user(optval, (char *)&opts, len))
711 err = -EFAULT;
712
713 break;
714
715 case SCO_CONNINFO:
716 if (sk->sk_state != BT_CONNECTED) {
717 err = -ENOTCONN;
718 break;
719 }
720
Vasiliy Kulikovc4c896e2011-02-14 13:54:26 +0300721 memset(&cinfo, 0, sizeof(cinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722 cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle;
723 memcpy(cinfo.dev_class, sco_pi(sk)->conn->hcon->dev_class, 3);
724
725 len = min_t(unsigned int, len, sizeof(cinfo));
726 if (copy_to_user(optval, (char *)&cinfo, len))
727 err = -EFAULT;
728
729 break;
730
731 default:
732 err = -ENOPROTOOPT;
733 break;
734 }
735
736 release_sock(sk);
737 return err;
738}
739
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100740static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
741{
742 struct sock *sk = sock->sk;
743 int len, err = 0;
744
745 BT_DBG("sk %p", sk);
746
747 if (level == SOL_SCO)
748 return sco_sock_getsockopt_old(sock, optname, optval, optlen);
749
750 if (get_user(len, optlen))
751 return -EFAULT;
752
753 lock_sock(sk);
754
755 switch (optname) {
756 default:
757 err = -ENOPROTOOPT;
758 break;
759 }
760
761 release_sock(sk);
762 return err;
763}
764
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200765static int sco_sock_shutdown(struct socket *sock, int how)
766{
767 struct sock *sk = sock->sk;
768 int err = 0;
769
770 BT_DBG("sock %p, sk %p", sock, sk);
771
772 if (!sk)
773 return 0;
774
775 lock_sock(sk);
776 if (!sk->sk_shutdown) {
777 sk->sk_shutdown = SHUTDOWN_MASK;
778 sco_sock_clear_timer(sk);
779 __sco_sock_close(sk);
780
781 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
782 err = bt_sock_wait_state(sk, BT_CLOSED,
783 sk->sk_lingertime);
784 }
785 release_sock(sk);
786 return err;
787}
788
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789static int sco_sock_release(struct socket *sock)
790{
791 struct sock *sk = sock->sk;
792 int err = 0;
793
794 BT_DBG("sock %p, sk %p", sock, sk);
795
796 if (!sk)
797 return 0;
798
799 sco_sock_close(sk);
800
801 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) {
802 lock_sock(sk);
803 err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
804 release_sock(sk);
805 }
806
807 sock_orphan(sk);
808 sco_sock_kill(sk);
809 return err;
810}
811
812static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
813{
814 BT_DBG("conn %p", conn);
815
816 sco_pi(sk)->conn = conn;
817 conn->sk = sk;
818
819 if (parent)
820 bt_accept_enqueue(parent, sk);
821}
822
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900823/* Delete channel.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824 * Must be called on the locked socket. */
825static void sco_chan_del(struct sock *sk, int err)
826{
827 struct sco_conn *conn;
828
829 conn = sco_pi(sk)->conn;
830
831 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
832
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900833 if (conn) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834 sco_conn_lock(conn);
835 conn->sk = NULL;
836 sco_pi(sk)->conn = NULL;
837 sco_conn_unlock(conn);
838 hci_conn_put(conn->hcon);
839 }
840
841 sk->sk_state = BT_CLOSED;
842 sk->sk_err = err;
843 sk->sk_state_change(sk);
844
845 sock_set_flag(sk, SOCK_ZAPPED);
846}
847
848static void sco_conn_ready(struct sco_conn *conn)
849{
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200850 struct sock *parent;
851 struct sock *sk = conn->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852
853 BT_DBG("conn %p", conn);
854
855 sco_conn_lock(conn);
856
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200857 if (sk) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858 sco_sock_clear_timer(sk);
859 bh_lock_sock(sk);
860 sk->sk_state = BT_CONNECTED;
861 sk->sk_state_change(sk);
862 bh_unlock_sock(sk);
863 } else {
864 parent = sco_get_sock_listen(conn->src);
865 if (!parent)
866 goto done;
867
868 bh_lock_sock(parent);
869
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300870 sk = sco_sock_alloc(sock_net(parent), NULL,
871 BTPROTO_SCO, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872 if (!sk) {
873 bh_unlock_sock(parent);
874 goto done;
875 }
876
877 sco_sock_init(sk, parent);
878
879 bacpy(&bt_sk(sk)->src, conn->src);
880 bacpy(&bt_sk(sk)->dst, conn->dst);
881
882 hci_conn_hold(conn->hcon);
883 __sco_chan_add(conn, sk, parent);
884
885 sk->sk_state = BT_CONNECTED;
886
887 /* Wake up parent */
888 parent->sk_data_ready(parent, 1);
889
890 bh_unlock_sock(parent);
891 }
892
893done:
894 sco_conn_unlock(conn);
895}
896
897/* ----- SCO interface with lower layer (HCI) ----- */
898static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
899{
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +0100900 register struct sock *sk;
901 struct hlist_node *node;
902 int lm = 0;
903
904 if (type != SCO_LINK && type != ESCO_LINK)
Gustavo F. Padovanc89ad732010-11-01 19:08:50 +0000905 return -EINVAL;
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +0100906
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
908
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +0100909 /* Find listening sockets */
910 read_lock(&sco_sk_list.lock);
911 sk_for_each(sk, node, &sco_sk_list.head) {
912 if (sk->sk_state != BT_LISTEN)
913 continue;
914
915 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr) ||
916 !bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
917 lm |= HCI_LM_ACCEPT;
918 break;
919 }
920 }
921 read_unlock(&sco_sk_list.lock);
922
923 return lm;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924}
925
926static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
927{
928 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
929
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200930 if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
Gustavo F. Padovanc89ad732010-11-01 19:08:50 +0000931 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700932
933 if (!status) {
934 struct sco_conn *conn;
935
936 conn = sco_conn_add(hcon, status);
937 if (conn)
938 sco_conn_ready(conn);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900939 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940 sco_conn_del(hcon, bt_err(status));
941
942 return 0;
943}
944
Marcel Holtmann2950f212009-02-12 14:02:50 +0100945static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946{
947 BT_DBG("hcon %p reason %d", hcon, reason);
948
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200949 if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
Gustavo F. Padovanc89ad732010-11-01 19:08:50 +0000950 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951
952 sco_conn_del(hcon, bt_err(reason));
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200953
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954 return 0;
955}
956
957static int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb)
958{
959 struct sco_conn *conn = hcon->sco_data;
960
961 if (!conn)
962 goto drop;
963
964 BT_DBG("conn %p len %d", conn, skb->len);
965
966 if (skb->len) {
967 sco_recv_frame(conn, skb);
968 return 0;
969 }
970
971drop:
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900972 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973 return 0;
974}
975
Marcel Holtmannaef7d972010-03-21 05:27:45 +0100976static int sco_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977{
978 struct sock *sk;
979 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980
981 read_lock_bh(&sco_sk_list.lock);
982
Marcel Holtmannbe9d1222005-11-08 09:57:38 -0800983 sk_for_each(sk, node, &sco_sk_list.head) {
Marcel Holtmannaef7d972010-03-21 05:27:45 +0100984 seq_printf(f, "%s %s %d\n", batostr(&bt_sk(sk)->src),
985 batostr(&bt_sk(sk)->dst), sk->sk_state);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -0800986 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988 read_unlock_bh(&sco_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -0800989
Marcel Holtmannaef7d972010-03-21 05:27:45 +0100990 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991}
992
Marcel Holtmannaef7d972010-03-21 05:27:45 +0100993static int sco_debugfs_open(struct inode *inode, struct file *file)
994{
995 return single_open(file, sco_debugfs_show, inode->i_private);
996}
997
998static const struct file_operations sco_debugfs_fops = {
999 .open = sco_debugfs_open,
1000 .read = seq_read,
1001 .llseek = seq_lseek,
1002 .release = single_release,
1003};
1004
1005static struct dentry *sco_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001006
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08001007static const struct proto_ops sco_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008 .family = PF_BLUETOOTH,
1009 .owner = THIS_MODULE,
1010 .release = sco_sock_release,
1011 .bind = sco_sock_bind,
1012 .connect = sco_sock_connect,
1013 .listen = sco_sock_listen,
1014 .accept = sco_sock_accept,
1015 .getname = sco_sock_getname,
1016 .sendmsg = sco_sock_sendmsg,
1017 .recvmsg = bt_sock_recvmsg,
1018 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02001019 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020 .mmap = sock_no_mmap,
1021 .socketpair = sock_no_socketpair,
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +02001022 .shutdown = sco_sock_shutdown,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023 .setsockopt = sco_sock_setsockopt,
1024 .getsockopt = sco_sock_getsockopt
1025};
1026
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00001027static const struct net_proto_family sco_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 .family = PF_BLUETOOTH,
1029 .owner = THIS_MODULE,
1030 .create = sco_sock_create,
1031};
1032
1033static struct hci_proto sco_hci_proto = {
1034 .name = "SCO",
1035 .id = HCI_PROTO_SCO,
1036 .connect_ind = sco_connect_ind,
1037 .connect_cfm = sco_connect_cfm,
Marcel Holtmann2950f212009-02-12 14:02:50 +01001038 .disconn_cfm = sco_disconn_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039 .recv_scodata = sco_recv_scodata
1040};
1041
Gustavo F. Padovan64274512011-02-07 20:08:52 -02001042int __init sco_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001043{
1044 int err;
1045
1046 err = proto_register(&sco_proto, 0);
1047 if (err < 0)
1048 return err;
1049
1050 err = bt_sock_register(BTPROTO_SCO, &sco_sock_family_ops);
1051 if (err < 0) {
1052 BT_ERR("SCO socket registration failed");
1053 goto error;
1054 }
1055
1056 err = hci_register_proto(&sco_hci_proto);
1057 if (err < 0) {
1058 BT_ERR("SCO protocol registration failed");
1059 bt_sock_unregister(BTPROTO_SCO);
1060 goto error;
1061 }
1062
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001063 if (bt_debugfs) {
1064 sco_debugfs = debugfs_create_file("sco", 0444,
1065 bt_debugfs, NULL, &sco_debugfs_fops);
1066 if (!sco_debugfs)
1067 BT_ERR("Failed to create SCO debug file");
1068 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001069
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 BT_INFO("SCO socket layer initialized");
1071
1072 return 0;
1073
1074error:
1075 proto_unregister(&sco_proto);
1076 return err;
1077}
1078
Gustavo F. Padovan64274512011-02-07 20:08:52 -02001079void __exit sco_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001081 debugfs_remove(sco_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082
1083 if (bt_sock_unregister(BTPROTO_SCO) < 0)
1084 BT_ERR("SCO socket unregistration failed");
1085
1086 if (hci_unregister_proto(&sco_hci_proto) < 0)
1087 BT_ERR("SCO protocol unregistration failed");
1088
1089 proto_unregister(&sco_proto);
1090}
1091
Marcel Holtmann7cb127d2008-07-14 20:13:53 +02001092module_param(disable_esco, bool, 0644);
1093MODULE_PARM_DESC(disable_esco, "Disable eSCO connection creation");