blob: a0690a84f3e9c2346b8bd19bb74387f650ba3e0a [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
Linus Torvalds1da177e2005-04-16 15:20:36 -070024/*
25 * Bluetooth RFCOMM core.
Linus Torvalds1da177e2005-04-16 15:20:36 -070026 */
27
Linus Torvalds1da177e2005-04-16 15:20:36 -070028#include <linux/module.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010029#include <linux/debugfs.h>
Marcel Holtmanna524ecc2007-10-20 21:37:20 +020030#include <linux/kthread.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <asm/unaligned.h>
32
33#include <net/bluetooth/bluetooth.h>
34#include <net/bluetooth/hci_core.h>
35#include <net/bluetooth/l2cap.h>
36#include <net/bluetooth/rfcomm.h>
37
Marcel Holtmann5f9018a2009-01-16 10:09:50 +010038#define VERSION "1.11"
Marcel Holtmann56f3a402006-02-13 11:39:57 +010039
Rusty Russelleb939922011-12-19 14:08:01 +000040static bool disable_cfc;
41static bool l2cap_ertm;
Marcel Holtmann98bcd082006-07-14 11:42:12 +020042static int channel_mtu = -1;
Marcel Holtmann56f3a402006-02-13 11:39:57 +010043static unsigned int l2cap_mtu = RFCOMM_MAX_L2CAP_MTU;
44
Linus Torvalds1da177e2005-04-16 15:20:36 -070045static struct task_struct *rfcomm_thread;
46
Arjan van de Ven4a3e2f72006-03-20 22:33:17 -080047static DEFINE_MUTEX(rfcomm_mutex);
48#define rfcomm_lock() mutex_lock(&rfcomm_mutex)
49#define rfcomm_unlock() mutex_unlock(&rfcomm_mutex)
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
52static LIST_HEAD(session_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -070053
Gustavo F. Padovan54365382011-12-20 16:30:44 -020054static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len);
Linus Torvalds1da177e2005-04-16 15:20:36 -070055static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci);
56static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci);
57static int rfcomm_queue_disc(struct rfcomm_dlc *d);
58static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type);
59static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d);
60static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig);
61static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len);
62static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits);
63static void rfcomm_make_uih(struct sk_buff *skb, u8 addr);
64
65static void rfcomm_process_connect(struct rfcomm_session *s);
66
Luiz Augusto von Dentz63ce0902010-08-19 14:06:10 +030067static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
68 bdaddr_t *dst,
69 u8 sec_level,
70 int *err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070071static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst);
Dean Jenkins8ff52f72013-02-28 14:21:55 +000072static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s);
Linus Torvalds1da177e2005-04-16 15:20:36 -070073
74/* ---- RFCOMM frame parsing macros ---- */
75#define __get_dlci(b) ((b & 0xfc) >> 2)
76#define __get_channel(b) ((b & 0xf8) >> 3)
77#define __get_dir(b) ((b & 0x04) >> 2)
78#define __get_type(b) ((b & 0xef))
79
80#define __test_ea(b) ((b & 0x01))
81#define __test_cr(b) ((b & 0x02))
82#define __test_pf(b) ((b & 0x10))
83
84#define __addr(cr, dlci) (((dlci & 0x3f) << 2) | (cr << 1) | 0x01)
85#define __ctrl(type, pf) (((type & 0xef) | (pf << 4)))
86#define __dlci(dir, chn) (((chn & 0x1f) << 1) | dir)
87#define __srv_channel(dlci) (dlci >> 1)
88#define __dir(dlci) (dlci & 0x01)
89
90#define __len8(len) (((len) << 1) | 1)
91#define __len16(len) ((len) << 1)
92
93/* MCC macros */
94#define __mcc_type(cr, type) (((type << 2) | (cr << 1) | 0x01))
95#define __get_mcc_type(b) ((b & 0xfc) >> 2)
96#define __get_mcc_len(b) ((b & 0xfe) >> 1)
97
98/* RPN macros */
J. Suter3a5e9032005-08-09 20:28:46 -070099#define __rpn_line_settings(data, stop, parity) ((data & 0x3) | ((stop & 0x1) << 2) | ((parity & 0x7) << 3))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100#define __get_rpn_data_bits(line) ((line) & 0x3)
101#define __get_rpn_stop_bits(line) (((line) >> 2) & 0x1)
J. Suter3a5e9032005-08-09 20:28:46 -0700102#define __get_rpn_parity(line) (((line) >> 3) & 0x7)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103
Gustavo Padovan6039aa72012-05-23 04:04:18 -0300104static void rfcomm_schedule(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105{
106 if (!rfcomm_thread)
107 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 wake_up_process(rfcomm_thread);
109}
110
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111/* ---- RFCOMM FCS computation ---- */
112
Marcel Holtmann408c1ce2005-10-28 19:20:36 +0200113/* reversed, 8-bit, poly=0x07 */
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900114static unsigned char rfcomm_crc_table[256] = {
Marcel Holtmann408c1ce2005-10-28 19:20:36 +0200115 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
116 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
117 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
118 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
119
120 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
121 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
122 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
123 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
124
125 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
126 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
127 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
128 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
129
130 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
131 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
132 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
133 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
134
135 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
136 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
137 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
138 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
139
140 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
141 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
142 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
143 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
144
145 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
146 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
147 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
148 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
149
150 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
151 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
152 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
153 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
154};
155
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156/* CRC on 2 bytes */
157#define __crc(data) (rfcomm_crc_table[rfcomm_crc_table[0xff ^ data[0]] ^ data[1]])
158
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900159/* FCS on 2 bytes */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160static inline u8 __fcs(u8 *data)
161{
Eric Dumazeta02cec22010-09-22 20:43:57 +0000162 return 0xff - __crc(data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163}
164
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900165/* FCS on 3 bytes */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166static inline u8 __fcs2(u8 *data)
167{
Eric Dumazeta02cec22010-09-22 20:43:57 +0000168 return 0xff - rfcomm_crc_table[__crc(data) ^ data[2]];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169}
170
171/* Check FCS */
172static inline int __check_fcs(u8 *data, int type, u8 fcs)
173{
174 u8 f = __crc(data);
175
176 if (type != RFCOMM_UIH)
177 f = rfcomm_crc_table[f ^ data[2]];
178
179 return rfcomm_crc_table[f ^ fcs] != 0xcf;
180}
181
182/* ---- L2CAP callbacks ---- */
183static void rfcomm_l2state_change(struct sock *sk)
184{
185 BT_DBG("%p state %d", sk, sk->sk_state);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300186 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187}
188
David S. Miller676d2362014-04-11 16:15:36 -0400189static void rfcomm_l2data_ready(struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190{
David S. Miller676d2362014-04-11 16:15:36 -0400191 BT_DBG("%p", sk);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300192 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193}
194
195static int rfcomm_l2sock_create(struct socket **sock)
196{
197 int err;
198
199 BT_DBG("");
200
201 err = sock_create_kern(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP, sock);
202 if (!err) {
203 struct sock *sk = (*sock)->sk;
204 sk->sk_data_ready = rfcomm_l2data_ready;
205 sk->sk_state_change = rfcomm_l2state_change;
206 }
207 return err;
208}
209
Gustavo Padovan6039aa72012-05-23 04:04:18 -0300210static int rfcomm_check_security(struct rfcomm_dlc *d)
Marcel Holtmann77db1982008-07-14 20:13:45 +0200211{
212 struct sock *sk = d->session->sock->sk;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300213 struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;
214
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100215 __u8 auth_type;
Marcel Holtmann77db1982008-07-14 20:13:45 +0200216
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100217 switch (d->sec_level) {
218 case BT_SECURITY_HIGH:
Marcel Holtmann2c068e02014-01-15 22:37:41 -0800219 case BT_SECURITY_FIPS:
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100220 auth_type = HCI_AT_GENERAL_BONDING_MITM;
221 break;
222 case BT_SECURITY_MEDIUM:
223 auth_type = HCI_AT_GENERAL_BONDING;
224 break;
225 default:
226 auth_type = HCI_AT_NO_BONDING;
227 break;
228 }
229
Johan Hedberge7cafc42014-07-17 15:35:38 +0300230 return hci_conn_security(conn->hcon, d->sec_level, auth_type,
231 d->out);
Marcel Holtmann77db1982008-07-14 20:13:45 +0200232}
233
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300234static void rfcomm_session_timeout(unsigned long arg)
235{
236 struct rfcomm_session *s = (void *) arg;
237
238 BT_DBG("session %p state %ld", s, s->state);
239
240 set_bit(RFCOMM_TIMED_OUT, &s->flags);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300241 rfcomm_schedule();
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300242}
243
244static void rfcomm_session_set_timer(struct rfcomm_session *s, long timeout)
245{
246 BT_DBG("session %p state %ld timeout %ld", s, s->state, timeout);
247
Dean Jenkins08c30ac2013-02-28 14:21:56 +0000248 mod_timer(&s->timer, jiffies + timeout);
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300249}
250
251static void rfcomm_session_clear_timer(struct rfcomm_session *s)
252{
253 BT_DBG("session %p state %ld", s, s->state);
254
Dean Jenkins08c30ac2013-02-28 14:21:56 +0000255 del_timer_sync(&s->timer);
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300256}
257
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258/* ---- RFCOMM DLCs ---- */
259static void rfcomm_dlc_timeout(unsigned long arg)
260{
261 struct rfcomm_dlc *d = (void *) arg;
262
263 BT_DBG("dlc %p state %ld", d, d->state);
264
265 set_bit(RFCOMM_TIMED_OUT, &d->flags);
266 rfcomm_dlc_put(d);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300267 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268}
269
270static void rfcomm_dlc_set_timer(struct rfcomm_dlc *d, long timeout)
271{
272 BT_DBG("dlc %p state %ld timeout %ld", d, d->state, timeout);
273
274 if (!mod_timer(&d->timer, jiffies + timeout))
275 rfcomm_dlc_hold(d);
276}
277
278static void rfcomm_dlc_clear_timer(struct rfcomm_dlc *d)
279{
280 BT_DBG("dlc %p state %ld", d, d->state);
281
Ying Xue25cc4ae2013-02-03 20:32:57 +0000282 if (del_timer(&d->timer))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 rfcomm_dlc_put(d);
284}
285
286static void rfcomm_dlc_clear_state(struct rfcomm_dlc *d)
287{
288 BT_DBG("%p", d);
289
290 d->state = BT_OPEN;
291 d->flags = 0;
292 d->mscex = 0;
Johan Hedberg183f7322010-12-06 15:56:17 +0200293 d->sec_level = BT_SECURITY_LOW;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294 d->mtu = RFCOMM_DEFAULT_MTU;
295 d->v24_sig = RFCOMM_V24_RTC | RFCOMM_V24_RTR | RFCOMM_V24_DV;
296
297 d->cfc = RFCOMM_CFC_DISABLED;
298 d->rx_credits = RFCOMM_DEFAULT_CREDITS;
299}
300
Al Virodd0fc662005-10-07 07:46:04 +0100301struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302{
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200303 struct rfcomm_dlc *d = kzalloc(sizeof(*d), prio);
304
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305 if (!d)
306 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307
Pavel Emelyanovb24b8a22008-01-23 21:20:07 -0800308 setup_timer(&d->timer, rfcomm_dlc_timeout, (unsigned long)d);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309
310 skb_queue_head_init(&d->tx_queue);
Libor Pechacek86aae6c2014-04-29 20:38:34 +0200311 mutex_init(&d->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312 atomic_set(&d->refcnt, 1);
313
314 rfcomm_dlc_clear_state(d);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900315
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316 BT_DBG("%p", d);
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200317
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318 return d;
319}
320
321void rfcomm_dlc_free(struct rfcomm_dlc *d)
322{
323 BT_DBG("%p", d);
324
325 skb_queue_purge(&d->tx_queue);
326 kfree(d);
327}
328
329static void rfcomm_dlc_link(struct rfcomm_session *s, struct rfcomm_dlc *d)
330{
331 BT_DBG("dlc %p session %p", d, s);
332
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300333 rfcomm_session_clear_timer(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334 rfcomm_dlc_hold(d);
335 list_add(&d->list, &s->dlcs);
336 d->session = s;
337}
338
339static void rfcomm_dlc_unlink(struct rfcomm_dlc *d)
340{
341 struct rfcomm_session *s = d->session;
342
343 BT_DBG("dlc %p refcnt %d session %p", d, atomic_read(&d->refcnt), s);
344
345 list_del(&d->list);
346 d->session = NULL;
347 rfcomm_dlc_put(d);
348
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300349 if (list_empty(&s->dlcs))
350 rfcomm_session_set_timer(s, RFCOMM_IDLE_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351}
352
353static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, u8 dlci)
354{
355 struct rfcomm_dlc *d;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200357 list_for_each_entry(d, &s->dlcs, list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358 if (d->dlci == dlci)
359 return d;
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200360
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361 return NULL;
362}
363
Peter Hurleyc10a8482014-02-09 20:59:10 -0500364static int rfcomm_check_channel(u8 channel)
365{
366 return channel < 1 || channel > 30;
367}
368
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
370{
371 struct rfcomm_session *s;
372 int err = 0;
373 u8 dlci;
374
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +0300375 BT_DBG("dlc %p state %ld %pMR -> %pMR channel %d",
376 d, d->state, src, dst, channel);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377
Peter Hurleyc10a8482014-02-09 20:59:10 -0500378 if (rfcomm_check_channel(channel))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 return -EINVAL;
380
381 if (d->state != BT_OPEN && d->state != BT_CLOSED)
382 return 0;
383
384 s = rfcomm_session_get(src, dst);
385 if (!s) {
Luiz Augusto von Dentz63ce0902010-08-19 14:06:10 +0300386 s = rfcomm_session_create(src, dst, d->sec_level, &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387 if (!s)
388 return err;
389 }
390
391 dlci = __dlci(!s->initiator, channel);
392
393 /* Check if DLCI already exists */
394 if (rfcomm_dlc_get(s, dlci))
395 return -EBUSY;
396
397 rfcomm_dlc_clear_state(d);
398
399 d->dlci = dlci;
400 d->addr = __addr(s->initiator, dlci);
401 d->priority = 7;
402
Marcel Holtmann77db1982008-07-14 20:13:45 +0200403 d->state = BT_CONFIG;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404 rfcomm_dlc_link(s, d);
405
Marcel Holtmann77db1982008-07-14 20:13:45 +0200406 d->out = 1;
407
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408 d->mtu = s->mtu;
409 d->cfc = (s->cfc == RFCOMM_CFC_UNKNOWN) ? 0 : s->cfc;
410
Marcel Holtmann77db1982008-07-14 20:13:45 +0200411 if (s->state == BT_CONNECTED) {
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100412 if (rfcomm_check_security(d))
Marcel Holtmann77db1982008-07-14 20:13:45 +0200413 rfcomm_send_pn(s, 1, d);
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100414 else
415 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
Marcel Holtmann77db1982008-07-14 20:13:45 +0200416 }
417
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT);
Marcel Holtmann77db1982008-07-14 20:13:45 +0200419
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 return 0;
421}
422
423int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
424{
425 int r;
426
427 rfcomm_lock();
428
429 r = __rfcomm_dlc_open(d, src, dst, channel);
430
431 rfcomm_unlock();
432 return r;
433}
434
Peter Hurleyf6223572014-02-09 20:59:13 -0500435static void __rfcomm_dlc_disconn(struct rfcomm_dlc *d)
436{
437 struct rfcomm_session *s = d->session;
438
439 d->state = BT_DISCONN;
440 if (skb_queue_empty(&d->tx_queue)) {
441 rfcomm_send_disc(s, d->dlci);
442 rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT);
443 } else {
444 rfcomm_queue_disc(d);
445 rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT * 2);
446 }
447}
448
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
450{
451 struct rfcomm_session *s = d->session;
452 if (!s)
453 return 0;
454
455 BT_DBG("dlc %p state %ld dlci %d err %d session %p",
456 d, d->state, d->dlci, err, s);
457
458 switch (d->state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459 case BT_CONNECT:
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100460 case BT_CONFIG:
Peter Hurley5998e042014-02-09 20:59:12 -0500461 case BT_OPEN:
462 case BT_CONNECT2:
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100463 if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
464 set_bit(RFCOMM_AUTH_REJECT, &d->flags);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300465 rfcomm_schedule();
Peter Hurley5998e042014-02-09 20:59:12 -0500466 return 0;
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100467 }
Peter Hurley5998e042014-02-09 20:59:12 -0500468 }
469
470 switch (d->state) {
471 case BT_CONNECT:
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100472 case BT_CONNECTED:
Peter Hurleyf6223572014-02-09 20:59:13 -0500473 __rfcomm_dlc_disconn(d);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474 break;
475
Peter Hurleyc4fd3182014-02-09 20:59:14 -0500476 case BT_CONFIG:
477 if (s->state != BT_BOUND) {
478 __rfcomm_dlc_disconn(d);
479 break;
480 }
481 /* if closing a dlc in a session that hasn't been started,
482 * just close and unlink the dlc
483 */
484
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485 default:
486 rfcomm_dlc_clear_timer(d);
487
488 rfcomm_dlc_lock(d);
489 d->state = BT_CLOSED;
Dave Young1905f6c2008-04-01 23:59:06 -0700490 d->state_change(d, err);
Arjan van de Ven4c8411f2008-05-29 01:32:47 -0700491 rfcomm_dlc_unlock(d);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492
493 skb_queue_purge(&d->tx_queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494 rfcomm_dlc_unlink(d);
495 }
496
497 return 0;
498}
499
500int rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
501{
Dean Jenkinsc06f7d52013-02-28 14:21:54 +0000502 int r = 0;
503 struct rfcomm_dlc *d_list;
504 struct rfcomm_session *s, *s_list;
505
506 BT_DBG("dlc %p state %ld dlci %d err %d", d, d->state, d->dlci, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507
508 rfcomm_lock();
509
Dean Jenkinsc06f7d52013-02-28 14:21:54 +0000510 s = d->session;
511 if (!s)
512 goto no_session;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513
Dean Jenkinsc06f7d52013-02-28 14:21:54 +0000514 /* after waiting on the mutex check the session still exists
515 * then check the dlc still exists
516 */
517 list_for_each_entry(s_list, &session_list, list) {
518 if (s_list == s) {
519 list_for_each_entry(d_list, &s->dlcs, list) {
520 if (d_list == d) {
521 r = __rfcomm_dlc_close(d, err);
522 break;
523 }
524 }
525 break;
526 }
527 }
528
529no_session:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 rfcomm_unlock();
531 return r;
532}
533
Peter Hurleyc10a8482014-02-09 20:59:10 -0500534struct rfcomm_dlc *rfcomm_dlc_exists(bdaddr_t *src, bdaddr_t *dst, u8 channel)
535{
536 struct rfcomm_session *s;
537 struct rfcomm_dlc *dlc = NULL;
538 u8 dlci;
539
540 if (rfcomm_check_channel(channel))
541 return ERR_PTR(-EINVAL);
542
543 rfcomm_lock();
544 s = rfcomm_session_get(src, dst);
545 if (s) {
546 dlci = __dlci(!s->initiator, channel);
547 dlc = rfcomm_dlc_get(s, dlci);
548 }
549 rfcomm_unlock();
550 return dlc;
551}
552
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb)
554{
555 int len = skb->len;
556
557 if (d->state != BT_CONNECTED)
558 return -ENOTCONN;
559
560 BT_DBG("dlc %p mtu %d len %d", d, d->mtu, len);
561
562 if (len > d->mtu)
563 return -EINVAL;
564
565 rfcomm_make_uih(skb, d->addr);
566 skb_queue_tail(&d->tx_queue, skb);
567
568 if (!test_bit(RFCOMM_TX_THROTTLED, &d->flags))
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300569 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570 return len;
571}
572
Peter Hurley72e51082014-02-09 20:59:22 -0500573void rfcomm_dlc_send_noerror(struct rfcomm_dlc *d, struct sk_buff *skb)
574{
575 int len = skb->len;
576
577 BT_DBG("dlc %p mtu %d len %d", d, d->mtu, len);
578
579 rfcomm_make_uih(skb, d->addr);
580 skb_queue_tail(&d->tx_queue, skb);
581
582 if (d->state == BT_CONNECTED &&
583 !test_bit(RFCOMM_TX_THROTTLED, &d->flags))
584 rfcomm_schedule();
585}
586
Harvey Harrisonb5606c22008-02-13 15:03:16 -0800587void __rfcomm_dlc_throttle(struct rfcomm_dlc *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588{
589 BT_DBG("dlc %p state %ld", d, d->state);
590
591 if (!d->cfc) {
592 d->v24_sig |= RFCOMM_V24_FC;
593 set_bit(RFCOMM_MSC_PENDING, &d->flags);
594 }
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300595 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596}
597
Harvey Harrisonb5606c22008-02-13 15:03:16 -0800598void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599{
600 BT_DBG("dlc %p state %ld", d, d->state);
601
602 if (!d->cfc) {
603 d->v24_sig &= ~RFCOMM_V24_FC;
604 set_bit(RFCOMM_MSC_PENDING, &d->flags);
605 }
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300606 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607}
608
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900609/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610 Set/get modem status functions use _local_ status i.e. what we report
611 to the other side.
612 Remote status is provided by dlc->modem_status() callback.
613 */
614int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig)
615{
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900616 BT_DBG("dlc %p state %ld v24_sig 0x%x",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617 d, d->state, v24_sig);
618
619 if (test_bit(RFCOMM_RX_THROTTLED, &d->flags))
620 v24_sig |= RFCOMM_V24_FC;
621 else
622 v24_sig &= ~RFCOMM_V24_FC;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900623
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624 d->v24_sig = v24_sig;
625
626 if (!test_and_set_bit(RFCOMM_MSC_PENDING, &d->flags))
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300627 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628
629 return 0;
630}
631
632int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig)
633{
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900634 BT_DBG("dlc %p state %ld v24_sig 0x%x",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 d, d->state, d->v24_sig);
636
637 *v24_sig = d->v24_sig;
638 return 0;
639}
640
641/* ---- RFCOMM sessions ---- */
642static struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
643{
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200644 struct rfcomm_session *s = kzalloc(sizeof(*s), GFP_KERNEL);
645
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646 if (!s)
647 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648
649 BT_DBG("session %p sock %p", s, sock);
650
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300651 setup_timer(&s->timer, rfcomm_session_timeout, (unsigned long) s);
652
Linus Torvalds1da177e2005-04-16 15:20:36 -0700653 INIT_LIST_HEAD(&s->dlcs);
654 s->state = state;
655 s->sock = sock;
656
657 s->mtu = RFCOMM_DEFAULT_MTU;
Marcel Holtmann7c2660b2006-07-03 10:02:51 +0200658 s->cfc = disable_cfc ? RFCOMM_CFC_DISABLED : RFCOMM_CFC_UNKNOWN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700659
660 /* Do not increment module usage count for listening sessions.
661 * Otherwise we won't be able to unload the module. */
662 if (state != BT_LISTEN)
663 if (!try_module_get(THIS_MODULE)) {
664 kfree(s);
665 return NULL;
666 }
667
668 list_add(&s->list, &session_list);
669
670 return s;
671}
672
Dean Jenkins8ff52f72013-02-28 14:21:55 +0000673static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674{
675 int state = s->state;
676
677 BT_DBG("session %p state %ld", s, s->state);
678
679 list_del(&s->list);
680
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300681 rfcomm_session_clear_timer(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682 sock_release(s->sock);
683 kfree(s);
684
685 if (state != BT_LISTEN)
686 module_put(THIS_MODULE);
Dean Jenkins8ff52f72013-02-28 14:21:55 +0000687
688 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689}
690
691static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
692{
693 struct rfcomm_session *s;
694 struct list_head *p, *n;
Marcel Holtmann24bc10c2013-10-13 09:49:54 -0700695 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696 list_for_each_safe(p, n, &session_list) {
697 s = list_entry(p, struct rfcomm_session, list);
Marcel Holtmann24bc10c2013-10-13 09:49:54 -0700698 chan = l2cap_pi(s->sock->sk)->chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699
Marcel Holtmann24bc10c2013-10-13 09:49:54 -0700700 if ((!bacmp(src, BDADDR_ANY) || !bacmp(&chan->src, src)) &&
701 !bacmp(&chan->dst, dst))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700702 return s;
703 }
704 return NULL;
705}
706
Dean Jenkins8ff52f72013-02-28 14:21:55 +0000707static struct rfcomm_session *rfcomm_session_close(struct rfcomm_session *s,
708 int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709{
710 struct rfcomm_dlc *d;
711 struct list_head *p, *n;
712
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713 s->state = BT_CLOSED;
714
Dean Jenkins24fd6422013-02-28 14:21:58 +0000715 BT_DBG("session %p state %ld err %d", s, s->state, err);
716
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 /* Close all dlcs */
718 list_for_each_safe(p, n, &s->dlcs) {
719 d = list_entry(p, struct rfcomm_dlc, list);
720 d->state = BT_CLOSED;
721 __rfcomm_dlc_close(d, err);
722 }
723
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300724 rfcomm_session_clear_timer(s);
Dean Jenkins08c30ac2013-02-28 14:21:56 +0000725 return rfcomm_session_del(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726}
727
Luiz Augusto von Dentz63ce0902010-08-19 14:06:10 +0300728static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
729 bdaddr_t *dst,
730 u8 sec_level,
731 int *err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732{
733 struct rfcomm_session *s = NULL;
734 struct sockaddr_l2 addr;
735 struct socket *sock;
736 struct sock *sk;
737
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +0300738 BT_DBG("%pMR -> %pMR", src, dst);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739
740 *err = rfcomm_l2sock_create(&sock);
741 if (*err < 0)
742 return NULL;
743
744 bacpy(&addr.l2_bdaddr, src);
745 addr.l2_family = AF_BLUETOOTH;
746 addr.l2_psm = 0;
Marcel Holtmann37e62f52009-02-17 21:49:33 +0100747 addr.l2_cid = 0;
Seung-Woo Kimc507f132013-11-05 16:02:24 +0900748 addr.l2_bdaddr_type = BDADDR_BREDR;
Marcel Holtmann48db9ca2007-05-05 00:36:06 +0200749 *err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750 if (*err < 0)
751 goto failed;
752
753 /* Set L2CAP options */
754 sk = sock->sk;
755 lock_sock(sk);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300756 l2cap_pi(sk)->chan->imtu = l2cap_mtu;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300757 l2cap_pi(sk)->chan->sec_level = sec_level;
Marcel Holtmanneae38ee2009-10-05 12:23:48 +0200758 if (l2cap_ertm)
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300759 l2cap_pi(sk)->chan->mode = L2CAP_MODE_ERTM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760 release_sock(sk);
761
762 s = rfcomm_session_add(sock, BT_BOUND);
763 if (!s) {
764 *err = -ENOMEM;
765 goto failed;
766 }
767
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 s->initiator = 1;
769
770 bacpy(&addr.l2_bdaddr, dst);
771 addr.l2_family = AF_BLUETOOTH;
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700772 addr.l2_psm = cpu_to_le16(RFCOMM_PSM);
Marcel Holtmann37e62f52009-02-17 21:49:33 +0100773 addr.l2_cid = 0;
Seung-Woo Kim8992da02013-11-05 17:15:42 +0900774 addr.l2_bdaddr_type = BDADDR_BREDR;
Marcel Holtmann48db9ca2007-05-05 00:36:06 +0200775 *err = kernel_connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);
Marcel Holtmannb4c612a2006-09-23 09:54:38 +0200776 if (*err == 0 || *err == -EINPROGRESS)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777 return s;
778
Dean Jenkins8ff52f72013-02-28 14:21:55 +0000779 return rfcomm_session_del(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780
781failed:
782 sock_release(sock);
783 return NULL;
784}
785
786void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst)
787{
Marcel Holtmann24bc10c2013-10-13 09:49:54 -0700788 struct l2cap_chan *chan = l2cap_pi(s->sock->sk)->chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 if (src)
Marcel Holtmann24bc10c2013-10-13 09:49:54 -0700790 bacpy(src, &chan->src);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791 if (dst)
Marcel Holtmann24bc10c2013-10-13 09:49:54 -0700792 bacpy(dst, &chan->dst);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793}
794
795/* ---- RFCOMM frame sending ---- */
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200796static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798 struct kvec iv = { data, len };
799 struct msghdr msg;
800
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200801 BT_DBG("session %p len %d", s, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802
803 memset(&msg, 0, sizeof(msg));
804
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200805 return kernel_sendmsg(s->sock, &msg, &iv, 1, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806}
807
Luiz Augusto von Dentz262038f2011-11-01 10:58:58 +0200808static int rfcomm_send_cmd(struct rfcomm_session *s, struct rfcomm_cmd *cmd)
809{
810 BT_DBG("%p cmd %u", s, cmd->ctrl);
811
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200812 return rfcomm_send_frame(s, (void *) cmd, sizeof(*cmd));
Luiz Augusto von Dentz262038f2011-11-01 10:58:58 +0200813}
814
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci)
816{
817 struct rfcomm_cmd cmd;
818
819 BT_DBG("%p dlci %d", s, dlci);
820
821 cmd.addr = __addr(s->initiator, dlci);
822 cmd.ctrl = __ctrl(RFCOMM_SABM, 1);
823 cmd.len = __len8(0);
824 cmd.fcs = __fcs2((u8 *) &cmd);
825
Luiz Augusto von Dentz262038f2011-11-01 10:58:58 +0200826 return rfcomm_send_cmd(s, &cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827}
828
829static int rfcomm_send_ua(struct rfcomm_session *s, u8 dlci)
830{
831 struct rfcomm_cmd cmd;
832
833 BT_DBG("%p dlci %d", s, dlci);
834
835 cmd.addr = __addr(!s->initiator, dlci);
836 cmd.ctrl = __ctrl(RFCOMM_UA, 1);
837 cmd.len = __len8(0);
838 cmd.fcs = __fcs2((u8 *) &cmd);
839
Luiz Augusto von Dentz262038f2011-11-01 10:58:58 +0200840 return rfcomm_send_cmd(s, &cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841}
842
843static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci)
844{
845 struct rfcomm_cmd cmd;
846
847 BT_DBG("%p dlci %d", s, dlci);
848
849 cmd.addr = __addr(s->initiator, dlci);
850 cmd.ctrl = __ctrl(RFCOMM_DISC, 1);
851 cmd.len = __len8(0);
852 cmd.fcs = __fcs2((u8 *) &cmd);
853
Luiz Augusto von Dentz262038f2011-11-01 10:58:58 +0200854 return rfcomm_send_cmd(s, &cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855}
856
857static int rfcomm_queue_disc(struct rfcomm_dlc *d)
858{
859 struct rfcomm_cmd *cmd;
860 struct sk_buff *skb;
861
862 BT_DBG("dlc %p dlci %d", d, d->dlci);
863
864 skb = alloc_skb(sizeof(*cmd), GFP_KERNEL);
865 if (!skb)
866 return -ENOMEM;
867
868 cmd = (void *) __skb_put(skb, sizeof(*cmd));
869 cmd->addr = d->addr;
870 cmd->ctrl = __ctrl(RFCOMM_DISC, 1);
871 cmd->len = __len8(0);
872 cmd->fcs = __fcs2((u8 *) cmd);
873
874 skb_queue_tail(&d->tx_queue, skb);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300875 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876 return 0;
877}
878
879static int rfcomm_send_dm(struct rfcomm_session *s, u8 dlci)
880{
881 struct rfcomm_cmd cmd;
882
883 BT_DBG("%p dlci %d", s, dlci);
884
885 cmd.addr = __addr(!s->initiator, dlci);
886 cmd.ctrl = __ctrl(RFCOMM_DM, 1);
887 cmd.len = __len8(0);
888 cmd.fcs = __fcs2((u8 *) &cmd);
889
Luiz Augusto von Dentz262038f2011-11-01 10:58:58 +0200890 return rfcomm_send_cmd(s, &cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891}
892
893static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type)
894{
895 struct rfcomm_hdr *hdr;
896 struct rfcomm_mcc *mcc;
897 u8 buf[16], *ptr = buf;
898
899 BT_DBG("%p cr %d type %d", s, cr, type);
900
901 hdr = (void *) ptr; ptr += sizeof(*hdr);
902 hdr->addr = __addr(s->initiator, 0);
903 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
904 hdr->len = __len8(sizeof(*mcc) + 1);
905
906 mcc = (void *) ptr; ptr += sizeof(*mcc);
907 mcc->type = __mcc_type(cr, RFCOMM_NSC);
908 mcc->len = __len8(1);
909
910 /* Type that we didn't like */
911 *ptr = __mcc_type(cr, type); ptr++;
912
913 *ptr = __fcs(buf); ptr++;
914
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200915 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916}
917
918static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d)
919{
920 struct rfcomm_hdr *hdr;
921 struct rfcomm_mcc *mcc;
922 struct rfcomm_pn *pn;
923 u8 buf[16], *ptr = buf;
924
925 BT_DBG("%p cr %d dlci %d mtu %d", s, cr, d->dlci, d->mtu);
926
927 hdr = (void *) ptr; ptr += sizeof(*hdr);
928 hdr->addr = __addr(s->initiator, 0);
929 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
930 hdr->len = __len8(sizeof(*mcc) + sizeof(*pn));
931
932 mcc = (void *) ptr; ptr += sizeof(*mcc);
933 mcc->type = __mcc_type(cr, RFCOMM_PN);
934 mcc->len = __len8(sizeof(*pn));
935
936 pn = (void *) ptr; ptr += sizeof(*pn);
937 pn->dlci = d->dlci;
938 pn->priority = d->priority;
939 pn->ack_timer = 0;
940 pn->max_retrans = 0;
941
942 if (s->cfc) {
943 pn->flow_ctrl = cr ? 0xf0 : 0xe0;
944 pn->credits = RFCOMM_DEFAULT_CREDITS;
945 } else {
946 pn->flow_ctrl = 0;
947 pn->credits = 0;
948 }
949
Marcel Holtmann98bcd082006-07-14 11:42:12 +0200950 if (cr && channel_mtu >= 0)
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200951 pn->mtu = cpu_to_le16(channel_mtu);
Marcel Holtmann98bcd082006-07-14 11:42:12 +0200952 else
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200953 pn->mtu = cpu_to_le16(d->mtu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954
955 *ptr = __fcs(buf); ptr++;
956
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200957 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958}
959
J. Suter3a5e9032005-08-09 20:28:46 -0700960int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci,
961 u8 bit_rate, u8 data_bits, u8 stop_bits,
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900962 u8 parity, u8 flow_ctrl_settings,
J. Suter3a5e9032005-08-09 20:28:46 -0700963 u8 xon_char, u8 xoff_char, u16 param_mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700964{
965 struct rfcomm_hdr *hdr;
966 struct rfcomm_mcc *mcc;
967 struct rfcomm_rpn *rpn;
968 u8 buf[16], *ptr = buf;
969
970 BT_DBG("%p cr %d dlci %d bit_r 0x%x data_b 0x%x stop_b 0x%x parity 0x%x"
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900971 " flwc_s 0x%x xon_c 0x%x xoff_c 0x%x p_mask 0x%x",
972 s, cr, dlci, bit_rate, data_bits, stop_bits, parity,
J. Suter3a5e9032005-08-09 20:28:46 -0700973 flow_ctrl_settings, xon_char, xoff_char, param_mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974
975 hdr = (void *) ptr; ptr += sizeof(*hdr);
976 hdr->addr = __addr(s->initiator, 0);
977 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
978 hdr->len = __len8(sizeof(*mcc) + sizeof(*rpn));
979
980 mcc = (void *) ptr; ptr += sizeof(*mcc);
981 mcc->type = __mcc_type(cr, RFCOMM_RPN);
982 mcc->len = __len8(sizeof(*rpn));
983
984 rpn = (void *) ptr; ptr += sizeof(*rpn);
985 rpn->dlci = __addr(1, dlci);
986 rpn->bit_rate = bit_rate;
987 rpn->line_settings = __rpn_line_settings(data_bits, stop_bits, parity);
988 rpn->flow_ctrl = flow_ctrl_settings;
989 rpn->xon_char = xon_char;
990 rpn->xoff_char = xoff_char;
Al Viroe8db8c92006-11-08 00:28:44 -0800991 rpn->param_mask = cpu_to_le16(param_mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992
993 *ptr = __fcs(buf); ptr++;
994
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200995 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996}
997
998static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status)
999{
1000 struct rfcomm_hdr *hdr;
1001 struct rfcomm_mcc *mcc;
1002 struct rfcomm_rls *rls;
1003 u8 buf[16], *ptr = buf;
1004
1005 BT_DBG("%p cr %d status 0x%x", s, cr, status);
1006
1007 hdr = (void *) ptr; ptr += sizeof(*hdr);
1008 hdr->addr = __addr(s->initiator, 0);
1009 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
1010 hdr->len = __len8(sizeof(*mcc) + sizeof(*rls));
1011
1012 mcc = (void *) ptr; ptr += sizeof(*mcc);
1013 mcc->type = __mcc_type(cr, RFCOMM_RLS);
1014 mcc->len = __len8(sizeof(*rls));
1015
1016 rls = (void *) ptr; ptr += sizeof(*rls);
1017 rls->dlci = __addr(1, dlci);
1018 rls->status = status;
1019
1020 *ptr = __fcs(buf); ptr++;
1021
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001022 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023}
1024
1025static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig)
1026{
1027 struct rfcomm_hdr *hdr;
1028 struct rfcomm_mcc *mcc;
1029 struct rfcomm_msc *msc;
1030 u8 buf[16], *ptr = buf;
1031
1032 BT_DBG("%p cr %d v24 0x%x", s, cr, v24_sig);
1033
1034 hdr = (void *) ptr; ptr += sizeof(*hdr);
1035 hdr->addr = __addr(s->initiator, 0);
1036 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
1037 hdr->len = __len8(sizeof(*mcc) + sizeof(*msc));
1038
1039 mcc = (void *) ptr; ptr += sizeof(*mcc);
1040 mcc->type = __mcc_type(cr, RFCOMM_MSC);
1041 mcc->len = __len8(sizeof(*msc));
1042
1043 msc = (void *) ptr; ptr += sizeof(*msc);
1044 msc->dlci = __addr(1, dlci);
1045 msc->v24_sig = v24_sig | 0x01;
1046
1047 *ptr = __fcs(buf); ptr++;
1048
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001049 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050}
1051
1052static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr)
1053{
1054 struct rfcomm_hdr *hdr;
1055 struct rfcomm_mcc *mcc;
1056 u8 buf[16], *ptr = buf;
1057
1058 BT_DBG("%p cr %d", s, cr);
1059
1060 hdr = (void *) ptr; ptr += sizeof(*hdr);
1061 hdr->addr = __addr(s->initiator, 0);
1062 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
1063 hdr->len = __len8(sizeof(*mcc));
1064
1065 mcc = (void *) ptr; ptr += sizeof(*mcc);
1066 mcc->type = __mcc_type(cr, RFCOMM_FCOFF);
1067 mcc->len = __len8(0);
1068
1069 *ptr = __fcs(buf); ptr++;
1070
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001071 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072}
1073
1074static int rfcomm_send_fcon(struct rfcomm_session *s, int cr)
1075{
1076 struct rfcomm_hdr *hdr;
1077 struct rfcomm_mcc *mcc;
1078 u8 buf[16], *ptr = buf;
1079
1080 BT_DBG("%p cr %d", s, cr);
1081
1082 hdr = (void *) ptr; ptr += sizeof(*hdr);
1083 hdr->addr = __addr(s->initiator, 0);
1084 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
1085 hdr->len = __len8(sizeof(*mcc));
1086
1087 mcc = (void *) ptr; ptr += sizeof(*mcc);
1088 mcc->type = __mcc_type(cr, RFCOMM_FCON);
1089 mcc->len = __len8(0);
1090
1091 *ptr = __fcs(buf); ptr++;
1092
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001093 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094}
1095
1096static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len)
1097{
1098 struct socket *sock = s->sock;
1099 struct kvec iv[3];
1100 struct msghdr msg;
1101 unsigned char hdr[5], crc[1];
1102
1103 if (len > 125)
1104 return -EINVAL;
1105
1106 BT_DBG("%p cr %d", s, cr);
1107
1108 hdr[0] = __addr(s->initiator, 0);
1109 hdr[1] = __ctrl(RFCOMM_UIH, 0);
1110 hdr[2] = 0x01 | ((len + 2) << 1);
1111 hdr[3] = 0x01 | ((cr & 0x01) << 1) | (RFCOMM_TEST << 2);
1112 hdr[4] = 0x01 | (len << 1);
1113
1114 crc[0] = __fcs(hdr);
1115
1116 iv[0].iov_base = hdr;
1117 iv[0].iov_len = 5;
1118 iv[1].iov_base = pattern;
1119 iv[1].iov_len = len;
1120 iv[2].iov_base = crc;
1121 iv[2].iov_len = 1;
1122
1123 memset(&msg, 0, sizeof(msg));
1124
1125 return kernel_sendmsg(sock, &msg, iv, 3, 6 + len);
1126}
1127
1128static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits)
1129{
1130 struct rfcomm_hdr *hdr;
1131 u8 buf[16], *ptr = buf;
1132
1133 BT_DBG("%p addr %d credits %d", s, addr, credits);
1134
1135 hdr = (void *) ptr; ptr += sizeof(*hdr);
1136 hdr->addr = addr;
1137 hdr->ctrl = __ctrl(RFCOMM_UIH, 1);
1138 hdr->len = __len8(0);
1139
1140 *ptr = credits; ptr++;
1141
1142 *ptr = __fcs(buf); ptr++;
1143
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001144 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145}
1146
1147static void rfcomm_make_uih(struct sk_buff *skb, u8 addr)
1148{
1149 struct rfcomm_hdr *hdr;
1150 int len = skb->len;
1151 u8 *crc;
1152
1153 if (len > 127) {
1154 hdr = (void *) skb_push(skb, 4);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001155 put_unaligned(cpu_to_le16(__len16(len)), (__le16 *) &hdr->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001156 } else {
1157 hdr = (void *) skb_push(skb, 3);
1158 hdr->len = __len8(len);
1159 }
1160 hdr->addr = addr;
1161 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
1162
1163 crc = skb_put(skb, 1);
1164 *crc = __fcs((void *) hdr);
1165}
1166
1167/* ---- RFCOMM frame reception ---- */
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001168static struct rfcomm_session *rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169{
1170 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1171
1172 if (dlci) {
1173 /* Data channel */
1174 struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
1175 if (!d) {
1176 rfcomm_send_dm(s, dlci);
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001177 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178 }
1179
1180 switch (d->state) {
1181 case BT_CONNECT:
1182 rfcomm_dlc_clear_timer(d);
1183
1184 rfcomm_dlc_lock(d);
1185 d->state = BT_CONNECTED;
1186 d->state_change(d, 0);
1187 rfcomm_dlc_unlock(d);
1188
1189 rfcomm_send_msc(s, 1, dlci, d->v24_sig);
1190 break;
1191
1192 case BT_DISCONN:
1193 d->state = BT_CLOSED;
1194 __rfcomm_dlc_close(d, 0);
Marcel Holtmann9cf5b0e2007-05-05 00:36:13 +02001195
1196 if (list_empty(&s->dlcs)) {
1197 s->state = BT_DISCONN;
1198 rfcomm_send_disc(s, 0);
Mat Martineau79e65472011-12-06 16:23:26 -08001199 rfcomm_session_clear_timer(s);
Marcel Holtmann9cf5b0e2007-05-05 00:36:13 +02001200 }
1201
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202 break;
1203 }
1204 } else {
1205 /* Control channel */
1206 switch (s->state) {
1207 case BT_CONNECT:
1208 s->state = BT_CONNECTED;
1209 rfcomm_process_connect(s);
1210 break;
Marcel Holtmann9cf5b0e2007-05-05 00:36:13 +02001211
1212 case BT_DISCONN:
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001213 s = rfcomm_session_close(s, ECONNRESET);
Marcel Holtmann9cf5b0e2007-05-05 00:36:13 +02001214 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215 }
1216 }
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001217 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218}
1219
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001220static struct rfcomm_session *rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221{
1222 int err = 0;
1223
1224 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1225
1226 if (dlci) {
1227 /* Data DLC */
1228 struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
1229 if (d) {
1230 if (d->state == BT_CONNECT || d->state == BT_CONFIG)
1231 err = ECONNREFUSED;
1232 else
1233 err = ECONNRESET;
1234
1235 d->state = BT_CLOSED;
1236 __rfcomm_dlc_close(d, err);
1237 }
1238 } else {
1239 if (s->state == BT_CONNECT)
1240 err = ECONNREFUSED;
1241 else
1242 err = ECONNRESET;
1243
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001244 s = rfcomm_session_close(s, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245 }
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001246 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247}
1248
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001249static struct rfcomm_session *rfcomm_recv_disc(struct rfcomm_session *s,
1250 u8 dlci)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001251{
1252 int err = 0;
1253
1254 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1255
1256 if (dlci) {
1257 struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
1258 if (d) {
1259 rfcomm_send_ua(s, dlci);
1260
1261 if (d->state == BT_CONNECT || d->state == BT_CONFIG)
1262 err = ECONNREFUSED;
1263 else
1264 err = ECONNRESET;
1265
1266 d->state = BT_CLOSED;
1267 __rfcomm_dlc_close(d, err);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001268 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001269 rfcomm_send_dm(s, dlci);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001270
Linus Torvalds1da177e2005-04-16 15:20:36 -07001271 } else {
1272 rfcomm_send_ua(s, 0);
1273
1274 if (s->state == BT_CONNECT)
1275 err = ECONNREFUSED;
1276 else
1277 err = ECONNRESET;
1278
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001279 s = rfcomm_session_close(s, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001280 }
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001281 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001282}
1283
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001284void rfcomm_dlc_accept(struct rfcomm_dlc *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001285{
Marcel Holtmann300b9392006-07-03 10:37:55 +02001286 struct sock *sk = d->session->sock->sk;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001287 struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;
Marcel Holtmann300b9392006-07-03 10:37:55 +02001288
Linus Torvalds1da177e2005-04-16 15:20:36 -07001289 BT_DBG("dlc %p", d);
1290
1291 rfcomm_send_ua(d->session, d->dlci);
1292
Johan Hedberge2139b32009-03-26 16:41:56 +02001293 rfcomm_dlc_clear_timer(d);
1294
Linus Torvalds1da177e2005-04-16 15:20:36 -07001295 rfcomm_dlc_lock(d);
1296 d->state = BT_CONNECTED;
1297 d->state_change(d, 0);
1298 rfcomm_dlc_unlock(d);
1299
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +01001300 if (d->role_switch)
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001301 hci_conn_switch_role(conn->hcon, 0x00);
Marcel Holtmann300b9392006-07-03 10:37:55 +02001302
Linus Torvalds1da177e2005-04-16 15:20:36 -07001303 rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
1304}
1305
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001306static void rfcomm_check_accept(struct rfcomm_dlc *d)
1307{
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +01001308 if (rfcomm_check_security(d)) {
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001309 if (d->defer_setup) {
1310 set_bit(RFCOMM_DEFER_SETUP, &d->flags);
1311 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
Marcel Holtmann8bf47942009-02-16 02:59:49 +01001312
1313 rfcomm_dlc_lock(d);
1314 d->state = BT_CONNECT2;
1315 d->state_change(d, 0);
1316 rfcomm_dlc_unlock(d);
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001317 } else
1318 rfcomm_dlc_accept(d);
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001319 } else {
1320 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
1321 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001322 }
1323}
1324
Linus Torvalds1da177e2005-04-16 15:20:36 -07001325static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
1326{
1327 struct rfcomm_dlc *d;
1328 u8 channel;
1329
1330 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1331
1332 if (!dlci) {
1333 rfcomm_send_ua(s, 0);
1334
1335 if (s->state == BT_OPEN) {
1336 s->state = BT_CONNECTED;
1337 rfcomm_process_connect(s);
1338 }
1339 return 0;
1340 }
1341
1342 /* Check if DLC exists */
1343 d = rfcomm_dlc_get(s, dlci);
1344 if (d) {
1345 if (d->state == BT_OPEN) {
1346 /* DLC was previously opened by PN request */
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001347 rfcomm_check_accept(d);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348 }
1349 return 0;
1350 }
1351
1352 /* Notify socket layer about incoming connection */
1353 channel = __srv_channel(dlci);
1354 if (rfcomm_connect_ind(s, channel, &d)) {
1355 d->dlci = dlci;
1356 d->addr = __addr(s->initiator, dlci);
1357 rfcomm_dlc_link(s, d);
1358
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001359 rfcomm_check_accept(d);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001360 } else {
1361 rfcomm_send_dm(s, dlci);
1362 }
1363
1364 return 0;
1365}
1366
1367static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn)
1368{
1369 struct rfcomm_session *s = d->session;
1370
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001371 BT_DBG("dlc %p state %ld dlci %d mtu %d fc 0x%x credits %d",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372 d, d->state, d->dlci, pn->mtu, pn->flow_ctrl, pn->credits);
1373
Marcel Holtmann7c2660b2006-07-03 10:02:51 +02001374 if ((pn->flow_ctrl == 0xf0 && s->cfc != RFCOMM_CFC_DISABLED) ||
1375 pn->flow_ctrl == 0xe0) {
1376 d->cfc = RFCOMM_CFC_ENABLED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377 d->tx_credits = pn->credits;
1378 } else {
Marcel Holtmann7c2660b2006-07-03 10:02:51 +02001379 d->cfc = RFCOMM_CFC_DISABLED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380 set_bit(RFCOMM_TX_THROTTLED, &d->flags);
1381 }
1382
Marcel Holtmann7c2660b2006-07-03 10:02:51 +02001383 if (s->cfc == RFCOMM_CFC_UNKNOWN)
1384 s->cfc = d->cfc;
1385
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386 d->priority = pn->priority;
1387
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001388 d->mtu = __le16_to_cpu(pn->mtu);
Marcel Holtmann98bcd082006-07-14 11:42:12 +02001389
1390 if (cr && d->mtu > s->mtu)
1391 d->mtu = s->mtu;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392
1393 return 0;
1394}
1395
1396static int rfcomm_recv_pn(struct rfcomm_session *s, int cr, struct sk_buff *skb)
1397{
1398 struct rfcomm_pn *pn = (void *) skb->data;
1399 struct rfcomm_dlc *d;
1400 u8 dlci = pn->dlci;
1401
1402 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1403
1404 if (!dlci)
1405 return 0;
1406
1407 d = rfcomm_dlc_get(s, dlci);
1408 if (d) {
1409 if (cr) {
1410 /* PN request */
1411 rfcomm_apply_pn(d, cr, pn);
1412 rfcomm_send_pn(s, 0, d);
1413 } else {
1414 /* PN response */
1415 switch (d->state) {
1416 case BT_CONFIG:
1417 rfcomm_apply_pn(d, cr, pn);
1418
1419 d->state = BT_CONNECT;
1420 rfcomm_send_sabm(s, d->dlci);
1421 break;
1422 }
1423 }
1424 } else {
1425 u8 channel = __srv_channel(dlci);
1426
1427 if (!cr)
1428 return 0;
1429
1430 /* PN request for non existing DLC.
1431 * Assume incoming connection. */
1432 if (rfcomm_connect_ind(s, channel, &d)) {
1433 d->dlci = dlci;
1434 d->addr = __addr(s->initiator, dlci);
1435 rfcomm_dlc_link(s, d);
1436
1437 rfcomm_apply_pn(d, cr, pn);
1438
1439 d->state = BT_OPEN;
1440 rfcomm_send_pn(s, 0, d);
1441 } else {
1442 rfcomm_send_dm(s, dlci);
1443 }
1444 }
1445 return 0;
1446}
1447
1448static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_buff *skb)
1449{
1450 struct rfcomm_rpn *rpn = (void *) skb->data;
1451 u8 dlci = __get_dlci(rpn->dlci);
1452
1453 u8 bit_rate = 0;
1454 u8 data_bits = 0;
1455 u8 stop_bits = 0;
1456 u8 parity = 0;
1457 u8 flow_ctrl = 0;
1458 u8 xon_char = 0;
1459 u8 xoff_char = 0;
1460 u16 rpn_mask = RFCOMM_RPN_PM_ALL;
J. Suter3a5e9032005-08-09 20:28:46 -07001461
1462 BT_DBG("dlci %d cr %d len 0x%x bitr 0x%x line 0x%x flow 0x%x xonc 0x%x xoffc 0x%x pm 0x%x",
1463 dlci, cr, len, rpn->bit_rate, rpn->line_settings, rpn->flow_ctrl,
1464 rpn->xon_char, rpn->xoff_char, rpn->param_mask);
1465
1466 if (!cr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467 return 0;
J. Suter3a5e9032005-08-09 20:28:46 -07001468
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469 if (len == 1) {
Yuri Kululin08601462010-07-23 13:57:12 +04001470 /* This is a request, return default (according to ETSI TS 07.10) settings */
1471 bit_rate = RFCOMM_RPN_BR_9600;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472 data_bits = RFCOMM_RPN_DATA_8;
1473 stop_bits = RFCOMM_RPN_STOP_1;
1474 parity = RFCOMM_RPN_PARITY_NONE;
1475 flow_ctrl = RFCOMM_RPN_FLOW_NONE;
1476 xon_char = RFCOMM_RPN_XON_CHAR;
1477 xoff_char = RFCOMM_RPN_XOFF_CHAR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001478 goto rpn_out;
1479 }
J. Suter3a5e9032005-08-09 20:28:46 -07001480
1481 /* Check for sane values, ignore/accept bit_rate, 8 bits, 1 stop bit,
1482 * no parity, no flow control lines, normal XON/XOFF chars */
1483
Al Viroe8db8c92006-11-08 00:28:44 -08001484 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_BITRATE)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485 bit_rate = rpn->bit_rate;
Yuri Kululin08601462010-07-23 13:57:12 +04001486 if (bit_rate > RFCOMM_RPN_BR_230400) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487 BT_DBG("RPN bit rate mismatch 0x%x", bit_rate);
Yuri Kululin08601462010-07-23 13:57:12 +04001488 bit_rate = RFCOMM_RPN_BR_9600;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 rpn_mask ^= RFCOMM_RPN_PM_BITRATE;
1490 }
1491 }
J. Suter3a5e9032005-08-09 20:28:46 -07001492
Al Viroe8db8c92006-11-08 00:28:44 -08001493 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_DATA)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494 data_bits = __get_rpn_data_bits(rpn->line_settings);
1495 if (data_bits != RFCOMM_RPN_DATA_8) {
1496 BT_DBG("RPN data bits mismatch 0x%x", data_bits);
1497 data_bits = RFCOMM_RPN_DATA_8;
1498 rpn_mask ^= RFCOMM_RPN_PM_DATA;
1499 }
1500 }
J. Suter3a5e9032005-08-09 20:28:46 -07001501
Al Viroe8db8c92006-11-08 00:28:44 -08001502 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_STOP)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001503 stop_bits = __get_rpn_stop_bits(rpn->line_settings);
1504 if (stop_bits != RFCOMM_RPN_STOP_1) {
1505 BT_DBG("RPN stop bits mismatch 0x%x", stop_bits);
1506 stop_bits = RFCOMM_RPN_STOP_1;
1507 rpn_mask ^= RFCOMM_RPN_PM_STOP;
1508 }
1509 }
J. Suter3a5e9032005-08-09 20:28:46 -07001510
Al Viroe8db8c92006-11-08 00:28:44 -08001511 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_PARITY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512 parity = __get_rpn_parity(rpn->line_settings);
1513 if (parity != RFCOMM_RPN_PARITY_NONE) {
1514 BT_DBG("RPN parity mismatch 0x%x", parity);
1515 parity = RFCOMM_RPN_PARITY_NONE;
1516 rpn_mask ^= RFCOMM_RPN_PM_PARITY;
1517 }
1518 }
J. Suter3a5e9032005-08-09 20:28:46 -07001519
Al Viroe8db8c92006-11-08 00:28:44 -08001520 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_FLOW)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521 flow_ctrl = rpn->flow_ctrl;
1522 if (flow_ctrl != RFCOMM_RPN_FLOW_NONE) {
1523 BT_DBG("RPN flow ctrl mismatch 0x%x", flow_ctrl);
1524 flow_ctrl = RFCOMM_RPN_FLOW_NONE;
1525 rpn_mask ^= RFCOMM_RPN_PM_FLOW;
1526 }
1527 }
J. Suter3a5e9032005-08-09 20:28:46 -07001528
Al Viroe8db8c92006-11-08 00:28:44 -08001529 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_XON)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530 xon_char = rpn->xon_char;
1531 if (xon_char != RFCOMM_RPN_XON_CHAR) {
1532 BT_DBG("RPN XON char mismatch 0x%x", xon_char);
1533 xon_char = RFCOMM_RPN_XON_CHAR;
1534 rpn_mask ^= RFCOMM_RPN_PM_XON;
1535 }
1536 }
J. Suter3a5e9032005-08-09 20:28:46 -07001537
Al Viroe8db8c92006-11-08 00:28:44 -08001538 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_XOFF)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539 xoff_char = rpn->xoff_char;
1540 if (xoff_char != RFCOMM_RPN_XOFF_CHAR) {
1541 BT_DBG("RPN XOFF char mismatch 0x%x", xoff_char);
1542 xoff_char = RFCOMM_RPN_XOFF_CHAR;
1543 rpn_mask ^= RFCOMM_RPN_PM_XOFF;
1544 }
1545 }
1546
1547rpn_out:
J. Suter3a5e9032005-08-09 20:28:46 -07001548 rfcomm_send_rpn(s, 0, dlci, bit_rate, data_bits, stop_bits,
1549 parity, flow_ctrl, xon_char, xoff_char, rpn_mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550
1551 return 0;
1552}
1553
1554static int rfcomm_recv_rls(struct rfcomm_session *s, int cr, struct sk_buff *skb)
1555{
1556 struct rfcomm_rls *rls = (void *) skb->data;
1557 u8 dlci = __get_dlci(rls->dlci);
1558
1559 BT_DBG("dlci %d cr %d status 0x%x", dlci, cr, rls->status);
J. Suter3a5e9032005-08-09 20:28:46 -07001560
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561 if (!cr)
1562 return 0;
1563
J. Suter3a5e9032005-08-09 20:28:46 -07001564 /* We should probably do something with this information here. But
1565 * for now it's sufficient just to reply -- Bluetooth 1.1 says it's
1566 * mandatory to recognise and respond to RLS */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567
1568 rfcomm_send_rls(s, 0, dlci, rls->status);
1569
1570 return 0;
1571}
1572
1573static int rfcomm_recv_msc(struct rfcomm_session *s, int cr, struct sk_buff *skb)
1574{
1575 struct rfcomm_msc *msc = (void *) skb->data;
1576 struct rfcomm_dlc *d;
1577 u8 dlci = __get_dlci(msc->dlci);
1578
1579 BT_DBG("dlci %d cr %d v24 0x%x", dlci, cr, msc->v24_sig);
1580
1581 d = rfcomm_dlc_get(s, dlci);
J. Suter3a5e9032005-08-09 20:28:46 -07001582 if (!d)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583 return 0;
1584
1585 if (cr) {
1586 if (msc->v24_sig & RFCOMM_V24_FC && !d->cfc)
1587 set_bit(RFCOMM_TX_THROTTLED, &d->flags);
1588 else
1589 clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
J. Suter3a5e9032005-08-09 20:28:46 -07001590
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591 rfcomm_dlc_lock(d);
Marcel Holtmann8b6b3da2008-07-14 20:13:52 +02001592
1593 d->remote_v24_sig = msc->v24_sig;
1594
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595 if (d->modem_status)
1596 d->modem_status(d, msc->v24_sig);
Marcel Holtmann8b6b3da2008-07-14 20:13:52 +02001597
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598 rfcomm_dlc_unlock(d);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001599
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600 rfcomm_send_msc(s, 0, dlci, msc->v24_sig);
1601
1602 d->mscex |= RFCOMM_MSCEX_RX;
J. Suter3a5e9032005-08-09 20:28:46 -07001603 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604 d->mscex |= RFCOMM_MSCEX_TX;
1605
1606 return 0;
1607}
1608
1609static int rfcomm_recv_mcc(struct rfcomm_session *s, struct sk_buff *skb)
1610{
1611 struct rfcomm_mcc *mcc = (void *) skb->data;
1612 u8 type, cr, len;
1613
1614 cr = __test_cr(mcc->type);
1615 type = __get_mcc_type(mcc->type);
1616 len = __get_mcc_len(mcc->len);
1617
1618 BT_DBG("%p type 0x%x cr %d", s, type, cr);
1619
1620 skb_pull(skb, 2);
1621
1622 switch (type) {
1623 case RFCOMM_PN:
1624 rfcomm_recv_pn(s, cr, skb);
1625 break;
1626
1627 case RFCOMM_RPN:
1628 rfcomm_recv_rpn(s, cr, len, skb);
1629 break;
1630
1631 case RFCOMM_RLS:
1632 rfcomm_recv_rls(s, cr, skb);
1633 break;
1634
1635 case RFCOMM_MSC:
1636 rfcomm_recv_msc(s, cr, skb);
1637 break;
1638
1639 case RFCOMM_FCOFF:
1640 if (cr) {
1641 set_bit(RFCOMM_TX_THROTTLED, &s->flags);
1642 rfcomm_send_fcoff(s, 0);
1643 }
1644 break;
1645
1646 case RFCOMM_FCON:
1647 if (cr) {
1648 clear_bit(RFCOMM_TX_THROTTLED, &s->flags);
1649 rfcomm_send_fcon(s, 0);
1650 }
1651 break;
1652
1653 case RFCOMM_TEST:
1654 if (cr)
1655 rfcomm_send_test(s, 0, skb->data, skb->len);
1656 break;
1657
1658 case RFCOMM_NSC:
1659 break;
1660
1661 default:
1662 BT_ERR("Unknown control type 0x%02x", type);
1663 rfcomm_send_nsc(s, cr, type);
1664 break;
1665 }
1666 return 0;
1667}
1668
1669static int rfcomm_recv_data(struct rfcomm_session *s, u8 dlci, int pf, struct sk_buff *skb)
1670{
1671 struct rfcomm_dlc *d;
1672
1673 BT_DBG("session %p state %ld dlci %d pf %d", s, s->state, dlci, pf);
1674
1675 d = rfcomm_dlc_get(s, dlci);
1676 if (!d) {
1677 rfcomm_send_dm(s, dlci);
1678 goto drop;
1679 }
1680
1681 if (pf && d->cfc) {
1682 u8 credits = *(u8 *) skb->data; skb_pull(skb, 1);
1683
1684 d->tx_credits += credits;
1685 if (d->tx_credits)
1686 clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
1687 }
1688
1689 if (skb->len && d->state == BT_CONNECTED) {
1690 rfcomm_dlc_lock(d);
1691 d->rx_credits--;
1692 d->data_ready(d, skb);
1693 rfcomm_dlc_unlock(d);
1694 return 0;
1695 }
1696
1697drop:
1698 kfree_skb(skb);
1699 return 0;
1700}
1701
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001702static struct rfcomm_session *rfcomm_recv_frame(struct rfcomm_session *s,
1703 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704{
1705 struct rfcomm_hdr *hdr = (void *) skb->data;
1706 u8 type, dlci, fcs;
1707
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001708 if (!s) {
1709 /* no session, so free socket data */
1710 kfree_skb(skb);
1711 return s;
1712 }
1713
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714 dlci = __get_dlci(hdr->addr);
1715 type = __get_type(hdr->ctrl);
1716
1717 /* Trim FCS */
1718 skb->len--; skb->tail--;
Arnaldo Carvalho de Melo27a884d2007-04-19 20:29:13 -07001719 fcs = *(u8 *)skb_tail_pointer(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720
1721 if (__check_fcs(skb->data, type, fcs)) {
1722 BT_ERR("bad checksum in packet");
1723 kfree_skb(skb);
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001724 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 }
1726
1727 if (__test_ea(hdr->len))
1728 skb_pull(skb, 3);
1729 else
1730 skb_pull(skb, 4);
1731
1732 switch (type) {
1733 case RFCOMM_SABM:
1734 if (__test_pf(hdr->ctrl))
1735 rfcomm_recv_sabm(s, dlci);
1736 break;
1737
1738 case RFCOMM_DISC:
1739 if (__test_pf(hdr->ctrl))
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001740 s = rfcomm_recv_disc(s, dlci);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 break;
1742
1743 case RFCOMM_UA:
1744 if (__test_pf(hdr->ctrl))
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001745 s = rfcomm_recv_ua(s, dlci);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746 break;
1747
1748 case RFCOMM_DM:
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001749 s = rfcomm_recv_dm(s, dlci);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750 break;
1751
1752 case RFCOMM_UIH:
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001753 if (dlci) {
1754 rfcomm_recv_data(s, dlci, __test_pf(hdr->ctrl), skb);
1755 return s;
1756 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757 rfcomm_recv_mcc(s, skb);
1758 break;
1759
1760 default:
Andrei Emeltchenko5017d8d2010-09-08 16:26:53 +03001761 BT_ERR("Unknown packet type 0x%02x", type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762 break;
1763 }
1764 kfree_skb(skb);
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001765 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766}
1767
1768/* ---- Connection and data processing ---- */
1769
1770static void rfcomm_process_connect(struct rfcomm_session *s)
1771{
1772 struct rfcomm_dlc *d;
1773 struct list_head *p, *n;
1774
1775 BT_DBG("session %p state %ld", s, s->state);
1776
1777 list_for_each_safe(p, n, &s->dlcs) {
1778 d = list_entry(p, struct rfcomm_dlc, list);
1779 if (d->state == BT_CONFIG) {
1780 d->mtu = s->mtu;
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +01001781 if (rfcomm_check_security(d)) {
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001782 rfcomm_send_pn(s, 1, d);
1783 } else {
Marcel Holtmann77db1982008-07-14 20:13:45 +02001784 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
1785 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001786 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787 }
1788 }
1789}
1790
1791/* Send data queued for the DLC.
1792 * Return number of frames left in the queue.
1793 */
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001794static int rfcomm_process_tx(struct rfcomm_dlc *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795{
1796 struct sk_buff *skb;
1797 int err;
1798
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001799 BT_DBG("dlc %p state %ld cfc %d rx_credits %d tx_credits %d",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800 d, d->state, d->cfc, d->rx_credits, d->tx_credits);
1801
1802 /* Send pending MSC */
1803 if (test_and_clear_bit(RFCOMM_MSC_PENDING, &d->flags))
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001804 rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805
1806 if (d->cfc) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001807 /* CFC enabled.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 * Give them some credits */
1809 if (!test_bit(RFCOMM_RX_THROTTLED, &d->flags) &&
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001810 d->rx_credits <= (d->cfc >> 2)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811 rfcomm_send_credits(d->session, d->addr, d->cfc - d->rx_credits);
1812 d->rx_credits = d->cfc;
1813 }
1814 } else {
1815 /* CFC disabled.
1816 * Give ourselves some credits */
1817 d->tx_credits = 5;
1818 }
1819
1820 if (test_bit(RFCOMM_TX_THROTTLED, &d->flags))
1821 return skb_queue_len(&d->tx_queue);
1822
1823 while (d->tx_credits && (skb = skb_dequeue(&d->tx_queue))) {
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001824 err = rfcomm_send_frame(d->session, skb->data, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825 if (err < 0) {
1826 skb_queue_head(&d->tx_queue, skb);
1827 break;
1828 }
1829 kfree_skb(skb);
1830 d->tx_credits--;
1831 }
1832
1833 if (d->cfc && !d->tx_credits) {
1834 /* We're out of TX credits.
1835 * Set TX_THROTTLED flag to avoid unnesary wakeups by dlc_send. */
1836 set_bit(RFCOMM_TX_THROTTLED, &d->flags);
1837 }
1838
1839 return skb_queue_len(&d->tx_queue);
1840}
1841
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001842static void rfcomm_process_dlcs(struct rfcomm_session *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843{
1844 struct rfcomm_dlc *d;
1845 struct list_head *p, *n;
1846
1847 BT_DBG("session %p state %ld", s, s->state);
1848
1849 list_for_each_safe(p, n, &s->dlcs) {
1850 d = list_entry(p, struct rfcomm_dlc, list);
1851
1852 if (test_bit(RFCOMM_TIMED_OUT, &d->flags)) {
1853 __rfcomm_dlc_close(d, ETIMEDOUT);
1854 continue;
1855 }
1856
Szymon Jancdb544672011-09-26 14:19:47 +02001857 if (test_bit(RFCOMM_ENC_DROP, &d->flags)) {
1858 __rfcomm_dlc_close(d, ECONNREFUSED);
1859 continue;
1860 }
1861
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862 if (test_and_clear_bit(RFCOMM_AUTH_ACCEPT, &d->flags)) {
1863 rfcomm_dlc_clear_timer(d);
Marcel Holtmann77db1982008-07-14 20:13:45 +02001864 if (d->out) {
1865 rfcomm_send_pn(s, 1, d);
1866 rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT);
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001867 } else {
1868 if (d->defer_setup) {
1869 set_bit(RFCOMM_DEFER_SETUP, &d->flags);
1870 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
Marcel Holtmann8bf47942009-02-16 02:59:49 +01001871
1872 rfcomm_dlc_lock(d);
1873 d->state = BT_CONNECT2;
1874 d->state_change(d, 0);
1875 rfcomm_dlc_unlock(d);
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001876 } else
1877 rfcomm_dlc_accept(d);
1878 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879 continue;
1880 } else if (test_and_clear_bit(RFCOMM_AUTH_REJECT, &d->flags)) {
1881 rfcomm_dlc_clear_timer(d);
Marcel Holtmann77db1982008-07-14 20:13:45 +02001882 if (!d->out)
1883 rfcomm_send_dm(s, d->dlci);
1884 else
1885 d->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886 __rfcomm_dlc_close(d, ECONNREFUSED);
1887 continue;
1888 }
1889
Jaikumar Ganesh6e1031a2009-02-02 18:03:57 -08001890 if (test_bit(RFCOMM_SEC_PENDING, &d->flags))
1891 continue;
1892
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893 if (test_bit(RFCOMM_TX_THROTTLED, &s->flags))
1894 continue;
1895
1896 if ((d->state == BT_CONNECTED || d->state == BT_DISCONN) &&
Marcel Holtmann77db1982008-07-14 20:13:45 +02001897 d->mscex == RFCOMM_MSCEX_OK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001898 rfcomm_process_tx(d);
1899 }
1900}
1901
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001902static struct rfcomm_session *rfcomm_process_rx(struct rfcomm_session *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001903{
1904 struct socket *sock = s->sock;
1905 struct sock *sk = sock->sk;
1906 struct sk_buff *skb;
1907
1908 BT_DBG("session %p state %ld qlen %d", s, s->state, skb_queue_len(&sk->sk_receive_queue));
1909
1910 /* Get data directly from socket receive queue without copying it. */
1911 while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
1912 skb_orphan(skb);
Mat Martineau44935722011-07-22 14:53:58 -07001913 if (!skb_linearize(skb))
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001914 s = rfcomm_recv_frame(s, skb);
Mat Martineau44935722011-07-22 14:53:58 -07001915 else
1916 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001917 }
1918
Dean Jenkins08c30ac2013-02-28 14:21:56 +00001919 if (s && (sk->sk_state == BT_CLOSED))
1920 s = rfcomm_session_close(s, sk->sk_err);
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001921
1922 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001923}
1924
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001925static void rfcomm_accept_connection(struct rfcomm_session *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926{
1927 struct socket *sock = s->sock, *nsock;
1928 int err;
1929
1930 /* Fast check for a new connection.
1931 * Avoids unnesesary socket allocations. */
1932 if (list_empty(&bt_sk(sock->sk)->accept_q))
1933 return;
1934
1935 BT_DBG("session %p", s);
1936
Marcel Holtmann48db9ca2007-05-05 00:36:06 +02001937 err = kernel_accept(sock, &nsock, O_NONBLOCK);
1938 if (err < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001939 return;
1940
Linus Torvalds1da177e2005-04-16 15:20:36 -07001941 /* Set our callbacks */
1942 nsock->sk->sk_data_ready = rfcomm_l2data_ready;
1943 nsock->sk->sk_state_change = rfcomm_l2state_change;
1944
1945 s = rfcomm_session_add(nsock, BT_OPEN);
1946 if (s) {
Marcel Holtmann98bcd082006-07-14 11:42:12 +02001947 /* We should adjust MTU on incoming sessions.
1948 * L2CAP MTU minus UIH header and FCS. */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001949 s->mtu = min(l2cap_pi(nsock->sk)->chan->omtu,
1950 l2cap_pi(nsock->sk)->chan->imtu) - 5;
Marcel Holtmann98bcd082006-07-14 11:42:12 +02001951
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +03001952 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001953 } else
1954 sock_release(nsock);
1955}
1956
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001957static struct rfcomm_session *rfcomm_check_connection(struct rfcomm_session *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958{
1959 struct sock *sk = s->sock->sk;
1960
1961 BT_DBG("%p state %ld", s, s->state);
1962
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +02001963 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001964 case BT_CONNECTED:
1965 s->state = BT_CONNECT;
1966
1967 /* We can adjust MTU on outgoing sessions.
1968 * L2CAP MTU minus UIH header and FCS. */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001969 s->mtu = min(l2cap_pi(sk)->chan->omtu, l2cap_pi(sk)->chan->imtu) - 5;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001970
1971 rfcomm_send_sabm(s, 0);
1972 break;
1973
1974 case BT_CLOSED:
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001975 s = rfcomm_session_close(s, sk->sk_err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001976 break;
1977 }
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001978 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001979}
1980
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001981static void rfcomm_process_sessions(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001982{
1983 struct list_head *p, *n;
1984
1985 rfcomm_lock();
1986
1987 list_for_each_safe(p, n, &session_list) {
1988 struct rfcomm_session *s;
1989 s = list_entry(p, struct rfcomm_session, list);
1990
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -03001991 if (test_and_clear_bit(RFCOMM_TIMED_OUT, &s->flags)) {
1992 s->state = BT_DISCONN;
1993 rfcomm_send_disc(s, 0);
1994 continue;
1995 }
1996
Peter Hurley4339c252014-02-09 20:59:11 -05001997 switch (s->state) {
1998 case BT_LISTEN:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001999 rfcomm_accept_connection(s);
2000 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002001
Linus Torvalds1da177e2005-04-16 15:20:36 -07002002 case BT_BOUND:
Dean Jenkins8ff52f72013-02-28 14:21:55 +00002003 s = rfcomm_check_connection(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002004 break;
2005
2006 default:
Dean Jenkins8ff52f72013-02-28 14:21:55 +00002007 s = rfcomm_process_rx(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002008 break;
2009 }
2010
Dean Jenkins8ff52f72013-02-28 14:21:55 +00002011 if (s)
2012 rfcomm_process_dlcs(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002013 }
2014
2015 rfcomm_unlock();
2016}
2017
Linus Torvalds1da177e2005-04-16 15:20:36 -07002018static int rfcomm_add_listener(bdaddr_t *ba)
2019{
2020 struct sockaddr_l2 addr;
2021 struct socket *sock;
2022 struct sock *sk;
2023 struct rfcomm_session *s;
2024 int err = 0;
2025
2026 /* Create socket */
2027 err = rfcomm_l2sock_create(&sock);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002028 if (err < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002029 BT_ERR("Create socket failed %d", err);
2030 return err;
2031 }
2032
2033 /* Bind socket */
2034 bacpy(&addr.l2_bdaddr, ba);
2035 addr.l2_family = AF_BLUETOOTH;
Joe Perchesdcf4adb2014-03-12 10:52:35 -07002036 addr.l2_psm = cpu_to_le16(RFCOMM_PSM);
Marcel Holtmann37e62f52009-02-17 21:49:33 +01002037 addr.l2_cid = 0;
Seung-Woo Kimc507f132013-11-05 16:02:24 +09002038 addr.l2_bdaddr_type = BDADDR_BREDR;
Marcel Holtmann48db9ca2007-05-05 00:36:06 +02002039 err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002040 if (err < 0) {
2041 BT_ERR("Bind failed %d", err);
2042 goto failed;
2043 }
2044
2045 /* Set L2CAP options */
2046 sk = sock->sk;
2047 lock_sock(sk);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002048 l2cap_pi(sk)->chan->imtu = l2cap_mtu;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002049 release_sock(sk);
2050
2051 /* Start listening on the socket */
Marcel Holtmann48db9ca2007-05-05 00:36:06 +02002052 err = kernel_listen(sock, 10);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002053 if (err) {
2054 BT_ERR("Listen failed %d", err);
2055 goto failed;
2056 }
2057
2058 /* Add listening session */
2059 s = rfcomm_session_add(sock, BT_LISTEN);
Wei Yongjun0227c7b2013-03-20 20:23:37 +08002060 if (!s) {
2061 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002062 goto failed;
Wei Yongjun0227c7b2013-03-20 20:23:37 +08002063 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002064
Linus Torvalds1da177e2005-04-16 15:20:36 -07002065 return 0;
2066failed:
2067 sock_release(sock);
2068 return err;
2069}
2070
2071static void rfcomm_kill_listener(void)
2072{
2073 struct rfcomm_session *s;
2074 struct list_head *p, *n;
2075
2076 BT_DBG("");
2077
2078 list_for_each_safe(p, n, &session_list) {
2079 s = list_entry(p, struct rfcomm_session, list);
2080 rfcomm_session_del(s);
2081 }
2082}
2083
2084static int rfcomm_run(void *unused)
2085{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086 BT_DBG("");
2087
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002088 set_user_nice(current, -10);
2089
Linus Torvalds1da177e2005-04-16 15:20:36 -07002090 rfcomm_add_listener(BDADDR_ANY);
2091
Peter Hurleye5842cd2011-07-24 00:10:35 -04002092 while (1) {
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002093 set_current_state(TASK_INTERRUPTIBLE);
Peter Hurleye5842cd2011-07-24 00:10:35 -04002094
2095 if (kthread_should_stop())
2096 break;
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002097
2098 /* Process stuff */
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002099 rfcomm_process_sessions();
Peter Hurleye5842cd2011-07-24 00:10:35 -04002100
2101 schedule();
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002102 }
Peter Hurleye5842cd2011-07-24 00:10:35 -04002103 __set_current_state(TASK_RUNNING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002104
2105 rfcomm_kill_listener();
2106
Linus Torvalds1da177e2005-04-16 15:20:36 -07002107 return 0;
2108}
2109
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01002110static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002111{
2112 struct rfcomm_session *s;
2113 struct rfcomm_dlc *d;
2114 struct list_head *p, *n;
2115
2116 BT_DBG("conn %p status 0x%02x encrypt 0x%02x", conn, status, encrypt);
2117
2118 s = rfcomm_session_get(&conn->hdev->bdaddr, &conn->dst);
2119 if (!s)
2120 return;
2121
Linus Torvalds1da177e2005-04-16 15:20:36 -07002122 list_for_each_safe(p, n, &s->dlcs) {
2123 d = list_entry(p, struct rfcomm_dlc, list);
2124
Marcel Holtmann8c84b832009-01-16 08:17:51 +01002125 if (test_and_clear_bit(RFCOMM_SEC_PENDING, &d->flags)) {
2126 rfcomm_dlc_clear_timer(d);
2127 if (status || encrypt == 0x00) {
Szymon Jancdb544672011-09-26 14:19:47 +02002128 set_bit(RFCOMM_ENC_DROP, &d->flags);
Marcel Holtmann8c84b832009-01-16 08:17:51 +01002129 continue;
2130 }
2131 }
2132
2133 if (d->state == BT_CONNECTED && !status && encrypt == 0x00) {
2134 if (d->sec_level == BT_SECURITY_MEDIUM) {
2135 set_bit(RFCOMM_SEC_PENDING, &d->flags);
2136 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
2137 continue;
Marcel Holtmann2c068e02014-01-15 22:37:41 -08002138 } else if (d->sec_level == BT_SECURITY_HIGH ||
2139 d->sec_level == BT_SECURITY_FIPS) {
Szymon Jancdb544672011-09-26 14:19:47 +02002140 set_bit(RFCOMM_ENC_DROP, &d->flags);
Marcel Holtmann8c84b832009-01-16 08:17:51 +01002141 continue;
2142 }
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02002143 }
2144
Linus Torvalds1da177e2005-04-16 15:20:36 -07002145 if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags))
2146 continue;
2147
Waldemar Rymarkiewiczb3b1b062011-05-06 09:42:31 +02002148 if (!status && hci_conn_check_secure(conn, d->sec_level))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002149 set_bit(RFCOMM_AUTH_ACCEPT, &d->flags);
2150 else
2151 set_bit(RFCOMM_AUTH_REJECT, &d->flags);
2152 }
2153
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +03002154 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002155}
2156
2157static struct hci_cb rfcomm_cb = {
2158 .name = "RFCOMM",
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01002159 .security_cfm = rfcomm_security_cfm
Linus Torvalds1da177e2005-04-16 15:20:36 -07002160};
2161
Marcel Holtmannaef7d972010-03-21 05:27:45 +01002162static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002163{
2164 struct rfcomm_session *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002165
2166 rfcomm_lock();
2167
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +02002168 list_for_each_entry(s, &session_list, list) {
Marcel Holtmann24bc10c2013-10-13 09:49:54 -07002169 struct l2cap_chan *chan = l2cap_pi(s->sock->sk)->chan;
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +02002170 struct rfcomm_dlc *d;
2171 list_for_each_entry(d, &s->dlcs, list) {
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03002172 seq_printf(f, "%pMR %pMR %ld %d %d %d %d\n",
Marcel Holtmann24bc10c2013-10-13 09:49:54 -07002173 &chan->src, &chan->dst,
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03002174 d->state, d->dlci, d->mtu,
2175 d->rx_credits, d->tx_credits);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002176 }
2177 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002178
Linus Torvalds1da177e2005-04-16 15:20:36 -07002179 rfcomm_unlock();
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08002180
Marcel Holtmannaef7d972010-03-21 05:27:45 +01002181 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002182}
2183
Marcel Holtmannaef7d972010-03-21 05:27:45 +01002184static int rfcomm_dlc_debugfs_open(struct inode *inode, struct file *file)
2185{
2186 return single_open(file, rfcomm_dlc_debugfs_show, inode->i_private);
2187}
2188
2189static const struct file_operations rfcomm_dlc_debugfs_fops = {
2190 .open = rfcomm_dlc_debugfs_open,
2191 .read = seq_read,
2192 .llseek = seq_lseek,
2193 .release = single_release,
2194};
2195
2196static struct dentry *rfcomm_dlc_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002197
2198/* ---- Initialization ---- */
2199static int __init rfcomm_init(void)
2200{
Marcel Holtmann52d18342009-08-22 14:49:36 -07002201 int err;
Dave Youngaf0d3b12009-08-03 04:26:16 +00002202
Linus Torvalds1da177e2005-04-16 15:20:36 -07002203 hci_register_cb(&rfcomm_cb);
2204
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002205 rfcomm_thread = kthread_run(rfcomm_run, NULL, "krfcommd");
2206 if (IS_ERR(rfcomm_thread)) {
Marcel Holtmann52d18342009-08-22 14:49:36 -07002207 err = PTR_ERR(rfcomm_thread);
2208 goto unregister;
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002209 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002210
Marcel Holtmann52d18342009-08-22 14:49:36 -07002211 err = rfcomm_init_ttys();
2212 if (err < 0)
2213 goto stop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002214
Marcel Holtmann52d18342009-08-22 14:49:36 -07002215 err = rfcomm_init_sockets();
2216 if (err < 0)
2217 goto cleanup;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002218
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08002219 BT_INFO("RFCOMM ver %s", VERSION);
2220
Marcel Holtmann1120e4b2013-10-17 17:24:16 -07002221 if (IS_ERR_OR_NULL(bt_debugfs))
2222 return 0;
2223
2224 rfcomm_dlc_debugfs = debugfs_create_file("rfcomm_dlc", 0444,
2225 bt_debugfs, NULL,
2226 &rfcomm_dlc_debugfs_fops);
2227
Linus Torvalds1da177e2005-04-16 15:20:36 -07002228 return 0;
Dave Youngaf0d3b12009-08-03 04:26:16 +00002229
Marcel Holtmann52d18342009-08-22 14:49:36 -07002230cleanup:
Dave Youngaf0d3b12009-08-03 04:26:16 +00002231 rfcomm_cleanup_ttys();
Marcel Holtmann52d18342009-08-22 14:49:36 -07002232
2233stop:
Dave Youngaf0d3b12009-08-03 04:26:16 +00002234 kthread_stop(rfcomm_thread);
Marcel Holtmann52d18342009-08-22 14:49:36 -07002235
2236unregister:
Dave Youngaf0d3b12009-08-03 04:26:16 +00002237 hci_unregister_cb(&rfcomm_cb);
2238
Marcel Holtmann52d18342009-08-22 14:49:36 -07002239 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002240}
2241
2242static void __exit rfcomm_exit(void)
2243{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01002244 debugfs_remove(rfcomm_dlc_debugfs);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08002245
Linus Torvalds1da177e2005-04-16 15:20:36 -07002246 hci_unregister_cb(&rfcomm_cb);
2247
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002248 kthread_stop(rfcomm_thread);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249
Linus Torvalds1da177e2005-04-16 15:20:36 -07002250 rfcomm_cleanup_ttys();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002251
2252 rfcomm_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002253}
2254
2255module_init(rfcomm_init);
2256module_exit(rfcomm_exit);
2257
Marcel Holtmann7c2660b2006-07-03 10:02:51 +02002258module_param(disable_cfc, bool, 0644);
2259MODULE_PARM_DESC(disable_cfc, "Disable credit based flow control");
2260
Marcel Holtmann98bcd082006-07-14 11:42:12 +02002261module_param(channel_mtu, int, 0644);
2262MODULE_PARM_DESC(channel_mtu, "Default MTU for the RFCOMM channel");
2263
Marcel Holtmann56f3a402006-02-13 11:39:57 +01002264module_param(l2cap_mtu, uint, 0644);
2265MODULE_PARM_DESC(l2cap_mtu, "Default MTU for the L2CAP connection");
2266
Marcel Holtmanneae38ee2009-10-05 12:23:48 +02002267module_param(l2cap_ertm, bool, 0644);
2268MODULE_PARM_DESC(l2cap_ertm, "Use L2CAP ERTM mode for connection");
2269
Marcel Holtmann63fbd242008-08-18 13:23:53 +02002270MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002271MODULE_DESCRIPTION("Bluetooth RFCOMM ver " VERSION);
2272MODULE_VERSION(VERSION);
2273MODULE_LICENSE("GPL");
2274MODULE_ALIAS("bt-proto-3");