blob: 216068f4af129b64a99b37e1311df19c40f61ca4 [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
Linus Torvalds1da177e2005-04-16 15:20:36 -070028#include <linux/module.h>
29
30#include <linux/types.h>
31#include <linux/errno.h>
32#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/sched.h>
34#include <linux/slab.h>
35#include <linux/poll.h>
36#include <linux/fcntl.h>
37#include <linux/init.h>
38#include <linux/interrupt.h>
39#include <linux/socket.h>
40#include <linux/skbuff.h>
41#include <linux/list.h>
Marcel Holtmannbe9d1222005-11-08 09:57:38 -080042#include <linux/device.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010043#include <linux/debugfs.h>
44#include <linux/seq_file.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070045#include <net/sock.h>
46
47#include <asm/system.h>
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +020048#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
50#include <net/bluetooth/bluetooth.h>
51#include <net/bluetooth/hci_core.h>
52#include <net/bluetooth/l2cap.h>
53#include <net/bluetooth/rfcomm.h>
54
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080055static const struct proto_ops rfcomm_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070056
57static struct bt_sock_list rfcomm_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070058 .lock = __RW_LOCK_UNLOCKED(rfcomm_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070059};
60
61static void rfcomm_sock_close(struct sock *sk);
62static void rfcomm_sock_kill(struct sock *sk);
63
64/* ---- DLC callbacks ----
65 *
66 * called under rfcomm_dlc_lock()
67 */
68static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb)
69{
70 struct sock *sk = d->owner;
71 if (!sk)
72 return;
73
74 atomic_add(skb->len, &sk->sk_rmem_alloc);
75 skb_queue_tail(&sk->sk_receive_queue, skb);
76 sk->sk_data_ready(sk, skb->len);
77
78 if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)
79 rfcomm_dlc_throttle(d);
80}
81
82static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
83{
84 struct sock *sk = d->owner, *parent;
Gustavo F. Padovanfad003b2010-08-14 00:48:07 -030085 unsigned long flags;
86
Linus Torvalds1da177e2005-04-16 15:20:36 -070087 if (!sk)
88 return;
89
90 BT_DBG("dlc %p state %ld err %d", d, d->state, err);
91
Gustavo F. Padovanfad003b2010-08-14 00:48:07 -030092 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -070093 bh_lock_sock(sk);
94
95 if (err)
96 sk->sk_err = err;
97
98 sk->sk_state = d->state;
99
100 parent = bt_sk(sk)->parent;
101 if (parent) {
102 if (d->state == BT_CLOSED) {
103 sock_set_flag(sk, SOCK_ZAPPED);
104 bt_accept_unlink(sk);
105 }
106 parent->sk_data_ready(parent, 0);
107 } else {
108 if (d->state == BT_CONNECTED)
109 rfcomm_session_getaddr(d->session, &bt_sk(sk)->src, NULL);
110 sk->sk_state_change(sk);
111 }
112
113 bh_unlock_sock(sk);
Gustavo F. Padovanfad003b2010-08-14 00:48:07 -0300114 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115
116 if (parent && sock_flag(sk, SOCK_ZAPPED)) {
117 /* We have to drop DLC lock here, otherwise
118 * rfcomm_sock_destruct() will dead lock. */
119 rfcomm_dlc_unlock(d);
120 rfcomm_sock_kill(sk);
121 rfcomm_dlc_lock(d);
122 }
123}
124
125/* ---- Socket functions ---- */
126static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src)
127{
128 struct sock *sk = NULL;
129 struct hlist_node *node;
130
131 sk_for_each(sk, node, &rfcomm_sk_list.head) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900132 if (rfcomm_pi(sk)->channel == channel &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133 !bacmp(&bt_sk(sk)->src, src))
134 break;
135 }
136
137 return node ? sk : NULL;
138}
139
140/* Find socket with channel and source bdaddr.
141 * Returns closest match.
142 */
Gustavo F. Padovaneeb36652010-11-01 18:43:53 +0000143static struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144{
145 struct sock *sk = NULL, *sk1 = NULL;
146 struct hlist_node *node;
147
Gustavo F. Padovaneeb36652010-11-01 18:43:53 +0000148 read_lock(&rfcomm_sk_list.lock);
149
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150 sk_for_each(sk, node, &rfcomm_sk_list.head) {
151 if (state && sk->sk_state != state)
152 continue;
153
154 if (rfcomm_pi(sk)->channel == channel) {
155 /* Exact match. */
156 if (!bacmp(&bt_sk(sk)->src, src))
157 break;
158
159 /* Closest match */
160 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
161 sk1 = sk;
162 }
163 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165 read_unlock(&rfcomm_sk_list.lock);
Gustavo F. Padovaneeb36652010-11-01 18:43:53 +0000166
167 return node ? sk : sk1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168}
169
170static void rfcomm_sock_destruct(struct sock *sk)
171{
172 struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
173
174 BT_DBG("sk %p dlc %p", sk, d);
175
176 skb_queue_purge(&sk->sk_receive_queue);
177 skb_queue_purge(&sk->sk_write_queue);
178
179 rfcomm_dlc_lock(d);
180 rfcomm_pi(sk)->dlc = NULL;
181
182 /* Detach DLC if it's owned by this socket */
183 if (d->owner == sk)
184 d->owner = NULL;
185 rfcomm_dlc_unlock(d);
186
187 rfcomm_dlc_put(d);
188}
189
190static void rfcomm_sock_cleanup_listen(struct sock *parent)
191{
192 struct sock *sk;
193
194 BT_DBG("parent %p", parent);
195
196 /* Close not yet accepted dlcs */
197 while ((sk = bt_accept_dequeue(parent, NULL))) {
198 rfcomm_sock_close(sk);
199 rfcomm_sock_kill(sk);
200 }
201
202 parent->sk_state = BT_CLOSED;
203 sock_set_flag(parent, SOCK_ZAPPED);
204}
205
206/* Kill socket (only if zapped and orphan)
207 * Must be called on unlocked socket.
208 */
209static void rfcomm_sock_kill(struct sock *sk)
210{
211 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
212 return;
213
214 BT_DBG("sk %p state %d refcnt %d", sk, sk->sk_state, atomic_read(&sk->sk_refcnt));
215
216 /* Kill poor orphan */
217 bt_sock_unlink(&rfcomm_sk_list, sk);
218 sock_set_flag(sk, SOCK_DEAD);
219 sock_put(sk);
220}
221
222static void __rfcomm_sock_close(struct sock *sk)
223{
224 struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
225
226 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
227
228 switch (sk->sk_state) {
229 case BT_LISTEN:
230 rfcomm_sock_cleanup_listen(sk);
231 break;
232
233 case BT_CONNECT:
234 case BT_CONNECT2:
235 case BT_CONFIG:
236 case BT_CONNECTED:
237 rfcomm_dlc_close(d, 0);
238
239 default:
240 sock_set_flag(sk, SOCK_ZAPPED);
241 break;
242 }
243}
244
245/* Close socket.
246 * Must be called on unlocked socket.
247 */
248static void rfcomm_sock_close(struct sock *sk)
249{
250 lock_sock(sk);
251 __rfcomm_sock_close(sk);
252 release_sock(sk);
253}
254
255static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
256{
257 struct rfcomm_pinfo *pi = rfcomm_pi(sk);
258
259 BT_DBG("sk %p", sk);
260
261 if (parent) {
262 sk->sk_type = parent->sk_type;
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100263 pi->dlc->defer_setup = bt_sk(parent)->defer_setup;
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100264
265 pi->sec_level = rfcomm_pi(parent)->sec_level;
266 pi->role_switch = rfcomm_pi(parent)->role_switch;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267 } else {
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100268 pi->dlc->defer_setup = 0;
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100269
270 pi->sec_level = BT_SECURITY_LOW;
271 pi->role_switch = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272 }
273
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100274 pi->dlc->sec_level = pi->sec_level;
275 pi->dlc->role_switch = pi->role_switch;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276}
277
278static struct proto rfcomm_proto = {
279 .name = "RFCOMM",
280 .owner = THIS_MODULE,
281 .obj_size = sizeof(struct rfcomm_pinfo)
282};
283
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700284static struct sock *rfcomm_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285{
286 struct rfcomm_dlc *d;
287 struct sock *sk;
288
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700289 sk = sk_alloc(net, PF_BLUETOOTH, prio, &rfcomm_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290 if (!sk)
291 return NULL;
292
293 sock_init_data(sock, sk);
294 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
295
296 d = rfcomm_dlc_alloc(prio);
297 if (!d) {
298 sk_free(sk);
299 return NULL;
300 }
301
302 d->data_ready = rfcomm_sk_data_ready;
303 d->state_change = rfcomm_sk_state_change;
304
305 rfcomm_pi(sk)->dlc = d;
306 d->owner = sk;
307
308 sk->sk_destruct = rfcomm_sock_destruct;
309 sk->sk_sndtimeo = RFCOMM_CONN_TIMEOUT;
310
Marcel Holtmann77db1982008-07-14 20:13:45 +0200311 sk->sk_sndbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10;
312 sk->sk_rcvbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313
314 sock_reset_flag(sk, SOCK_ZAPPED);
315
316 sk->sk_protocol = proto;
Marcel Holtmann77db1982008-07-14 20:13:45 +0200317 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318
319 bt_sock_link(&rfcomm_sk_list, sk);
320
321 BT_DBG("sk %p", sk);
322 return sk;
323}
324
Eric Paris3f378b62009-11-05 22:18:14 -0800325static int rfcomm_sock_create(struct net *net, struct socket *sock,
326 int protocol, int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327{
328 struct sock *sk;
329
330 BT_DBG("sock %p", sock);
331
332 sock->state = SS_UNCONNECTED;
333
334 if (sock->type != SOCK_STREAM && sock->type != SOCK_RAW)
335 return -ESOCKTNOSUPPORT;
336
337 sock->ops = &rfcomm_sock_ops;
338
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700339 sk = rfcomm_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Marcel Holtmann74da6262006-10-15 17:31:14 +0200340 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341 return -ENOMEM;
342
343 rfcomm_sock_init(sk, NULL);
344 return 0;
345}
346
347static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
348{
349 struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
350 struct sock *sk = sock->sk;
351 int err = 0;
352
353 BT_DBG("sk %p %s", sk, batostr(&sa->rc_bdaddr));
354
355 if (!addr || addr->sa_family != AF_BLUETOOTH)
356 return -EINVAL;
357
358 lock_sock(sk);
359
360 if (sk->sk_state != BT_OPEN) {
361 err = -EBADFD;
362 goto done;
363 }
364
Marcel Holtmann354d28d2005-09-13 01:32:31 +0200365 if (sk->sk_type != SOCK_STREAM) {
366 err = -EINVAL;
367 goto done;
368 }
369
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 write_lock_bh(&rfcomm_sk_list.lock);
371
372 if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) {
373 err = -EADDRINUSE;
374 } else {
375 /* Save source address */
376 bacpy(&bt_sk(sk)->src, &sa->rc_bdaddr);
377 rfcomm_pi(sk)->channel = sa->rc_channel;
378 sk->sk_state = BT_BOUND;
379 }
380
381 write_unlock_bh(&rfcomm_sk_list.lock);
382
383done:
384 release_sock(sk);
385 return err;
386}
387
388static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
389{
390 struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
391 struct sock *sk = sock->sk;
392 struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
393 int err = 0;
394
395 BT_DBG("sk %p", sk);
396
Changli Gao6503d962010-03-31 22:58:26 +0000397 if (alen < sizeof(struct sockaddr_rc) ||
398 addr->sa_family != AF_BLUETOOTH)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399 return -EINVAL;
400
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401 lock_sock(sk);
402
Marcel Holtmann354d28d2005-09-13 01:32:31 +0200403 if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) {
404 err = -EBADFD;
405 goto done;
406 }
407
408 if (sk->sk_type != SOCK_STREAM) {
409 err = -EINVAL;
410 goto done;
411 }
412
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 sk->sk_state = BT_CONNECT;
414 bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr);
415 rfcomm_pi(sk)->channel = sa->rc_channel;
416
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100417 d->sec_level = rfcomm_pi(sk)->sec_level;
418 d->role_switch = rfcomm_pi(sk)->role_switch;
Marcel Holtmann77db1982008-07-14 20:13:45 +0200419
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 err = rfcomm_dlc_open(d, &bt_sk(sk)->src, &sa->rc_bdaddr, sa->rc_channel);
421 if (!err)
422 err = bt_sock_wait_state(sk, BT_CONNECTED,
423 sock_sndtimeo(sk, flags & O_NONBLOCK));
424
Marcel Holtmann354d28d2005-09-13 01:32:31 +0200425done:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426 release_sock(sk);
427 return err;
428}
429
430static int rfcomm_sock_listen(struct socket *sock, int backlog)
431{
432 struct sock *sk = sock->sk;
433 int err = 0;
434
435 BT_DBG("sk %p backlog %d", sk, backlog);
436
437 lock_sock(sk);
438
439 if (sk->sk_state != BT_BOUND) {
440 err = -EBADFD;
441 goto done;
442 }
443
Marcel Holtmann354d28d2005-09-13 01:32:31 +0200444 if (sk->sk_type != SOCK_STREAM) {
445 err = -EINVAL;
446 goto done;
447 }
448
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 if (!rfcomm_pi(sk)->channel) {
450 bdaddr_t *src = &bt_sk(sk)->src;
451 u8 channel;
452
453 err = -EINVAL;
454
455 write_lock_bh(&rfcomm_sk_list.lock);
456
457 for (channel = 1; channel < 31; channel++)
458 if (!__rfcomm_get_sock_by_addr(channel, src)) {
459 rfcomm_pi(sk)->channel = channel;
460 err = 0;
461 break;
462 }
463
464 write_unlock_bh(&rfcomm_sk_list.lock);
465
466 if (err < 0)
467 goto done;
468 }
469
470 sk->sk_max_ack_backlog = backlog;
471 sk->sk_ack_backlog = 0;
472 sk->sk_state = BT_LISTEN;
473
474done:
475 release_sock(sk);
476 return err;
477}
478
479static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int flags)
480{
481 DECLARE_WAITQUEUE(wait, current);
482 struct sock *sk = sock->sk, *nsk;
483 long timeo;
484 int err = 0;
485
486 lock_sock(sk);
487
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700488 if (sk->sk_state != BT_LISTEN) {
489 err = -EBADFD;
490 goto done;
491 }
492
Marcel Holtmann354d28d2005-09-13 01:32:31 +0200493 if (sk->sk_type != SOCK_STREAM) {
494 err = -EINVAL;
495 goto done;
496 }
497
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
499
500 BT_DBG("sk %p timeo %ld", sk, timeo);
501
502 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +0000503 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700504 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 set_current_state(TASK_INTERRUPTIBLE);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700506 if (!timeo) {
507 err = -EAGAIN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508 break;
509 }
510
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700511 release_sock(sk);
512 timeo = schedule_timeout(timeo);
513 lock_sock(sk);
Peter Hurleye7a40bf2011-07-24 00:10:41 -0400514
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700515 if (sk->sk_state != BT_LISTEN) {
516 err = -EBADFD;
Peter Hurleye7a40bf2011-07-24 00:10:41 -0400517 break;
518 }
519
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520 if (signal_pending(current)) {
521 err = sock_intr_errno(timeo);
522 break;
523 }
524 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700525 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +0000526 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527
528 if (err)
529 goto done;
530
531 newsock->state = SS_CONNECTED;
532
533 BT_DBG("new socket %p", nsk);
534
535done:
536 release_sock(sk);
537 return err;
538}
539
540static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
541{
542 struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
543 struct sock *sk = sock->sk;
544
545 BT_DBG("sock %p, sk %p", sock, sk);
546
547 sa->rc_family = AF_BLUETOOTH;
548 sa->rc_channel = rfcomm_pi(sk)->channel;
549 if (peer)
550 bacpy(&sa->rc_bdaddr, &bt_sk(sk)->dst);
551 else
552 bacpy(&sa->rc_bdaddr, &bt_sk(sk)->src);
553
554 *len = sizeof(struct sockaddr_rc);
555 return 0;
556}
557
558static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
559 struct msghdr *msg, size_t len)
560{
561 struct sock *sk = sock->sk;
562 struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
563 struct sk_buff *skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564 int sent = 0;
565
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100566 if (test_bit(RFCOMM_DEFER_SETUP, &d->flags))
567 return -ENOTCONN;
568
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 if (msg->msg_flags & MSG_OOB)
570 return -EOPNOTSUPP;
571
572 if (sk->sk_shutdown & SEND_SHUTDOWN)
573 return -EPIPE;
574
575 BT_DBG("sock %p, sk %p", sock, sk);
576
577 lock_sock(sk);
578
579 while (len) {
580 size_t size = min_t(size_t, len, d->mtu);
Marcel Holtmann4d6a2182007-01-08 02:16:31 +0100581 int err;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900582
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583 skb = sock_alloc_send_skb(sk, size + RFCOMM_SKB_RESERVE,
584 msg->msg_flags & MSG_DONTWAIT, &err);
Victor Shcherbatyuk91aa35a2009-01-15 21:52:12 +0100585 if (!skb) {
586 if (sent == 0)
587 sent = err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 break;
Victor Shcherbatyuk91aa35a2009-01-15 21:52:12 +0100589 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590 skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
591
592 err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
593 if (err) {
594 kfree_skb(skb);
Marcel Holtmann4d6a2182007-01-08 02:16:31 +0100595 if (sent == 0)
596 sent = err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597 break;
598 }
599
600 err = rfcomm_dlc_send(d, skb);
601 if (err < 0) {
602 kfree_skb(skb);
Marcel Holtmann4d6a2182007-01-08 02:16:31 +0100603 if (sent == 0)
604 sent = err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605 break;
606 }
607
608 sent += size;
609 len -= size;
610 }
611
612 release_sock(sk);
613
Marcel Holtmann4d6a2182007-01-08 02:16:31 +0100614 return sent;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615}
616
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
618 struct msghdr *msg, size_t size, int flags)
619{
620 struct sock *sk = sock->sk;
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100621 struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
Mat Martineau3d7d01d2010-09-08 10:05:28 -0700622 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100624 if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
625 rfcomm_dlc_accept(d);
626 return 0;
627 }
628
Mat Martineau3d7d01d2010-09-08 10:05:28 -0700629 len = bt_sock_stream_recvmsg(iocb, sock, msg, size, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630
631 lock_sock(sk);
Mat Martineau3d7d01d2010-09-08 10:05:28 -0700632 if (!(flags & MSG_PEEK) && len > 0)
633 atomic_sub(len, &sk->sk_rmem_alloc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 if (atomic_read(&sk->sk_rmem_alloc) <= (sk->sk_rcvbuf >> 2))
636 rfcomm_dlc_unthrottle(rfcomm_pi(sk)->dlc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 release_sock(sk);
Mat Martineau3d7d01d2010-09-08 10:05:28 -0700638
639 return len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640}
641
David S. Millerb7058842009-09-30 16:12:20 -0700642static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643{
644 struct sock *sk = sock->sk;
645 int err = 0;
646 u32 opt;
647
648 BT_DBG("sk %p", sk);
649
650 lock_sock(sk);
651
652 switch (optname) {
653 case RFCOMM_LM:
654 if (get_user(opt, (u32 __user *) optval)) {
655 err = -EFAULT;
656 break;
657 }
658
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100659 if (opt & RFCOMM_LM_AUTH)
660 rfcomm_pi(sk)->sec_level = BT_SECURITY_LOW;
661 if (opt & RFCOMM_LM_ENCRYPT)
662 rfcomm_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
663 if (opt & RFCOMM_LM_SECURE)
664 rfcomm_pi(sk)->sec_level = BT_SECURITY_HIGH;
665
666 rfcomm_pi(sk)->role_switch = (opt & RFCOMM_LM_MASTER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667 break;
668
669 default:
670 err = -ENOPROTOOPT;
671 break;
672 }
673
674 release_sock(sk);
675 return err;
676}
677
David S. Millerb7058842009-09-30 16:12:20 -0700678static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100679{
680 struct sock *sk = sock->sk;
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100681 struct bt_security sec;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700682 int len, err = 0;
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100683 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100684
685 BT_DBG("sk %p", sk);
686
687 if (level == SOL_RFCOMM)
688 return rfcomm_sock_setsockopt_old(sock, optname, optval, optlen);
689
Marcel Holtmann0588d942009-01-16 10:06:13 +0100690 if (level != SOL_BLUETOOTH)
691 return -ENOPROTOOPT;
692
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100693 lock_sock(sk);
694
695 switch (optname) {
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100696 case BT_SECURITY:
Marcel Holtmann0588d942009-01-16 10:06:13 +0100697 if (sk->sk_type != SOCK_STREAM) {
698 err = -EINVAL;
699 break;
700 }
701
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100702 sec.level = BT_SECURITY_LOW;
703
704 len = min_t(unsigned int, sizeof(sec), optlen);
705 if (copy_from_user((char *) &sec, optval, len)) {
706 err = -EFAULT;
707 break;
708 }
709
Bhakthavatsala Raghavendrab03b5702013-02-12 19:44:47 +0530710 if (sec.level > BT_SECURITY_VERY_HIGH) {
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100711 err = -EINVAL;
712 break;
713 }
714
715 rfcomm_pi(sk)->sec_level = sec.level;
Bhakthavatsala Raghavendrab03b5702013-02-12 19:44:47 +0530716 BT_DBG("set to %d", sec.level);
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100717 break;
718
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100719 case BT_DEFER_SETUP:
720 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
721 err = -EINVAL;
722 break;
723 }
724
725 if (get_user(opt, (u32 __user *) optval)) {
726 err = -EFAULT;
727 break;
728 }
729
730 bt_sk(sk)->defer_setup = opt;
731 break;
732
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100733 default:
734 err = -ENOPROTOOPT;
735 break;
736 }
737
738 release_sock(sk);
739 return err;
740}
741
742static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743{
744 struct sock *sk = sock->sk;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700745 struct sock *l2cap_sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746 struct rfcomm_conninfo cinfo;
747 int len, err = 0;
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100748 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749
750 BT_DBG("sk %p", sk);
751
752 if (get_user(len, optlen))
753 return -EFAULT;
754
755 lock_sock(sk);
756
757 switch (optname) {
758 case RFCOMM_LM:
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100759 switch (rfcomm_pi(sk)->sec_level) {
760 case BT_SECURITY_LOW:
761 opt = RFCOMM_LM_AUTH;
762 break;
763 case BT_SECURITY_MEDIUM:
764 opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;
765 break;
766 case BT_SECURITY_HIGH:
Bhakthavatsala Raghavendrab03b5702013-02-12 19:44:47 +0530767 case BT_SECURITY_VERY_HIGH:
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100768 opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT |
769 RFCOMM_LM_SECURE;
770 break;
771 default:
772 opt = 0;
773 break;
774 }
775
776 if (rfcomm_pi(sk)->role_switch)
777 opt |= RFCOMM_LM_MASTER;
778
779 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 err = -EFAULT;
781 break;
782
783 case RFCOMM_CONNINFO:
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100784 if (sk->sk_state != BT_CONNECTED &&
785 !rfcomm_pi(sk)->dlc->defer_setup) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786 err = -ENOTCONN;
787 break;
788 }
789
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700790 l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700792 cinfo.hci_handle = l2cap_pi(l2cap_sk)->conn->hcon->handle;
793 memcpy(cinfo.dev_class, l2cap_pi(l2cap_sk)->conn->hcon->dev_class, 3);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794
795 len = min_t(unsigned int, len, sizeof(cinfo));
796 if (copy_to_user(optval, (char *) &cinfo, len))
797 err = -EFAULT;
798
799 break;
800
801 default:
802 err = -ENOPROTOOPT;
803 break;
804 }
805
806 release_sock(sk);
807 return err;
808}
809
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100810static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
811{
812 struct sock *sk = sock->sk;
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100813 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100814 int len, err = 0;
815
816 BT_DBG("sk %p", sk);
817
818 if (level == SOL_RFCOMM)
819 return rfcomm_sock_getsockopt_old(sock, optname, optval, optlen);
820
Marcel Holtmann0588d942009-01-16 10:06:13 +0100821 if (level != SOL_BLUETOOTH)
822 return -ENOPROTOOPT;
823
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100824 if (get_user(len, optlen))
825 return -EFAULT;
826
827 lock_sock(sk);
828
829 switch (optname) {
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100830 case BT_SECURITY:
Marcel Holtmann0588d942009-01-16 10:06:13 +0100831 if (sk->sk_type != SOCK_STREAM) {
832 err = -EINVAL;
833 break;
834 }
835
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100836 sec.level = rfcomm_pi(sk)->sec_level;
837
838 len = min_t(unsigned int, len, sizeof(sec));
839 if (copy_to_user(optval, (char *) &sec, len))
840 err = -EFAULT;
841
842 break;
843
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100844 case BT_DEFER_SETUP:
845 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
846 err = -EINVAL;
847 break;
848 }
849
850 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
851 err = -EFAULT;
852
853 break;
854
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100855 default:
856 err = -ENOPROTOOPT;
857 break;
858 }
859
860 release_sock(sk);
861 return err;
862}
863
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
865{
David S. Millere19caae2008-12-09 01:04:27 -0800866 struct sock *sk __maybe_unused = sock->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867 int err;
868
David S. Millere19caae2008-12-09 01:04:27 -0800869 BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870
Marcel Holtmann3241ad82008-07-14 20:13:50 +0200871 err = bt_sock_ioctl(sock, cmd, arg);
872
873 if (err == -ENOIOCTLCMD) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874#ifdef CONFIG_BT_RFCOMM_TTY
Marcel Holtmann3241ad82008-07-14 20:13:50 +0200875 lock_sock(sk);
876 err = rfcomm_dev_ioctl(sk, cmd, (void __user *) arg);
877 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878#else
Marcel Holtmann3241ad82008-07-14 20:13:50 +0200879 err = -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880#endif
Marcel Holtmann3241ad82008-07-14 20:13:50 +0200881 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883 return err;
884}
885
886static int rfcomm_sock_shutdown(struct socket *sock, int how)
887{
888 struct sock *sk = sock->sk;
889 int err = 0;
890
891 BT_DBG("sock %p, sk %p", sock, sk);
892
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200893 if (!sk)
894 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895
896 lock_sock(sk);
897 if (!sk->sk_shutdown) {
898 sk->sk_shutdown = SHUTDOWN_MASK;
899 __rfcomm_sock_close(sk);
900
901 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
902 err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
903 }
904 release_sock(sk);
905 return err;
906}
907
908static int rfcomm_sock_release(struct socket *sock)
909{
910 struct sock *sk = sock->sk;
911 int err;
912
913 BT_DBG("sock %p, sk %p", sock, sk);
914
915 if (!sk)
916 return 0;
917
918 err = rfcomm_sock_shutdown(sock, 2);
919
920 sock_orphan(sk);
921 rfcomm_sock_kill(sk);
922 return err;
923}
924
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900925/* ---- RFCOMM core layer callbacks ----
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926 *
927 * called under rfcomm_lock()
928 */
929int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d)
930{
931 struct sock *sk, *parent;
932 bdaddr_t src, dst;
933 int result = 0;
934
935 BT_DBG("session %p channel %d", s, channel);
936
937 rfcomm_session_getaddr(s, &src, &dst);
938
939 /* Check if we have socket listening on channel */
940 parent = rfcomm_get_sock_by_channel(BT_LISTEN, channel, &src);
941 if (!parent)
942 return 0;
943
Gustavo F. Padovaneeb36652010-11-01 18:43:53 +0000944 bh_lock_sock(parent);
945
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946 /* Check for backlog size */
947 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900948 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949 goto done;
950 }
951
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900952 sk = rfcomm_sock_alloc(sock_net(parent), NULL, BTPROTO_RFCOMM, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953 if (!sk)
954 goto done;
955
956 rfcomm_sock_init(sk, parent);
957 bacpy(&bt_sk(sk)->src, &src);
958 bacpy(&bt_sk(sk)->dst, &dst);
959 rfcomm_pi(sk)->channel = channel;
960
961 sk->sk_state = BT_CONFIG;
962 bt_accept_enqueue(parent, sk);
963
964 /* Accept connection and return socket DLC */
965 *d = rfcomm_pi(sk)->dlc;
966 result = 1;
967
968done:
969 bh_unlock_sock(parent);
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100970
971 if (bt_sk(parent)->defer_setup)
972 parent->sk_state_change(parent);
973
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974 return result;
975}
976
Marcel Holtmannaef7d972010-03-21 05:27:45 +0100977static int rfcomm_sock_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978{
979 struct sock *sk;
980 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981
982 read_lock_bh(&rfcomm_sk_list.lock);
983
Marcel Holtmannbe9d1222005-11-08 09:57:38 -0800984 sk_for_each(sk, node, &rfcomm_sk_list.head) {
Marcel Holtmannaef7d972010-03-21 05:27:45 +0100985 seq_printf(f, "%s %s %d %d\n",
986 batostr(&bt_sk(sk)->src),
987 batostr(&bt_sk(sk)->dst),
Marcel Holtmannbe9d1222005-11-08 09:57:38 -0800988 sk->sk_state, rfcomm_pi(sk)->channel);
989 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991 read_unlock_bh(&rfcomm_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -0800992
Marcel Holtmannaef7d972010-03-21 05:27:45 +0100993 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700994}
995
Marcel Holtmannaef7d972010-03-21 05:27:45 +0100996static int rfcomm_sock_debugfs_open(struct inode *inode, struct file *file)
997{
998 return single_open(file, rfcomm_sock_debugfs_show, inode->i_private);
999}
1000
1001static const struct file_operations rfcomm_sock_debugfs_fops = {
1002 .open = rfcomm_sock_debugfs_open,
1003 .read = seq_read,
1004 .llseek = seq_lseek,
1005 .release = single_release,
1006};
1007
1008static struct dentry *rfcomm_sock_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08001010static const struct proto_ops rfcomm_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011 .family = PF_BLUETOOTH,
1012 .owner = THIS_MODULE,
1013 .release = rfcomm_sock_release,
1014 .bind = rfcomm_sock_bind,
1015 .connect = rfcomm_sock_connect,
1016 .listen = rfcomm_sock_listen,
1017 .accept = rfcomm_sock_accept,
1018 .getname = rfcomm_sock_getname,
1019 .sendmsg = rfcomm_sock_sendmsg,
1020 .recvmsg = rfcomm_sock_recvmsg,
1021 .shutdown = rfcomm_sock_shutdown,
1022 .setsockopt = rfcomm_sock_setsockopt,
1023 .getsockopt = rfcomm_sock_getsockopt,
1024 .ioctl = rfcomm_sock_ioctl,
1025 .poll = bt_sock_poll,
1026 .socketpair = sock_no_socketpair,
1027 .mmap = sock_no_mmap
1028};
1029
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00001030static const struct net_proto_family rfcomm_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031 .family = PF_BLUETOOTH,
1032 .owner = THIS_MODULE,
1033 .create = rfcomm_sock_create
1034};
1035
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08001036int __init rfcomm_init_sockets(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037{
1038 int err;
1039
1040 err = proto_register(&rfcomm_proto, 0);
1041 if (err < 0)
1042 return err;
1043
1044 err = bt_sock_register(BTPROTO_RFCOMM, &rfcomm_sock_family_ops);
1045 if (err < 0)
1046 goto error;
1047
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001048 if (bt_debugfs) {
1049 rfcomm_sock_debugfs = debugfs_create_file("rfcomm", 0444,
1050 bt_debugfs, NULL, &rfcomm_sock_debugfs_fops);
1051 if (!rfcomm_sock_debugfs)
1052 BT_ERR("Failed to create RFCOMM debug file");
1053 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054
1055 BT_INFO("RFCOMM socket layer initialized");
1056
1057 return 0;
1058
1059error:
1060 BT_ERR("RFCOMM socket layer registration failed");
1061 proto_unregister(&rfcomm_proto);
1062 return err;
1063}
1064
Gustavo F. Padovan2f8362a2010-07-24 02:04:45 -03001065void __exit rfcomm_cleanup_sockets(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001067 debugfs_remove(rfcomm_sock_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068
1069 if (bt_sock_unregister(BTPROTO_RFCOMM) < 0)
1070 BT_ERR("RFCOMM socket layer unregistration failed");
1071
1072 proto_unregister(&rfcomm_proto);
1073}