blob: 1a17850d093cd652621ac54833c53b8dabd395bc [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 RFCOMM implementation for Linux Bluetooth stack (BlueZ).
3 Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
4 Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License version 2 as
8 published by the Free Software Foundation;
9
10 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
11 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
13 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090014 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
15 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070017 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090019 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
20 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070021 SOFTWARE IS DISCLAIMED.
22*/
23
24/*
25 * RFCOMM sockets.
Linus Torvalds1da177e2005-04-16 15:20:36 -070026 */
27
Gustavo Padovan8c520a52012-05-23 04:04:22 -030028#include <linux/export.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010029#include <linux/debugfs.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/l2cap.h>
34#include <net/bluetooth/rfcomm.h>
35
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080036static const struct proto_ops rfcomm_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070037
38static struct bt_sock_list rfcomm_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070039 .lock = __RW_LOCK_UNLOCKED(rfcomm_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070040};
41
42static void rfcomm_sock_close(struct sock *sk);
43static void rfcomm_sock_kill(struct sock *sk);
44
45/* ---- DLC callbacks ----
46 *
47 * called under rfcomm_dlc_lock()
48 */
49static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb)
50{
51 struct sock *sk = d->owner;
52 if (!sk)
53 return;
54
55 atomic_add(skb->len, &sk->sk_rmem_alloc);
56 skb_queue_tail(&sk->sk_receive_queue, skb);
57 sk->sk_data_ready(sk, skb->len);
58
59 if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)
60 rfcomm_dlc_throttle(d);
61}
62
63static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
64{
65 struct sock *sk = d->owner, *parent;
Gustavo F. Padovanfad003b2010-08-14 00:48:07 -030066 unsigned long flags;
67
Linus Torvalds1da177e2005-04-16 15:20:36 -070068 if (!sk)
69 return;
70
71 BT_DBG("dlc %p state %ld err %d", d, d->state, err);
72
Gustavo F. Padovanfad003b2010-08-14 00:48:07 -030073 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -070074 bh_lock_sock(sk);
75
76 if (err)
77 sk->sk_err = err;
78
79 sk->sk_state = d->state;
80
81 parent = bt_sk(sk)->parent;
82 if (parent) {
83 if (d->state == BT_CLOSED) {
84 sock_set_flag(sk, SOCK_ZAPPED);
85 bt_accept_unlink(sk);
86 }
87 parent->sk_data_ready(parent, 0);
88 } else {
89 if (d->state == BT_CONNECTED)
90 rfcomm_session_getaddr(d->session, &bt_sk(sk)->src, NULL);
91 sk->sk_state_change(sk);
92 }
93
94 bh_unlock_sock(sk);
Gustavo F. Padovanfad003b2010-08-14 00:48:07 -030095 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
97 if (parent && sock_flag(sk, SOCK_ZAPPED)) {
98 /* We have to drop DLC lock here, otherwise
99 * rfcomm_sock_destruct() will dead lock. */
100 rfcomm_dlc_unlock(d);
101 rfcomm_sock_kill(sk);
102 rfcomm_dlc_lock(d);
103 }
104}
105
106/* ---- Socket functions ---- */
107static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src)
108{
109 struct sock *sk = NULL;
110 struct hlist_node *node;
111
112 sk_for_each(sk, node, &rfcomm_sk_list.head) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900113 if (rfcomm_pi(sk)->channel == channel &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114 !bacmp(&bt_sk(sk)->src, src))
115 break;
116 }
117
118 return node ? sk : NULL;
119}
120
121/* Find socket with channel and source bdaddr.
122 * Returns closest match.
123 */
Gustavo F. Padovaneeb36652010-11-01 18:43:53 +0000124static struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125{
126 struct sock *sk = NULL, *sk1 = NULL;
127 struct hlist_node *node;
128
Gustavo F. Padovaneeb36652010-11-01 18:43:53 +0000129 read_lock(&rfcomm_sk_list.lock);
130
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131 sk_for_each(sk, node, &rfcomm_sk_list.head) {
132 if (state && sk->sk_state != state)
133 continue;
134
135 if (rfcomm_pi(sk)->channel == channel) {
136 /* Exact match. */
137 if (!bacmp(&bt_sk(sk)->src, src))
138 break;
139
140 /* Closest match */
141 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
142 sk1 = sk;
143 }
144 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 read_unlock(&rfcomm_sk_list.lock);
Gustavo F. Padovaneeb36652010-11-01 18:43:53 +0000147
148 return node ? sk : sk1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149}
150
151static void rfcomm_sock_destruct(struct sock *sk)
152{
153 struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
154
155 BT_DBG("sk %p dlc %p", sk, d);
156
157 skb_queue_purge(&sk->sk_receive_queue);
158 skb_queue_purge(&sk->sk_write_queue);
159
160 rfcomm_dlc_lock(d);
161 rfcomm_pi(sk)->dlc = NULL;
162
163 /* Detach DLC if it's owned by this socket */
164 if (d->owner == sk)
165 d->owner = NULL;
166 rfcomm_dlc_unlock(d);
167
168 rfcomm_dlc_put(d);
169}
170
171static void rfcomm_sock_cleanup_listen(struct sock *parent)
172{
173 struct sock *sk;
174
175 BT_DBG("parent %p", parent);
176
177 /* Close not yet accepted dlcs */
178 while ((sk = bt_accept_dequeue(parent, NULL))) {
179 rfcomm_sock_close(sk);
180 rfcomm_sock_kill(sk);
181 }
182
183 parent->sk_state = BT_CLOSED;
184 sock_set_flag(parent, SOCK_ZAPPED);
185}
186
187/* Kill socket (only if zapped and orphan)
188 * Must be called on unlocked socket.
189 */
190static void rfcomm_sock_kill(struct sock *sk)
191{
192 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
193 return;
194
195 BT_DBG("sk %p state %d refcnt %d", sk, sk->sk_state, atomic_read(&sk->sk_refcnt));
196
197 /* Kill poor orphan */
198 bt_sock_unlink(&rfcomm_sk_list, sk);
199 sock_set_flag(sk, SOCK_DEAD);
200 sock_put(sk);
201}
202
203static void __rfcomm_sock_close(struct sock *sk)
204{
205 struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
206
207 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
208
209 switch (sk->sk_state) {
210 case BT_LISTEN:
211 rfcomm_sock_cleanup_listen(sk);
212 break;
213
214 case BT_CONNECT:
215 case BT_CONNECT2:
216 case BT_CONFIG:
217 case BT_CONNECTED:
218 rfcomm_dlc_close(d, 0);
219
220 default:
221 sock_set_flag(sk, SOCK_ZAPPED);
222 break;
223 }
224}
225
226/* Close socket.
227 * Must be called on unlocked socket.
228 */
229static void rfcomm_sock_close(struct sock *sk)
230{
231 lock_sock(sk);
232 __rfcomm_sock_close(sk);
233 release_sock(sk);
234}
235
236static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
237{
238 struct rfcomm_pinfo *pi = rfcomm_pi(sk);
239
240 BT_DBG("sk %p", sk);
241
242 if (parent) {
243 sk->sk_type = parent->sk_type;
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300244 pi->dlc->defer_setup = test_bit(BT_SK_DEFER_SETUP,
245 &bt_sk(parent)->flags);
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100246
247 pi->sec_level = rfcomm_pi(parent)->sec_level;
248 pi->role_switch = rfcomm_pi(parent)->role_switch;
Paul Moore6230c9b2011-10-07 09:40:59 +0000249
250 security_sk_clone(parent, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251 } else {
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100252 pi->dlc->defer_setup = 0;
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100253
254 pi->sec_level = BT_SECURITY_LOW;
255 pi->role_switch = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256 }
257
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100258 pi->dlc->sec_level = pi->sec_level;
259 pi->dlc->role_switch = pi->role_switch;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260}
261
262static struct proto rfcomm_proto = {
263 .name = "RFCOMM",
264 .owner = THIS_MODULE,
265 .obj_size = sizeof(struct rfcomm_pinfo)
266};
267
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700268static struct sock *rfcomm_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269{
270 struct rfcomm_dlc *d;
271 struct sock *sk;
272
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700273 sk = sk_alloc(net, PF_BLUETOOTH, prio, &rfcomm_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274 if (!sk)
275 return NULL;
276
277 sock_init_data(sock, sk);
278 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
279
280 d = rfcomm_dlc_alloc(prio);
281 if (!d) {
282 sk_free(sk);
283 return NULL;
284 }
285
286 d->data_ready = rfcomm_sk_data_ready;
287 d->state_change = rfcomm_sk_state_change;
288
289 rfcomm_pi(sk)->dlc = d;
290 d->owner = sk;
291
292 sk->sk_destruct = rfcomm_sock_destruct;
293 sk->sk_sndtimeo = RFCOMM_CONN_TIMEOUT;
294
Marcel Holtmann77db1982008-07-14 20:13:45 +0200295 sk->sk_sndbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10;
296 sk->sk_rcvbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297
298 sock_reset_flag(sk, SOCK_ZAPPED);
299
300 sk->sk_protocol = proto;
Marcel Holtmann77db1982008-07-14 20:13:45 +0200301 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302
303 bt_sock_link(&rfcomm_sk_list, sk);
304
305 BT_DBG("sk %p", sk);
306 return sk;
307}
308
Eric Paris3f378b62009-11-05 22:18:14 -0800309static int rfcomm_sock_create(struct net *net, struct socket *sock,
310 int protocol, int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311{
312 struct sock *sk;
313
314 BT_DBG("sock %p", sock);
315
316 sock->state = SS_UNCONNECTED;
317
318 if (sock->type != SOCK_STREAM && sock->type != SOCK_RAW)
319 return -ESOCKTNOSUPPORT;
320
321 sock->ops = &rfcomm_sock_ops;
322
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700323 sk = rfcomm_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Marcel Holtmann74da6262006-10-15 17:31:14 +0200324 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325 return -ENOMEM;
326
327 rfcomm_sock_init(sk, NULL);
328 return 0;
329}
330
331static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
332{
333 struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
334 struct sock *sk = sock->sk;
335 int err = 0;
336
337 BT_DBG("sk %p %s", sk, batostr(&sa->rc_bdaddr));
338
339 if (!addr || addr->sa_family != AF_BLUETOOTH)
340 return -EINVAL;
341
342 lock_sock(sk);
343
344 if (sk->sk_state != BT_OPEN) {
345 err = -EBADFD;
346 goto done;
347 }
348
Marcel Holtmann354d28d2005-09-13 01:32:31 +0200349 if (sk->sk_type != SOCK_STREAM) {
350 err = -EINVAL;
351 goto done;
352 }
353
Gustavo F. Padovan95ca83f2011-12-27 15:28:44 -0200354 write_lock(&rfcomm_sk_list.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355
356 if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) {
357 err = -EADDRINUSE;
358 } else {
359 /* Save source address */
360 bacpy(&bt_sk(sk)->src, &sa->rc_bdaddr);
361 rfcomm_pi(sk)->channel = sa->rc_channel;
362 sk->sk_state = BT_BOUND;
363 }
364
Gustavo F. Padovan95ca83f2011-12-27 15:28:44 -0200365 write_unlock(&rfcomm_sk_list.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366
367done:
368 release_sock(sk);
369 return err;
370}
371
372static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
373{
374 struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
375 struct sock *sk = sock->sk;
376 struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
377 int err = 0;
378
379 BT_DBG("sk %p", sk);
380
Changli Gao6503d962010-03-31 22:58:26 +0000381 if (alen < sizeof(struct sockaddr_rc) ||
382 addr->sa_family != AF_BLUETOOTH)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 return -EINVAL;
384
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385 lock_sock(sk);
386
Marcel Holtmann354d28d2005-09-13 01:32:31 +0200387 if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) {
388 err = -EBADFD;
389 goto done;
390 }
391
392 if (sk->sk_type != SOCK_STREAM) {
393 err = -EINVAL;
394 goto done;
395 }
396
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 sk->sk_state = BT_CONNECT;
398 bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr);
399 rfcomm_pi(sk)->channel = sa->rc_channel;
400
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100401 d->sec_level = rfcomm_pi(sk)->sec_level;
402 d->role_switch = rfcomm_pi(sk)->role_switch;
Marcel Holtmann77db1982008-07-14 20:13:45 +0200403
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404 err = rfcomm_dlc_open(d, &bt_sk(sk)->src, &sa->rc_bdaddr, sa->rc_channel);
405 if (!err)
406 err = bt_sock_wait_state(sk, BT_CONNECTED,
407 sock_sndtimeo(sk, flags & O_NONBLOCK));
408
Marcel Holtmann354d28d2005-09-13 01:32:31 +0200409done:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410 release_sock(sk);
411 return err;
412}
413
414static int rfcomm_sock_listen(struct socket *sock, int backlog)
415{
416 struct sock *sk = sock->sk;
417 int err = 0;
418
419 BT_DBG("sk %p backlog %d", sk, backlog);
420
421 lock_sock(sk);
422
423 if (sk->sk_state != BT_BOUND) {
424 err = -EBADFD;
425 goto done;
426 }
427
Marcel Holtmann354d28d2005-09-13 01:32:31 +0200428 if (sk->sk_type != SOCK_STREAM) {
429 err = -EINVAL;
430 goto done;
431 }
432
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433 if (!rfcomm_pi(sk)->channel) {
434 bdaddr_t *src = &bt_sk(sk)->src;
435 u8 channel;
436
437 err = -EINVAL;
438
Gustavo F. Padovan95ca83f2011-12-27 15:28:44 -0200439 write_lock(&rfcomm_sk_list.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440
441 for (channel = 1; channel < 31; channel++)
442 if (!__rfcomm_get_sock_by_addr(channel, src)) {
443 rfcomm_pi(sk)->channel = channel;
444 err = 0;
445 break;
446 }
447
Gustavo F. Padovan95ca83f2011-12-27 15:28:44 -0200448 write_unlock(&rfcomm_sk_list.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449
450 if (err < 0)
451 goto done;
452 }
453
454 sk->sk_max_ack_backlog = backlog;
455 sk->sk_ack_backlog = 0;
456 sk->sk_state = BT_LISTEN;
457
458done:
459 release_sock(sk);
460 return err;
461}
462
463static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int flags)
464{
465 DECLARE_WAITQUEUE(wait, current);
466 struct sock *sk = sock->sk, *nsk;
467 long timeo;
468 int err = 0;
469
470 lock_sock(sk);
471
Marcel Holtmann354d28d2005-09-13 01:32:31 +0200472 if (sk->sk_type != SOCK_STREAM) {
473 err = -EINVAL;
474 goto done;
475 }
476
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
478
479 BT_DBG("sk %p timeo %ld", sk, timeo);
480
481 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +0000482 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Peter Hurley950e2d52011-07-24 00:10:41 -0400483 while (1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484 set_current_state(TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485
486 if (sk->sk_state != BT_LISTEN) {
487 err = -EBADFD;
488 break;
489 }
490
Peter Hurley950e2d52011-07-24 00:10:41 -0400491 nsk = bt_accept_dequeue(sk, newsock);
492 if (nsk)
493 break;
494
495 if (!timeo) {
496 err = -EAGAIN;
497 break;
498 }
499
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 if (signal_pending(current)) {
501 err = sock_intr_errno(timeo);
502 break;
503 }
Peter Hurley950e2d52011-07-24 00:10:41 -0400504
505 release_sock(sk);
506 timeo = schedule_timeout(timeo);
507 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508 }
Peter Hurley950e2d52011-07-24 00:10:41 -0400509 __set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +0000510 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511
512 if (err)
513 goto done;
514
515 newsock->state = SS_CONNECTED;
516
517 BT_DBG("new socket %p", nsk);
518
519done:
520 release_sock(sk);
521 return err;
522}
523
524static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
525{
526 struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
527 struct sock *sk = sock->sk;
528
529 BT_DBG("sock %p, sk %p", sock, sk);
530
Mathias Krause9344a972012-08-15 11:31:50 +0000531 memset(sa, 0, sizeof(*sa));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532 sa->rc_family = AF_BLUETOOTH;
533 sa->rc_channel = rfcomm_pi(sk)->channel;
534 if (peer)
535 bacpy(&sa->rc_bdaddr, &bt_sk(sk)->dst);
536 else
537 bacpy(&sa->rc_bdaddr, &bt_sk(sk)->src);
538
539 *len = sizeof(struct sockaddr_rc);
540 return 0;
541}
542
543static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
544 struct msghdr *msg, size_t len)
545{
546 struct sock *sk = sock->sk;
547 struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
548 struct sk_buff *skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549 int sent = 0;
550
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100551 if (test_bit(RFCOMM_DEFER_SETUP, &d->flags))
552 return -ENOTCONN;
553
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554 if (msg->msg_flags & MSG_OOB)
555 return -EOPNOTSUPP;
556
557 if (sk->sk_shutdown & SEND_SHUTDOWN)
558 return -EPIPE;
559
560 BT_DBG("sock %p, sk %p", sock, sk);
561
562 lock_sock(sk);
563
564 while (len) {
565 size_t size = min_t(size_t, len, d->mtu);
Marcel Holtmann4d6a2182007-01-08 02:16:31 +0100566 int err;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900567
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 skb = sock_alloc_send_skb(sk, size + RFCOMM_SKB_RESERVE,
569 msg->msg_flags & MSG_DONTWAIT, &err);
Victor Shcherbatyuk91aa35a2009-01-15 21:52:12 +0100570 if (!skb) {
571 if (sent == 0)
572 sent = err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573 break;
Victor Shcherbatyuk91aa35a2009-01-15 21:52:12 +0100574 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575 skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
576
577 err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
578 if (err) {
579 kfree_skb(skb);
Marcel Holtmann4d6a2182007-01-08 02:16:31 +0100580 if (sent == 0)
581 sent = err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582 break;
583 }
584
Luiz Augusto von Dentz262038f2011-11-01 10:58:58 +0200585 skb->priority = sk->sk_priority;
586
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587 err = rfcomm_dlc_send(d, skb);
588 if (err < 0) {
589 kfree_skb(skb);
Marcel Holtmann4d6a2182007-01-08 02:16:31 +0100590 if (sent == 0)
591 sent = err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592 break;
593 }
594
595 sent += size;
596 len -= size;
597 }
598
599 release_sock(sk);
600
Marcel Holtmann4d6a2182007-01-08 02:16:31 +0100601 return sent;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602}
603
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
605 struct msghdr *msg, size_t size, int flags)
606{
607 struct sock *sk = sock->sk;
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100608 struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
Mat Martineau3d7d01d2010-09-08 10:05:28 -0700609 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100611 if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
612 rfcomm_dlc_accept(d);
613 return 0;
614 }
615
Mat Martineau3d7d01d2010-09-08 10:05:28 -0700616 len = bt_sock_stream_recvmsg(iocb, sock, msg, size, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617
618 lock_sock(sk);
Mat Martineau3d7d01d2010-09-08 10:05:28 -0700619 if (!(flags & MSG_PEEK) && len > 0)
620 atomic_sub(len, &sk->sk_rmem_alloc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622 if (atomic_read(&sk->sk_rmem_alloc) <= (sk->sk_rcvbuf >> 2))
623 rfcomm_dlc_unthrottle(rfcomm_pi(sk)->dlc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624 release_sock(sk);
Mat Martineau3d7d01d2010-09-08 10:05:28 -0700625
626 return len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627}
628
David S. Millerb7058842009-09-30 16:12:20 -0700629static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630{
631 struct sock *sk = sock->sk;
632 int err = 0;
633 u32 opt;
634
635 BT_DBG("sk %p", sk);
636
637 lock_sock(sk);
638
639 switch (optname) {
640 case RFCOMM_LM:
641 if (get_user(opt, (u32 __user *) optval)) {
642 err = -EFAULT;
643 break;
644 }
645
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100646 if (opt & RFCOMM_LM_AUTH)
647 rfcomm_pi(sk)->sec_level = BT_SECURITY_LOW;
648 if (opt & RFCOMM_LM_ENCRYPT)
649 rfcomm_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
650 if (opt & RFCOMM_LM_SECURE)
651 rfcomm_pi(sk)->sec_level = BT_SECURITY_HIGH;
652
653 rfcomm_pi(sk)->role_switch = (opt & RFCOMM_LM_MASTER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654 break;
655
656 default:
657 err = -ENOPROTOOPT;
658 break;
659 }
660
661 release_sock(sk);
662 return err;
663}
664
David S. Millerb7058842009-09-30 16:12:20 -0700665static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100666{
667 struct sock *sk = sock->sk;
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100668 struct bt_security sec;
Stephen Boydd0fad892011-05-12 16:50:09 -0700669 int err = 0;
670 size_t len;
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100671 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100672
673 BT_DBG("sk %p", sk);
674
675 if (level == SOL_RFCOMM)
676 return rfcomm_sock_setsockopt_old(sock, optname, optval, optlen);
677
Marcel Holtmann0588d942009-01-16 10:06:13 +0100678 if (level != SOL_BLUETOOTH)
679 return -ENOPROTOOPT;
680
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100681 lock_sock(sk);
682
683 switch (optname) {
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100684 case BT_SECURITY:
Marcel Holtmann0588d942009-01-16 10:06:13 +0100685 if (sk->sk_type != SOCK_STREAM) {
686 err = -EINVAL;
687 break;
688 }
689
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100690 sec.level = BT_SECURITY_LOW;
691
692 len = min_t(unsigned int, sizeof(sec), optlen);
693 if (copy_from_user((char *) &sec, optval, len)) {
694 err = -EFAULT;
695 break;
696 }
697
698 if (sec.level > BT_SECURITY_HIGH) {
699 err = -EINVAL;
700 break;
701 }
702
703 rfcomm_pi(sk)->sec_level = sec.level;
704 break;
705
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100706 case BT_DEFER_SETUP:
707 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
708 err = -EINVAL;
709 break;
710 }
711
712 if (get_user(opt, (u32 __user *) optval)) {
713 err = -EFAULT;
714 break;
715 }
716
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300717 if (opt)
718 set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
719 else
720 clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
721
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100722 break;
723
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100724 default:
725 err = -ENOPROTOOPT;
726 break;
727 }
728
729 release_sock(sk);
730 return err;
731}
732
733static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734{
735 struct sock *sk = sock->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736 struct rfcomm_conninfo cinfo;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300737 struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738 int len, err = 0;
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100739 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740
741 BT_DBG("sk %p", sk);
742
743 if (get_user(len, optlen))
744 return -EFAULT;
745
746 lock_sock(sk);
747
748 switch (optname) {
749 case RFCOMM_LM:
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100750 switch (rfcomm_pi(sk)->sec_level) {
751 case BT_SECURITY_LOW:
752 opt = RFCOMM_LM_AUTH;
753 break;
754 case BT_SECURITY_MEDIUM:
755 opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;
756 break;
757 case BT_SECURITY_HIGH:
758 opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT |
759 RFCOMM_LM_SECURE;
760 break;
761 default:
762 opt = 0;
763 break;
764 }
765
766 if (rfcomm_pi(sk)->role_switch)
767 opt |= RFCOMM_LM_MASTER;
768
769 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770 err = -EFAULT;
771 break;
772
773 case RFCOMM_CONNINFO:
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100774 if (sk->sk_state != BT_CONNECTED &&
775 !rfcomm_pi(sk)->dlc->defer_setup) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776 err = -ENOTCONN;
777 break;
778 }
779
Filip Palian8d03e972011-05-12 19:32:46 +0200780 memset(&cinfo, 0, sizeof(cinfo));
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300781 cinfo.hci_handle = conn->hcon->handle;
782 memcpy(cinfo.dev_class, conn->hcon->dev_class, 3);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783
784 len = min_t(unsigned int, len, sizeof(cinfo));
785 if (copy_to_user(optval, (char *) &cinfo, len))
786 err = -EFAULT;
787
788 break;
789
790 default:
791 err = -ENOPROTOOPT;
792 break;
793 }
794
795 release_sock(sk);
796 return err;
797}
798
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100799static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
800{
801 struct sock *sk = sock->sk;
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100802 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100803 int len, err = 0;
804
805 BT_DBG("sk %p", sk);
806
807 if (level == SOL_RFCOMM)
808 return rfcomm_sock_getsockopt_old(sock, optname, optval, optlen);
809
Marcel Holtmann0588d942009-01-16 10:06:13 +0100810 if (level != SOL_BLUETOOTH)
811 return -ENOPROTOOPT;
812
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100813 if (get_user(len, optlen))
814 return -EFAULT;
815
816 lock_sock(sk);
817
818 switch (optname) {
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100819 case BT_SECURITY:
Marcel Holtmann0588d942009-01-16 10:06:13 +0100820 if (sk->sk_type != SOCK_STREAM) {
821 err = -EINVAL;
822 break;
823 }
824
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100825 sec.level = rfcomm_pi(sk)->sec_level;
Mathias Krause9ad2de42012-08-15 11:31:48 +0000826 sec.key_size = 0;
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100827
828 len = min_t(unsigned int, len, sizeof(sec));
829 if (copy_to_user(optval, (char *) &sec, len))
830 err = -EFAULT;
831
832 break;
833
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100834 case BT_DEFER_SETUP:
835 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
836 err = -EINVAL;
837 break;
838 }
839
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300840 if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags),
841 (u32 __user *) optval))
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100842 err = -EFAULT;
843
844 break;
845
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100846 default:
847 err = -ENOPROTOOPT;
848 break;
849 }
850
851 release_sock(sk);
852 return err;
853}
854
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
856{
David S. Millere19caae2008-12-09 01:04:27 -0800857 struct sock *sk __maybe_unused = sock->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858 int err;
859
David S. Millere19caae2008-12-09 01:04:27 -0800860 BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861
Marcel Holtmann3241ad82008-07-14 20:13:50 +0200862 err = bt_sock_ioctl(sock, cmd, arg);
863
864 if (err == -ENOIOCTLCMD) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865#ifdef CONFIG_BT_RFCOMM_TTY
Marcel Holtmann3241ad82008-07-14 20:13:50 +0200866 lock_sock(sk);
867 err = rfcomm_dev_ioctl(sk, cmd, (void __user *) arg);
868 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869#else
Marcel Holtmann3241ad82008-07-14 20:13:50 +0200870 err = -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871#endif
Marcel Holtmann3241ad82008-07-14 20:13:50 +0200872 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 return err;
875}
876
877static int rfcomm_sock_shutdown(struct socket *sock, int how)
878{
879 struct sock *sk = sock->sk;
880 int err = 0;
881
882 BT_DBG("sock %p, sk %p", sock, sk);
883
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200884 if (!sk)
885 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886
887 lock_sock(sk);
888 if (!sk->sk_shutdown) {
889 sk->sk_shutdown = SHUTDOWN_MASK;
890 __rfcomm_sock_close(sk);
891
892 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
893 err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
894 }
895 release_sock(sk);
896 return err;
897}
898
899static int rfcomm_sock_release(struct socket *sock)
900{
901 struct sock *sk = sock->sk;
902 int err;
903
904 BT_DBG("sock %p, sk %p", sock, sk);
905
906 if (!sk)
907 return 0;
908
909 err = rfcomm_sock_shutdown(sock, 2);
910
911 sock_orphan(sk);
912 rfcomm_sock_kill(sk);
913 return err;
914}
915
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900916/* ---- RFCOMM core layer callbacks ----
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917 *
918 * called under rfcomm_lock()
919 */
920int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d)
921{
922 struct sock *sk, *parent;
923 bdaddr_t src, dst;
924 int result = 0;
925
926 BT_DBG("session %p channel %d", s, channel);
927
928 rfcomm_session_getaddr(s, &src, &dst);
929
930 /* Check if we have socket listening on channel */
931 parent = rfcomm_get_sock_by_channel(BT_LISTEN, channel, &src);
932 if (!parent)
933 return 0;
934
Gustavo F. Padovaneeb36652010-11-01 18:43:53 +0000935 bh_lock_sock(parent);
936
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937 /* Check for backlog size */
938 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900939 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940 goto done;
941 }
942
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900943 sk = rfcomm_sock_alloc(sock_net(parent), NULL, BTPROTO_RFCOMM, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700944 if (!sk)
945 goto done;
946
Octavian Purdilab5a30dd2012-01-22 00:28:34 +0200947 bt_sock_reclassify_lock(sk, BTPROTO_RFCOMM);
948
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949 rfcomm_sock_init(sk, parent);
950 bacpy(&bt_sk(sk)->src, &src);
951 bacpy(&bt_sk(sk)->dst, &dst);
952 rfcomm_pi(sk)->channel = channel;
953
954 sk->sk_state = BT_CONFIG;
955 bt_accept_enqueue(parent, sk);
956
957 /* Accept connection and return socket DLC */
958 *d = rfcomm_pi(sk)->dlc;
959 result = 1;
960
961done:
962 bh_unlock_sock(parent);
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100963
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300964 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags))
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100965 parent->sk_state_change(parent);
966
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967 return result;
968}
969
Marcel Holtmannaef7d972010-03-21 05:27:45 +0100970static int rfcomm_sock_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971{
972 struct sock *sk;
973 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974
Gustavo F. Padovan95ca83f2011-12-27 15:28:44 -0200975 read_lock(&rfcomm_sk_list.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700976
Marcel Holtmannbe9d1222005-11-08 09:57:38 -0800977 sk_for_each(sk, node, &rfcomm_sk_list.head) {
Marcel Holtmannaef7d972010-03-21 05:27:45 +0100978 seq_printf(f, "%s %s %d %d\n",
979 batostr(&bt_sk(sk)->src),
980 batostr(&bt_sk(sk)->dst),
Marcel Holtmannbe9d1222005-11-08 09:57:38 -0800981 sk->sk_state, rfcomm_pi(sk)->channel);
982 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983
Gustavo F. Padovan95ca83f2011-12-27 15:28:44 -0200984 read_unlock(&rfcomm_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -0800985
Marcel Holtmannaef7d972010-03-21 05:27:45 +0100986 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987}
988
Marcel Holtmannaef7d972010-03-21 05:27:45 +0100989static int rfcomm_sock_debugfs_open(struct inode *inode, struct file *file)
990{
991 return single_open(file, rfcomm_sock_debugfs_show, inode->i_private);
992}
993
994static const struct file_operations rfcomm_sock_debugfs_fops = {
995 .open = rfcomm_sock_debugfs_open,
996 .read = seq_read,
997 .llseek = seq_lseek,
998 .release = single_release,
999};
1000
1001static struct dentry *rfcomm_sock_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08001003static const struct proto_ops rfcomm_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004 .family = PF_BLUETOOTH,
1005 .owner = THIS_MODULE,
1006 .release = rfcomm_sock_release,
1007 .bind = rfcomm_sock_bind,
1008 .connect = rfcomm_sock_connect,
1009 .listen = rfcomm_sock_listen,
1010 .accept = rfcomm_sock_accept,
1011 .getname = rfcomm_sock_getname,
1012 .sendmsg = rfcomm_sock_sendmsg,
1013 .recvmsg = rfcomm_sock_recvmsg,
1014 .shutdown = rfcomm_sock_shutdown,
1015 .setsockopt = rfcomm_sock_setsockopt,
1016 .getsockopt = rfcomm_sock_getsockopt,
1017 .ioctl = rfcomm_sock_ioctl,
1018 .poll = bt_sock_poll,
1019 .socketpair = sock_no_socketpair,
1020 .mmap = sock_no_mmap
1021};
1022
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00001023static const struct net_proto_family rfcomm_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024 .family = PF_BLUETOOTH,
1025 .owner = THIS_MODULE,
1026 .create = rfcomm_sock_create
1027};
1028
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08001029int __init rfcomm_init_sockets(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030{
1031 int err;
1032
1033 err = proto_register(&rfcomm_proto, 0);
1034 if (err < 0)
1035 return err;
1036
1037 err = bt_sock_register(BTPROTO_RFCOMM, &rfcomm_sock_family_ops);
1038 if (err < 0)
1039 goto error;
1040
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001041 if (bt_debugfs) {
1042 rfcomm_sock_debugfs = debugfs_create_file("rfcomm", 0444,
1043 bt_debugfs, NULL, &rfcomm_sock_debugfs_fops);
1044 if (!rfcomm_sock_debugfs)
1045 BT_ERR("Failed to create RFCOMM debug file");
1046 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047
1048 BT_INFO("RFCOMM socket layer initialized");
1049
1050 return 0;
1051
1052error:
1053 BT_ERR("RFCOMM socket layer registration failed");
1054 proto_unregister(&rfcomm_proto);
1055 return err;
1056}
1057
Gustavo F. Padovan2f8362a2010-07-24 02:04:45 -03001058void __exit rfcomm_cleanup_sockets(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001060 debugfs_remove(rfcomm_sock_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061
1062 if (bt_sock_unregister(BTPROTO_RFCOMM) < 0)
1063 BT_ERR("RFCOMM socket layer unregistration failed");
1064
1065 proto_unregister(&rfcomm_proto);
1066}