blob: 5acc82fa020044228a07d0174987e397b21043c6 [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 Padovan6039aa732012-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
189static void rfcomm_l2data_ready(struct sock *sk, int bytes)
190{
191 BT_DBG("%p bytes %d", sk, bytes);
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 Padovan6039aa732012-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
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300230 return hci_conn_security(conn->hcon, d->sec_level, auth_type);
Marcel Holtmann77db1982008-07-14 20:13:45 +0200231}
232
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300233static void rfcomm_session_timeout(unsigned long arg)
234{
235 struct rfcomm_session *s = (void *) arg;
236
237 BT_DBG("session %p state %ld", s, s->state);
238
239 set_bit(RFCOMM_TIMED_OUT, &s->flags);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300240 rfcomm_schedule();
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300241}
242
243static void rfcomm_session_set_timer(struct rfcomm_session *s, long timeout)
244{
245 BT_DBG("session %p state %ld timeout %ld", s, s->state, timeout);
246
Dean Jenkins08c30ac2013-02-28 14:21:56 +0000247 mod_timer(&s->timer, jiffies + timeout);
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300248}
249
250static void rfcomm_session_clear_timer(struct rfcomm_session *s)
251{
252 BT_DBG("session %p state %ld", s, s->state);
253
Dean Jenkins08c30ac2013-02-28 14:21:56 +0000254 del_timer_sync(&s->timer);
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300255}
256
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257/* ---- RFCOMM DLCs ---- */
258static void rfcomm_dlc_timeout(unsigned long arg)
259{
260 struct rfcomm_dlc *d = (void *) arg;
261
262 BT_DBG("dlc %p state %ld", d, d->state);
263
264 set_bit(RFCOMM_TIMED_OUT, &d->flags);
265 rfcomm_dlc_put(d);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300266 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267}
268
269static void rfcomm_dlc_set_timer(struct rfcomm_dlc *d, long timeout)
270{
271 BT_DBG("dlc %p state %ld timeout %ld", d, d->state, timeout);
272
273 if (!mod_timer(&d->timer, jiffies + timeout))
274 rfcomm_dlc_hold(d);
275}
276
277static void rfcomm_dlc_clear_timer(struct rfcomm_dlc *d)
278{
279 BT_DBG("dlc %p state %ld", d, d->state);
280
Ying Xue25cc4ae2013-02-03 20:32:57 +0000281 if (del_timer(&d->timer))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 rfcomm_dlc_put(d);
283}
284
285static void rfcomm_dlc_clear_state(struct rfcomm_dlc *d)
286{
287 BT_DBG("%p", d);
288
289 d->state = BT_OPEN;
290 d->flags = 0;
291 d->mscex = 0;
Johan Hedberg183f7322010-12-06 15:56:17 +0200292 d->sec_level = BT_SECURITY_LOW;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 d->mtu = RFCOMM_DEFAULT_MTU;
294 d->v24_sig = RFCOMM_V24_RTC | RFCOMM_V24_RTR | RFCOMM_V24_DV;
295
296 d->cfc = RFCOMM_CFC_DISABLED;
297 d->rx_credits = RFCOMM_DEFAULT_CREDITS;
298}
299
Al Virodd0fc662005-10-07 07:46:04 +0100300struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301{
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200302 struct rfcomm_dlc *d = kzalloc(sizeof(*d), prio);
303
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304 if (!d)
305 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306
Pavel Emelyanovb24b8a22008-01-23 21:20:07 -0800307 setup_timer(&d->timer, rfcomm_dlc_timeout, (unsigned long)d);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308
309 skb_queue_head_init(&d->tx_queue);
310 spin_lock_init(&d->lock);
311 atomic_set(&d->refcnt, 1);
312
313 rfcomm_dlc_clear_state(d);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900314
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315 BT_DBG("%p", d);
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200316
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317 return d;
318}
319
320void rfcomm_dlc_free(struct rfcomm_dlc *d)
321{
322 BT_DBG("%p", d);
323
324 skb_queue_purge(&d->tx_queue);
325 kfree(d);
326}
327
328static void rfcomm_dlc_link(struct rfcomm_session *s, struct rfcomm_dlc *d)
329{
330 BT_DBG("dlc %p session %p", d, s);
331
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300332 rfcomm_session_clear_timer(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700333 rfcomm_dlc_hold(d);
334 list_add(&d->list, &s->dlcs);
335 d->session = s;
336}
337
338static void rfcomm_dlc_unlink(struct rfcomm_dlc *d)
339{
340 struct rfcomm_session *s = d->session;
341
342 BT_DBG("dlc %p refcnt %d session %p", d, atomic_read(&d->refcnt), s);
343
344 list_del(&d->list);
345 d->session = NULL;
346 rfcomm_dlc_put(d);
347
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300348 if (list_empty(&s->dlcs))
349 rfcomm_session_set_timer(s, RFCOMM_IDLE_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350}
351
352static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, u8 dlci)
353{
354 struct rfcomm_dlc *d;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200356 list_for_each_entry(d, &s->dlcs, list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357 if (d->dlci == dlci)
358 return d;
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200359
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360 return NULL;
361}
362
Peter Hurleyc10a8482014-02-09 20:59:10 -0500363static int rfcomm_check_channel(u8 channel)
364{
365 return channel < 1 || channel > 30;
366}
367
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
369{
370 struct rfcomm_session *s;
371 int err = 0;
372 u8 dlci;
373
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +0300374 BT_DBG("dlc %p state %ld %pMR -> %pMR channel %d",
375 d, d->state, src, dst, channel);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376
Peter Hurleyc10a8482014-02-09 20:59:10 -0500377 if (rfcomm_check_channel(channel))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 return -EINVAL;
379
380 if (d->state != BT_OPEN && d->state != BT_CLOSED)
381 return 0;
382
383 s = rfcomm_session_get(src, dst);
384 if (!s) {
Luiz Augusto von Dentz63ce0902010-08-19 14:06:10 +0300385 s = rfcomm_session_create(src, dst, d->sec_level, &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 if (!s)
387 return err;
388 }
389
390 dlci = __dlci(!s->initiator, channel);
391
392 /* Check if DLCI already exists */
393 if (rfcomm_dlc_get(s, dlci))
394 return -EBUSY;
395
396 rfcomm_dlc_clear_state(d);
397
398 d->dlci = dlci;
399 d->addr = __addr(s->initiator, dlci);
400 d->priority = 7;
401
Marcel Holtmann77db1982008-07-14 20:13:45 +0200402 d->state = BT_CONFIG;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403 rfcomm_dlc_link(s, d);
404
Marcel Holtmann77db1982008-07-14 20:13:45 +0200405 d->out = 1;
406
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407 d->mtu = s->mtu;
408 d->cfc = (s->cfc == RFCOMM_CFC_UNKNOWN) ? 0 : s->cfc;
409
Marcel Holtmann77db1982008-07-14 20:13:45 +0200410 if (s->state == BT_CONNECTED) {
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100411 if (rfcomm_check_security(d))
Marcel Holtmann77db1982008-07-14 20:13:45 +0200412 rfcomm_send_pn(s, 1, d);
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100413 else
414 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
Marcel Holtmann77db1982008-07-14 20:13:45 +0200415 }
416
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417 rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT);
Marcel Holtmann77db1982008-07-14 20:13:45 +0200418
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 return 0;
420}
421
422int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
423{
424 int r;
425
426 rfcomm_lock();
427
428 r = __rfcomm_dlc_open(d, src, dst, channel);
429
430 rfcomm_unlock();
431 return r;
432}
433
Peter Hurleyf6223572014-02-09 20:59:13 -0500434static void __rfcomm_dlc_disconn(struct rfcomm_dlc *d)
435{
436 struct rfcomm_session *s = d->session;
437
438 d->state = BT_DISCONN;
439 if (skb_queue_empty(&d->tx_queue)) {
440 rfcomm_send_disc(s, d->dlci);
441 rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT);
442 } else {
443 rfcomm_queue_disc(d);
444 rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT * 2);
445 }
446}
447
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
449{
450 struct rfcomm_session *s = d->session;
451 if (!s)
452 return 0;
453
454 BT_DBG("dlc %p state %ld dlci %d err %d session %p",
455 d, d->state, d->dlci, err, s);
456
457 switch (d->state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458 case BT_CONNECT:
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100459 case BT_CONFIG:
Peter Hurley5998e042014-02-09 20:59:12 -0500460 case BT_OPEN:
461 case BT_CONNECT2:
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100462 if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
463 set_bit(RFCOMM_AUTH_REJECT, &d->flags);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300464 rfcomm_schedule();
Peter Hurley5998e042014-02-09 20:59:12 -0500465 return 0;
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100466 }
Peter Hurley5998e042014-02-09 20:59:12 -0500467 }
468
469 switch (d->state) {
470 case BT_CONNECT:
471 case BT_CONFIG:
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100472 /* Fall through */
473
474 case BT_CONNECTED:
Peter Hurleyf6223572014-02-09 20:59:13 -0500475 __rfcomm_dlc_disconn(d);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 break;
477
478 default:
479 rfcomm_dlc_clear_timer(d);
480
481 rfcomm_dlc_lock(d);
482 d->state = BT_CLOSED;
Dave Young1905f6c2008-04-01 23:59:06 -0700483 d->state_change(d, err);
Arjan van de Ven4c8411f2008-05-29 01:32:47 -0700484 rfcomm_dlc_unlock(d);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485
486 skb_queue_purge(&d->tx_queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487 rfcomm_dlc_unlink(d);
488 }
489
490 return 0;
491}
492
493int rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
494{
Dean Jenkinsc06f7d52013-02-28 14:21:54 +0000495 int r = 0;
496 struct rfcomm_dlc *d_list;
497 struct rfcomm_session *s, *s_list;
498
499 BT_DBG("dlc %p state %ld dlci %d err %d", d, d->state, d->dlci, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500
501 rfcomm_lock();
502
Dean Jenkinsc06f7d52013-02-28 14:21:54 +0000503 s = d->session;
504 if (!s)
505 goto no_session;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506
Dean Jenkinsc06f7d52013-02-28 14:21:54 +0000507 /* after waiting on the mutex check the session still exists
508 * then check the dlc still exists
509 */
510 list_for_each_entry(s_list, &session_list, list) {
511 if (s_list == s) {
512 list_for_each_entry(d_list, &s->dlcs, list) {
513 if (d_list == d) {
514 r = __rfcomm_dlc_close(d, err);
515 break;
516 }
517 }
518 break;
519 }
520 }
521
522no_session:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523 rfcomm_unlock();
524 return r;
525}
526
Peter Hurleyc10a8482014-02-09 20:59:10 -0500527struct rfcomm_dlc *rfcomm_dlc_exists(bdaddr_t *src, bdaddr_t *dst, u8 channel)
528{
529 struct rfcomm_session *s;
530 struct rfcomm_dlc *dlc = NULL;
531 u8 dlci;
532
533 if (rfcomm_check_channel(channel))
534 return ERR_PTR(-EINVAL);
535
536 rfcomm_lock();
537 s = rfcomm_session_get(src, dst);
538 if (s) {
539 dlci = __dlci(!s->initiator, channel);
540 dlc = rfcomm_dlc_get(s, dlci);
541 }
542 rfcomm_unlock();
543 return dlc;
544}
545
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb)
547{
548 int len = skb->len;
549
550 if (d->state != BT_CONNECTED)
551 return -ENOTCONN;
552
553 BT_DBG("dlc %p mtu %d len %d", d, d->mtu, len);
554
555 if (len > d->mtu)
556 return -EINVAL;
557
558 rfcomm_make_uih(skb, d->addr);
559 skb_queue_tail(&d->tx_queue, skb);
560
561 if (!test_bit(RFCOMM_TX_THROTTLED, &d->flags))
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300562 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 return len;
564}
565
Harvey Harrisonb5606c22008-02-13 15:03:16 -0800566void __rfcomm_dlc_throttle(struct rfcomm_dlc *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567{
568 BT_DBG("dlc %p state %ld", d, d->state);
569
570 if (!d->cfc) {
571 d->v24_sig |= RFCOMM_V24_FC;
572 set_bit(RFCOMM_MSC_PENDING, &d->flags);
573 }
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300574 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575}
576
Harvey Harrisonb5606c22008-02-13 15:03:16 -0800577void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578{
579 BT_DBG("dlc %p state %ld", d, d->state);
580
581 if (!d->cfc) {
582 d->v24_sig &= ~RFCOMM_V24_FC;
583 set_bit(RFCOMM_MSC_PENDING, &d->flags);
584 }
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300585 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586}
587
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900588/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589 Set/get modem status functions use _local_ status i.e. what we report
590 to the other side.
591 Remote status is provided by dlc->modem_status() callback.
592 */
593int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig)
594{
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900595 BT_DBG("dlc %p state %ld v24_sig 0x%x",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596 d, d->state, v24_sig);
597
598 if (test_bit(RFCOMM_RX_THROTTLED, &d->flags))
599 v24_sig |= RFCOMM_V24_FC;
600 else
601 v24_sig &= ~RFCOMM_V24_FC;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900602
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603 d->v24_sig = v24_sig;
604
605 if (!test_and_set_bit(RFCOMM_MSC_PENDING, &d->flags))
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300606 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607
608 return 0;
609}
610
611int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig)
612{
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900613 BT_DBG("dlc %p state %ld v24_sig 0x%x",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 d, d->state, d->v24_sig);
615
616 *v24_sig = d->v24_sig;
617 return 0;
618}
619
620/* ---- RFCOMM sessions ---- */
621static struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
622{
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200623 struct rfcomm_session *s = kzalloc(sizeof(*s), GFP_KERNEL);
624
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 if (!s)
626 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627
628 BT_DBG("session %p sock %p", s, sock);
629
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300630 setup_timer(&s->timer, rfcomm_session_timeout, (unsigned long) s);
631
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632 INIT_LIST_HEAD(&s->dlcs);
633 s->state = state;
634 s->sock = sock;
635
636 s->mtu = RFCOMM_DEFAULT_MTU;
Marcel Holtmann7c2660b2006-07-03 10:02:51 +0200637 s->cfc = disable_cfc ? RFCOMM_CFC_DISABLED : RFCOMM_CFC_UNKNOWN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638
639 /* Do not increment module usage count for listening sessions.
640 * Otherwise we won't be able to unload the module. */
641 if (state != BT_LISTEN)
642 if (!try_module_get(THIS_MODULE)) {
643 kfree(s);
644 return NULL;
645 }
646
647 list_add(&s->list, &session_list);
648
649 return s;
650}
651
Dean Jenkins8ff52f72013-02-28 14:21:55 +0000652static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700653{
654 int state = s->state;
655
656 BT_DBG("session %p state %ld", s, s->state);
657
658 list_del(&s->list);
659
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300660 rfcomm_session_clear_timer(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661 sock_release(s->sock);
662 kfree(s);
663
664 if (state != BT_LISTEN)
665 module_put(THIS_MODULE);
Dean Jenkins8ff52f72013-02-28 14:21:55 +0000666
667 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668}
669
670static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
671{
672 struct rfcomm_session *s;
673 struct list_head *p, *n;
Marcel Holtmann24bc10c2013-10-13 09:49:54 -0700674 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675 list_for_each_safe(p, n, &session_list) {
676 s = list_entry(p, struct rfcomm_session, list);
Marcel Holtmann24bc10c2013-10-13 09:49:54 -0700677 chan = l2cap_pi(s->sock->sk)->chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678
Marcel Holtmann24bc10c2013-10-13 09:49:54 -0700679 if ((!bacmp(src, BDADDR_ANY) || !bacmp(&chan->src, src)) &&
680 !bacmp(&chan->dst, dst))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 return s;
682 }
683 return NULL;
684}
685
Dean Jenkins8ff52f72013-02-28 14:21:55 +0000686static struct rfcomm_session *rfcomm_session_close(struct rfcomm_session *s,
687 int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688{
689 struct rfcomm_dlc *d;
690 struct list_head *p, *n;
691
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692 s->state = BT_CLOSED;
693
Dean Jenkins24fd6422013-02-28 14:21:58 +0000694 BT_DBG("session %p state %ld err %d", s, s->state, err);
695
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696 /* Close all dlcs */
697 list_for_each_safe(p, n, &s->dlcs) {
698 d = list_entry(p, struct rfcomm_dlc, list);
699 d->state = BT_CLOSED;
700 __rfcomm_dlc_close(d, err);
701 }
702
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300703 rfcomm_session_clear_timer(s);
Dean Jenkins08c30ac2013-02-28 14:21:56 +0000704 return rfcomm_session_del(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705}
706
Luiz Augusto von Dentz63ce0902010-08-19 14:06:10 +0300707static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
708 bdaddr_t *dst,
709 u8 sec_level,
710 int *err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711{
712 struct rfcomm_session *s = NULL;
713 struct sockaddr_l2 addr;
714 struct socket *sock;
715 struct sock *sk;
716
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +0300717 BT_DBG("%pMR -> %pMR", src, dst);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718
719 *err = rfcomm_l2sock_create(&sock);
720 if (*err < 0)
721 return NULL;
722
723 bacpy(&addr.l2_bdaddr, src);
724 addr.l2_family = AF_BLUETOOTH;
725 addr.l2_psm = 0;
Marcel Holtmann37e62f52009-02-17 21:49:33 +0100726 addr.l2_cid = 0;
Seung-Woo Kimc507f132013-11-05 16:02:24 +0900727 addr.l2_bdaddr_type = BDADDR_BREDR;
Marcel Holtmann48db9ca2007-05-05 00:36:06 +0200728 *err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729 if (*err < 0)
730 goto failed;
731
732 /* Set L2CAP options */
733 sk = sock->sk;
734 lock_sock(sk);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300735 l2cap_pi(sk)->chan->imtu = l2cap_mtu;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300736 l2cap_pi(sk)->chan->sec_level = sec_level;
Marcel Holtmanneae38ee2009-10-05 12:23:48 +0200737 if (l2cap_ertm)
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300738 l2cap_pi(sk)->chan->mode = L2CAP_MODE_ERTM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 release_sock(sk);
740
741 s = rfcomm_session_add(sock, BT_BOUND);
742 if (!s) {
743 *err = -ENOMEM;
744 goto failed;
745 }
746
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747 s->initiator = 1;
748
749 bacpy(&addr.l2_bdaddr, dst);
750 addr.l2_family = AF_BLUETOOTH;
Syam Sidhardhan5bcb8092012-10-10 22:09:29 +0530751 addr.l2_psm = __constant_cpu_to_le16(RFCOMM_PSM);
Marcel Holtmann37e62f52009-02-17 21:49:33 +0100752 addr.l2_cid = 0;
Seung-Woo Kim8992da02013-11-05 17:15:42 +0900753 addr.l2_bdaddr_type = BDADDR_BREDR;
Marcel Holtmann48db9ca2007-05-05 00:36:06 +0200754 *err = kernel_connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);
Marcel Holtmannb4c612a2006-09-23 09:54:38 +0200755 if (*err == 0 || *err == -EINPROGRESS)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756 return s;
757
Dean Jenkins8ff52f72013-02-28 14:21:55 +0000758 return rfcomm_session_del(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759
760failed:
761 sock_release(sock);
762 return NULL;
763}
764
765void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst)
766{
Marcel Holtmann24bc10c2013-10-13 09:49:54 -0700767 struct l2cap_chan *chan = l2cap_pi(s->sock->sk)->chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 if (src)
Marcel Holtmann24bc10c2013-10-13 09:49:54 -0700769 bacpy(src, &chan->src);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770 if (dst)
Marcel Holtmann24bc10c2013-10-13 09:49:54 -0700771 bacpy(dst, &chan->dst);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772}
773
774/* ---- RFCOMM frame sending ---- */
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200775static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777 struct kvec iv = { data, len };
778 struct msghdr msg;
779
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200780 BT_DBG("session %p len %d", s, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781
782 memset(&msg, 0, sizeof(msg));
783
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200784 return kernel_sendmsg(s->sock, &msg, &iv, 1, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785}
786
Luiz Augusto von Dentz262038f2011-11-01 10:58:58 +0200787static int rfcomm_send_cmd(struct rfcomm_session *s, struct rfcomm_cmd *cmd)
788{
789 BT_DBG("%p cmd %u", s, cmd->ctrl);
790
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200791 return rfcomm_send_frame(s, (void *) cmd, sizeof(*cmd));
Luiz Augusto von Dentz262038f2011-11-01 10:58:58 +0200792}
793
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci)
795{
796 struct rfcomm_cmd cmd;
797
798 BT_DBG("%p dlci %d", s, dlci);
799
800 cmd.addr = __addr(s->initiator, dlci);
801 cmd.ctrl = __ctrl(RFCOMM_SABM, 1);
802 cmd.len = __len8(0);
803 cmd.fcs = __fcs2((u8 *) &cmd);
804
Luiz Augusto von Dentz262038f2011-11-01 10:58:58 +0200805 return rfcomm_send_cmd(s, &cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806}
807
808static int rfcomm_send_ua(struct rfcomm_session *s, u8 dlci)
809{
810 struct rfcomm_cmd cmd;
811
812 BT_DBG("%p dlci %d", s, dlci);
813
814 cmd.addr = __addr(!s->initiator, dlci);
815 cmd.ctrl = __ctrl(RFCOMM_UA, 1);
816 cmd.len = __len8(0);
817 cmd.fcs = __fcs2((u8 *) &cmd);
818
Luiz Augusto von Dentz262038f2011-11-01 10:58:58 +0200819 return rfcomm_send_cmd(s, &cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820}
821
822static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci)
823{
824 struct rfcomm_cmd cmd;
825
826 BT_DBG("%p dlci %d", s, dlci);
827
828 cmd.addr = __addr(s->initiator, dlci);
829 cmd.ctrl = __ctrl(RFCOMM_DISC, 1);
830 cmd.len = __len8(0);
831 cmd.fcs = __fcs2((u8 *) &cmd);
832
Luiz Augusto von Dentz262038f2011-11-01 10:58:58 +0200833 return rfcomm_send_cmd(s, &cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834}
835
836static int rfcomm_queue_disc(struct rfcomm_dlc *d)
837{
838 struct rfcomm_cmd *cmd;
839 struct sk_buff *skb;
840
841 BT_DBG("dlc %p dlci %d", d, d->dlci);
842
843 skb = alloc_skb(sizeof(*cmd), GFP_KERNEL);
844 if (!skb)
845 return -ENOMEM;
846
847 cmd = (void *) __skb_put(skb, sizeof(*cmd));
848 cmd->addr = d->addr;
849 cmd->ctrl = __ctrl(RFCOMM_DISC, 1);
850 cmd->len = __len8(0);
851 cmd->fcs = __fcs2((u8 *) cmd);
852
853 skb_queue_tail(&d->tx_queue, skb);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300854 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 return 0;
856}
857
858static int rfcomm_send_dm(struct rfcomm_session *s, u8 dlci)
859{
860 struct rfcomm_cmd cmd;
861
862 BT_DBG("%p dlci %d", s, dlci);
863
864 cmd.addr = __addr(!s->initiator, dlci);
865 cmd.ctrl = __ctrl(RFCOMM_DM, 1);
866 cmd.len = __len8(0);
867 cmd.fcs = __fcs2((u8 *) &cmd);
868
Luiz Augusto von Dentz262038f2011-11-01 10:58:58 +0200869 return rfcomm_send_cmd(s, &cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870}
871
872static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type)
873{
874 struct rfcomm_hdr *hdr;
875 struct rfcomm_mcc *mcc;
876 u8 buf[16], *ptr = buf;
877
878 BT_DBG("%p cr %d type %d", s, cr, type);
879
880 hdr = (void *) ptr; ptr += sizeof(*hdr);
881 hdr->addr = __addr(s->initiator, 0);
882 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
883 hdr->len = __len8(sizeof(*mcc) + 1);
884
885 mcc = (void *) ptr; ptr += sizeof(*mcc);
886 mcc->type = __mcc_type(cr, RFCOMM_NSC);
887 mcc->len = __len8(1);
888
889 /* Type that we didn't like */
890 *ptr = __mcc_type(cr, type); ptr++;
891
892 *ptr = __fcs(buf); ptr++;
893
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200894 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895}
896
897static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d)
898{
899 struct rfcomm_hdr *hdr;
900 struct rfcomm_mcc *mcc;
901 struct rfcomm_pn *pn;
902 u8 buf[16], *ptr = buf;
903
904 BT_DBG("%p cr %d dlci %d mtu %d", s, cr, d->dlci, d->mtu);
905
906 hdr = (void *) ptr; ptr += sizeof(*hdr);
907 hdr->addr = __addr(s->initiator, 0);
908 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
909 hdr->len = __len8(sizeof(*mcc) + sizeof(*pn));
910
911 mcc = (void *) ptr; ptr += sizeof(*mcc);
912 mcc->type = __mcc_type(cr, RFCOMM_PN);
913 mcc->len = __len8(sizeof(*pn));
914
915 pn = (void *) ptr; ptr += sizeof(*pn);
916 pn->dlci = d->dlci;
917 pn->priority = d->priority;
918 pn->ack_timer = 0;
919 pn->max_retrans = 0;
920
921 if (s->cfc) {
922 pn->flow_ctrl = cr ? 0xf0 : 0xe0;
923 pn->credits = RFCOMM_DEFAULT_CREDITS;
924 } else {
925 pn->flow_ctrl = 0;
926 pn->credits = 0;
927 }
928
Marcel Holtmann98bcd082006-07-14 11:42:12 +0200929 if (cr && channel_mtu >= 0)
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200930 pn->mtu = cpu_to_le16(channel_mtu);
Marcel Holtmann98bcd082006-07-14 11:42:12 +0200931 else
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200932 pn->mtu = cpu_to_le16(d->mtu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700933
934 *ptr = __fcs(buf); ptr++;
935
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200936 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937}
938
J. Suter3a5e9032005-08-09 20:28:46 -0700939int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci,
940 u8 bit_rate, u8 data_bits, u8 stop_bits,
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900941 u8 parity, u8 flow_ctrl_settings,
J. Suter3a5e9032005-08-09 20:28:46 -0700942 u8 xon_char, u8 xoff_char, u16 param_mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943{
944 struct rfcomm_hdr *hdr;
945 struct rfcomm_mcc *mcc;
946 struct rfcomm_rpn *rpn;
947 u8 buf[16], *ptr = buf;
948
949 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 +0900950 " flwc_s 0x%x xon_c 0x%x xoff_c 0x%x p_mask 0x%x",
951 s, cr, dlci, bit_rate, data_bits, stop_bits, parity,
J. Suter3a5e9032005-08-09 20:28:46 -0700952 flow_ctrl_settings, xon_char, xoff_char, param_mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953
954 hdr = (void *) ptr; ptr += sizeof(*hdr);
955 hdr->addr = __addr(s->initiator, 0);
956 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
957 hdr->len = __len8(sizeof(*mcc) + sizeof(*rpn));
958
959 mcc = (void *) ptr; ptr += sizeof(*mcc);
960 mcc->type = __mcc_type(cr, RFCOMM_RPN);
961 mcc->len = __len8(sizeof(*rpn));
962
963 rpn = (void *) ptr; ptr += sizeof(*rpn);
964 rpn->dlci = __addr(1, dlci);
965 rpn->bit_rate = bit_rate;
966 rpn->line_settings = __rpn_line_settings(data_bits, stop_bits, parity);
967 rpn->flow_ctrl = flow_ctrl_settings;
968 rpn->xon_char = xon_char;
969 rpn->xoff_char = xoff_char;
Al Viroe8db8c92006-11-08 00:28:44 -0800970 rpn->param_mask = cpu_to_le16(param_mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971
972 *ptr = __fcs(buf); ptr++;
973
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200974 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975}
976
977static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status)
978{
979 struct rfcomm_hdr *hdr;
980 struct rfcomm_mcc *mcc;
981 struct rfcomm_rls *rls;
982 u8 buf[16], *ptr = buf;
983
984 BT_DBG("%p cr %d status 0x%x", s, cr, status);
985
986 hdr = (void *) ptr; ptr += sizeof(*hdr);
987 hdr->addr = __addr(s->initiator, 0);
988 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
989 hdr->len = __len8(sizeof(*mcc) + sizeof(*rls));
990
991 mcc = (void *) ptr; ptr += sizeof(*mcc);
992 mcc->type = __mcc_type(cr, RFCOMM_RLS);
993 mcc->len = __len8(sizeof(*rls));
994
995 rls = (void *) ptr; ptr += sizeof(*rls);
996 rls->dlci = __addr(1, dlci);
997 rls->status = status;
998
999 *ptr = __fcs(buf); ptr++;
1000
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001001 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002}
1003
1004static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig)
1005{
1006 struct rfcomm_hdr *hdr;
1007 struct rfcomm_mcc *mcc;
1008 struct rfcomm_msc *msc;
1009 u8 buf[16], *ptr = buf;
1010
1011 BT_DBG("%p cr %d v24 0x%x", s, cr, v24_sig);
1012
1013 hdr = (void *) ptr; ptr += sizeof(*hdr);
1014 hdr->addr = __addr(s->initiator, 0);
1015 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
1016 hdr->len = __len8(sizeof(*mcc) + sizeof(*msc));
1017
1018 mcc = (void *) ptr; ptr += sizeof(*mcc);
1019 mcc->type = __mcc_type(cr, RFCOMM_MSC);
1020 mcc->len = __len8(sizeof(*msc));
1021
1022 msc = (void *) ptr; ptr += sizeof(*msc);
1023 msc->dlci = __addr(1, dlci);
1024 msc->v24_sig = v24_sig | 0x01;
1025
1026 *ptr = __fcs(buf); ptr++;
1027
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001028 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029}
1030
1031static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr)
1032{
1033 struct rfcomm_hdr *hdr;
1034 struct rfcomm_mcc *mcc;
1035 u8 buf[16], *ptr = buf;
1036
1037 BT_DBG("%p cr %d", s, cr);
1038
1039 hdr = (void *) ptr; ptr += sizeof(*hdr);
1040 hdr->addr = __addr(s->initiator, 0);
1041 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
1042 hdr->len = __len8(sizeof(*mcc));
1043
1044 mcc = (void *) ptr; ptr += sizeof(*mcc);
1045 mcc->type = __mcc_type(cr, RFCOMM_FCOFF);
1046 mcc->len = __len8(0);
1047
1048 *ptr = __fcs(buf); ptr++;
1049
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001050 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051}
1052
1053static int rfcomm_send_fcon(struct rfcomm_session *s, int cr)
1054{
1055 struct rfcomm_hdr *hdr;
1056 struct rfcomm_mcc *mcc;
1057 u8 buf[16], *ptr = buf;
1058
1059 BT_DBG("%p cr %d", s, cr);
1060
1061 hdr = (void *) ptr; ptr += sizeof(*hdr);
1062 hdr->addr = __addr(s->initiator, 0);
1063 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
1064 hdr->len = __len8(sizeof(*mcc));
1065
1066 mcc = (void *) ptr; ptr += sizeof(*mcc);
1067 mcc->type = __mcc_type(cr, RFCOMM_FCON);
1068 mcc->len = __len8(0);
1069
1070 *ptr = __fcs(buf); ptr++;
1071
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001072 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073}
1074
1075static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len)
1076{
1077 struct socket *sock = s->sock;
1078 struct kvec iv[3];
1079 struct msghdr msg;
1080 unsigned char hdr[5], crc[1];
1081
1082 if (len > 125)
1083 return -EINVAL;
1084
1085 BT_DBG("%p cr %d", s, cr);
1086
1087 hdr[0] = __addr(s->initiator, 0);
1088 hdr[1] = __ctrl(RFCOMM_UIH, 0);
1089 hdr[2] = 0x01 | ((len + 2) << 1);
1090 hdr[3] = 0x01 | ((cr & 0x01) << 1) | (RFCOMM_TEST << 2);
1091 hdr[4] = 0x01 | (len << 1);
1092
1093 crc[0] = __fcs(hdr);
1094
1095 iv[0].iov_base = hdr;
1096 iv[0].iov_len = 5;
1097 iv[1].iov_base = pattern;
1098 iv[1].iov_len = len;
1099 iv[2].iov_base = crc;
1100 iv[2].iov_len = 1;
1101
1102 memset(&msg, 0, sizeof(msg));
1103
1104 return kernel_sendmsg(sock, &msg, iv, 3, 6 + len);
1105}
1106
1107static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits)
1108{
1109 struct rfcomm_hdr *hdr;
1110 u8 buf[16], *ptr = buf;
1111
1112 BT_DBG("%p addr %d credits %d", s, addr, credits);
1113
1114 hdr = (void *) ptr; ptr += sizeof(*hdr);
1115 hdr->addr = addr;
1116 hdr->ctrl = __ctrl(RFCOMM_UIH, 1);
1117 hdr->len = __len8(0);
1118
1119 *ptr = credits; ptr++;
1120
1121 *ptr = __fcs(buf); ptr++;
1122
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001123 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124}
1125
1126static void rfcomm_make_uih(struct sk_buff *skb, u8 addr)
1127{
1128 struct rfcomm_hdr *hdr;
1129 int len = skb->len;
1130 u8 *crc;
1131
1132 if (len > 127) {
1133 hdr = (void *) skb_push(skb, 4);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001134 put_unaligned(cpu_to_le16(__len16(len)), (__le16 *) &hdr->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135 } else {
1136 hdr = (void *) skb_push(skb, 3);
1137 hdr->len = __len8(len);
1138 }
1139 hdr->addr = addr;
1140 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
1141
1142 crc = skb_put(skb, 1);
1143 *crc = __fcs((void *) hdr);
1144}
1145
1146/* ---- RFCOMM frame reception ---- */
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001147static struct rfcomm_session *rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148{
1149 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1150
1151 if (dlci) {
1152 /* Data channel */
1153 struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
1154 if (!d) {
1155 rfcomm_send_dm(s, dlci);
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001156 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157 }
1158
1159 switch (d->state) {
1160 case BT_CONNECT:
1161 rfcomm_dlc_clear_timer(d);
1162
1163 rfcomm_dlc_lock(d);
1164 d->state = BT_CONNECTED;
1165 d->state_change(d, 0);
1166 rfcomm_dlc_unlock(d);
1167
1168 rfcomm_send_msc(s, 1, dlci, d->v24_sig);
1169 break;
1170
1171 case BT_DISCONN:
1172 d->state = BT_CLOSED;
1173 __rfcomm_dlc_close(d, 0);
Marcel Holtmann9cf5b0e2007-05-05 00:36:13 +02001174
1175 if (list_empty(&s->dlcs)) {
1176 s->state = BT_DISCONN;
1177 rfcomm_send_disc(s, 0);
Mat Martineau79e65472011-12-06 16:23:26 -08001178 rfcomm_session_clear_timer(s);
Marcel Holtmann9cf5b0e2007-05-05 00:36:13 +02001179 }
1180
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181 break;
1182 }
1183 } else {
1184 /* Control channel */
1185 switch (s->state) {
1186 case BT_CONNECT:
1187 s->state = BT_CONNECTED;
1188 rfcomm_process_connect(s);
1189 break;
Marcel Holtmann9cf5b0e2007-05-05 00:36:13 +02001190
1191 case BT_DISCONN:
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001192 s = rfcomm_session_close(s, ECONNRESET);
Marcel Holtmann9cf5b0e2007-05-05 00:36:13 +02001193 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194 }
1195 }
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001196 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197}
1198
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001199static struct rfcomm_session *rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200{
1201 int err = 0;
1202
1203 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1204
1205 if (dlci) {
1206 /* Data DLC */
1207 struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
1208 if (d) {
1209 if (d->state == BT_CONNECT || d->state == BT_CONFIG)
1210 err = ECONNREFUSED;
1211 else
1212 err = ECONNRESET;
1213
1214 d->state = BT_CLOSED;
1215 __rfcomm_dlc_close(d, err);
1216 }
1217 } else {
1218 if (s->state == BT_CONNECT)
1219 err = ECONNREFUSED;
1220 else
1221 err = ECONNRESET;
1222
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001223 s = rfcomm_session_close(s, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224 }
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001225 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226}
1227
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001228static struct rfcomm_session *rfcomm_recv_disc(struct rfcomm_session *s,
1229 u8 dlci)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230{
1231 int err = 0;
1232
1233 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1234
1235 if (dlci) {
1236 struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
1237 if (d) {
1238 rfcomm_send_ua(s, dlci);
1239
1240 if (d->state == BT_CONNECT || d->state == BT_CONFIG)
1241 err = ECONNREFUSED;
1242 else
1243 err = ECONNRESET;
1244
1245 d->state = BT_CLOSED;
1246 __rfcomm_dlc_close(d, err);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001247 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248 rfcomm_send_dm(s, dlci);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001249
Linus Torvalds1da177e2005-04-16 15:20:36 -07001250 } else {
1251 rfcomm_send_ua(s, 0);
1252
1253 if (s->state == BT_CONNECT)
1254 err = ECONNREFUSED;
1255 else
1256 err = ECONNRESET;
1257
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001258 s = rfcomm_session_close(s, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001259 }
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001260 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261}
1262
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001263void rfcomm_dlc_accept(struct rfcomm_dlc *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001264{
Marcel Holtmann300b9392006-07-03 10:37:55 +02001265 struct sock *sk = d->session->sock->sk;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001266 struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;
Marcel Holtmann300b9392006-07-03 10:37:55 +02001267
Linus Torvalds1da177e2005-04-16 15:20:36 -07001268 BT_DBG("dlc %p", d);
1269
1270 rfcomm_send_ua(d->session, d->dlci);
1271
Johan Hedberge2139b32009-03-26 16:41:56 +02001272 rfcomm_dlc_clear_timer(d);
1273
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274 rfcomm_dlc_lock(d);
1275 d->state = BT_CONNECTED;
1276 d->state_change(d, 0);
1277 rfcomm_dlc_unlock(d);
1278
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +01001279 if (d->role_switch)
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001280 hci_conn_switch_role(conn->hcon, 0x00);
Marcel Holtmann300b9392006-07-03 10:37:55 +02001281
Linus Torvalds1da177e2005-04-16 15:20:36 -07001282 rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
1283}
1284
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001285static void rfcomm_check_accept(struct rfcomm_dlc *d)
1286{
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +01001287 if (rfcomm_check_security(d)) {
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001288 if (d->defer_setup) {
1289 set_bit(RFCOMM_DEFER_SETUP, &d->flags);
1290 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
Marcel Holtmann8bf47942009-02-16 02:59:49 +01001291
1292 rfcomm_dlc_lock(d);
1293 d->state = BT_CONNECT2;
1294 d->state_change(d, 0);
1295 rfcomm_dlc_unlock(d);
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001296 } else
1297 rfcomm_dlc_accept(d);
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001298 } else {
1299 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
1300 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001301 }
1302}
1303
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
1305{
1306 struct rfcomm_dlc *d;
1307 u8 channel;
1308
1309 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1310
1311 if (!dlci) {
1312 rfcomm_send_ua(s, 0);
1313
1314 if (s->state == BT_OPEN) {
1315 s->state = BT_CONNECTED;
1316 rfcomm_process_connect(s);
1317 }
1318 return 0;
1319 }
1320
1321 /* Check if DLC exists */
1322 d = rfcomm_dlc_get(s, dlci);
1323 if (d) {
1324 if (d->state == BT_OPEN) {
1325 /* DLC was previously opened by PN request */
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001326 rfcomm_check_accept(d);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327 }
1328 return 0;
1329 }
1330
1331 /* Notify socket layer about incoming connection */
1332 channel = __srv_channel(dlci);
1333 if (rfcomm_connect_ind(s, channel, &d)) {
1334 d->dlci = dlci;
1335 d->addr = __addr(s->initiator, dlci);
1336 rfcomm_dlc_link(s, d);
1337
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001338 rfcomm_check_accept(d);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339 } else {
1340 rfcomm_send_dm(s, dlci);
1341 }
1342
1343 return 0;
1344}
1345
1346static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn)
1347{
1348 struct rfcomm_session *s = d->session;
1349
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001350 BT_DBG("dlc %p state %ld dlci %d mtu %d fc 0x%x credits %d",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351 d, d->state, d->dlci, pn->mtu, pn->flow_ctrl, pn->credits);
1352
Marcel Holtmann7c2660b2006-07-03 10:02:51 +02001353 if ((pn->flow_ctrl == 0xf0 && s->cfc != RFCOMM_CFC_DISABLED) ||
1354 pn->flow_ctrl == 0xe0) {
1355 d->cfc = RFCOMM_CFC_ENABLED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356 d->tx_credits = pn->credits;
1357 } else {
Marcel Holtmann7c2660b2006-07-03 10:02:51 +02001358 d->cfc = RFCOMM_CFC_DISABLED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359 set_bit(RFCOMM_TX_THROTTLED, &d->flags);
1360 }
1361
Marcel Holtmann7c2660b2006-07-03 10:02:51 +02001362 if (s->cfc == RFCOMM_CFC_UNKNOWN)
1363 s->cfc = d->cfc;
1364
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365 d->priority = pn->priority;
1366
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001367 d->mtu = __le16_to_cpu(pn->mtu);
Marcel Holtmann98bcd082006-07-14 11:42:12 +02001368
1369 if (cr && d->mtu > s->mtu)
1370 d->mtu = s->mtu;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001371
1372 return 0;
1373}
1374
1375static int rfcomm_recv_pn(struct rfcomm_session *s, int cr, struct sk_buff *skb)
1376{
1377 struct rfcomm_pn *pn = (void *) skb->data;
1378 struct rfcomm_dlc *d;
1379 u8 dlci = pn->dlci;
1380
1381 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1382
1383 if (!dlci)
1384 return 0;
1385
1386 d = rfcomm_dlc_get(s, dlci);
1387 if (d) {
1388 if (cr) {
1389 /* PN request */
1390 rfcomm_apply_pn(d, cr, pn);
1391 rfcomm_send_pn(s, 0, d);
1392 } else {
1393 /* PN response */
1394 switch (d->state) {
1395 case BT_CONFIG:
1396 rfcomm_apply_pn(d, cr, pn);
1397
1398 d->state = BT_CONNECT;
1399 rfcomm_send_sabm(s, d->dlci);
1400 break;
1401 }
1402 }
1403 } else {
1404 u8 channel = __srv_channel(dlci);
1405
1406 if (!cr)
1407 return 0;
1408
1409 /* PN request for non existing DLC.
1410 * Assume incoming connection. */
1411 if (rfcomm_connect_ind(s, channel, &d)) {
1412 d->dlci = dlci;
1413 d->addr = __addr(s->initiator, dlci);
1414 rfcomm_dlc_link(s, d);
1415
1416 rfcomm_apply_pn(d, cr, pn);
1417
1418 d->state = BT_OPEN;
1419 rfcomm_send_pn(s, 0, d);
1420 } else {
1421 rfcomm_send_dm(s, dlci);
1422 }
1423 }
1424 return 0;
1425}
1426
1427static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_buff *skb)
1428{
1429 struct rfcomm_rpn *rpn = (void *) skb->data;
1430 u8 dlci = __get_dlci(rpn->dlci);
1431
1432 u8 bit_rate = 0;
1433 u8 data_bits = 0;
1434 u8 stop_bits = 0;
1435 u8 parity = 0;
1436 u8 flow_ctrl = 0;
1437 u8 xon_char = 0;
1438 u8 xoff_char = 0;
1439 u16 rpn_mask = RFCOMM_RPN_PM_ALL;
J. Suter3a5e9032005-08-09 20:28:46 -07001440
1441 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",
1442 dlci, cr, len, rpn->bit_rate, rpn->line_settings, rpn->flow_ctrl,
1443 rpn->xon_char, rpn->xoff_char, rpn->param_mask);
1444
1445 if (!cr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446 return 0;
J. Suter3a5e9032005-08-09 20:28:46 -07001447
Linus Torvalds1da177e2005-04-16 15:20:36 -07001448 if (len == 1) {
Yuri Kululin08601462010-07-23 13:57:12 +04001449 /* This is a request, return default (according to ETSI TS 07.10) settings */
1450 bit_rate = RFCOMM_RPN_BR_9600;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451 data_bits = RFCOMM_RPN_DATA_8;
1452 stop_bits = RFCOMM_RPN_STOP_1;
1453 parity = RFCOMM_RPN_PARITY_NONE;
1454 flow_ctrl = RFCOMM_RPN_FLOW_NONE;
1455 xon_char = RFCOMM_RPN_XON_CHAR;
1456 xoff_char = RFCOMM_RPN_XOFF_CHAR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001457 goto rpn_out;
1458 }
J. Suter3a5e9032005-08-09 20:28:46 -07001459
1460 /* Check for sane values, ignore/accept bit_rate, 8 bits, 1 stop bit,
1461 * no parity, no flow control lines, normal XON/XOFF chars */
1462
Al Viroe8db8c92006-11-08 00:28:44 -08001463 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_BITRATE)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464 bit_rate = rpn->bit_rate;
Yuri Kululin08601462010-07-23 13:57:12 +04001465 if (bit_rate > RFCOMM_RPN_BR_230400) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466 BT_DBG("RPN bit rate mismatch 0x%x", bit_rate);
Yuri Kululin08601462010-07-23 13:57:12 +04001467 bit_rate = RFCOMM_RPN_BR_9600;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468 rpn_mask ^= RFCOMM_RPN_PM_BITRATE;
1469 }
1470 }
J. Suter3a5e9032005-08-09 20:28:46 -07001471
Al Viroe8db8c92006-11-08 00:28:44 -08001472 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_DATA)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473 data_bits = __get_rpn_data_bits(rpn->line_settings);
1474 if (data_bits != RFCOMM_RPN_DATA_8) {
1475 BT_DBG("RPN data bits mismatch 0x%x", data_bits);
1476 data_bits = RFCOMM_RPN_DATA_8;
1477 rpn_mask ^= RFCOMM_RPN_PM_DATA;
1478 }
1479 }
J. Suter3a5e9032005-08-09 20:28:46 -07001480
Al Viroe8db8c92006-11-08 00:28:44 -08001481 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_STOP)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001482 stop_bits = __get_rpn_stop_bits(rpn->line_settings);
1483 if (stop_bits != RFCOMM_RPN_STOP_1) {
1484 BT_DBG("RPN stop bits mismatch 0x%x", stop_bits);
1485 stop_bits = RFCOMM_RPN_STOP_1;
1486 rpn_mask ^= RFCOMM_RPN_PM_STOP;
1487 }
1488 }
J. Suter3a5e9032005-08-09 20:28:46 -07001489
Al Viroe8db8c92006-11-08 00:28:44 -08001490 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_PARITY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491 parity = __get_rpn_parity(rpn->line_settings);
1492 if (parity != RFCOMM_RPN_PARITY_NONE) {
1493 BT_DBG("RPN parity mismatch 0x%x", parity);
1494 parity = RFCOMM_RPN_PARITY_NONE;
1495 rpn_mask ^= RFCOMM_RPN_PM_PARITY;
1496 }
1497 }
J. Suter3a5e9032005-08-09 20:28:46 -07001498
Al Viroe8db8c92006-11-08 00:28:44 -08001499 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_FLOW)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500 flow_ctrl = rpn->flow_ctrl;
1501 if (flow_ctrl != RFCOMM_RPN_FLOW_NONE) {
1502 BT_DBG("RPN flow ctrl mismatch 0x%x", flow_ctrl);
1503 flow_ctrl = RFCOMM_RPN_FLOW_NONE;
1504 rpn_mask ^= RFCOMM_RPN_PM_FLOW;
1505 }
1506 }
J. Suter3a5e9032005-08-09 20:28:46 -07001507
Al Viroe8db8c92006-11-08 00:28:44 -08001508 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_XON)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509 xon_char = rpn->xon_char;
1510 if (xon_char != RFCOMM_RPN_XON_CHAR) {
1511 BT_DBG("RPN XON char mismatch 0x%x", xon_char);
1512 xon_char = RFCOMM_RPN_XON_CHAR;
1513 rpn_mask ^= RFCOMM_RPN_PM_XON;
1514 }
1515 }
J. Suter3a5e9032005-08-09 20:28:46 -07001516
Al Viroe8db8c92006-11-08 00:28:44 -08001517 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_XOFF)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518 xoff_char = rpn->xoff_char;
1519 if (xoff_char != RFCOMM_RPN_XOFF_CHAR) {
1520 BT_DBG("RPN XOFF char mismatch 0x%x", xoff_char);
1521 xoff_char = RFCOMM_RPN_XOFF_CHAR;
1522 rpn_mask ^= RFCOMM_RPN_PM_XOFF;
1523 }
1524 }
1525
1526rpn_out:
J. Suter3a5e9032005-08-09 20:28:46 -07001527 rfcomm_send_rpn(s, 0, dlci, bit_rate, data_bits, stop_bits,
1528 parity, flow_ctrl, xon_char, xoff_char, rpn_mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529
1530 return 0;
1531}
1532
1533static int rfcomm_recv_rls(struct rfcomm_session *s, int cr, struct sk_buff *skb)
1534{
1535 struct rfcomm_rls *rls = (void *) skb->data;
1536 u8 dlci = __get_dlci(rls->dlci);
1537
1538 BT_DBG("dlci %d cr %d status 0x%x", dlci, cr, rls->status);
J. Suter3a5e9032005-08-09 20:28:46 -07001539
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540 if (!cr)
1541 return 0;
1542
J. Suter3a5e9032005-08-09 20:28:46 -07001543 /* We should probably do something with this information here. But
1544 * for now it's sufficient just to reply -- Bluetooth 1.1 says it's
1545 * mandatory to recognise and respond to RLS */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546
1547 rfcomm_send_rls(s, 0, dlci, rls->status);
1548
1549 return 0;
1550}
1551
1552static int rfcomm_recv_msc(struct rfcomm_session *s, int cr, struct sk_buff *skb)
1553{
1554 struct rfcomm_msc *msc = (void *) skb->data;
1555 struct rfcomm_dlc *d;
1556 u8 dlci = __get_dlci(msc->dlci);
1557
1558 BT_DBG("dlci %d cr %d v24 0x%x", dlci, cr, msc->v24_sig);
1559
1560 d = rfcomm_dlc_get(s, dlci);
J. Suter3a5e9032005-08-09 20:28:46 -07001561 if (!d)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562 return 0;
1563
1564 if (cr) {
1565 if (msc->v24_sig & RFCOMM_V24_FC && !d->cfc)
1566 set_bit(RFCOMM_TX_THROTTLED, &d->flags);
1567 else
1568 clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
J. Suter3a5e9032005-08-09 20:28:46 -07001569
Linus Torvalds1da177e2005-04-16 15:20:36 -07001570 rfcomm_dlc_lock(d);
Marcel Holtmann8b6b3da2008-07-14 20:13:52 +02001571
1572 d->remote_v24_sig = msc->v24_sig;
1573
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 if (d->modem_status)
1575 d->modem_status(d, msc->v24_sig);
Marcel Holtmann8b6b3da2008-07-14 20:13:52 +02001576
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 rfcomm_dlc_unlock(d);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001578
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579 rfcomm_send_msc(s, 0, dlci, msc->v24_sig);
1580
1581 d->mscex |= RFCOMM_MSCEX_RX;
J. Suter3a5e9032005-08-09 20:28:46 -07001582 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583 d->mscex |= RFCOMM_MSCEX_TX;
1584
1585 return 0;
1586}
1587
1588static int rfcomm_recv_mcc(struct rfcomm_session *s, struct sk_buff *skb)
1589{
1590 struct rfcomm_mcc *mcc = (void *) skb->data;
1591 u8 type, cr, len;
1592
1593 cr = __test_cr(mcc->type);
1594 type = __get_mcc_type(mcc->type);
1595 len = __get_mcc_len(mcc->len);
1596
1597 BT_DBG("%p type 0x%x cr %d", s, type, cr);
1598
1599 skb_pull(skb, 2);
1600
1601 switch (type) {
1602 case RFCOMM_PN:
1603 rfcomm_recv_pn(s, cr, skb);
1604 break;
1605
1606 case RFCOMM_RPN:
1607 rfcomm_recv_rpn(s, cr, len, skb);
1608 break;
1609
1610 case RFCOMM_RLS:
1611 rfcomm_recv_rls(s, cr, skb);
1612 break;
1613
1614 case RFCOMM_MSC:
1615 rfcomm_recv_msc(s, cr, skb);
1616 break;
1617
1618 case RFCOMM_FCOFF:
1619 if (cr) {
1620 set_bit(RFCOMM_TX_THROTTLED, &s->flags);
1621 rfcomm_send_fcoff(s, 0);
1622 }
1623 break;
1624
1625 case RFCOMM_FCON:
1626 if (cr) {
1627 clear_bit(RFCOMM_TX_THROTTLED, &s->flags);
1628 rfcomm_send_fcon(s, 0);
1629 }
1630 break;
1631
1632 case RFCOMM_TEST:
1633 if (cr)
1634 rfcomm_send_test(s, 0, skb->data, skb->len);
1635 break;
1636
1637 case RFCOMM_NSC:
1638 break;
1639
1640 default:
1641 BT_ERR("Unknown control type 0x%02x", type);
1642 rfcomm_send_nsc(s, cr, type);
1643 break;
1644 }
1645 return 0;
1646}
1647
1648static int rfcomm_recv_data(struct rfcomm_session *s, u8 dlci, int pf, struct sk_buff *skb)
1649{
1650 struct rfcomm_dlc *d;
1651
1652 BT_DBG("session %p state %ld dlci %d pf %d", s, s->state, dlci, pf);
1653
1654 d = rfcomm_dlc_get(s, dlci);
1655 if (!d) {
1656 rfcomm_send_dm(s, dlci);
1657 goto drop;
1658 }
1659
1660 if (pf && d->cfc) {
1661 u8 credits = *(u8 *) skb->data; skb_pull(skb, 1);
1662
1663 d->tx_credits += credits;
1664 if (d->tx_credits)
1665 clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
1666 }
1667
1668 if (skb->len && d->state == BT_CONNECTED) {
1669 rfcomm_dlc_lock(d);
1670 d->rx_credits--;
1671 d->data_ready(d, skb);
1672 rfcomm_dlc_unlock(d);
1673 return 0;
1674 }
1675
1676drop:
1677 kfree_skb(skb);
1678 return 0;
1679}
1680
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001681static struct rfcomm_session *rfcomm_recv_frame(struct rfcomm_session *s,
1682 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683{
1684 struct rfcomm_hdr *hdr = (void *) skb->data;
1685 u8 type, dlci, fcs;
1686
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001687 if (!s) {
1688 /* no session, so free socket data */
1689 kfree_skb(skb);
1690 return s;
1691 }
1692
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693 dlci = __get_dlci(hdr->addr);
1694 type = __get_type(hdr->ctrl);
1695
1696 /* Trim FCS */
1697 skb->len--; skb->tail--;
Arnaldo Carvalho de Melo27a884d2007-04-19 20:29:13 -07001698 fcs = *(u8 *)skb_tail_pointer(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699
1700 if (__check_fcs(skb->data, type, fcs)) {
1701 BT_ERR("bad checksum in packet");
1702 kfree_skb(skb);
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001703 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704 }
1705
1706 if (__test_ea(hdr->len))
1707 skb_pull(skb, 3);
1708 else
1709 skb_pull(skb, 4);
1710
1711 switch (type) {
1712 case RFCOMM_SABM:
1713 if (__test_pf(hdr->ctrl))
1714 rfcomm_recv_sabm(s, dlci);
1715 break;
1716
1717 case RFCOMM_DISC:
1718 if (__test_pf(hdr->ctrl))
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001719 s = rfcomm_recv_disc(s, dlci);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 break;
1721
1722 case RFCOMM_UA:
1723 if (__test_pf(hdr->ctrl))
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001724 s = rfcomm_recv_ua(s, dlci);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 break;
1726
1727 case RFCOMM_DM:
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001728 s = rfcomm_recv_dm(s, dlci);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 break;
1730
1731 case RFCOMM_UIH:
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001732 if (dlci) {
1733 rfcomm_recv_data(s, dlci, __test_pf(hdr->ctrl), skb);
1734 return s;
1735 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736 rfcomm_recv_mcc(s, skb);
1737 break;
1738
1739 default:
Andrei Emeltchenko5017d8d2010-09-08 16:26:53 +03001740 BT_ERR("Unknown packet type 0x%02x", type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 break;
1742 }
1743 kfree_skb(skb);
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001744 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745}
1746
1747/* ---- Connection and data processing ---- */
1748
1749static void rfcomm_process_connect(struct rfcomm_session *s)
1750{
1751 struct rfcomm_dlc *d;
1752 struct list_head *p, *n;
1753
1754 BT_DBG("session %p state %ld", s, s->state);
1755
1756 list_for_each_safe(p, n, &s->dlcs) {
1757 d = list_entry(p, struct rfcomm_dlc, list);
1758 if (d->state == BT_CONFIG) {
1759 d->mtu = s->mtu;
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +01001760 if (rfcomm_check_security(d)) {
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001761 rfcomm_send_pn(s, 1, d);
1762 } else {
Marcel Holtmann77db1982008-07-14 20:13:45 +02001763 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
1764 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001765 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766 }
1767 }
1768}
1769
1770/* Send data queued for the DLC.
1771 * Return number of frames left in the queue.
1772 */
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001773static int rfcomm_process_tx(struct rfcomm_dlc *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774{
1775 struct sk_buff *skb;
1776 int err;
1777
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001778 BT_DBG("dlc %p state %ld cfc %d rx_credits %d tx_credits %d",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 d, d->state, d->cfc, d->rx_credits, d->tx_credits);
1780
1781 /* Send pending MSC */
1782 if (test_and_clear_bit(RFCOMM_MSC_PENDING, &d->flags))
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001783 rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784
1785 if (d->cfc) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001786 /* CFC enabled.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787 * Give them some credits */
1788 if (!test_bit(RFCOMM_RX_THROTTLED, &d->flags) &&
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001789 d->rx_credits <= (d->cfc >> 2)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790 rfcomm_send_credits(d->session, d->addr, d->cfc - d->rx_credits);
1791 d->rx_credits = d->cfc;
1792 }
1793 } else {
1794 /* CFC disabled.
1795 * Give ourselves some credits */
1796 d->tx_credits = 5;
1797 }
1798
1799 if (test_bit(RFCOMM_TX_THROTTLED, &d->flags))
1800 return skb_queue_len(&d->tx_queue);
1801
1802 while (d->tx_credits && (skb = skb_dequeue(&d->tx_queue))) {
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001803 err = rfcomm_send_frame(d->session, skb->data, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804 if (err < 0) {
1805 skb_queue_head(&d->tx_queue, skb);
1806 break;
1807 }
1808 kfree_skb(skb);
1809 d->tx_credits--;
1810 }
1811
1812 if (d->cfc && !d->tx_credits) {
1813 /* We're out of TX credits.
1814 * Set TX_THROTTLED flag to avoid unnesary wakeups by dlc_send. */
1815 set_bit(RFCOMM_TX_THROTTLED, &d->flags);
1816 }
1817
1818 return skb_queue_len(&d->tx_queue);
1819}
1820
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001821static void rfcomm_process_dlcs(struct rfcomm_session *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822{
1823 struct rfcomm_dlc *d;
1824 struct list_head *p, *n;
1825
1826 BT_DBG("session %p state %ld", s, s->state);
1827
1828 list_for_each_safe(p, n, &s->dlcs) {
1829 d = list_entry(p, struct rfcomm_dlc, list);
1830
1831 if (test_bit(RFCOMM_TIMED_OUT, &d->flags)) {
1832 __rfcomm_dlc_close(d, ETIMEDOUT);
1833 continue;
1834 }
1835
Szymon Jancdb544672011-09-26 14:19:47 +02001836 if (test_bit(RFCOMM_ENC_DROP, &d->flags)) {
1837 __rfcomm_dlc_close(d, ECONNREFUSED);
1838 continue;
1839 }
1840
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 if (test_and_clear_bit(RFCOMM_AUTH_ACCEPT, &d->flags)) {
1842 rfcomm_dlc_clear_timer(d);
Marcel Holtmann77db1982008-07-14 20:13:45 +02001843 if (d->out) {
1844 rfcomm_send_pn(s, 1, d);
1845 rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT);
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001846 } else {
1847 if (d->defer_setup) {
1848 set_bit(RFCOMM_DEFER_SETUP, &d->flags);
1849 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
Marcel Holtmann8bf47942009-02-16 02:59:49 +01001850
1851 rfcomm_dlc_lock(d);
1852 d->state = BT_CONNECT2;
1853 d->state_change(d, 0);
1854 rfcomm_dlc_unlock(d);
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001855 } else
1856 rfcomm_dlc_accept(d);
1857 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858 continue;
1859 } else if (test_and_clear_bit(RFCOMM_AUTH_REJECT, &d->flags)) {
1860 rfcomm_dlc_clear_timer(d);
Marcel Holtmann77db1982008-07-14 20:13:45 +02001861 if (!d->out)
1862 rfcomm_send_dm(s, d->dlci);
1863 else
1864 d->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865 __rfcomm_dlc_close(d, ECONNREFUSED);
1866 continue;
1867 }
1868
Jaikumar Ganesh6e1031a2009-02-02 18:03:57 -08001869 if (test_bit(RFCOMM_SEC_PENDING, &d->flags))
1870 continue;
1871
Linus Torvalds1da177e2005-04-16 15:20:36 -07001872 if (test_bit(RFCOMM_TX_THROTTLED, &s->flags))
1873 continue;
1874
1875 if ((d->state == BT_CONNECTED || d->state == BT_DISCONN) &&
Marcel Holtmann77db1982008-07-14 20:13:45 +02001876 d->mscex == RFCOMM_MSCEX_OK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877 rfcomm_process_tx(d);
1878 }
1879}
1880
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001881static struct rfcomm_session *rfcomm_process_rx(struct rfcomm_session *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882{
1883 struct socket *sock = s->sock;
1884 struct sock *sk = sock->sk;
1885 struct sk_buff *skb;
1886
1887 BT_DBG("session %p state %ld qlen %d", s, s->state, skb_queue_len(&sk->sk_receive_queue));
1888
1889 /* Get data directly from socket receive queue without copying it. */
1890 while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
1891 skb_orphan(skb);
Mat Martineau44935722011-07-22 14:53:58 -07001892 if (!skb_linearize(skb))
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001893 s = rfcomm_recv_frame(s, skb);
Mat Martineau44935722011-07-22 14:53:58 -07001894 else
1895 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896 }
1897
Dean Jenkins08c30ac2013-02-28 14:21:56 +00001898 if (s && (sk->sk_state == BT_CLOSED))
1899 s = rfcomm_session_close(s, sk->sk_err);
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001900
1901 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902}
1903
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001904static void rfcomm_accept_connection(struct rfcomm_session *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905{
1906 struct socket *sock = s->sock, *nsock;
1907 int err;
1908
1909 /* Fast check for a new connection.
1910 * Avoids unnesesary socket allocations. */
1911 if (list_empty(&bt_sk(sock->sk)->accept_q))
1912 return;
1913
1914 BT_DBG("session %p", s);
1915
Marcel Holtmann48db9ca2007-05-05 00:36:06 +02001916 err = kernel_accept(sock, &nsock, O_NONBLOCK);
1917 if (err < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918 return;
1919
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920 /* Set our callbacks */
1921 nsock->sk->sk_data_ready = rfcomm_l2data_ready;
1922 nsock->sk->sk_state_change = rfcomm_l2state_change;
1923
1924 s = rfcomm_session_add(nsock, BT_OPEN);
1925 if (s) {
Marcel Holtmann98bcd082006-07-14 11:42:12 +02001926 /* We should adjust MTU on incoming sessions.
1927 * L2CAP MTU minus UIH header and FCS. */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001928 s->mtu = min(l2cap_pi(nsock->sk)->chan->omtu,
1929 l2cap_pi(nsock->sk)->chan->imtu) - 5;
Marcel Holtmann98bcd082006-07-14 11:42:12 +02001930
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +03001931 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001932 } else
1933 sock_release(nsock);
1934}
1935
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001936static struct rfcomm_session *rfcomm_check_connection(struct rfcomm_session *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001937{
1938 struct sock *sk = s->sock->sk;
1939
1940 BT_DBG("%p state %ld", s, s->state);
1941
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +02001942 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943 case BT_CONNECTED:
1944 s->state = BT_CONNECT;
1945
1946 /* We can adjust MTU on outgoing sessions.
1947 * L2CAP MTU minus UIH header and FCS. */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001948 s->mtu = min(l2cap_pi(sk)->chan->omtu, l2cap_pi(sk)->chan->imtu) - 5;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949
1950 rfcomm_send_sabm(s, 0);
1951 break;
1952
1953 case BT_CLOSED:
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001954 s = rfcomm_session_close(s, sk->sk_err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001955 break;
1956 }
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001957 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958}
1959
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001960static void rfcomm_process_sessions(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961{
1962 struct list_head *p, *n;
1963
1964 rfcomm_lock();
1965
1966 list_for_each_safe(p, n, &session_list) {
1967 struct rfcomm_session *s;
1968 s = list_entry(p, struct rfcomm_session, list);
1969
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -03001970 if (test_and_clear_bit(RFCOMM_TIMED_OUT, &s->flags)) {
1971 s->state = BT_DISCONN;
1972 rfcomm_send_disc(s, 0);
1973 continue;
1974 }
1975
Peter Hurley4339c252014-02-09 20:59:11 -05001976 switch (s->state) {
1977 case BT_LISTEN:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001978 rfcomm_accept_connection(s);
1979 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001980
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981 case BT_BOUND:
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001982 s = rfcomm_check_connection(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001983 break;
1984
1985 default:
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001986 s = rfcomm_process_rx(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001987 break;
1988 }
1989
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001990 if (s)
1991 rfcomm_process_dlcs(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001992 }
1993
1994 rfcomm_unlock();
1995}
1996
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997static int rfcomm_add_listener(bdaddr_t *ba)
1998{
1999 struct sockaddr_l2 addr;
2000 struct socket *sock;
2001 struct sock *sk;
2002 struct rfcomm_session *s;
2003 int err = 0;
2004
2005 /* Create socket */
2006 err = rfcomm_l2sock_create(&sock);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002007 if (err < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002008 BT_ERR("Create socket failed %d", err);
2009 return err;
2010 }
2011
2012 /* Bind socket */
2013 bacpy(&addr.l2_bdaddr, ba);
2014 addr.l2_family = AF_BLUETOOTH;
Syam Sidhardhan5bcb8092012-10-10 22:09:29 +05302015 addr.l2_psm = __constant_cpu_to_le16(RFCOMM_PSM);
Marcel Holtmann37e62f52009-02-17 21:49:33 +01002016 addr.l2_cid = 0;
Seung-Woo Kimc507f132013-11-05 16:02:24 +09002017 addr.l2_bdaddr_type = BDADDR_BREDR;
Marcel Holtmann48db9ca2007-05-05 00:36:06 +02002018 err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002019 if (err < 0) {
2020 BT_ERR("Bind failed %d", err);
2021 goto failed;
2022 }
2023
2024 /* Set L2CAP options */
2025 sk = sock->sk;
2026 lock_sock(sk);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002027 l2cap_pi(sk)->chan->imtu = l2cap_mtu;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002028 release_sock(sk);
2029
2030 /* Start listening on the socket */
Marcel Holtmann48db9ca2007-05-05 00:36:06 +02002031 err = kernel_listen(sock, 10);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002032 if (err) {
2033 BT_ERR("Listen failed %d", err);
2034 goto failed;
2035 }
2036
2037 /* Add listening session */
2038 s = rfcomm_session_add(sock, BT_LISTEN);
Wei Yongjun0227c7b2013-03-20 20:23:37 +08002039 if (!s) {
2040 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002041 goto failed;
Wei Yongjun0227c7b2013-03-20 20:23:37 +08002042 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002043
Linus Torvalds1da177e2005-04-16 15:20:36 -07002044 return 0;
2045failed:
2046 sock_release(sock);
2047 return err;
2048}
2049
2050static void rfcomm_kill_listener(void)
2051{
2052 struct rfcomm_session *s;
2053 struct list_head *p, *n;
2054
2055 BT_DBG("");
2056
2057 list_for_each_safe(p, n, &session_list) {
2058 s = list_entry(p, struct rfcomm_session, list);
2059 rfcomm_session_del(s);
2060 }
2061}
2062
2063static int rfcomm_run(void *unused)
2064{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002065 BT_DBG("");
2066
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002067 set_user_nice(current, -10);
2068
Linus Torvalds1da177e2005-04-16 15:20:36 -07002069 rfcomm_add_listener(BDADDR_ANY);
2070
Peter Hurleye5842cd2011-07-24 00:10:35 -04002071 while (1) {
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002072 set_current_state(TASK_INTERRUPTIBLE);
Peter Hurleye5842cd2011-07-24 00:10:35 -04002073
2074 if (kthread_should_stop())
2075 break;
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002076
2077 /* Process stuff */
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002078 rfcomm_process_sessions();
Peter Hurleye5842cd2011-07-24 00:10:35 -04002079
2080 schedule();
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002081 }
Peter Hurleye5842cd2011-07-24 00:10:35 -04002082 __set_current_state(TASK_RUNNING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002083
2084 rfcomm_kill_listener();
2085
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086 return 0;
2087}
2088
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01002089static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002090{
2091 struct rfcomm_session *s;
2092 struct rfcomm_dlc *d;
2093 struct list_head *p, *n;
2094
2095 BT_DBG("conn %p status 0x%02x encrypt 0x%02x", conn, status, encrypt);
2096
2097 s = rfcomm_session_get(&conn->hdev->bdaddr, &conn->dst);
2098 if (!s)
2099 return;
2100
Linus Torvalds1da177e2005-04-16 15:20:36 -07002101 list_for_each_safe(p, n, &s->dlcs) {
2102 d = list_entry(p, struct rfcomm_dlc, list);
2103
Marcel Holtmann8c84b832009-01-16 08:17:51 +01002104 if (test_and_clear_bit(RFCOMM_SEC_PENDING, &d->flags)) {
2105 rfcomm_dlc_clear_timer(d);
2106 if (status || encrypt == 0x00) {
Szymon Jancdb544672011-09-26 14:19:47 +02002107 set_bit(RFCOMM_ENC_DROP, &d->flags);
Marcel Holtmann8c84b832009-01-16 08:17:51 +01002108 continue;
2109 }
2110 }
2111
2112 if (d->state == BT_CONNECTED && !status && encrypt == 0x00) {
2113 if (d->sec_level == BT_SECURITY_MEDIUM) {
2114 set_bit(RFCOMM_SEC_PENDING, &d->flags);
2115 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
2116 continue;
Marcel Holtmann2c068e02014-01-15 22:37:41 -08002117 } else if (d->sec_level == BT_SECURITY_HIGH ||
2118 d->sec_level == BT_SECURITY_FIPS) {
Szymon Jancdb544672011-09-26 14:19:47 +02002119 set_bit(RFCOMM_ENC_DROP, &d->flags);
Marcel Holtmann8c84b832009-01-16 08:17:51 +01002120 continue;
2121 }
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02002122 }
2123
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124 if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags))
2125 continue;
2126
Waldemar Rymarkiewiczb3b1b062011-05-06 09:42:31 +02002127 if (!status && hci_conn_check_secure(conn, d->sec_level))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002128 set_bit(RFCOMM_AUTH_ACCEPT, &d->flags);
2129 else
2130 set_bit(RFCOMM_AUTH_REJECT, &d->flags);
2131 }
2132
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +03002133 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002134}
2135
2136static struct hci_cb rfcomm_cb = {
2137 .name = "RFCOMM",
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01002138 .security_cfm = rfcomm_security_cfm
Linus Torvalds1da177e2005-04-16 15:20:36 -07002139};
2140
Marcel Holtmannaef7d972010-03-21 05:27:45 +01002141static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002142{
2143 struct rfcomm_session *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002144
2145 rfcomm_lock();
2146
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +02002147 list_for_each_entry(s, &session_list, list) {
Marcel Holtmann24bc10c2013-10-13 09:49:54 -07002148 struct l2cap_chan *chan = l2cap_pi(s->sock->sk)->chan;
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +02002149 struct rfcomm_dlc *d;
2150 list_for_each_entry(d, &s->dlcs, list) {
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03002151 seq_printf(f, "%pMR %pMR %ld %d %d %d %d\n",
Marcel Holtmann24bc10c2013-10-13 09:49:54 -07002152 &chan->src, &chan->dst,
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03002153 d->state, d->dlci, d->mtu,
2154 d->rx_credits, d->tx_credits);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002155 }
2156 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002157
Linus Torvalds1da177e2005-04-16 15:20:36 -07002158 rfcomm_unlock();
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08002159
Marcel Holtmannaef7d972010-03-21 05:27:45 +01002160 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002161}
2162
Marcel Holtmannaef7d972010-03-21 05:27:45 +01002163static int rfcomm_dlc_debugfs_open(struct inode *inode, struct file *file)
2164{
2165 return single_open(file, rfcomm_dlc_debugfs_show, inode->i_private);
2166}
2167
2168static const struct file_operations rfcomm_dlc_debugfs_fops = {
2169 .open = rfcomm_dlc_debugfs_open,
2170 .read = seq_read,
2171 .llseek = seq_lseek,
2172 .release = single_release,
2173};
2174
2175static struct dentry *rfcomm_dlc_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002176
2177/* ---- Initialization ---- */
2178static int __init rfcomm_init(void)
2179{
Marcel Holtmann52d18342009-08-22 14:49:36 -07002180 int err;
Dave Youngaf0d3b12009-08-03 04:26:16 +00002181
Linus Torvalds1da177e2005-04-16 15:20:36 -07002182 hci_register_cb(&rfcomm_cb);
2183
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002184 rfcomm_thread = kthread_run(rfcomm_run, NULL, "krfcommd");
2185 if (IS_ERR(rfcomm_thread)) {
Marcel Holtmann52d18342009-08-22 14:49:36 -07002186 err = PTR_ERR(rfcomm_thread);
2187 goto unregister;
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002188 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002189
Marcel Holtmann52d18342009-08-22 14:49:36 -07002190 err = rfcomm_init_ttys();
2191 if (err < 0)
2192 goto stop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002193
Marcel Holtmann52d18342009-08-22 14:49:36 -07002194 err = rfcomm_init_sockets();
2195 if (err < 0)
2196 goto cleanup;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002197
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08002198 BT_INFO("RFCOMM ver %s", VERSION);
2199
Marcel Holtmann1120e4b2013-10-17 17:24:16 -07002200 if (IS_ERR_OR_NULL(bt_debugfs))
2201 return 0;
2202
2203 rfcomm_dlc_debugfs = debugfs_create_file("rfcomm_dlc", 0444,
2204 bt_debugfs, NULL,
2205 &rfcomm_dlc_debugfs_fops);
2206
Linus Torvalds1da177e2005-04-16 15:20:36 -07002207 return 0;
Dave Youngaf0d3b12009-08-03 04:26:16 +00002208
Marcel Holtmann52d18342009-08-22 14:49:36 -07002209cleanup:
Dave Youngaf0d3b12009-08-03 04:26:16 +00002210 rfcomm_cleanup_ttys();
Marcel Holtmann52d18342009-08-22 14:49:36 -07002211
2212stop:
Dave Youngaf0d3b12009-08-03 04:26:16 +00002213 kthread_stop(rfcomm_thread);
Marcel Holtmann52d18342009-08-22 14:49:36 -07002214
2215unregister:
Dave Youngaf0d3b12009-08-03 04:26:16 +00002216 hci_unregister_cb(&rfcomm_cb);
2217
Marcel Holtmann52d18342009-08-22 14:49:36 -07002218 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002219}
2220
2221static void __exit rfcomm_exit(void)
2222{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01002223 debugfs_remove(rfcomm_dlc_debugfs);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08002224
Linus Torvalds1da177e2005-04-16 15:20:36 -07002225 hci_unregister_cb(&rfcomm_cb);
2226
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002227 kthread_stop(rfcomm_thread);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002228
Linus Torvalds1da177e2005-04-16 15:20:36 -07002229 rfcomm_cleanup_ttys();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002230
2231 rfcomm_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002232}
2233
2234module_init(rfcomm_init);
2235module_exit(rfcomm_exit);
2236
Marcel Holtmann7c2660b2006-07-03 10:02:51 +02002237module_param(disable_cfc, bool, 0644);
2238MODULE_PARM_DESC(disable_cfc, "Disable credit based flow control");
2239
Marcel Holtmann98bcd082006-07-14 11:42:12 +02002240module_param(channel_mtu, int, 0644);
2241MODULE_PARM_DESC(channel_mtu, "Default MTU for the RFCOMM channel");
2242
Marcel Holtmann56f3a402006-02-13 11:39:57 +01002243module_param(l2cap_mtu, uint, 0644);
2244MODULE_PARM_DESC(l2cap_mtu, "Default MTU for the L2CAP connection");
2245
Marcel Holtmanneae38ee2009-10-05 12:23:48 +02002246module_param(l2cap_ertm, bool, 0644);
2247MODULE_PARM_DESC(l2cap_ertm, "Use L2CAP ERTM mode for connection");
2248
Marcel Holtmann63fbd242008-08-18 13:23:53 +02002249MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002250MODULE_DESCRIPTION("Bluetooth RFCOMM ver " VERSION);
2251MODULE_VERSION(VERSION);
2252MODULE_LICENSE("GPL");
2253MODULE_ALIAS("bt-proto-3");