blob: 292fa64a19dd2005d5c07784f6bada434afbdd13 [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
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 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:
219 auth_type = HCI_AT_GENERAL_BONDING_MITM;
220 break;
221 case BT_SECURITY_MEDIUM:
222 auth_type = HCI_AT_GENERAL_BONDING;
223 break;
224 default:
225 auth_type = HCI_AT_NO_BONDING;
226 break;
227 }
228
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300229 return hci_conn_security(conn->hcon, d->sec_level, auth_type);
Marcel Holtmann77db1982008-07-14 20:13:45 +0200230}
231
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300232static void rfcomm_session_timeout(unsigned long arg)
233{
234 struct rfcomm_session *s = (void *) arg;
235
236 BT_DBG("session %p state %ld", s, s->state);
237
238 set_bit(RFCOMM_TIMED_OUT, &s->flags);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300239 rfcomm_schedule();
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300240}
241
242static void rfcomm_session_set_timer(struct rfcomm_session *s, long timeout)
243{
244 BT_DBG("session %p state %ld timeout %ld", s, s->state, timeout);
245
Dean Jenkins08c30ac2013-02-28 14:21:56 +0000246 mod_timer(&s->timer, jiffies + timeout);
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300247}
248
249static void rfcomm_session_clear_timer(struct rfcomm_session *s)
250{
251 BT_DBG("session %p state %ld", s, s->state);
252
Dean Jenkins08c30ac2013-02-28 14:21:56 +0000253 del_timer_sync(&s->timer);
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300254}
255
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256/* ---- RFCOMM DLCs ---- */
257static void rfcomm_dlc_timeout(unsigned long arg)
258{
259 struct rfcomm_dlc *d = (void *) arg;
260
261 BT_DBG("dlc %p state %ld", d, d->state);
262
263 set_bit(RFCOMM_TIMED_OUT, &d->flags);
264 rfcomm_dlc_put(d);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300265 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266}
267
268static void rfcomm_dlc_set_timer(struct rfcomm_dlc *d, long timeout)
269{
270 BT_DBG("dlc %p state %ld timeout %ld", d, d->state, timeout);
271
272 if (!mod_timer(&d->timer, jiffies + timeout))
273 rfcomm_dlc_hold(d);
274}
275
276static void rfcomm_dlc_clear_timer(struct rfcomm_dlc *d)
277{
278 BT_DBG("dlc %p state %ld", d, d->state);
279
Ying Xue25cc4ae2013-02-03 20:32:57 +0000280 if (del_timer(&d->timer))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281 rfcomm_dlc_put(d);
282}
283
284static void rfcomm_dlc_clear_state(struct rfcomm_dlc *d)
285{
286 BT_DBG("%p", d);
287
288 d->state = BT_OPEN;
289 d->flags = 0;
290 d->mscex = 0;
Johan Hedberg183f7322010-12-06 15:56:17 +0200291 d->sec_level = BT_SECURITY_LOW;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292 d->mtu = RFCOMM_DEFAULT_MTU;
293 d->v24_sig = RFCOMM_V24_RTC | RFCOMM_V24_RTR | RFCOMM_V24_DV;
294
295 d->cfc = RFCOMM_CFC_DISABLED;
296 d->rx_credits = RFCOMM_DEFAULT_CREDITS;
297}
298
Al Virodd0fc662005-10-07 07:46:04 +0100299struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300{
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200301 struct rfcomm_dlc *d = kzalloc(sizeof(*d), prio);
302
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303 if (!d)
304 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305
Pavel Emelyanovb24b8a22008-01-23 21:20:07 -0800306 setup_timer(&d->timer, rfcomm_dlc_timeout, (unsigned long)d);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307
308 skb_queue_head_init(&d->tx_queue);
309 spin_lock_init(&d->lock);
310 atomic_set(&d->refcnt, 1);
311
312 rfcomm_dlc_clear_state(d);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900313
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314 BT_DBG("%p", d);
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200315
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316 return d;
317}
318
319void rfcomm_dlc_free(struct rfcomm_dlc *d)
320{
321 BT_DBG("%p", d);
322
323 skb_queue_purge(&d->tx_queue);
324 kfree(d);
325}
326
327static void rfcomm_dlc_link(struct rfcomm_session *s, struct rfcomm_dlc *d)
328{
329 BT_DBG("dlc %p session %p", d, s);
330
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300331 rfcomm_session_clear_timer(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332 rfcomm_dlc_hold(d);
333 list_add(&d->list, &s->dlcs);
334 d->session = s;
335}
336
337static void rfcomm_dlc_unlink(struct rfcomm_dlc *d)
338{
339 struct rfcomm_session *s = d->session;
340
341 BT_DBG("dlc %p refcnt %d session %p", d, atomic_read(&d->refcnt), s);
342
343 list_del(&d->list);
344 d->session = NULL;
345 rfcomm_dlc_put(d);
346
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300347 if (list_empty(&s->dlcs))
348 rfcomm_session_set_timer(s, RFCOMM_IDLE_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349}
350
351static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, u8 dlci)
352{
353 struct rfcomm_dlc *d;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200355 list_for_each_entry(d, &s->dlcs, list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356 if (d->dlci == dlci)
357 return d;
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200358
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359 return NULL;
360}
361
362static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
363{
364 struct rfcomm_session *s;
365 int err = 0;
366 u8 dlci;
367
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +0300368 BT_DBG("dlc %p state %ld %pMR -> %pMR channel %d",
369 d, d->state, src, dst, channel);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370
371 if (channel < 1 || channel > 30)
372 return -EINVAL;
373
374 if (d->state != BT_OPEN && d->state != BT_CLOSED)
375 return 0;
376
377 s = rfcomm_session_get(src, dst);
378 if (!s) {
Luiz Augusto von Dentz63ce0902010-08-19 14:06:10 +0300379 s = rfcomm_session_create(src, dst, d->sec_level, &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 if (!s)
381 return err;
382 }
383
384 dlci = __dlci(!s->initiator, channel);
385
386 /* Check if DLCI already exists */
387 if (rfcomm_dlc_get(s, dlci))
388 return -EBUSY;
389
390 rfcomm_dlc_clear_state(d);
391
392 d->dlci = dlci;
393 d->addr = __addr(s->initiator, dlci);
394 d->priority = 7;
395
Marcel Holtmann77db1982008-07-14 20:13:45 +0200396 d->state = BT_CONFIG;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 rfcomm_dlc_link(s, d);
398
Marcel Holtmann77db1982008-07-14 20:13:45 +0200399 d->out = 1;
400
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401 d->mtu = s->mtu;
402 d->cfc = (s->cfc == RFCOMM_CFC_UNKNOWN) ? 0 : s->cfc;
403
Marcel Holtmann77db1982008-07-14 20:13:45 +0200404 if (s->state == BT_CONNECTED) {
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100405 if (rfcomm_check_security(d))
Marcel Holtmann77db1982008-07-14 20:13:45 +0200406 rfcomm_send_pn(s, 1, d);
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100407 else
408 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
Marcel Holtmann77db1982008-07-14 20:13:45 +0200409 }
410
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411 rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT);
Marcel Holtmann77db1982008-07-14 20:13:45 +0200412
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 return 0;
414}
415
416int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
417{
418 int r;
419
420 rfcomm_lock();
421
422 r = __rfcomm_dlc_open(d, src, dst, channel);
423
424 rfcomm_unlock();
425 return r;
426}
427
428static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
429{
430 struct rfcomm_session *s = d->session;
431 if (!s)
432 return 0;
433
434 BT_DBG("dlc %p state %ld dlci %d err %d session %p",
435 d, d->state, d->dlci, err, s);
436
437 switch (d->state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438 case BT_CONNECT:
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100439 case BT_CONFIG:
440 if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
441 set_bit(RFCOMM_AUTH_REJECT, &d->flags);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300442 rfcomm_schedule();
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100443 break;
444 }
445 /* Fall through */
446
447 case BT_CONNECTED:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448 d->state = BT_DISCONN;
449 if (skb_queue_empty(&d->tx_queue)) {
450 rfcomm_send_disc(s, d->dlci);
451 rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT);
452 } else {
453 rfcomm_queue_disc(d);
454 rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT * 2);
455 }
456 break;
457
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100458 case BT_OPEN:
Marcel Holtmann8bf47942009-02-16 02:59:49 +0100459 case BT_CONNECT2:
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100460 if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
461 set_bit(RFCOMM_AUTH_REJECT, &d->flags);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300462 rfcomm_schedule();
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100463 break;
464 }
465 /* Fall through */
466
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467 default:
468 rfcomm_dlc_clear_timer(d);
469
470 rfcomm_dlc_lock(d);
471 d->state = BT_CLOSED;
Dave Young1905f6c2008-04-01 23:59:06 -0700472 d->state_change(d, err);
Arjan van de Ven4c8411f2008-05-29 01:32:47 -0700473 rfcomm_dlc_unlock(d);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474
475 skb_queue_purge(&d->tx_queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 rfcomm_dlc_unlink(d);
477 }
478
479 return 0;
480}
481
482int rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
483{
Dean Jenkinsc06f7d52013-02-28 14:21:54 +0000484 int r = 0;
485 struct rfcomm_dlc *d_list;
486 struct rfcomm_session *s, *s_list;
487
488 BT_DBG("dlc %p state %ld dlci %d err %d", d, d->state, d->dlci, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489
490 rfcomm_lock();
491
Dean Jenkinsc06f7d52013-02-28 14:21:54 +0000492 s = d->session;
493 if (!s)
494 goto no_session;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495
Dean Jenkinsc06f7d52013-02-28 14:21:54 +0000496 /* after waiting on the mutex check the session still exists
497 * then check the dlc still exists
498 */
499 list_for_each_entry(s_list, &session_list, list) {
500 if (s_list == s) {
501 list_for_each_entry(d_list, &s->dlcs, list) {
502 if (d_list == d) {
503 r = __rfcomm_dlc_close(d, err);
504 break;
505 }
506 }
507 break;
508 }
509 }
510
511no_session:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512 rfcomm_unlock();
513 return r;
514}
515
516int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb)
517{
518 int len = skb->len;
519
520 if (d->state != BT_CONNECTED)
521 return -ENOTCONN;
522
523 BT_DBG("dlc %p mtu %d len %d", d, d->mtu, len);
524
525 if (len > d->mtu)
526 return -EINVAL;
527
528 rfcomm_make_uih(skb, d->addr);
529 skb_queue_tail(&d->tx_queue, skb);
530
531 if (!test_bit(RFCOMM_TX_THROTTLED, &d->flags))
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300532 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533 return len;
534}
535
Harvey Harrisonb5606c22008-02-13 15:03:16 -0800536void __rfcomm_dlc_throttle(struct rfcomm_dlc *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537{
538 BT_DBG("dlc %p state %ld", d, d->state);
539
540 if (!d->cfc) {
541 d->v24_sig |= RFCOMM_V24_FC;
542 set_bit(RFCOMM_MSC_PENDING, &d->flags);
543 }
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300544 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545}
546
Harvey Harrisonb5606c22008-02-13 15:03:16 -0800547void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548{
549 BT_DBG("dlc %p state %ld", d, d->state);
550
551 if (!d->cfc) {
552 d->v24_sig &= ~RFCOMM_V24_FC;
553 set_bit(RFCOMM_MSC_PENDING, &d->flags);
554 }
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300555 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556}
557
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900558/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559 Set/get modem status functions use _local_ status i.e. what we report
560 to the other side.
561 Remote status is provided by dlc->modem_status() callback.
562 */
563int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig)
564{
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900565 BT_DBG("dlc %p state %ld v24_sig 0x%x",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 d, d->state, v24_sig);
567
568 if (test_bit(RFCOMM_RX_THROTTLED, &d->flags))
569 v24_sig |= RFCOMM_V24_FC;
570 else
571 v24_sig &= ~RFCOMM_V24_FC;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900572
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573 d->v24_sig = v24_sig;
574
575 if (!test_and_set_bit(RFCOMM_MSC_PENDING, &d->flags))
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300576 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577
578 return 0;
579}
580
581int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig)
582{
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900583 BT_DBG("dlc %p state %ld v24_sig 0x%x",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 d, d->state, d->v24_sig);
585
586 *v24_sig = d->v24_sig;
587 return 0;
588}
589
590/* ---- RFCOMM sessions ---- */
591static struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
592{
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200593 struct rfcomm_session *s = kzalloc(sizeof(*s), GFP_KERNEL);
594
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595 if (!s)
596 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597
598 BT_DBG("session %p sock %p", s, sock);
599
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300600 setup_timer(&s->timer, rfcomm_session_timeout, (unsigned long) s);
601
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602 INIT_LIST_HEAD(&s->dlcs);
603 s->state = state;
604 s->sock = sock;
605
606 s->mtu = RFCOMM_DEFAULT_MTU;
Marcel Holtmann7c2660b2006-07-03 10:02:51 +0200607 s->cfc = disable_cfc ? RFCOMM_CFC_DISABLED : RFCOMM_CFC_UNKNOWN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608
609 /* Do not increment module usage count for listening sessions.
610 * Otherwise we won't be able to unload the module. */
611 if (state != BT_LISTEN)
612 if (!try_module_get(THIS_MODULE)) {
613 kfree(s);
614 return NULL;
615 }
616
617 list_add(&s->list, &session_list);
618
619 return s;
620}
621
Dean Jenkins8ff52f72013-02-28 14:21:55 +0000622static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623{
624 int state = s->state;
625
626 BT_DBG("session %p state %ld", s, s->state);
627
628 list_del(&s->list);
629
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300630 rfcomm_session_clear_timer(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631 sock_release(s->sock);
632 kfree(s);
633
634 if (state != BT_LISTEN)
635 module_put(THIS_MODULE);
Dean Jenkins8ff52f72013-02-28 14:21:55 +0000636
637 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638}
639
640static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
641{
642 struct rfcomm_session *s;
643 struct list_head *p, *n;
644 struct bt_sock *sk;
645 list_for_each_safe(p, n, &session_list) {
646 s = list_entry(p, struct rfcomm_session, list);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900647 sk = bt_sk(s->sock->sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648
649 if ((!bacmp(src, BDADDR_ANY) || !bacmp(&sk->src, src)) &&
650 !bacmp(&sk->dst, dst))
651 return s;
652 }
653 return NULL;
654}
655
Dean Jenkins8ff52f72013-02-28 14:21:55 +0000656static struct rfcomm_session *rfcomm_session_close(struct rfcomm_session *s,
657 int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658{
659 struct rfcomm_dlc *d;
660 struct list_head *p, *n;
661
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662 s->state = BT_CLOSED;
663
Dean Jenkins24fd6422013-02-28 14:21:58 +0000664 BT_DBG("session %p state %ld err %d", s, s->state, err);
665
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666 /* Close all dlcs */
667 list_for_each_safe(p, n, &s->dlcs) {
668 d = list_entry(p, struct rfcomm_dlc, list);
669 d->state = BT_CLOSED;
670 __rfcomm_dlc_close(d, err);
671 }
672
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300673 rfcomm_session_clear_timer(s);
Dean Jenkins08c30ac2013-02-28 14:21:56 +0000674 return rfcomm_session_del(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675}
676
Luiz Augusto von Dentz63ce0902010-08-19 14:06:10 +0300677static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
678 bdaddr_t *dst,
679 u8 sec_level,
680 int *err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681{
682 struct rfcomm_session *s = NULL;
683 struct sockaddr_l2 addr;
684 struct socket *sock;
685 struct sock *sk;
686
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +0300687 BT_DBG("%pMR -> %pMR", src, dst);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688
689 *err = rfcomm_l2sock_create(&sock);
690 if (*err < 0)
691 return NULL;
692
693 bacpy(&addr.l2_bdaddr, src);
694 addr.l2_family = AF_BLUETOOTH;
695 addr.l2_psm = 0;
Marcel Holtmann37e62f52009-02-17 21:49:33 +0100696 addr.l2_cid = 0;
Seung-Woo Kimc507f132013-11-05 16:02:24 +0900697 addr.l2_bdaddr_type = BDADDR_BREDR;
Marcel Holtmann48db9ca2007-05-05 00:36:06 +0200698 *err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699 if (*err < 0)
700 goto failed;
701
702 /* Set L2CAP options */
703 sk = sock->sk;
704 lock_sock(sk);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300705 l2cap_pi(sk)->chan->imtu = l2cap_mtu;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300706 l2cap_pi(sk)->chan->sec_level = sec_level;
Marcel Holtmanneae38ee2009-10-05 12:23:48 +0200707 if (l2cap_ertm)
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300708 l2cap_pi(sk)->chan->mode = L2CAP_MODE_ERTM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709 release_sock(sk);
710
711 s = rfcomm_session_add(sock, BT_BOUND);
712 if (!s) {
713 *err = -ENOMEM;
714 goto failed;
715 }
716
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 s->initiator = 1;
718
719 bacpy(&addr.l2_bdaddr, dst);
720 addr.l2_family = AF_BLUETOOTH;
Syam Sidhardhan5bcb8092012-10-10 22:09:29 +0530721 addr.l2_psm = __constant_cpu_to_le16(RFCOMM_PSM);
Marcel Holtmann37e62f52009-02-17 21:49:33 +0100722 addr.l2_cid = 0;
Marcel Holtmann48db9ca2007-05-05 00:36:06 +0200723 *err = kernel_connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);
Marcel Holtmannb4c612a2006-09-23 09:54:38 +0200724 if (*err == 0 || *err == -EINPROGRESS)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725 return s;
726
Dean Jenkins8ff52f72013-02-28 14:21:55 +0000727 return rfcomm_session_del(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728
729failed:
730 sock_release(sock);
731 return NULL;
732}
733
734void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst)
735{
736 struct sock *sk = s->sock->sk;
737 if (src)
738 bacpy(src, &bt_sk(sk)->src);
739 if (dst)
740 bacpy(dst, &bt_sk(sk)->dst);
741}
742
743/* ---- RFCOMM frame sending ---- */
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200744static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746 struct kvec iv = { data, len };
747 struct msghdr msg;
748
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200749 BT_DBG("session %p len %d", s, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750
751 memset(&msg, 0, sizeof(msg));
752
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200753 return kernel_sendmsg(s->sock, &msg, &iv, 1, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754}
755
Luiz Augusto von Dentz262038f2011-11-01 10:58:58 +0200756static int rfcomm_send_cmd(struct rfcomm_session *s, struct rfcomm_cmd *cmd)
757{
758 BT_DBG("%p cmd %u", s, cmd->ctrl);
759
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200760 return rfcomm_send_frame(s, (void *) cmd, sizeof(*cmd));
Luiz Augusto von Dentz262038f2011-11-01 10:58:58 +0200761}
762
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci)
764{
765 struct rfcomm_cmd cmd;
766
767 BT_DBG("%p dlci %d", s, dlci);
768
769 cmd.addr = __addr(s->initiator, dlci);
770 cmd.ctrl = __ctrl(RFCOMM_SABM, 1);
771 cmd.len = __len8(0);
772 cmd.fcs = __fcs2((u8 *) &cmd);
773
Luiz Augusto von Dentz262038f2011-11-01 10:58:58 +0200774 return rfcomm_send_cmd(s, &cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775}
776
777static int rfcomm_send_ua(struct rfcomm_session *s, u8 dlci)
778{
779 struct rfcomm_cmd cmd;
780
781 BT_DBG("%p dlci %d", s, dlci);
782
783 cmd.addr = __addr(!s->initiator, dlci);
784 cmd.ctrl = __ctrl(RFCOMM_UA, 1);
785 cmd.len = __len8(0);
786 cmd.fcs = __fcs2((u8 *) &cmd);
787
Luiz Augusto von Dentz262038f2011-11-01 10:58:58 +0200788 return rfcomm_send_cmd(s, &cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789}
790
791static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci)
792{
793 struct rfcomm_cmd cmd;
794
795 BT_DBG("%p dlci %d", s, dlci);
796
797 cmd.addr = __addr(s->initiator, dlci);
798 cmd.ctrl = __ctrl(RFCOMM_DISC, 1);
799 cmd.len = __len8(0);
800 cmd.fcs = __fcs2((u8 *) &cmd);
801
Luiz Augusto von Dentz262038f2011-11-01 10:58:58 +0200802 return rfcomm_send_cmd(s, &cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803}
804
805static int rfcomm_queue_disc(struct rfcomm_dlc *d)
806{
807 struct rfcomm_cmd *cmd;
808 struct sk_buff *skb;
809
810 BT_DBG("dlc %p dlci %d", d, d->dlci);
811
812 skb = alloc_skb(sizeof(*cmd), GFP_KERNEL);
813 if (!skb)
814 return -ENOMEM;
815
816 cmd = (void *) __skb_put(skb, sizeof(*cmd));
817 cmd->addr = d->addr;
818 cmd->ctrl = __ctrl(RFCOMM_DISC, 1);
819 cmd->len = __len8(0);
820 cmd->fcs = __fcs2((u8 *) cmd);
821
822 skb_queue_tail(&d->tx_queue, skb);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300823 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824 return 0;
825}
826
827static int rfcomm_send_dm(struct rfcomm_session *s, u8 dlci)
828{
829 struct rfcomm_cmd cmd;
830
831 BT_DBG("%p dlci %d", s, dlci);
832
833 cmd.addr = __addr(!s->initiator, dlci);
834 cmd.ctrl = __ctrl(RFCOMM_DM, 1);
835 cmd.len = __len8(0);
836 cmd.fcs = __fcs2((u8 *) &cmd);
837
Luiz Augusto von Dentz262038f2011-11-01 10:58:58 +0200838 return rfcomm_send_cmd(s, &cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839}
840
841static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type)
842{
843 struct rfcomm_hdr *hdr;
844 struct rfcomm_mcc *mcc;
845 u8 buf[16], *ptr = buf;
846
847 BT_DBG("%p cr %d type %d", s, cr, type);
848
849 hdr = (void *) ptr; ptr += sizeof(*hdr);
850 hdr->addr = __addr(s->initiator, 0);
851 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
852 hdr->len = __len8(sizeof(*mcc) + 1);
853
854 mcc = (void *) ptr; ptr += sizeof(*mcc);
855 mcc->type = __mcc_type(cr, RFCOMM_NSC);
856 mcc->len = __len8(1);
857
858 /* Type that we didn't like */
859 *ptr = __mcc_type(cr, type); ptr++;
860
861 *ptr = __fcs(buf); ptr++;
862
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200863 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864}
865
866static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d)
867{
868 struct rfcomm_hdr *hdr;
869 struct rfcomm_mcc *mcc;
870 struct rfcomm_pn *pn;
871 u8 buf[16], *ptr = buf;
872
873 BT_DBG("%p cr %d dlci %d mtu %d", s, cr, d->dlci, d->mtu);
874
875 hdr = (void *) ptr; ptr += sizeof(*hdr);
876 hdr->addr = __addr(s->initiator, 0);
877 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
878 hdr->len = __len8(sizeof(*mcc) + sizeof(*pn));
879
880 mcc = (void *) ptr; ptr += sizeof(*mcc);
881 mcc->type = __mcc_type(cr, RFCOMM_PN);
882 mcc->len = __len8(sizeof(*pn));
883
884 pn = (void *) ptr; ptr += sizeof(*pn);
885 pn->dlci = d->dlci;
886 pn->priority = d->priority;
887 pn->ack_timer = 0;
888 pn->max_retrans = 0;
889
890 if (s->cfc) {
891 pn->flow_ctrl = cr ? 0xf0 : 0xe0;
892 pn->credits = RFCOMM_DEFAULT_CREDITS;
893 } else {
894 pn->flow_ctrl = 0;
895 pn->credits = 0;
896 }
897
Marcel Holtmann98bcd082006-07-14 11:42:12 +0200898 if (cr && channel_mtu >= 0)
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200899 pn->mtu = cpu_to_le16(channel_mtu);
Marcel Holtmann98bcd082006-07-14 11:42:12 +0200900 else
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200901 pn->mtu = cpu_to_le16(d->mtu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902
903 *ptr = __fcs(buf); ptr++;
904
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200905 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906}
907
J. Suter3a5e9032005-08-09 20:28:46 -0700908int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci,
909 u8 bit_rate, u8 data_bits, u8 stop_bits,
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900910 u8 parity, u8 flow_ctrl_settings,
J. Suter3a5e9032005-08-09 20:28:46 -0700911 u8 xon_char, u8 xoff_char, u16 param_mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912{
913 struct rfcomm_hdr *hdr;
914 struct rfcomm_mcc *mcc;
915 struct rfcomm_rpn *rpn;
916 u8 buf[16], *ptr = buf;
917
918 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 +0900919 " flwc_s 0x%x xon_c 0x%x xoff_c 0x%x p_mask 0x%x",
920 s, cr, dlci, bit_rate, data_bits, stop_bits, parity,
J. Suter3a5e9032005-08-09 20:28:46 -0700921 flow_ctrl_settings, xon_char, xoff_char, param_mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922
923 hdr = (void *) ptr; ptr += sizeof(*hdr);
924 hdr->addr = __addr(s->initiator, 0);
925 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
926 hdr->len = __len8(sizeof(*mcc) + sizeof(*rpn));
927
928 mcc = (void *) ptr; ptr += sizeof(*mcc);
929 mcc->type = __mcc_type(cr, RFCOMM_RPN);
930 mcc->len = __len8(sizeof(*rpn));
931
932 rpn = (void *) ptr; ptr += sizeof(*rpn);
933 rpn->dlci = __addr(1, dlci);
934 rpn->bit_rate = bit_rate;
935 rpn->line_settings = __rpn_line_settings(data_bits, stop_bits, parity);
936 rpn->flow_ctrl = flow_ctrl_settings;
937 rpn->xon_char = xon_char;
938 rpn->xoff_char = xoff_char;
Al Viroe8db8c92006-11-08 00:28:44 -0800939 rpn->param_mask = cpu_to_le16(param_mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940
941 *ptr = __fcs(buf); ptr++;
942
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200943 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700944}
945
946static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status)
947{
948 struct rfcomm_hdr *hdr;
949 struct rfcomm_mcc *mcc;
950 struct rfcomm_rls *rls;
951 u8 buf[16], *ptr = buf;
952
953 BT_DBG("%p cr %d status 0x%x", s, cr, status);
954
955 hdr = (void *) ptr; ptr += sizeof(*hdr);
956 hdr->addr = __addr(s->initiator, 0);
957 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
958 hdr->len = __len8(sizeof(*mcc) + sizeof(*rls));
959
960 mcc = (void *) ptr; ptr += sizeof(*mcc);
961 mcc->type = __mcc_type(cr, RFCOMM_RLS);
962 mcc->len = __len8(sizeof(*rls));
963
964 rls = (void *) ptr; ptr += sizeof(*rls);
965 rls->dlci = __addr(1, dlci);
966 rls->status = status;
967
968 *ptr = __fcs(buf); ptr++;
969
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200970 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971}
972
973static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig)
974{
975 struct rfcomm_hdr *hdr;
976 struct rfcomm_mcc *mcc;
977 struct rfcomm_msc *msc;
978 u8 buf[16], *ptr = buf;
979
980 BT_DBG("%p cr %d v24 0x%x", s, cr, v24_sig);
981
982 hdr = (void *) ptr; ptr += sizeof(*hdr);
983 hdr->addr = __addr(s->initiator, 0);
984 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
985 hdr->len = __len8(sizeof(*mcc) + sizeof(*msc));
986
987 mcc = (void *) ptr; ptr += sizeof(*mcc);
988 mcc->type = __mcc_type(cr, RFCOMM_MSC);
989 mcc->len = __len8(sizeof(*msc));
990
991 msc = (void *) ptr; ptr += sizeof(*msc);
992 msc->dlci = __addr(1, dlci);
993 msc->v24_sig = v24_sig | 0x01;
994
995 *ptr = __fcs(buf); ptr++;
996
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200997 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998}
999
1000static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr)
1001{
1002 struct rfcomm_hdr *hdr;
1003 struct rfcomm_mcc *mcc;
1004 u8 buf[16], *ptr = buf;
1005
1006 BT_DBG("%p cr %d", s, cr);
1007
1008 hdr = (void *) ptr; ptr += sizeof(*hdr);
1009 hdr->addr = __addr(s->initiator, 0);
1010 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
1011 hdr->len = __len8(sizeof(*mcc));
1012
1013 mcc = (void *) ptr; ptr += sizeof(*mcc);
1014 mcc->type = __mcc_type(cr, RFCOMM_FCOFF);
1015 mcc->len = __len8(0);
1016
1017 *ptr = __fcs(buf); ptr++;
1018
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001019 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020}
1021
1022static int rfcomm_send_fcon(struct rfcomm_session *s, int cr)
1023{
1024 struct rfcomm_hdr *hdr;
1025 struct rfcomm_mcc *mcc;
1026 u8 buf[16], *ptr = buf;
1027
1028 BT_DBG("%p cr %d", s, cr);
1029
1030 hdr = (void *) ptr; ptr += sizeof(*hdr);
1031 hdr->addr = __addr(s->initiator, 0);
1032 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
1033 hdr->len = __len8(sizeof(*mcc));
1034
1035 mcc = (void *) ptr; ptr += sizeof(*mcc);
1036 mcc->type = __mcc_type(cr, RFCOMM_FCON);
1037 mcc->len = __len8(0);
1038
1039 *ptr = __fcs(buf); ptr++;
1040
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001041 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042}
1043
1044static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len)
1045{
1046 struct socket *sock = s->sock;
1047 struct kvec iv[3];
1048 struct msghdr msg;
1049 unsigned char hdr[5], crc[1];
1050
1051 if (len > 125)
1052 return -EINVAL;
1053
1054 BT_DBG("%p cr %d", s, cr);
1055
1056 hdr[0] = __addr(s->initiator, 0);
1057 hdr[1] = __ctrl(RFCOMM_UIH, 0);
1058 hdr[2] = 0x01 | ((len + 2) << 1);
1059 hdr[3] = 0x01 | ((cr & 0x01) << 1) | (RFCOMM_TEST << 2);
1060 hdr[4] = 0x01 | (len << 1);
1061
1062 crc[0] = __fcs(hdr);
1063
1064 iv[0].iov_base = hdr;
1065 iv[0].iov_len = 5;
1066 iv[1].iov_base = pattern;
1067 iv[1].iov_len = len;
1068 iv[2].iov_base = crc;
1069 iv[2].iov_len = 1;
1070
1071 memset(&msg, 0, sizeof(msg));
1072
1073 return kernel_sendmsg(sock, &msg, iv, 3, 6 + len);
1074}
1075
1076static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits)
1077{
1078 struct rfcomm_hdr *hdr;
1079 u8 buf[16], *ptr = buf;
1080
1081 BT_DBG("%p addr %d credits %d", s, addr, credits);
1082
1083 hdr = (void *) ptr; ptr += sizeof(*hdr);
1084 hdr->addr = addr;
1085 hdr->ctrl = __ctrl(RFCOMM_UIH, 1);
1086 hdr->len = __len8(0);
1087
1088 *ptr = credits; ptr++;
1089
1090 *ptr = __fcs(buf); ptr++;
1091
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001092 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093}
1094
1095static void rfcomm_make_uih(struct sk_buff *skb, u8 addr)
1096{
1097 struct rfcomm_hdr *hdr;
1098 int len = skb->len;
1099 u8 *crc;
1100
1101 if (len > 127) {
1102 hdr = (void *) skb_push(skb, 4);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001103 put_unaligned(cpu_to_le16(__len16(len)), (__le16 *) &hdr->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104 } else {
1105 hdr = (void *) skb_push(skb, 3);
1106 hdr->len = __len8(len);
1107 }
1108 hdr->addr = addr;
1109 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
1110
1111 crc = skb_put(skb, 1);
1112 *crc = __fcs((void *) hdr);
1113}
1114
1115/* ---- RFCOMM frame reception ---- */
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001116static struct rfcomm_session *rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117{
1118 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1119
1120 if (dlci) {
1121 /* Data channel */
1122 struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
1123 if (!d) {
1124 rfcomm_send_dm(s, dlci);
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001125 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126 }
1127
1128 switch (d->state) {
1129 case BT_CONNECT:
1130 rfcomm_dlc_clear_timer(d);
1131
1132 rfcomm_dlc_lock(d);
1133 d->state = BT_CONNECTED;
1134 d->state_change(d, 0);
1135 rfcomm_dlc_unlock(d);
1136
1137 rfcomm_send_msc(s, 1, dlci, d->v24_sig);
1138 break;
1139
1140 case BT_DISCONN:
1141 d->state = BT_CLOSED;
1142 __rfcomm_dlc_close(d, 0);
Marcel Holtmann9cf5b0e2007-05-05 00:36:13 +02001143
1144 if (list_empty(&s->dlcs)) {
1145 s->state = BT_DISCONN;
1146 rfcomm_send_disc(s, 0);
Mat Martineau79e65472011-12-06 16:23:26 -08001147 rfcomm_session_clear_timer(s);
Marcel Holtmann9cf5b0e2007-05-05 00:36:13 +02001148 }
1149
Linus Torvalds1da177e2005-04-16 15:20:36 -07001150 break;
1151 }
1152 } else {
1153 /* Control channel */
1154 switch (s->state) {
1155 case BT_CONNECT:
1156 s->state = BT_CONNECTED;
1157 rfcomm_process_connect(s);
1158 break;
Marcel Holtmann9cf5b0e2007-05-05 00:36:13 +02001159
1160 case BT_DISCONN:
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001161 s = rfcomm_session_close(s, ECONNRESET);
Marcel Holtmann9cf5b0e2007-05-05 00:36:13 +02001162 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163 }
1164 }
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001165 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166}
1167
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001168static struct rfcomm_session *rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169{
1170 int err = 0;
1171
1172 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1173
1174 if (dlci) {
1175 /* Data DLC */
1176 struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
1177 if (d) {
1178 if (d->state == BT_CONNECT || d->state == BT_CONFIG)
1179 err = ECONNREFUSED;
1180 else
1181 err = ECONNRESET;
1182
1183 d->state = BT_CLOSED;
1184 __rfcomm_dlc_close(d, err);
1185 }
1186 } else {
1187 if (s->state == BT_CONNECT)
1188 err = ECONNREFUSED;
1189 else
1190 err = ECONNRESET;
1191
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001192 s = rfcomm_session_close(s, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 }
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001194 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195}
1196
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001197static struct rfcomm_session *rfcomm_recv_disc(struct rfcomm_session *s,
1198 u8 dlci)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199{
1200 int err = 0;
1201
1202 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1203
1204 if (dlci) {
1205 struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
1206 if (d) {
1207 rfcomm_send_ua(s, dlci);
1208
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);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001216 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217 rfcomm_send_dm(s, dlci);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001218
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219 } else {
1220 rfcomm_send_ua(s, 0);
1221
1222 if (s->state == BT_CONNECT)
1223 err = ECONNREFUSED;
1224 else
1225 err = ECONNRESET;
1226
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001227 s = rfcomm_session_close(s, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228 }
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001229 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230}
1231
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001232void rfcomm_dlc_accept(struct rfcomm_dlc *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233{
Marcel Holtmann300b9392006-07-03 10:37:55 +02001234 struct sock *sk = d->session->sock->sk;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001235 struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;
Marcel Holtmann300b9392006-07-03 10:37:55 +02001236
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237 BT_DBG("dlc %p", d);
1238
1239 rfcomm_send_ua(d->session, d->dlci);
1240
Johan Hedberge2139b32009-03-26 16:41:56 +02001241 rfcomm_dlc_clear_timer(d);
1242
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243 rfcomm_dlc_lock(d);
1244 d->state = BT_CONNECTED;
1245 d->state_change(d, 0);
1246 rfcomm_dlc_unlock(d);
1247
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +01001248 if (d->role_switch)
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001249 hci_conn_switch_role(conn->hcon, 0x00);
Marcel Holtmann300b9392006-07-03 10:37:55 +02001250
Linus Torvalds1da177e2005-04-16 15:20:36 -07001251 rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
1252}
1253
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001254static void rfcomm_check_accept(struct rfcomm_dlc *d)
1255{
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +01001256 if (rfcomm_check_security(d)) {
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001257 if (d->defer_setup) {
1258 set_bit(RFCOMM_DEFER_SETUP, &d->flags);
1259 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
Marcel Holtmann8bf47942009-02-16 02:59:49 +01001260
1261 rfcomm_dlc_lock(d);
1262 d->state = BT_CONNECT2;
1263 d->state_change(d, 0);
1264 rfcomm_dlc_unlock(d);
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001265 } else
1266 rfcomm_dlc_accept(d);
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001267 } else {
1268 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
1269 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001270 }
1271}
1272
Linus Torvalds1da177e2005-04-16 15:20:36 -07001273static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
1274{
1275 struct rfcomm_dlc *d;
1276 u8 channel;
1277
1278 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1279
1280 if (!dlci) {
1281 rfcomm_send_ua(s, 0);
1282
1283 if (s->state == BT_OPEN) {
1284 s->state = BT_CONNECTED;
1285 rfcomm_process_connect(s);
1286 }
1287 return 0;
1288 }
1289
1290 /* Check if DLC exists */
1291 d = rfcomm_dlc_get(s, dlci);
1292 if (d) {
1293 if (d->state == BT_OPEN) {
1294 /* DLC was previously opened by PN request */
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001295 rfcomm_check_accept(d);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296 }
1297 return 0;
1298 }
1299
1300 /* Notify socket layer about incoming connection */
1301 channel = __srv_channel(dlci);
1302 if (rfcomm_connect_ind(s, channel, &d)) {
1303 d->dlci = dlci;
1304 d->addr = __addr(s->initiator, dlci);
1305 rfcomm_dlc_link(s, d);
1306
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001307 rfcomm_check_accept(d);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001308 } else {
1309 rfcomm_send_dm(s, dlci);
1310 }
1311
1312 return 0;
1313}
1314
1315static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn)
1316{
1317 struct rfcomm_session *s = d->session;
1318
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001319 BT_DBG("dlc %p state %ld dlci %d mtu %d fc 0x%x credits %d",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320 d, d->state, d->dlci, pn->mtu, pn->flow_ctrl, pn->credits);
1321
Marcel Holtmann7c2660b2006-07-03 10:02:51 +02001322 if ((pn->flow_ctrl == 0xf0 && s->cfc != RFCOMM_CFC_DISABLED) ||
1323 pn->flow_ctrl == 0xe0) {
1324 d->cfc = RFCOMM_CFC_ENABLED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001325 d->tx_credits = pn->credits;
1326 } else {
Marcel Holtmann7c2660b2006-07-03 10:02:51 +02001327 d->cfc = RFCOMM_CFC_DISABLED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328 set_bit(RFCOMM_TX_THROTTLED, &d->flags);
1329 }
1330
Marcel Holtmann7c2660b2006-07-03 10:02:51 +02001331 if (s->cfc == RFCOMM_CFC_UNKNOWN)
1332 s->cfc = d->cfc;
1333
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334 d->priority = pn->priority;
1335
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001336 d->mtu = __le16_to_cpu(pn->mtu);
Marcel Holtmann98bcd082006-07-14 11:42:12 +02001337
1338 if (cr && d->mtu > s->mtu)
1339 d->mtu = s->mtu;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340
1341 return 0;
1342}
1343
1344static int rfcomm_recv_pn(struct rfcomm_session *s, int cr, struct sk_buff *skb)
1345{
1346 struct rfcomm_pn *pn = (void *) skb->data;
1347 struct rfcomm_dlc *d;
1348 u8 dlci = pn->dlci;
1349
1350 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1351
1352 if (!dlci)
1353 return 0;
1354
1355 d = rfcomm_dlc_get(s, dlci);
1356 if (d) {
1357 if (cr) {
1358 /* PN request */
1359 rfcomm_apply_pn(d, cr, pn);
1360 rfcomm_send_pn(s, 0, d);
1361 } else {
1362 /* PN response */
1363 switch (d->state) {
1364 case BT_CONFIG:
1365 rfcomm_apply_pn(d, cr, pn);
1366
1367 d->state = BT_CONNECT;
1368 rfcomm_send_sabm(s, d->dlci);
1369 break;
1370 }
1371 }
1372 } else {
1373 u8 channel = __srv_channel(dlci);
1374
1375 if (!cr)
1376 return 0;
1377
1378 /* PN request for non existing DLC.
1379 * Assume incoming connection. */
1380 if (rfcomm_connect_ind(s, channel, &d)) {
1381 d->dlci = dlci;
1382 d->addr = __addr(s->initiator, dlci);
1383 rfcomm_dlc_link(s, d);
1384
1385 rfcomm_apply_pn(d, cr, pn);
1386
1387 d->state = BT_OPEN;
1388 rfcomm_send_pn(s, 0, d);
1389 } else {
1390 rfcomm_send_dm(s, dlci);
1391 }
1392 }
1393 return 0;
1394}
1395
1396static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_buff *skb)
1397{
1398 struct rfcomm_rpn *rpn = (void *) skb->data;
1399 u8 dlci = __get_dlci(rpn->dlci);
1400
1401 u8 bit_rate = 0;
1402 u8 data_bits = 0;
1403 u8 stop_bits = 0;
1404 u8 parity = 0;
1405 u8 flow_ctrl = 0;
1406 u8 xon_char = 0;
1407 u8 xoff_char = 0;
1408 u16 rpn_mask = RFCOMM_RPN_PM_ALL;
J. Suter3a5e9032005-08-09 20:28:46 -07001409
1410 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",
1411 dlci, cr, len, rpn->bit_rate, rpn->line_settings, rpn->flow_ctrl,
1412 rpn->xon_char, rpn->xoff_char, rpn->param_mask);
1413
1414 if (!cr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415 return 0;
J. Suter3a5e9032005-08-09 20:28:46 -07001416
Linus Torvalds1da177e2005-04-16 15:20:36 -07001417 if (len == 1) {
Yuri Kululin08601462010-07-23 13:57:12 +04001418 /* This is a request, return default (according to ETSI TS 07.10) settings */
1419 bit_rate = RFCOMM_RPN_BR_9600;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420 data_bits = RFCOMM_RPN_DATA_8;
1421 stop_bits = RFCOMM_RPN_STOP_1;
1422 parity = RFCOMM_RPN_PARITY_NONE;
1423 flow_ctrl = RFCOMM_RPN_FLOW_NONE;
1424 xon_char = RFCOMM_RPN_XON_CHAR;
1425 xoff_char = RFCOMM_RPN_XOFF_CHAR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426 goto rpn_out;
1427 }
J. Suter3a5e9032005-08-09 20:28:46 -07001428
1429 /* Check for sane values, ignore/accept bit_rate, 8 bits, 1 stop bit,
1430 * no parity, no flow control lines, normal XON/XOFF chars */
1431
Al Viroe8db8c92006-11-08 00:28:44 -08001432 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_BITRATE)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001433 bit_rate = rpn->bit_rate;
Yuri Kululin08601462010-07-23 13:57:12 +04001434 if (bit_rate > RFCOMM_RPN_BR_230400) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435 BT_DBG("RPN bit rate mismatch 0x%x", bit_rate);
Yuri Kululin08601462010-07-23 13:57:12 +04001436 bit_rate = RFCOMM_RPN_BR_9600;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437 rpn_mask ^= RFCOMM_RPN_PM_BITRATE;
1438 }
1439 }
J. Suter3a5e9032005-08-09 20:28:46 -07001440
Al Viroe8db8c92006-11-08 00:28:44 -08001441 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_DATA)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442 data_bits = __get_rpn_data_bits(rpn->line_settings);
1443 if (data_bits != RFCOMM_RPN_DATA_8) {
1444 BT_DBG("RPN data bits mismatch 0x%x", data_bits);
1445 data_bits = RFCOMM_RPN_DATA_8;
1446 rpn_mask ^= RFCOMM_RPN_PM_DATA;
1447 }
1448 }
J. Suter3a5e9032005-08-09 20:28:46 -07001449
Al Viroe8db8c92006-11-08 00:28:44 -08001450 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_STOP)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451 stop_bits = __get_rpn_stop_bits(rpn->line_settings);
1452 if (stop_bits != RFCOMM_RPN_STOP_1) {
1453 BT_DBG("RPN stop bits mismatch 0x%x", stop_bits);
1454 stop_bits = RFCOMM_RPN_STOP_1;
1455 rpn_mask ^= RFCOMM_RPN_PM_STOP;
1456 }
1457 }
J. Suter3a5e9032005-08-09 20:28:46 -07001458
Al Viroe8db8c92006-11-08 00:28:44 -08001459 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_PARITY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001460 parity = __get_rpn_parity(rpn->line_settings);
1461 if (parity != RFCOMM_RPN_PARITY_NONE) {
1462 BT_DBG("RPN parity mismatch 0x%x", parity);
1463 parity = RFCOMM_RPN_PARITY_NONE;
1464 rpn_mask ^= RFCOMM_RPN_PM_PARITY;
1465 }
1466 }
J. Suter3a5e9032005-08-09 20:28:46 -07001467
Al Viroe8db8c92006-11-08 00:28:44 -08001468 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_FLOW)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469 flow_ctrl = rpn->flow_ctrl;
1470 if (flow_ctrl != RFCOMM_RPN_FLOW_NONE) {
1471 BT_DBG("RPN flow ctrl mismatch 0x%x", flow_ctrl);
1472 flow_ctrl = RFCOMM_RPN_FLOW_NONE;
1473 rpn_mask ^= RFCOMM_RPN_PM_FLOW;
1474 }
1475 }
J. Suter3a5e9032005-08-09 20:28:46 -07001476
Al Viroe8db8c92006-11-08 00:28:44 -08001477 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_XON)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001478 xon_char = rpn->xon_char;
1479 if (xon_char != RFCOMM_RPN_XON_CHAR) {
1480 BT_DBG("RPN XON char mismatch 0x%x", xon_char);
1481 xon_char = RFCOMM_RPN_XON_CHAR;
1482 rpn_mask ^= RFCOMM_RPN_PM_XON;
1483 }
1484 }
J. Suter3a5e9032005-08-09 20:28:46 -07001485
Al Viroe8db8c92006-11-08 00:28:44 -08001486 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_XOFF)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487 xoff_char = rpn->xoff_char;
1488 if (xoff_char != RFCOMM_RPN_XOFF_CHAR) {
1489 BT_DBG("RPN XOFF char mismatch 0x%x", xoff_char);
1490 xoff_char = RFCOMM_RPN_XOFF_CHAR;
1491 rpn_mask ^= RFCOMM_RPN_PM_XOFF;
1492 }
1493 }
1494
1495rpn_out:
J. Suter3a5e9032005-08-09 20:28:46 -07001496 rfcomm_send_rpn(s, 0, dlci, bit_rate, data_bits, stop_bits,
1497 parity, flow_ctrl, xon_char, xoff_char, rpn_mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498
1499 return 0;
1500}
1501
1502static int rfcomm_recv_rls(struct rfcomm_session *s, int cr, struct sk_buff *skb)
1503{
1504 struct rfcomm_rls *rls = (void *) skb->data;
1505 u8 dlci = __get_dlci(rls->dlci);
1506
1507 BT_DBG("dlci %d cr %d status 0x%x", dlci, cr, rls->status);
J. Suter3a5e9032005-08-09 20:28:46 -07001508
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509 if (!cr)
1510 return 0;
1511
J. Suter3a5e9032005-08-09 20:28:46 -07001512 /* We should probably do something with this information here. But
1513 * for now it's sufficient just to reply -- Bluetooth 1.1 says it's
1514 * mandatory to recognise and respond to RLS */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515
1516 rfcomm_send_rls(s, 0, dlci, rls->status);
1517
1518 return 0;
1519}
1520
1521static int rfcomm_recv_msc(struct rfcomm_session *s, int cr, struct sk_buff *skb)
1522{
1523 struct rfcomm_msc *msc = (void *) skb->data;
1524 struct rfcomm_dlc *d;
1525 u8 dlci = __get_dlci(msc->dlci);
1526
1527 BT_DBG("dlci %d cr %d v24 0x%x", dlci, cr, msc->v24_sig);
1528
1529 d = rfcomm_dlc_get(s, dlci);
J. Suter3a5e9032005-08-09 20:28:46 -07001530 if (!d)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531 return 0;
1532
1533 if (cr) {
1534 if (msc->v24_sig & RFCOMM_V24_FC && !d->cfc)
1535 set_bit(RFCOMM_TX_THROTTLED, &d->flags);
1536 else
1537 clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
J. Suter3a5e9032005-08-09 20:28:46 -07001538
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539 rfcomm_dlc_lock(d);
Marcel Holtmann8b6b3da2008-07-14 20:13:52 +02001540
1541 d->remote_v24_sig = msc->v24_sig;
1542
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543 if (d->modem_status)
1544 d->modem_status(d, msc->v24_sig);
Marcel Holtmann8b6b3da2008-07-14 20:13:52 +02001545
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546 rfcomm_dlc_unlock(d);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001547
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548 rfcomm_send_msc(s, 0, dlci, msc->v24_sig);
1549
1550 d->mscex |= RFCOMM_MSCEX_RX;
J. Suter3a5e9032005-08-09 20:28:46 -07001551 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552 d->mscex |= RFCOMM_MSCEX_TX;
1553
1554 return 0;
1555}
1556
1557static int rfcomm_recv_mcc(struct rfcomm_session *s, struct sk_buff *skb)
1558{
1559 struct rfcomm_mcc *mcc = (void *) skb->data;
1560 u8 type, cr, len;
1561
1562 cr = __test_cr(mcc->type);
1563 type = __get_mcc_type(mcc->type);
1564 len = __get_mcc_len(mcc->len);
1565
1566 BT_DBG("%p type 0x%x cr %d", s, type, cr);
1567
1568 skb_pull(skb, 2);
1569
1570 switch (type) {
1571 case RFCOMM_PN:
1572 rfcomm_recv_pn(s, cr, skb);
1573 break;
1574
1575 case RFCOMM_RPN:
1576 rfcomm_recv_rpn(s, cr, len, skb);
1577 break;
1578
1579 case RFCOMM_RLS:
1580 rfcomm_recv_rls(s, cr, skb);
1581 break;
1582
1583 case RFCOMM_MSC:
1584 rfcomm_recv_msc(s, cr, skb);
1585 break;
1586
1587 case RFCOMM_FCOFF:
1588 if (cr) {
1589 set_bit(RFCOMM_TX_THROTTLED, &s->flags);
1590 rfcomm_send_fcoff(s, 0);
1591 }
1592 break;
1593
1594 case RFCOMM_FCON:
1595 if (cr) {
1596 clear_bit(RFCOMM_TX_THROTTLED, &s->flags);
1597 rfcomm_send_fcon(s, 0);
1598 }
1599 break;
1600
1601 case RFCOMM_TEST:
1602 if (cr)
1603 rfcomm_send_test(s, 0, skb->data, skb->len);
1604 break;
1605
1606 case RFCOMM_NSC:
1607 break;
1608
1609 default:
1610 BT_ERR("Unknown control type 0x%02x", type);
1611 rfcomm_send_nsc(s, cr, type);
1612 break;
1613 }
1614 return 0;
1615}
1616
1617static int rfcomm_recv_data(struct rfcomm_session *s, u8 dlci, int pf, struct sk_buff *skb)
1618{
1619 struct rfcomm_dlc *d;
1620
1621 BT_DBG("session %p state %ld dlci %d pf %d", s, s->state, dlci, pf);
1622
1623 d = rfcomm_dlc_get(s, dlci);
1624 if (!d) {
1625 rfcomm_send_dm(s, dlci);
1626 goto drop;
1627 }
1628
1629 if (pf && d->cfc) {
1630 u8 credits = *(u8 *) skb->data; skb_pull(skb, 1);
1631
1632 d->tx_credits += credits;
1633 if (d->tx_credits)
1634 clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
1635 }
1636
1637 if (skb->len && d->state == BT_CONNECTED) {
1638 rfcomm_dlc_lock(d);
1639 d->rx_credits--;
1640 d->data_ready(d, skb);
1641 rfcomm_dlc_unlock(d);
1642 return 0;
1643 }
1644
1645drop:
1646 kfree_skb(skb);
1647 return 0;
1648}
1649
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001650static struct rfcomm_session *rfcomm_recv_frame(struct rfcomm_session *s,
1651 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652{
1653 struct rfcomm_hdr *hdr = (void *) skb->data;
1654 u8 type, dlci, fcs;
1655
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001656 if (!s) {
1657 /* no session, so free socket data */
1658 kfree_skb(skb);
1659 return s;
1660 }
1661
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662 dlci = __get_dlci(hdr->addr);
1663 type = __get_type(hdr->ctrl);
1664
1665 /* Trim FCS */
1666 skb->len--; skb->tail--;
Arnaldo Carvalho de Melo27a884d2007-04-19 20:29:13 -07001667 fcs = *(u8 *)skb_tail_pointer(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668
1669 if (__check_fcs(skb->data, type, fcs)) {
1670 BT_ERR("bad checksum in packet");
1671 kfree_skb(skb);
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001672 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673 }
1674
1675 if (__test_ea(hdr->len))
1676 skb_pull(skb, 3);
1677 else
1678 skb_pull(skb, 4);
1679
1680 switch (type) {
1681 case RFCOMM_SABM:
1682 if (__test_pf(hdr->ctrl))
1683 rfcomm_recv_sabm(s, dlci);
1684 break;
1685
1686 case RFCOMM_DISC:
1687 if (__test_pf(hdr->ctrl))
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001688 s = rfcomm_recv_disc(s, dlci);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689 break;
1690
1691 case RFCOMM_UA:
1692 if (__test_pf(hdr->ctrl))
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001693 s = rfcomm_recv_ua(s, dlci);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694 break;
1695
1696 case RFCOMM_DM:
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001697 s = rfcomm_recv_dm(s, dlci);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 break;
1699
1700 case RFCOMM_UIH:
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001701 if (dlci) {
1702 rfcomm_recv_data(s, dlci, __test_pf(hdr->ctrl), skb);
1703 return s;
1704 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705 rfcomm_recv_mcc(s, skb);
1706 break;
1707
1708 default:
Andrei Emeltchenko5017d8d2010-09-08 16:26:53 +03001709 BT_ERR("Unknown packet type 0x%02x", type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710 break;
1711 }
1712 kfree_skb(skb);
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001713 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714}
1715
1716/* ---- Connection and data processing ---- */
1717
1718static void rfcomm_process_connect(struct rfcomm_session *s)
1719{
1720 struct rfcomm_dlc *d;
1721 struct list_head *p, *n;
1722
1723 BT_DBG("session %p state %ld", s, s->state);
1724
1725 list_for_each_safe(p, n, &s->dlcs) {
1726 d = list_entry(p, struct rfcomm_dlc, list);
1727 if (d->state == BT_CONFIG) {
1728 d->mtu = s->mtu;
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +01001729 if (rfcomm_check_security(d)) {
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001730 rfcomm_send_pn(s, 1, d);
1731 } else {
Marcel Holtmann77db1982008-07-14 20:13:45 +02001732 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
1733 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001734 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735 }
1736 }
1737}
1738
1739/* Send data queued for the DLC.
1740 * Return number of frames left in the queue.
1741 */
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001742static int rfcomm_process_tx(struct rfcomm_dlc *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743{
1744 struct sk_buff *skb;
1745 int err;
1746
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001747 BT_DBG("dlc %p state %ld cfc %d rx_credits %d tx_credits %d",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001748 d, d->state, d->cfc, d->rx_credits, d->tx_credits);
1749
1750 /* Send pending MSC */
1751 if (test_and_clear_bit(RFCOMM_MSC_PENDING, &d->flags))
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001752 rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753
1754 if (d->cfc) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001755 /* CFC enabled.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 * Give them some credits */
1757 if (!test_bit(RFCOMM_RX_THROTTLED, &d->flags) &&
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001758 d->rx_credits <= (d->cfc >> 2)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759 rfcomm_send_credits(d->session, d->addr, d->cfc - d->rx_credits);
1760 d->rx_credits = d->cfc;
1761 }
1762 } else {
1763 /* CFC disabled.
1764 * Give ourselves some credits */
1765 d->tx_credits = 5;
1766 }
1767
1768 if (test_bit(RFCOMM_TX_THROTTLED, &d->flags))
1769 return skb_queue_len(&d->tx_queue);
1770
1771 while (d->tx_credits && (skb = skb_dequeue(&d->tx_queue))) {
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001772 err = rfcomm_send_frame(d->session, skb->data, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773 if (err < 0) {
1774 skb_queue_head(&d->tx_queue, skb);
1775 break;
1776 }
1777 kfree_skb(skb);
1778 d->tx_credits--;
1779 }
1780
1781 if (d->cfc && !d->tx_credits) {
1782 /* We're out of TX credits.
1783 * Set TX_THROTTLED flag to avoid unnesary wakeups by dlc_send. */
1784 set_bit(RFCOMM_TX_THROTTLED, &d->flags);
1785 }
1786
1787 return skb_queue_len(&d->tx_queue);
1788}
1789
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001790static void rfcomm_process_dlcs(struct rfcomm_session *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791{
1792 struct rfcomm_dlc *d;
1793 struct list_head *p, *n;
1794
1795 BT_DBG("session %p state %ld", s, s->state);
1796
1797 list_for_each_safe(p, n, &s->dlcs) {
1798 d = list_entry(p, struct rfcomm_dlc, list);
1799
1800 if (test_bit(RFCOMM_TIMED_OUT, &d->flags)) {
1801 __rfcomm_dlc_close(d, ETIMEDOUT);
1802 continue;
1803 }
1804
Szymon Jancdb544672011-09-26 14:19:47 +02001805 if (test_bit(RFCOMM_ENC_DROP, &d->flags)) {
1806 __rfcomm_dlc_close(d, ECONNREFUSED);
1807 continue;
1808 }
1809
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810 if (test_and_clear_bit(RFCOMM_AUTH_ACCEPT, &d->flags)) {
1811 rfcomm_dlc_clear_timer(d);
Marcel Holtmann77db1982008-07-14 20:13:45 +02001812 if (d->out) {
1813 rfcomm_send_pn(s, 1, d);
1814 rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT);
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001815 } else {
1816 if (d->defer_setup) {
1817 set_bit(RFCOMM_DEFER_SETUP, &d->flags);
1818 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
Marcel Holtmann8bf47942009-02-16 02:59:49 +01001819
1820 rfcomm_dlc_lock(d);
1821 d->state = BT_CONNECT2;
1822 d->state_change(d, 0);
1823 rfcomm_dlc_unlock(d);
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001824 } else
1825 rfcomm_dlc_accept(d);
1826 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001827 continue;
1828 } else if (test_and_clear_bit(RFCOMM_AUTH_REJECT, &d->flags)) {
1829 rfcomm_dlc_clear_timer(d);
Marcel Holtmann77db1982008-07-14 20:13:45 +02001830 if (!d->out)
1831 rfcomm_send_dm(s, d->dlci);
1832 else
1833 d->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834 __rfcomm_dlc_close(d, ECONNREFUSED);
1835 continue;
1836 }
1837
Jaikumar Ganesh6e1031a2009-02-02 18:03:57 -08001838 if (test_bit(RFCOMM_SEC_PENDING, &d->flags))
1839 continue;
1840
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 if (test_bit(RFCOMM_TX_THROTTLED, &s->flags))
1842 continue;
1843
1844 if ((d->state == BT_CONNECTED || d->state == BT_DISCONN) &&
Marcel Holtmann77db1982008-07-14 20:13:45 +02001845 d->mscex == RFCOMM_MSCEX_OK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846 rfcomm_process_tx(d);
1847 }
1848}
1849
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001850static struct rfcomm_session *rfcomm_process_rx(struct rfcomm_session *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851{
1852 struct socket *sock = s->sock;
1853 struct sock *sk = sock->sk;
1854 struct sk_buff *skb;
1855
1856 BT_DBG("session %p state %ld qlen %d", s, s->state, skb_queue_len(&sk->sk_receive_queue));
1857
1858 /* Get data directly from socket receive queue without copying it. */
1859 while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
1860 skb_orphan(skb);
Mat Martineau44935722011-07-22 14:53:58 -07001861 if (!skb_linearize(skb))
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001862 s = rfcomm_recv_frame(s, skb);
Mat Martineau44935722011-07-22 14:53:58 -07001863 else
1864 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865 }
1866
Dean Jenkins08c30ac2013-02-28 14:21:56 +00001867 if (s && (sk->sk_state == BT_CLOSED))
1868 s = rfcomm_session_close(s, sk->sk_err);
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001869
1870 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871}
1872
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001873static void rfcomm_accept_connection(struct rfcomm_session *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001874{
1875 struct socket *sock = s->sock, *nsock;
1876 int err;
1877
1878 /* Fast check for a new connection.
1879 * Avoids unnesesary socket allocations. */
1880 if (list_empty(&bt_sk(sock->sk)->accept_q))
1881 return;
1882
1883 BT_DBG("session %p", s);
1884
Marcel Holtmann48db9ca2007-05-05 00:36:06 +02001885 err = kernel_accept(sock, &nsock, O_NONBLOCK);
1886 if (err < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887 return;
1888
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889 /* Set our callbacks */
1890 nsock->sk->sk_data_ready = rfcomm_l2data_ready;
1891 nsock->sk->sk_state_change = rfcomm_l2state_change;
1892
1893 s = rfcomm_session_add(nsock, BT_OPEN);
1894 if (s) {
Marcel Holtmann98bcd082006-07-14 11:42:12 +02001895 /* We should adjust MTU on incoming sessions.
1896 * L2CAP MTU minus UIH header and FCS. */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001897 s->mtu = min(l2cap_pi(nsock->sk)->chan->omtu,
1898 l2cap_pi(nsock->sk)->chan->imtu) - 5;
Marcel Holtmann98bcd082006-07-14 11:42:12 +02001899
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +03001900 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901 } else
1902 sock_release(nsock);
1903}
1904
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001905static struct rfcomm_session *rfcomm_check_connection(struct rfcomm_session *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001906{
1907 struct sock *sk = s->sock->sk;
1908
1909 BT_DBG("%p state %ld", s, s->state);
1910
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +02001911 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912 case BT_CONNECTED:
1913 s->state = BT_CONNECT;
1914
1915 /* We can adjust MTU on outgoing sessions.
1916 * L2CAP MTU minus UIH header and FCS. */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001917 s->mtu = min(l2cap_pi(sk)->chan->omtu, l2cap_pi(sk)->chan->imtu) - 5;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918
1919 rfcomm_send_sabm(s, 0);
1920 break;
1921
1922 case BT_CLOSED:
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001923 s = rfcomm_session_close(s, sk->sk_err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924 break;
1925 }
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001926 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001927}
1928
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001929static void rfcomm_process_sessions(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001930{
1931 struct list_head *p, *n;
1932
1933 rfcomm_lock();
1934
1935 list_for_each_safe(p, n, &session_list) {
1936 struct rfcomm_session *s;
1937 s = list_entry(p, struct rfcomm_session, list);
1938
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -03001939 if (test_and_clear_bit(RFCOMM_TIMED_OUT, &s->flags)) {
1940 s->state = BT_DISCONN;
1941 rfcomm_send_disc(s, 0);
1942 continue;
1943 }
1944
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945 if (s->state == BT_LISTEN) {
1946 rfcomm_accept_connection(s);
1947 continue;
1948 }
1949
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950 switch (s->state) {
1951 case BT_BOUND:
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001952 s = rfcomm_check_connection(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001953 break;
1954
1955 default:
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001956 s = rfcomm_process_rx(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001957 break;
1958 }
1959
Dean Jenkins8ff52f72013-02-28 14:21:55 +00001960 if (s)
1961 rfcomm_process_dlcs(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001962 }
1963
1964 rfcomm_unlock();
1965}
1966
Linus Torvalds1da177e2005-04-16 15:20:36 -07001967static int rfcomm_add_listener(bdaddr_t *ba)
1968{
1969 struct sockaddr_l2 addr;
1970 struct socket *sock;
1971 struct sock *sk;
1972 struct rfcomm_session *s;
1973 int err = 0;
1974
1975 /* Create socket */
1976 err = rfcomm_l2sock_create(&sock);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001977 if (err < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001978 BT_ERR("Create socket failed %d", err);
1979 return err;
1980 }
1981
1982 /* Bind socket */
1983 bacpy(&addr.l2_bdaddr, ba);
1984 addr.l2_family = AF_BLUETOOTH;
Syam Sidhardhan5bcb8092012-10-10 22:09:29 +05301985 addr.l2_psm = __constant_cpu_to_le16(RFCOMM_PSM);
Marcel Holtmann37e62f52009-02-17 21:49:33 +01001986 addr.l2_cid = 0;
Seung-Woo Kimc507f132013-11-05 16:02:24 +09001987 addr.l2_bdaddr_type = BDADDR_BREDR;
Marcel Holtmann48db9ca2007-05-05 00:36:06 +02001988 err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001989 if (err < 0) {
1990 BT_ERR("Bind failed %d", err);
1991 goto failed;
1992 }
1993
1994 /* Set L2CAP options */
1995 sk = sock->sk;
1996 lock_sock(sk);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001997 l2cap_pi(sk)->chan->imtu = l2cap_mtu;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001998 release_sock(sk);
1999
2000 /* Start listening on the socket */
Marcel Holtmann48db9ca2007-05-05 00:36:06 +02002001 err = kernel_listen(sock, 10);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002002 if (err) {
2003 BT_ERR("Listen failed %d", err);
2004 goto failed;
2005 }
2006
2007 /* Add listening session */
2008 s = rfcomm_session_add(sock, BT_LISTEN);
Wei Yongjun0227c7b2013-03-20 20:23:37 +08002009 if (!s) {
2010 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002011 goto failed;
Wei Yongjun0227c7b2013-03-20 20:23:37 +08002012 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002013
Linus Torvalds1da177e2005-04-16 15:20:36 -07002014 return 0;
2015failed:
2016 sock_release(sock);
2017 return err;
2018}
2019
2020static void rfcomm_kill_listener(void)
2021{
2022 struct rfcomm_session *s;
2023 struct list_head *p, *n;
2024
2025 BT_DBG("");
2026
2027 list_for_each_safe(p, n, &session_list) {
2028 s = list_entry(p, struct rfcomm_session, list);
2029 rfcomm_session_del(s);
2030 }
2031}
2032
2033static int rfcomm_run(void *unused)
2034{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002035 BT_DBG("");
2036
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002037 set_user_nice(current, -10);
2038
Linus Torvalds1da177e2005-04-16 15:20:36 -07002039 rfcomm_add_listener(BDADDR_ANY);
2040
Peter Hurleye5842cd2011-07-24 00:10:35 -04002041 while (1) {
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002042 set_current_state(TASK_INTERRUPTIBLE);
Peter Hurleye5842cd2011-07-24 00:10:35 -04002043
2044 if (kthread_should_stop())
2045 break;
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002046
2047 /* Process stuff */
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002048 rfcomm_process_sessions();
Peter Hurleye5842cd2011-07-24 00:10:35 -04002049
2050 schedule();
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002051 }
Peter Hurleye5842cd2011-07-24 00:10:35 -04002052 __set_current_state(TASK_RUNNING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002053
2054 rfcomm_kill_listener();
2055
Linus Torvalds1da177e2005-04-16 15:20:36 -07002056 return 0;
2057}
2058
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01002059static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002060{
2061 struct rfcomm_session *s;
2062 struct rfcomm_dlc *d;
2063 struct list_head *p, *n;
2064
2065 BT_DBG("conn %p status 0x%02x encrypt 0x%02x", conn, status, encrypt);
2066
2067 s = rfcomm_session_get(&conn->hdev->bdaddr, &conn->dst);
2068 if (!s)
2069 return;
2070
Linus Torvalds1da177e2005-04-16 15:20:36 -07002071 list_for_each_safe(p, n, &s->dlcs) {
2072 d = list_entry(p, struct rfcomm_dlc, list);
2073
Marcel Holtmann8c84b832009-01-16 08:17:51 +01002074 if (test_and_clear_bit(RFCOMM_SEC_PENDING, &d->flags)) {
2075 rfcomm_dlc_clear_timer(d);
2076 if (status || encrypt == 0x00) {
Szymon Jancdb544672011-09-26 14:19:47 +02002077 set_bit(RFCOMM_ENC_DROP, &d->flags);
Marcel Holtmann8c84b832009-01-16 08:17:51 +01002078 continue;
2079 }
2080 }
2081
2082 if (d->state == BT_CONNECTED && !status && encrypt == 0x00) {
2083 if (d->sec_level == BT_SECURITY_MEDIUM) {
2084 set_bit(RFCOMM_SEC_PENDING, &d->flags);
2085 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
2086 continue;
2087 } else if (d->sec_level == BT_SECURITY_HIGH) {
Szymon Jancdb544672011-09-26 14:19:47 +02002088 set_bit(RFCOMM_ENC_DROP, &d->flags);
Marcel Holtmann8c84b832009-01-16 08:17:51 +01002089 continue;
2090 }
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02002091 }
2092
Linus Torvalds1da177e2005-04-16 15:20:36 -07002093 if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags))
2094 continue;
2095
Waldemar Rymarkiewiczb3b1b062011-05-06 09:42:31 +02002096 if (!status && hci_conn_check_secure(conn, d->sec_level))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002097 set_bit(RFCOMM_AUTH_ACCEPT, &d->flags);
2098 else
2099 set_bit(RFCOMM_AUTH_REJECT, &d->flags);
2100 }
2101
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +03002102 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002103}
2104
2105static struct hci_cb rfcomm_cb = {
2106 .name = "RFCOMM",
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01002107 .security_cfm = rfcomm_security_cfm
Linus Torvalds1da177e2005-04-16 15:20:36 -07002108};
2109
Marcel Holtmannaef7d972010-03-21 05:27:45 +01002110static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002111{
2112 struct rfcomm_session *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002113
2114 rfcomm_lock();
2115
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +02002116 list_for_each_entry(s, &session_list, list) {
2117 struct rfcomm_dlc *d;
2118 list_for_each_entry(d, &s->dlcs, list) {
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08002119 struct sock *sk = s->sock->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002120
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03002121 seq_printf(f, "%pMR %pMR %ld %d %d %d %d\n",
2122 &bt_sk(sk)->src, &bt_sk(sk)->dst,
2123 d->state, d->dlci, d->mtu,
2124 d->rx_credits, d->tx_credits);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002125 }
2126 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002127
Linus Torvalds1da177e2005-04-16 15:20:36 -07002128 rfcomm_unlock();
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08002129
Marcel Holtmannaef7d972010-03-21 05:27:45 +01002130 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002131}
2132
Marcel Holtmannaef7d972010-03-21 05:27:45 +01002133static int rfcomm_dlc_debugfs_open(struct inode *inode, struct file *file)
2134{
2135 return single_open(file, rfcomm_dlc_debugfs_show, inode->i_private);
2136}
2137
2138static const struct file_operations rfcomm_dlc_debugfs_fops = {
2139 .open = rfcomm_dlc_debugfs_open,
2140 .read = seq_read,
2141 .llseek = seq_lseek,
2142 .release = single_release,
2143};
2144
2145static struct dentry *rfcomm_dlc_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002146
2147/* ---- Initialization ---- */
2148static int __init rfcomm_init(void)
2149{
Marcel Holtmann52d18342009-08-22 14:49:36 -07002150 int err;
Dave Youngaf0d3b12009-08-03 04:26:16 +00002151
Linus Torvalds1da177e2005-04-16 15:20:36 -07002152 hci_register_cb(&rfcomm_cb);
2153
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002154 rfcomm_thread = kthread_run(rfcomm_run, NULL, "krfcommd");
2155 if (IS_ERR(rfcomm_thread)) {
Marcel Holtmann52d18342009-08-22 14:49:36 -07002156 err = PTR_ERR(rfcomm_thread);
2157 goto unregister;
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002158 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002159
Marcel Holtmannaef7d972010-03-21 05:27:45 +01002160 if (bt_debugfs) {
2161 rfcomm_dlc_debugfs = debugfs_create_file("rfcomm_dlc", 0444,
2162 bt_debugfs, NULL, &rfcomm_dlc_debugfs_fops);
2163 if (!rfcomm_dlc_debugfs)
2164 BT_ERR("Failed to create RFCOMM debug file");
2165 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002166
Marcel Holtmann52d18342009-08-22 14:49:36 -07002167 err = rfcomm_init_ttys();
2168 if (err < 0)
2169 goto stop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002170
Marcel Holtmann52d18342009-08-22 14:49:36 -07002171 err = rfcomm_init_sockets();
2172 if (err < 0)
2173 goto cleanup;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002174
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08002175 BT_INFO("RFCOMM ver %s", VERSION);
2176
Linus Torvalds1da177e2005-04-16 15:20:36 -07002177 return 0;
Dave Youngaf0d3b12009-08-03 04:26:16 +00002178
Marcel Holtmann52d18342009-08-22 14:49:36 -07002179cleanup:
Dave Youngaf0d3b12009-08-03 04:26:16 +00002180 rfcomm_cleanup_ttys();
Marcel Holtmann52d18342009-08-22 14:49:36 -07002181
2182stop:
Dave Youngaf0d3b12009-08-03 04:26:16 +00002183 kthread_stop(rfcomm_thread);
Marcel Holtmann52d18342009-08-22 14:49:36 -07002184
2185unregister:
Dave Youngaf0d3b12009-08-03 04:26:16 +00002186 hci_unregister_cb(&rfcomm_cb);
2187
Marcel Holtmann52d18342009-08-22 14:49:36 -07002188 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002189}
2190
2191static void __exit rfcomm_exit(void)
2192{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01002193 debugfs_remove(rfcomm_dlc_debugfs);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08002194
Linus Torvalds1da177e2005-04-16 15:20:36 -07002195 hci_unregister_cb(&rfcomm_cb);
2196
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002197 kthread_stop(rfcomm_thread);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002198
Linus Torvalds1da177e2005-04-16 15:20:36 -07002199 rfcomm_cleanup_ttys();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002200
2201 rfcomm_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002202}
2203
2204module_init(rfcomm_init);
2205module_exit(rfcomm_exit);
2206
Marcel Holtmann7c2660b2006-07-03 10:02:51 +02002207module_param(disable_cfc, bool, 0644);
2208MODULE_PARM_DESC(disable_cfc, "Disable credit based flow control");
2209
Marcel Holtmann98bcd082006-07-14 11:42:12 +02002210module_param(channel_mtu, int, 0644);
2211MODULE_PARM_DESC(channel_mtu, "Default MTU for the RFCOMM channel");
2212
Marcel Holtmann56f3a402006-02-13 11:39:57 +01002213module_param(l2cap_mtu, uint, 0644);
2214MODULE_PARM_DESC(l2cap_mtu, "Default MTU for the L2CAP connection");
2215
Marcel Holtmanneae38ee2009-10-05 12:23:48 +02002216module_param(l2cap_ertm, bool, 0644);
2217MODULE_PARM_DESC(l2cap_ertm, "Use L2CAP ERTM mode for connection");
2218
Marcel Holtmann63fbd242008-08-18 13:23:53 +02002219MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002220MODULE_DESCRIPTION("Bluetooth RFCOMM ver " VERSION);
2221MODULE_VERSION(VERSION);
2222MODULE_LICENSE("GPL");
2223MODULE_ALIAS("bt-proto-3");