blob: dc4bf2f943fe8d91012e9c06dc333e9b25d7e337 [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>
29#include <linux/errno.h>
30#include <linux/kernel.h>
31#include <linux/sched.h>
32#include <linux/signal.h>
33#include <linux/init.h>
34#include <linux/wait.h>
Marcel Holtmannbe9d1222005-11-08 09:57:38 -080035#include <linux/device.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010036#include <linux/debugfs.h>
37#include <linux/seq_file.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070038#include <linux/net.h>
Arjan van de Ven4a3e2f72006-03-20 22:33:17 -080039#include <linux/mutex.h>
Marcel Holtmanna524ecc2007-10-20 21:37:20 +020040#include <linux/kthread.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090041#include <linux/slab.h>
Steve Mucklef132c6c2012-06-06 18:30:57 -070042#include <linux/interrupt.h>
Arjan van de Ven4a3e2f72006-03-20 22:33:17 -080043
Linus Torvalds1da177e2005-04-16 15:20:36 -070044#include <net/sock.h>
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +020045#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070046#include <asm/unaligned.h>
47
48#include <net/bluetooth/bluetooth.h>
49#include <net/bluetooth/hci_core.h>
50#include <net/bluetooth/l2cap.h>
51#include <net/bluetooth/rfcomm.h>
52
Marcel Holtmann5f9018a2009-01-16 10:09:50 +010053#define VERSION "1.11"
Mallikarjuna GB2da40bf2011-09-06 17:02:36 +053054/* 1 Byte DLCI, 1 Byte Control filed, 2 Bytes Length, 1 Byte for Credits,
55 * 1 Byte FCS */
56#define RFCOMM_HDR_SIZE 6
Marcel Holtmann56f3a402006-02-13 11:39:57 +010057
Rusty Russelleb939922011-12-19 14:08:01 +000058static bool disable_cfc;
59static bool l2cap_ertm;
Marcel Holtmann98bcd082006-07-14 11:42:12 +020060static int channel_mtu = -1;
Marcel Holtmann56f3a402006-02-13 11:39:57 +010061static unsigned int l2cap_mtu = RFCOMM_MAX_L2CAP_MTU;
62
Linus Torvalds1da177e2005-04-16 15:20:36 -070063static struct task_struct *rfcomm_thread;
64
Arjan van de Ven4a3e2f72006-03-20 22:33:17 -080065static DEFINE_MUTEX(rfcomm_mutex);
66#define rfcomm_lock() mutex_lock(&rfcomm_mutex)
67#define rfcomm_unlock() mutex_unlock(&rfcomm_mutex)
Linus Torvalds1da177e2005-04-16 15:20:36 -070068
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070069static unsigned long rfcomm_event;
Linus Torvalds1da177e2005-04-16 15:20:36 -070070
71static LIST_HEAD(session_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -070072
Gustavo F. Padovan54365382011-12-20 16:30:44 -020073static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len);
Linus Torvalds1da177e2005-04-16 15:20:36 -070074static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci);
75static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci);
76static int rfcomm_queue_disc(struct rfcomm_dlc *d);
77static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type);
78static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d);
79static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig);
80static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len);
81static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits);
82static void rfcomm_make_uih(struct sk_buff *skb, u8 addr);
83
84static void rfcomm_process_connect(struct rfcomm_session *s);
85
Luiz Augusto von Dentz63ce0902010-08-19 14:06:10 +030086static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
87 bdaddr_t *dst,
88 u8 sec_level,
Srinivas Krovvidi85aab232011-09-05 17:56:44 +053089 int *err,
90 u8 channel,
91 struct rfcomm_dlc *d);
Linus Torvalds1da177e2005-04-16 15:20:36 -070092static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst);
93static void rfcomm_session_del(struct rfcomm_session *s);
94
95/* ---- RFCOMM frame parsing macros ---- */
96#define __get_dlci(b) ((b & 0xfc) >> 2)
97#define __get_channel(b) ((b & 0xf8) >> 3)
98#define __get_dir(b) ((b & 0x04) >> 2)
99#define __get_type(b) ((b & 0xef))
100
101#define __test_ea(b) ((b & 0x01))
102#define __test_cr(b) ((b & 0x02))
103#define __test_pf(b) ((b & 0x10))
104
105#define __addr(cr, dlci) (((dlci & 0x3f) << 2) | (cr << 1) | 0x01)
106#define __ctrl(type, pf) (((type & 0xef) | (pf << 4)))
107#define __dlci(dir, chn) (((chn & 0x1f) << 1) | dir)
108#define __srv_channel(dlci) (dlci >> 1)
109#define __dir(dlci) (dlci & 0x01)
110
111#define __len8(len) (((len) << 1) | 1)
112#define __len16(len) ((len) << 1)
113
114/* MCC macros */
115#define __mcc_type(cr, type) (((type << 2) | (cr << 1) | 0x01))
116#define __get_mcc_type(b) ((b & 0xfc) >> 2)
117#define __get_mcc_len(b) ((b & 0xfe) >> 1)
118
119/* RPN macros */
J. Suter3a5e9032005-08-09 20:28:46 -0700120#define __rpn_line_settings(data, stop, parity) ((data & 0x3) | ((stop & 0x1) << 2) | ((parity & 0x7) << 3))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121#define __get_rpn_data_bits(line) ((line) & 0x3)
122#define __get_rpn_stop_bits(line) (((line) >> 2) & 0x1)
J. Suter3a5e9032005-08-09 20:28:46 -0700123#define __get_rpn_parity(line) (((line) >> 3) & 0x7)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124
Mat Martineau8cd0df02011-08-23 16:23:36 -0700125struct rfcomm_sock_release_work {
126 struct work_struct work;
127 struct socket *sock;
128 int state;
129};
130
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300131static inline void rfcomm_schedule(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132{
133 if (!rfcomm_thread)
134 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700135 set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136 wake_up_process(rfcomm_thread);
137}
138
139static inline void rfcomm_session_put(struct rfcomm_session *s)
140{
Srinivas Krovvidiff724cc2012-07-27 11:04:05 +0530141 bool match = false;
142 struct rfcomm_session *sess;
143 struct list_head *p, *n;
144 list_for_each_safe(p, n, &session_list) {
145 sess = list_entry(p, struct rfcomm_session, list);
146 if (s == sess) {
147 match = true;
148 break;
149 }
150 }
151 if (!match) {
152 BT_ERR("session already freed previously");
153 dump_stack();
154 return;
155 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156 if (atomic_dec_and_test(&s->refcnt))
157 rfcomm_session_del(s);
158}
159
160/* ---- RFCOMM FCS computation ---- */
161
Marcel Holtmann408c1ce2005-10-28 19:20:36 +0200162/* reversed, 8-bit, poly=0x07 */
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900163static unsigned char rfcomm_crc_table[256] = {
Marcel Holtmann408c1ce2005-10-28 19:20:36 +0200164 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
165 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
166 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
167 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
168
169 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
170 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
171 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
172 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
173
174 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
175 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
176 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
177 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
178
179 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
180 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
181 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
182 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
183
184 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
185 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
186 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
187 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
188
189 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
190 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
191 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
192 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
193
194 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
195 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
196 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
197 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
198
199 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
200 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
201 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
202 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
203};
204
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205/* CRC on 2 bytes */
206#define __crc(data) (rfcomm_crc_table[rfcomm_crc_table[0xff ^ data[0]] ^ data[1]])
207
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900208/* FCS on 2 bytes */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209static inline u8 __fcs(u8 *data)
210{
Eric Dumazeta02cec22010-09-22 20:43:57 +0000211 return 0xff - __crc(data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212}
213
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900214/* FCS on 3 bytes */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215static inline u8 __fcs2(u8 *data)
216{
Eric Dumazeta02cec22010-09-22 20:43:57 +0000217 return 0xff - rfcomm_crc_table[__crc(data) ^ data[2]];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218}
219
220/* Check FCS */
221static inline int __check_fcs(u8 *data, int type, u8 fcs)
222{
223 u8 f = __crc(data);
224
225 if (type != RFCOMM_UIH)
226 f = rfcomm_crc_table[f ^ data[2]];
227
228 return rfcomm_crc_table[f ^ fcs] != 0xcf;
229}
230
231/* ---- L2CAP callbacks ---- */
232static void rfcomm_l2state_change(struct sock *sk)
233{
234 BT_DBG("%p state %d", sk, sk->sk_state);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300235 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236}
237
238static void rfcomm_l2data_ready(struct sock *sk, int bytes)
239{
240 BT_DBG("%p bytes %d", sk, bytes);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300241 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242}
243
244static int rfcomm_l2sock_create(struct socket **sock)
245{
246 int err;
247
248 BT_DBG("");
249
250 err = sock_create_kern(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP, sock);
251 if (!err) {
252 struct sock *sk = (*sock)->sk;
253 sk->sk_data_ready = rfcomm_l2data_ready;
254 sk->sk_state_change = rfcomm_l2state_change;
255 }
256 return err;
257}
258
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100259static inline int rfcomm_check_security(struct rfcomm_dlc *d)
Marcel Holtmann77db1982008-07-14 20:13:45 +0200260{
261 struct sock *sk = d->session->sock->sk;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100262 __u8 auth_type;
Marcel Holtmann77db1982008-07-14 20:13:45 +0200263
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100264 switch (d->sec_level) {
265 case BT_SECURITY_HIGH:
266 auth_type = HCI_AT_GENERAL_BONDING_MITM;
267 break;
268 case BT_SECURITY_MEDIUM:
269 auth_type = HCI_AT_GENERAL_BONDING;
270 break;
271 default:
272 auth_type = HCI_AT_NO_BONDING;
273 break;
274 }
275
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700276 return hci_conn_security(l2cap_pi(sk)->conn->hcon, d->sec_level,
277 auth_type);
Marcel Holtmann77db1982008-07-14 20:13:45 +0200278}
279
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300280static void rfcomm_session_timeout(unsigned long arg)
281{
282 struct rfcomm_session *s = (void *) arg;
283
284 BT_DBG("session %p state %ld", s, s->state);
285
286 set_bit(RFCOMM_TIMED_OUT, &s->flags);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300287 rfcomm_schedule();
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300288}
289
290static void rfcomm_session_set_timer(struct rfcomm_session *s, long timeout)
291{
292 BT_DBG("session %p state %ld timeout %ld", s, s->state, timeout);
293
294 if (!mod_timer(&s->timer, jiffies + timeout))
295 rfcomm_session_hold(s);
296}
297
298static void rfcomm_session_clear_timer(struct rfcomm_session *s)
299{
300 BT_DBG("session %p state %ld", s, s->state);
301
302 if (timer_pending(&s->timer) && del_timer(&s->timer))
303 rfcomm_session_put(s);
304}
305
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306/* ---- RFCOMM DLCs ---- */
307static void rfcomm_dlc_timeout(unsigned long arg)
308{
309 struct rfcomm_dlc *d = (void *) arg;
310
311 BT_DBG("dlc %p state %ld", d, d->state);
312
313 set_bit(RFCOMM_TIMED_OUT, &d->flags);
314 rfcomm_dlc_put(d);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300315 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316}
317
318static void rfcomm_dlc_set_timer(struct rfcomm_dlc *d, long timeout)
319{
320 BT_DBG("dlc %p state %ld timeout %ld", d, d->state, timeout);
321
322 if (!mod_timer(&d->timer, jiffies + timeout))
323 rfcomm_dlc_hold(d);
324}
325
326static void rfcomm_dlc_clear_timer(struct rfcomm_dlc *d)
327{
328 BT_DBG("dlc %p state %ld", d, d->state);
329
330 if (timer_pending(&d->timer) && del_timer(&d->timer))
331 rfcomm_dlc_put(d);
332}
333
334static void rfcomm_dlc_clear_state(struct rfcomm_dlc *d)
335{
336 BT_DBG("%p", d);
337
338 d->state = BT_OPEN;
339 d->flags = 0;
340 d->mscex = 0;
Johan Hedberg183f7322010-12-06 15:56:17 +0200341 d->sec_level = BT_SECURITY_LOW;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 d->mtu = RFCOMM_DEFAULT_MTU;
343 d->v24_sig = RFCOMM_V24_RTC | RFCOMM_V24_RTR | RFCOMM_V24_DV;
344
345 d->cfc = RFCOMM_CFC_DISABLED;
346 d->rx_credits = RFCOMM_DEFAULT_CREDITS;
347}
348
Al Virodd0fc662005-10-07 07:46:04 +0100349struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350{
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200351 struct rfcomm_dlc *d = kzalloc(sizeof(*d), prio);
352
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353 if (!d)
354 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355
Pavel Emelyanovb24b8a22008-01-23 21:20:07 -0800356 setup_timer(&d->timer, rfcomm_dlc_timeout, (unsigned long)d);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357
358 skb_queue_head_init(&d->tx_queue);
359 spin_lock_init(&d->lock);
360 atomic_set(&d->refcnt, 1);
361
362 rfcomm_dlc_clear_state(d);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900363
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364 BT_DBG("%p", d);
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200365
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 return d;
367}
368
369void rfcomm_dlc_free(struct rfcomm_dlc *d)
370{
371 BT_DBG("%p", d);
372
373 skb_queue_purge(&d->tx_queue);
374 kfree(d);
375}
376
377static void rfcomm_dlc_link(struct rfcomm_session *s, struct rfcomm_dlc *d)
378{
379 BT_DBG("dlc %p session %p", d, s);
380
381 rfcomm_session_hold(s);
382
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300383 rfcomm_session_clear_timer(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384 rfcomm_dlc_hold(d);
385 list_add(&d->list, &s->dlcs);
386 d->session = s;
387}
388
389static void rfcomm_dlc_unlink(struct rfcomm_dlc *d)
390{
391 struct rfcomm_session *s = d->session;
392
393 BT_DBG("dlc %p refcnt %d session %p", d, atomic_read(&d->refcnt), s);
394
395 list_del(&d->list);
396 d->session = NULL;
397 rfcomm_dlc_put(d);
398
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300399 if (list_empty(&s->dlcs))
400 rfcomm_session_set_timer(s, RFCOMM_IDLE_TIMEOUT);
401
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402 rfcomm_session_put(s);
403}
404
405static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, u8 dlci)
406{
407 struct rfcomm_dlc *d;
408 struct list_head *p;
409
410 list_for_each(p, &s->dlcs) {
411 d = list_entry(p, struct rfcomm_dlc, list);
412 if (d->dlci == dlci)
413 return d;
414 }
415 return NULL;
416}
417
418static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
419{
420 struct rfcomm_session *s;
421 int err = 0;
422 u8 dlci;
423
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900424 BT_DBG("dlc %p state %ld %s %s channel %d",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425 d, d->state, batostr(src), batostr(dst), channel);
426
427 if (channel < 1 || channel > 30)
428 return -EINVAL;
429
430 if (d->state != BT_OPEN && d->state != BT_CLOSED)
431 return 0;
432
433 s = rfcomm_session_get(src, dst);
434 if (!s) {
Srinivas Krovvidi85aab232011-09-05 17:56:44 +0530435 s = rfcomm_session_create(src, dst,
436 d->sec_level, &err, channel, d);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437 if (!s)
438 return err;
Srinivas Krovvidi85aab232011-09-05 17:56:44 +0530439 } else {
440 dlci = __dlci(!s->initiator, channel);
441
442 /* Check if DLCI already exists */
443 if (rfcomm_dlc_get(s, dlci))
444 return -EBUSY;
445
446 rfcomm_dlc_clear_state(d);
447
448 d->dlci = dlci;
449 d->addr = __addr(s->initiator, dlci);
450 d->priority = 7;
451
452 d->state = BT_CONFIG;
453 rfcomm_dlc_link(s, d);
454
455 d->out = 1;
456
457 d->mtu = s->mtu;
458 d->cfc = (s->cfc == RFCOMM_CFC_UNKNOWN) ? 0 : s->cfc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459 }
Marcel Holtmann77db1982008-07-14 20:13:45 +0200460 if (s->state == BT_CONNECTED) {
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +0100461 if (rfcomm_check_security(d))
Marcel Holtmann77db1982008-07-14 20:13:45 +0200462 rfcomm_send_pn(s, 1, d);
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100463 else
464 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
Marcel Holtmann77db1982008-07-14 20:13:45 +0200465 }
466
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467 rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT);
Marcel Holtmann77db1982008-07-14 20:13:45 +0200468
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469 return 0;
470}
471
472int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
473{
474 int r;
475
476 rfcomm_lock();
477
478 r = __rfcomm_dlc_open(d, src, dst, channel);
479
480 rfcomm_unlock();
481 return r;
482}
483
484static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
485{
486 struct rfcomm_session *s = d->session;
487 if (!s)
488 return 0;
489
490 BT_DBG("dlc %p state %ld dlci %d err %d session %p",
491 d, d->state, d->dlci, err, s);
492
493 switch (d->state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494 case BT_CONNECT:
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100495 if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
496 set_bit(RFCOMM_AUTH_REJECT, &d->flags);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300497 rfcomm_schedule();
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100498 break;
499 }
500 /* Fall through */
501
502 case BT_CONNECTED:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503 d->state = BT_DISCONN;
504 if (skb_queue_empty(&d->tx_queue)) {
505 rfcomm_send_disc(s, d->dlci);
506 rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT);
507 } else {
508 rfcomm_queue_disc(d);
509 rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT * 2);
510 }
511 break;
512
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100513 case BT_OPEN:
Marcel Holtmann8bf47942009-02-16 02:59:49 +0100514 case BT_CONNECT2:
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100515 if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
516 set_bit(RFCOMM_AUTH_REJECT, &d->flags);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300517 rfcomm_schedule();
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +0100518 break;
519 }
520 /* Fall through */
521
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522 default:
523 rfcomm_dlc_clear_timer(d);
524
525 rfcomm_dlc_lock(d);
526 d->state = BT_CLOSED;
Dave Young1905f6c2008-04-01 23:59:06 -0700527 d->state_change(d, err);
Arjan van de Ven4c8411f2008-05-29 01:32:47 -0700528 rfcomm_dlc_unlock(d);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529
530 skb_queue_purge(&d->tx_queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531 rfcomm_dlc_unlink(d);
532 }
533
534 return 0;
535}
536
537int rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
538{
539 int r;
540
541 rfcomm_lock();
542
543 r = __rfcomm_dlc_close(d, err);
544
545 rfcomm_unlock();
546 return r;
547}
548
549int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb)
550{
551 int len = skb->len;
552
553 if (d->state != BT_CONNECTED)
554 return -ENOTCONN;
555
556 BT_DBG("dlc %p mtu %d len %d", d, d->mtu, len);
557
558 if (len > d->mtu)
559 return -EINVAL;
560
561 rfcomm_make_uih(skb, d->addr);
562 skb_queue_tail(&d->tx_queue, skb);
563
564 if (!test_bit(RFCOMM_TX_THROTTLED, &d->flags))
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300565 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 return len;
567}
568
Harvey Harrisonb5606c22008-02-13 15:03:16 -0800569void __rfcomm_dlc_throttle(struct rfcomm_dlc *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570{
571 BT_DBG("dlc %p state %ld", d, d->state);
572
573 if (!d->cfc) {
574 d->v24_sig |= RFCOMM_V24_FC;
575 set_bit(RFCOMM_MSC_PENDING, &d->flags);
576 }
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300577 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578}
579
Harvey Harrisonb5606c22008-02-13 15:03:16 -0800580void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581{
582 BT_DBG("dlc %p state %ld", d, d->state);
583
584 if (!d->cfc) {
585 d->v24_sig &= ~RFCOMM_V24_FC;
586 set_bit(RFCOMM_MSC_PENDING, &d->flags);
587 }
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300588 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589}
590
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900591/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592 Set/get modem status functions use _local_ status i.e. what we report
593 to the other side.
594 Remote status is provided by dlc->modem_status() callback.
595 */
596int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig)
597{
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900598 BT_DBG("dlc %p state %ld v24_sig 0x%x",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599 d, d->state, v24_sig);
600
601 if (test_bit(RFCOMM_RX_THROTTLED, &d->flags))
602 v24_sig |= RFCOMM_V24_FC;
603 else
604 v24_sig &= ~RFCOMM_V24_FC;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900605
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606 d->v24_sig = v24_sig;
607
608 if (!test_and_set_bit(RFCOMM_MSC_PENDING, &d->flags))
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300609 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610
611 return 0;
612}
613
614int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig)
615{
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900616 BT_DBG("dlc %p state %ld v24_sig 0x%x",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617 d, d->state, d->v24_sig);
618
619 *v24_sig = d->v24_sig;
620 return 0;
621}
622
623/* ---- RFCOMM sessions ---- */
624static struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
625{
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200626 struct rfcomm_session *s = kzalloc(sizeof(*s), GFP_KERNEL);
627
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 if (!s)
629 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630
631 BT_DBG("session %p sock %p", s, sock);
632
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300633 setup_timer(&s->timer, rfcomm_session_timeout, (unsigned long) s);
634
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 INIT_LIST_HEAD(&s->dlcs);
636 s->state = state;
637 s->sock = sock;
638
639 s->mtu = RFCOMM_DEFAULT_MTU;
Marcel Holtmann7c2660b2006-07-03 10:02:51 +0200640 s->cfc = disable_cfc ? RFCOMM_CFC_DISABLED : RFCOMM_CFC_UNKNOWN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641
642 /* Do not increment module usage count for listening sessions.
643 * Otherwise we won't be able to unload the module. */
644 if (state != BT_LISTEN)
645 if (!try_module_get(THIS_MODULE)) {
646 kfree(s);
647 return NULL;
648 }
649
650 list_add(&s->list, &session_list);
651
652 return s;
653}
654
Mat Martineau8cd0df02011-08-23 16:23:36 -0700655static void rfcomm_sock_release_worker(struct work_struct *work)
656{
657 struct rfcomm_sock_release_work *release_work =
658 container_of(work, struct rfcomm_sock_release_work, work);
659
660 BT_DBG("sock %p", release_work->sock);
661
662 sock_release(release_work->sock);
663 if (release_work->state != BT_LISTEN)
664 module_put(THIS_MODULE);
665
666 kfree(release_work);
667}
668
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669static void rfcomm_session_del(struct rfcomm_session *s)
670{
671 int state = s->state;
Mat Martineau8cd0df02011-08-23 16:23:36 -0700672 struct socket *sock = s->sock;
673 struct rfcomm_sock_release_work *release_work;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674
675 BT_DBG("session %p state %ld", s, s->state);
676
677 list_del(&s->list);
678
679 if (state == BT_CONNECTED)
680 rfcomm_send_disc(s, 0);
681
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300682 rfcomm_session_clear_timer(s);
Mat Martineau8cd0df02011-08-23 16:23:36 -0700683
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684 kfree(s);
685
Mat Martineau8cd0df02011-08-23 16:23:36 -0700686 release_work = kzalloc(sizeof(*release_work), GFP_ATOMIC);
687 if (release_work) {
688 INIT_WORK(&release_work->work, rfcomm_sock_release_worker);
689 release_work->sock = sock;
690 release_work->state = state;
691
692 if (!schedule_work(&release_work->work))
693 kfree(release_work);
694 }
695
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696}
697
698static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
699{
700 struct rfcomm_session *s;
701 struct list_head *p, *n;
702 struct bt_sock *sk;
703 list_for_each_safe(p, n, &session_list) {
704 s = list_entry(p, struct rfcomm_session, list);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900705 sk = bt_sk(s->sock->sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706
707 if ((!bacmp(src, BDADDR_ANY) || !bacmp(&sk->src, src)) &&
708 !bacmp(&sk->dst, dst))
709 return s;
710 }
711 return NULL;
712}
713
714static void rfcomm_session_close(struct rfcomm_session *s, int err)
715{
716 struct rfcomm_dlc *d;
717 struct list_head *p, *n;
718
719 BT_DBG("session %p state %ld err %d", s, s->state, err);
720
721 rfcomm_session_hold(s);
722
723 s->state = BT_CLOSED;
724
725 /* Close all dlcs */
726 list_for_each_safe(p, n, &s->dlcs) {
727 d = list_entry(p, struct rfcomm_dlc, list);
728 d->state = BT_CLOSED;
729 __rfcomm_dlc_close(d, err);
730 }
731
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -0300732 rfcomm_session_clear_timer(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733 rfcomm_session_put(s);
734}
735
Luiz Augusto von Dentz63ce0902010-08-19 14:06:10 +0300736static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
737 bdaddr_t *dst,
738 u8 sec_level,
Srinivas Krovvidi85aab232011-09-05 17:56:44 +0530739 int *err,
740 u8 channel,
741 struct rfcomm_dlc *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742{
743 struct rfcomm_session *s = NULL;
744 struct sockaddr_l2 addr;
745 struct socket *sock;
746 struct sock *sk;
Srinivas Krovvidi85aab232011-09-05 17:56:44 +0530747 u8 dlci;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700748
749 BT_DBG("%s %s", batostr(src), batostr(dst));
750
751 *err = rfcomm_l2sock_create(&sock);
752 if (*err < 0)
753 return NULL;
754
755 bacpy(&addr.l2_bdaddr, src);
756 addr.l2_family = AF_BLUETOOTH;
757 addr.l2_psm = 0;
Marcel Holtmann37e62f52009-02-17 21:49:33 +0100758 addr.l2_cid = 0;
Marcel Holtmann48db9ca2007-05-05 00:36:06 +0200759 *err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760 if (*err < 0)
761 goto failed;
762
763 /* Set L2CAP options */
764 sk = sock->sk;
765 lock_sock(sk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700766 l2cap_pi(sk)->imtu = l2cap_mtu;
767 l2cap_pi(sk)->sec_level = sec_level;
Marcel Holtmanneae38ee2009-10-05 12:23:48 +0200768 if (l2cap_ertm)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700769 l2cap_pi(sk)->mode = L2CAP_MODE_ERTM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770 release_sock(sk);
771
772 s = rfcomm_session_add(sock, BT_BOUND);
773 if (!s) {
774 *err = -ENOMEM;
775 goto failed;
776 }
777
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778 s->initiator = 1;
779
780 bacpy(&addr.l2_bdaddr, dst);
781 addr.l2_family = AF_BLUETOOTH;
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200782 addr.l2_psm = cpu_to_le16(RFCOMM_PSM);
Marcel Holtmann37e62f52009-02-17 21:49:33 +0100783 addr.l2_cid = 0;
Srinivas Krovvidi85aab232011-09-05 17:56:44 +0530784 dlci = __dlci(!s->initiator, channel);
785
786 /* Check if DLCI already exists */
787 if (rfcomm_dlc_get(s, dlci))
788 return NULL;
789
790 rfcomm_dlc_clear_state(d);
791
792 d->dlci = dlci;
793 d->addr = __addr(s->initiator, dlci);
794 d->priority = 7;
795
796 d->state = BT_CONFIG;
797 rfcomm_dlc_link(s, d);
798
799 d->out = 1;
800
801 d->mtu = s->mtu;
802 d->cfc = (s->cfc == RFCOMM_CFC_UNKNOWN) ? 0 : s->cfc;
Marcel Holtmann48db9ca2007-05-05 00:36:06 +0200803 *err = kernel_connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);
Marcel Holtmannb4c612a2006-09-23 09:54:38 +0200804 if (*err == 0 || *err == -EINPROGRESS)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805 return s;
Srinivas Krovvidi85aab232011-09-05 17:56:44 +0530806 BT_ERR("error ret is %d, going to delete session", *err);
807 rfcomm_dlc_unlink(d);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808 return NULL;
809
810failed:
811 sock_release(sock);
812 return NULL;
813}
814
815void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst)
816{
817 struct sock *sk = s->sock->sk;
818 if (src)
819 bacpy(src, &bt_sk(sk)->src);
820 if (dst)
821 bacpy(dst, &bt_sk(sk)->dst);
822}
823
824/* ---- RFCOMM frame sending ---- */
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200825static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826{
827 struct socket *sock = s->sock;
828 struct kvec iv = { data, len };
829 struct msghdr msg;
830
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200831 BT_DBG("session %p len %d", s, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832
833 memset(&msg, 0, sizeof(msg));
834
835 return kernel_sendmsg(sock, &msg, &iv, 1, len);
Luiz Augusto von Dentz262038f2011-11-01 10:58:58 +0200836}
837
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci)
839{
840 struct rfcomm_cmd cmd;
841
842 BT_DBG("%p dlci %d", s, dlci);
843
844 cmd.addr = __addr(s->initiator, dlci);
845 cmd.ctrl = __ctrl(RFCOMM_SABM, 1);
846 cmd.len = __len8(0);
847 cmd.fcs = __fcs2((u8 *) &cmd);
848
849 return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
850}
851
852static int rfcomm_send_ua(struct rfcomm_session *s, u8 dlci)
853{
854 struct rfcomm_cmd cmd;
855
856 BT_DBG("%p dlci %d", s, dlci);
857
858 cmd.addr = __addr(!s->initiator, dlci);
859 cmd.ctrl = __ctrl(RFCOMM_UA, 1);
860 cmd.len = __len8(0);
861 cmd.fcs = __fcs2((u8 *) &cmd);
862
863 return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
864}
865
866static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci)
867{
868 struct rfcomm_cmd cmd;
869
870 BT_DBG("%p dlci %d", s, dlci);
871
872 cmd.addr = __addr(s->initiator, dlci);
873 cmd.ctrl = __ctrl(RFCOMM_DISC, 1);
874 cmd.len = __len8(0);
875 cmd.fcs = __fcs2((u8 *) &cmd);
876
877 return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
878}
879
880static int rfcomm_queue_disc(struct rfcomm_dlc *d)
881{
882 struct rfcomm_cmd *cmd;
883 struct sk_buff *skb;
884
885 BT_DBG("dlc %p dlci %d", d, d->dlci);
886
887 skb = alloc_skb(sizeof(*cmd), GFP_KERNEL);
888 if (!skb)
889 return -ENOMEM;
890
891 cmd = (void *) __skb_put(skb, sizeof(*cmd));
892 cmd->addr = d->addr;
893 cmd->ctrl = __ctrl(RFCOMM_DISC, 1);
894 cmd->len = __len8(0);
895 cmd->fcs = __fcs2((u8 *) cmd);
896
897 skb_queue_tail(&d->tx_queue, skb);
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +0300898 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700899 return 0;
900}
901
902static int rfcomm_send_dm(struct rfcomm_session *s, u8 dlci)
903{
904 struct rfcomm_cmd cmd;
905
906 BT_DBG("%p dlci %d", s, dlci);
907
908 cmd.addr = __addr(!s->initiator, dlci);
909 cmd.ctrl = __ctrl(RFCOMM_DM, 1);
910 cmd.len = __len8(0);
911 cmd.fcs = __fcs2((u8 *) &cmd);
912
913 return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
914}
915
916static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type)
917{
918 struct rfcomm_hdr *hdr;
919 struct rfcomm_mcc *mcc;
920 u8 buf[16], *ptr = buf;
921
922 BT_DBG("%p cr %d type %d", s, cr, type);
923
924 hdr = (void *) ptr; ptr += sizeof(*hdr);
925 hdr->addr = __addr(s->initiator, 0);
926 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
927 hdr->len = __len8(sizeof(*mcc) + 1);
928
929 mcc = (void *) ptr; ptr += sizeof(*mcc);
930 mcc->type = __mcc_type(cr, RFCOMM_NSC);
931 mcc->len = __len8(1);
932
933 /* Type that we didn't like */
934 *ptr = __mcc_type(cr, type); ptr++;
935
936 *ptr = __fcs(buf); ptr++;
937
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200938 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939}
940
941static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d)
942{
943 struct rfcomm_hdr *hdr;
944 struct rfcomm_mcc *mcc;
945 struct rfcomm_pn *pn;
946 u8 buf[16], *ptr = buf;
947
948 BT_DBG("%p cr %d dlci %d mtu %d", s, cr, d->dlci, d->mtu);
949
950 hdr = (void *) ptr; ptr += sizeof(*hdr);
951 hdr->addr = __addr(s->initiator, 0);
952 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
953 hdr->len = __len8(sizeof(*mcc) + sizeof(*pn));
954
955 mcc = (void *) ptr; ptr += sizeof(*mcc);
956 mcc->type = __mcc_type(cr, RFCOMM_PN);
957 mcc->len = __len8(sizeof(*pn));
958
959 pn = (void *) ptr; ptr += sizeof(*pn);
960 pn->dlci = d->dlci;
961 pn->priority = d->priority;
962 pn->ack_timer = 0;
963 pn->max_retrans = 0;
964
965 if (s->cfc) {
966 pn->flow_ctrl = cr ? 0xf0 : 0xe0;
967 pn->credits = RFCOMM_DEFAULT_CREDITS;
968 } else {
969 pn->flow_ctrl = 0;
970 pn->credits = 0;
971 }
972
Marcel Holtmann98bcd082006-07-14 11:42:12 +0200973 if (cr && channel_mtu >= 0)
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200974 pn->mtu = cpu_to_le16(channel_mtu);
Marcel Holtmann98bcd082006-07-14 11:42:12 +0200975 else
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200976 pn->mtu = cpu_to_le16(d->mtu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977
978 *ptr = __fcs(buf); ptr++;
979
Gustavo F. Padovan54365382011-12-20 16:30:44 -0200980 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981}
982
J. Suter3a5e9032005-08-09 20:28:46 -0700983int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci,
984 u8 bit_rate, u8 data_bits, u8 stop_bits,
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900985 u8 parity, u8 flow_ctrl_settings,
J. Suter3a5e9032005-08-09 20:28:46 -0700986 u8 xon_char, u8 xoff_char, u16 param_mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987{
988 struct rfcomm_hdr *hdr;
989 struct rfcomm_mcc *mcc;
990 struct rfcomm_rpn *rpn;
991 u8 buf[16], *ptr = buf;
992
993 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 +0900994 " flwc_s 0x%x xon_c 0x%x xoff_c 0x%x p_mask 0x%x",
995 s, cr, dlci, bit_rate, data_bits, stop_bits, parity,
J. Suter3a5e9032005-08-09 20:28:46 -0700996 flow_ctrl_settings, xon_char, xoff_char, param_mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700997
998 hdr = (void *) ptr; ptr += sizeof(*hdr);
999 hdr->addr = __addr(s->initiator, 0);
1000 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
1001 hdr->len = __len8(sizeof(*mcc) + sizeof(*rpn));
1002
1003 mcc = (void *) ptr; ptr += sizeof(*mcc);
1004 mcc->type = __mcc_type(cr, RFCOMM_RPN);
1005 mcc->len = __len8(sizeof(*rpn));
1006
1007 rpn = (void *) ptr; ptr += sizeof(*rpn);
1008 rpn->dlci = __addr(1, dlci);
1009 rpn->bit_rate = bit_rate;
1010 rpn->line_settings = __rpn_line_settings(data_bits, stop_bits, parity);
1011 rpn->flow_ctrl = flow_ctrl_settings;
1012 rpn->xon_char = xon_char;
1013 rpn->xoff_char = xoff_char;
Al Viroe8db8c92006-11-08 00:28:44 -08001014 rpn->param_mask = cpu_to_le16(param_mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015
1016 *ptr = __fcs(buf); ptr++;
1017
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001018 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001019}
1020
1021static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status)
1022{
1023 struct rfcomm_hdr *hdr;
1024 struct rfcomm_mcc *mcc;
1025 struct rfcomm_rls *rls;
1026 u8 buf[16], *ptr = buf;
1027
1028 BT_DBG("%p cr %d status 0x%x", s, cr, status);
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) + sizeof(*rls));
1034
1035 mcc = (void *) ptr; ptr += sizeof(*mcc);
1036 mcc->type = __mcc_type(cr, RFCOMM_RLS);
1037 mcc->len = __len8(sizeof(*rls));
1038
1039 rls = (void *) ptr; ptr += sizeof(*rls);
1040 rls->dlci = __addr(1, dlci);
1041 rls->status = status;
1042
1043 *ptr = __fcs(buf); ptr++;
1044
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001045 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046}
1047
1048static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig)
1049{
1050 struct rfcomm_hdr *hdr;
1051 struct rfcomm_mcc *mcc;
1052 struct rfcomm_msc *msc;
1053 u8 buf[16], *ptr = buf;
1054
1055 BT_DBG("%p cr %d v24 0x%x", s, cr, v24_sig);
1056
1057 hdr = (void *) ptr; ptr += sizeof(*hdr);
1058 hdr->addr = __addr(s->initiator, 0);
1059 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
1060 hdr->len = __len8(sizeof(*mcc) + sizeof(*msc));
1061
1062 mcc = (void *) ptr; ptr += sizeof(*mcc);
1063 mcc->type = __mcc_type(cr, RFCOMM_MSC);
1064 mcc->len = __len8(sizeof(*msc));
1065
1066 msc = (void *) ptr; ptr += sizeof(*msc);
1067 msc->dlci = __addr(1, dlci);
1068 msc->v24_sig = v24_sig | 0x01;
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_fcoff(struct rfcomm_session *s, int cr)
1076{
1077 struct rfcomm_hdr *hdr;
1078 struct rfcomm_mcc *mcc;
1079 u8 buf[16], *ptr = buf;
1080
1081 BT_DBG("%p cr %d", s, cr);
1082
1083 hdr = (void *) ptr; ptr += sizeof(*hdr);
1084 hdr->addr = __addr(s->initiator, 0);
1085 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
1086 hdr->len = __len8(sizeof(*mcc));
1087
1088 mcc = (void *) ptr; ptr += sizeof(*mcc);
1089 mcc->type = __mcc_type(cr, RFCOMM_FCOFF);
1090 mcc->len = __len8(0);
1091
1092 *ptr = __fcs(buf); ptr++;
1093
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001094 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095}
1096
1097static int rfcomm_send_fcon(struct rfcomm_session *s, int cr)
1098{
1099 struct rfcomm_hdr *hdr;
1100 struct rfcomm_mcc *mcc;
1101 u8 buf[16], *ptr = buf;
1102
1103 BT_DBG("%p cr %d", s, cr);
1104
1105 hdr = (void *) ptr; ptr += sizeof(*hdr);
1106 hdr->addr = __addr(s->initiator, 0);
1107 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
1108 hdr->len = __len8(sizeof(*mcc));
1109
1110 mcc = (void *) ptr; ptr += sizeof(*mcc);
1111 mcc->type = __mcc_type(cr, RFCOMM_FCON);
1112 mcc->len = __len8(0);
1113
1114 *ptr = __fcs(buf); ptr++;
1115
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001116 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117}
1118
1119static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len)
1120{
1121 struct socket *sock = s->sock;
1122 struct kvec iv[3];
1123 struct msghdr msg;
1124 unsigned char hdr[5], crc[1];
1125
1126 if (len > 125)
1127 return -EINVAL;
1128
1129 BT_DBG("%p cr %d", s, cr);
1130
1131 hdr[0] = __addr(s->initiator, 0);
1132 hdr[1] = __ctrl(RFCOMM_UIH, 0);
1133 hdr[2] = 0x01 | ((len + 2) << 1);
1134 hdr[3] = 0x01 | ((cr & 0x01) << 1) | (RFCOMM_TEST << 2);
1135 hdr[4] = 0x01 | (len << 1);
1136
1137 crc[0] = __fcs(hdr);
1138
1139 iv[0].iov_base = hdr;
1140 iv[0].iov_len = 5;
1141 iv[1].iov_base = pattern;
1142 iv[1].iov_len = len;
1143 iv[2].iov_base = crc;
1144 iv[2].iov_len = 1;
1145
1146 memset(&msg, 0, sizeof(msg));
1147
1148 return kernel_sendmsg(sock, &msg, iv, 3, 6 + len);
1149}
1150
1151static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits)
1152{
1153 struct rfcomm_hdr *hdr;
1154 u8 buf[16], *ptr = buf;
1155
1156 BT_DBG("%p addr %d credits %d", s, addr, credits);
1157
1158 hdr = (void *) ptr; ptr += sizeof(*hdr);
1159 hdr->addr = addr;
1160 hdr->ctrl = __ctrl(RFCOMM_UIH, 1);
1161 hdr->len = __len8(0);
1162
1163 *ptr = credits; ptr++;
1164
1165 *ptr = __fcs(buf); ptr++;
1166
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001167 return rfcomm_send_frame(s, buf, ptr - buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168}
1169
1170static void rfcomm_make_uih(struct sk_buff *skb, u8 addr)
1171{
1172 struct rfcomm_hdr *hdr;
1173 int len = skb->len;
1174 u8 *crc;
1175
1176 if (len > 127) {
1177 hdr = (void *) skb_push(skb, 4);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001178 put_unaligned(cpu_to_le16(__len16(len)), (__le16 *) &hdr->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179 } else {
1180 hdr = (void *) skb_push(skb, 3);
1181 hdr->len = __len8(len);
1182 }
1183 hdr->addr = addr;
1184 hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
1185
1186 crc = skb_put(skb, 1);
1187 *crc = __fcs((void *) hdr);
1188}
1189
1190/* ---- RFCOMM frame reception ---- */
1191static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
1192{
1193 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1194
1195 if (dlci) {
1196 /* Data channel */
1197 struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
1198 if (!d) {
1199 rfcomm_send_dm(s, dlci);
1200 return 0;
1201 }
1202
1203 switch (d->state) {
1204 case BT_CONNECT:
1205 rfcomm_dlc_clear_timer(d);
1206
1207 rfcomm_dlc_lock(d);
1208 d->state = BT_CONNECTED;
1209 d->state_change(d, 0);
1210 rfcomm_dlc_unlock(d);
1211
1212 rfcomm_send_msc(s, 1, dlci, d->v24_sig);
1213 break;
1214
1215 case BT_DISCONN:
1216 d->state = BT_CLOSED;
1217 __rfcomm_dlc_close(d, 0);
Marcel Holtmann9cf5b0e2007-05-05 00:36:13 +02001218
1219 if (list_empty(&s->dlcs)) {
1220 s->state = BT_DISCONN;
1221 rfcomm_send_disc(s, 0);
Mat Martineau79e65472011-12-06 16:23:26 -08001222 rfcomm_session_clear_timer(s);
Marcel Holtmann9cf5b0e2007-05-05 00:36:13 +02001223 }
1224
Linus Torvalds1da177e2005-04-16 15:20:36 -07001225 break;
1226 }
1227 } else {
1228 /* Control channel */
1229 switch (s->state) {
1230 case BT_CONNECT:
1231 s->state = BT_CONNECTED;
1232 rfcomm_process_connect(s);
1233 break;
Marcel Holtmann9cf5b0e2007-05-05 00:36:13 +02001234
1235 case BT_DISCONN:
Nick Pelly6c2718d2010-02-03 16:18:36 -08001236 /* When socket is closed and we are not RFCOMM
1237 * initiator rfcomm_process_rx already calls
1238 * rfcomm_session_put() */
1239 if (s->sock->sk->sk_state != BT_CLOSED)
Lukáš Turek683d9492011-01-05 02:43:59 +01001240 if (list_empty(&s->dlcs))
1241 rfcomm_session_put(s);
Marcel Holtmann9cf5b0e2007-05-05 00:36:13 +02001242 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243 }
1244 }
1245 return 0;
1246}
1247
1248static int rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci)
1249{
1250 int err = 0;
1251
1252 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1253
1254 if (dlci) {
1255 /* Data DLC */
1256 struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
1257 if (d) {
1258 if (d->state == BT_CONNECT || d->state == BT_CONFIG)
1259 err = ECONNREFUSED;
1260 else
1261 err = ECONNRESET;
1262
1263 d->state = BT_CLOSED;
1264 __rfcomm_dlc_close(d, err);
1265 }
1266 } else {
1267 if (s->state == BT_CONNECT)
1268 err = ECONNREFUSED;
1269 else
1270 err = ECONNRESET;
1271
1272 s->state = BT_CLOSED;
1273 rfcomm_session_close(s, err);
1274 }
1275 return 0;
1276}
1277
1278static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci)
1279{
1280 int err = 0;
1281
1282 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1283
1284 if (dlci) {
1285 struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
1286 if (d) {
1287 rfcomm_send_ua(s, dlci);
1288
1289 if (d->state == BT_CONNECT || d->state == BT_CONFIG)
1290 err = ECONNREFUSED;
1291 else
1292 err = ECONNRESET;
1293
1294 d->state = BT_CLOSED;
1295 __rfcomm_dlc_close(d, err);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001296 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001297 rfcomm_send_dm(s, dlci);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001298
Linus Torvalds1da177e2005-04-16 15:20:36 -07001299 } else {
1300 rfcomm_send_ua(s, 0);
1301
1302 if (s->state == BT_CONNECT)
1303 err = ECONNREFUSED;
1304 else
1305 err = ECONNRESET;
1306
1307 s->state = BT_CLOSED;
1308 rfcomm_session_close(s, err);
1309 }
1310
1311 return 0;
1312}
1313
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001314void rfcomm_dlc_accept(struct rfcomm_dlc *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315{
Marcel Holtmann300b9392006-07-03 10:37:55 +02001316 struct sock *sk = d->session->sock->sk;
1317
Linus Torvalds1da177e2005-04-16 15:20:36 -07001318 BT_DBG("dlc %p", d);
1319
1320 rfcomm_send_ua(d->session, d->dlci);
1321
Johan Hedberge2139b32009-03-26 16:41:56 +02001322 rfcomm_dlc_clear_timer(d);
1323
Linus Torvalds1da177e2005-04-16 15:20:36 -07001324 rfcomm_dlc_lock(d);
1325 d->state = BT_CONNECTED;
1326 d->state_change(d, 0);
1327 rfcomm_dlc_unlock(d);
1328
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +01001329 if (d->role_switch)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001330 hci_conn_switch_role(l2cap_pi(sk)->conn->hcon, 0x00);
Marcel Holtmann300b9392006-07-03 10:37:55 +02001331
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332 rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
1333}
1334
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001335static void rfcomm_check_accept(struct rfcomm_dlc *d)
1336{
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +01001337 if (rfcomm_check_security(d)) {
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001338 if (d->defer_setup) {
1339 set_bit(RFCOMM_DEFER_SETUP, &d->flags);
1340 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
Marcel Holtmann8bf47942009-02-16 02:59:49 +01001341
1342 rfcomm_dlc_lock(d);
1343 d->state = BT_CONNECT2;
1344 d->state_change(d, 0);
1345 rfcomm_dlc_unlock(d);
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001346 } else
1347 rfcomm_dlc_accept(d);
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001348 } else {
1349 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
1350 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001351 }
1352}
1353
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
1355{
1356 struct rfcomm_dlc *d;
1357 u8 channel;
1358
1359 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1360
1361 if (!dlci) {
1362 rfcomm_send_ua(s, 0);
1363
1364 if (s->state == BT_OPEN) {
1365 s->state = BT_CONNECTED;
1366 rfcomm_process_connect(s);
1367 }
1368 return 0;
1369 }
1370
1371 /* Check if DLC exists */
1372 d = rfcomm_dlc_get(s, dlci);
1373 if (d) {
1374 if (d->state == BT_OPEN) {
1375 /* DLC was previously opened by PN request */
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001376 rfcomm_check_accept(d);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377 }
1378 return 0;
1379 }
1380
1381 /* Notify socket layer about incoming connection */
1382 channel = __srv_channel(dlci);
1383 if (rfcomm_connect_ind(s, channel, &d)) {
1384 d->dlci = dlci;
1385 d->addr = __addr(s->initiator, dlci);
1386 rfcomm_dlc_link(s, d);
1387
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001388 rfcomm_check_accept(d);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389 } else {
1390 rfcomm_send_dm(s, dlci);
1391 }
1392
1393 return 0;
1394}
1395
1396static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn)
1397{
1398 struct rfcomm_session *s = d->session;
1399
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001400 BT_DBG("dlc %p state %ld dlci %d mtu %d fc 0x%x credits %d",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401 d, d->state, d->dlci, pn->mtu, pn->flow_ctrl, pn->credits);
1402
Marcel Holtmann7c2660b2006-07-03 10:02:51 +02001403 if ((pn->flow_ctrl == 0xf0 && s->cfc != RFCOMM_CFC_DISABLED) ||
1404 pn->flow_ctrl == 0xe0) {
1405 d->cfc = RFCOMM_CFC_ENABLED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 d->tx_credits = pn->credits;
1407 } else {
Marcel Holtmann7c2660b2006-07-03 10:02:51 +02001408 d->cfc = RFCOMM_CFC_DISABLED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 set_bit(RFCOMM_TX_THROTTLED, &d->flags);
1410 }
1411
Marcel Holtmann7c2660b2006-07-03 10:02:51 +02001412 if (s->cfc == RFCOMM_CFC_UNKNOWN)
1413 s->cfc = d->cfc;
1414
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415 d->priority = pn->priority;
1416
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001417 d->mtu = __le16_to_cpu(pn->mtu);
Marcel Holtmann98bcd082006-07-14 11:42:12 +02001418
1419 if (cr && d->mtu > s->mtu)
1420 d->mtu = s->mtu;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421
1422 return 0;
1423}
1424
1425static int rfcomm_recv_pn(struct rfcomm_session *s, int cr, struct sk_buff *skb)
1426{
1427 struct rfcomm_pn *pn = (void *) skb->data;
1428 struct rfcomm_dlc *d;
1429 u8 dlci = pn->dlci;
1430
1431 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1432
1433 if (!dlci)
1434 return 0;
1435
1436 d = rfcomm_dlc_get(s, dlci);
1437 if (d) {
1438 if (cr) {
1439 /* PN request */
1440 rfcomm_apply_pn(d, cr, pn);
1441 rfcomm_send_pn(s, 0, d);
1442 } else {
1443 /* PN response */
1444 switch (d->state) {
1445 case BT_CONFIG:
1446 rfcomm_apply_pn(d, cr, pn);
1447
1448 d->state = BT_CONNECT;
1449 rfcomm_send_sabm(s, d->dlci);
1450 break;
1451 }
1452 }
1453 } else {
1454 u8 channel = __srv_channel(dlci);
1455
1456 if (!cr)
1457 return 0;
1458
1459 /* PN request for non existing DLC.
1460 * Assume incoming connection. */
1461 if (rfcomm_connect_ind(s, channel, &d)) {
1462 d->dlci = dlci;
1463 d->addr = __addr(s->initiator, dlci);
1464 rfcomm_dlc_link(s, d);
1465
1466 rfcomm_apply_pn(d, cr, pn);
1467
1468 d->state = BT_OPEN;
1469 rfcomm_send_pn(s, 0, d);
1470 } else {
1471 rfcomm_send_dm(s, dlci);
1472 }
1473 }
1474 return 0;
1475}
1476
1477static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_buff *skb)
1478{
1479 struct rfcomm_rpn *rpn = (void *) skb->data;
1480 u8 dlci = __get_dlci(rpn->dlci);
1481
1482 u8 bit_rate = 0;
1483 u8 data_bits = 0;
1484 u8 stop_bits = 0;
1485 u8 parity = 0;
1486 u8 flow_ctrl = 0;
1487 u8 xon_char = 0;
1488 u8 xoff_char = 0;
1489 u16 rpn_mask = RFCOMM_RPN_PM_ALL;
J. Suter3a5e9032005-08-09 20:28:46 -07001490
1491 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",
1492 dlci, cr, len, rpn->bit_rate, rpn->line_settings, rpn->flow_ctrl,
1493 rpn->xon_char, rpn->xoff_char, rpn->param_mask);
1494
1495 if (!cr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496 return 0;
J. Suter3a5e9032005-08-09 20:28:46 -07001497
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498 if (len == 1) {
Yuri Kululin08601462010-07-23 13:57:12 +04001499 /* This is a request, return default (according to ETSI TS 07.10) settings */
1500 bit_rate = RFCOMM_RPN_BR_9600;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001501 data_bits = RFCOMM_RPN_DATA_8;
1502 stop_bits = RFCOMM_RPN_STOP_1;
1503 parity = RFCOMM_RPN_PARITY_NONE;
1504 flow_ctrl = RFCOMM_RPN_FLOW_NONE;
1505 xon_char = RFCOMM_RPN_XON_CHAR;
1506 xoff_char = RFCOMM_RPN_XOFF_CHAR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507 goto rpn_out;
1508 }
J. Suter3a5e9032005-08-09 20:28:46 -07001509
1510 /* Check for sane values, ignore/accept bit_rate, 8 bits, 1 stop bit,
1511 * no parity, no flow control lines, normal XON/XOFF chars */
1512
Al Viroe8db8c92006-11-08 00:28:44 -08001513 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_BITRATE)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001514 bit_rate = rpn->bit_rate;
Yuri Kululin08601462010-07-23 13:57:12 +04001515 if (bit_rate > RFCOMM_RPN_BR_230400) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516 BT_DBG("RPN bit rate mismatch 0x%x", bit_rate);
Yuri Kululin08601462010-07-23 13:57:12 +04001517 bit_rate = RFCOMM_RPN_BR_9600;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518 rpn_mask ^= RFCOMM_RPN_PM_BITRATE;
1519 }
1520 }
J. Suter3a5e9032005-08-09 20:28:46 -07001521
Al Viroe8db8c92006-11-08 00:28:44 -08001522 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_DATA)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 data_bits = __get_rpn_data_bits(rpn->line_settings);
1524 if (data_bits != RFCOMM_RPN_DATA_8) {
1525 BT_DBG("RPN data bits mismatch 0x%x", data_bits);
1526 data_bits = RFCOMM_RPN_DATA_8;
1527 rpn_mask ^= RFCOMM_RPN_PM_DATA;
1528 }
1529 }
J. Suter3a5e9032005-08-09 20:28:46 -07001530
Al Viroe8db8c92006-11-08 00:28:44 -08001531 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_STOP)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532 stop_bits = __get_rpn_stop_bits(rpn->line_settings);
1533 if (stop_bits != RFCOMM_RPN_STOP_1) {
1534 BT_DBG("RPN stop bits mismatch 0x%x", stop_bits);
1535 stop_bits = RFCOMM_RPN_STOP_1;
1536 rpn_mask ^= RFCOMM_RPN_PM_STOP;
1537 }
1538 }
J. Suter3a5e9032005-08-09 20:28:46 -07001539
Al Viroe8db8c92006-11-08 00:28:44 -08001540 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_PARITY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541 parity = __get_rpn_parity(rpn->line_settings);
1542 if (parity != RFCOMM_RPN_PARITY_NONE) {
1543 BT_DBG("RPN parity mismatch 0x%x", parity);
1544 parity = RFCOMM_RPN_PARITY_NONE;
1545 rpn_mask ^= RFCOMM_RPN_PM_PARITY;
1546 }
1547 }
J. Suter3a5e9032005-08-09 20:28:46 -07001548
Al Viroe8db8c92006-11-08 00:28:44 -08001549 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_FLOW)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550 flow_ctrl = rpn->flow_ctrl;
1551 if (flow_ctrl != RFCOMM_RPN_FLOW_NONE) {
1552 BT_DBG("RPN flow ctrl mismatch 0x%x", flow_ctrl);
1553 flow_ctrl = RFCOMM_RPN_FLOW_NONE;
1554 rpn_mask ^= RFCOMM_RPN_PM_FLOW;
1555 }
1556 }
J. Suter3a5e9032005-08-09 20:28:46 -07001557
Al Viroe8db8c92006-11-08 00:28:44 -08001558 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_XON)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559 xon_char = rpn->xon_char;
1560 if (xon_char != RFCOMM_RPN_XON_CHAR) {
1561 BT_DBG("RPN XON char mismatch 0x%x", xon_char);
1562 xon_char = RFCOMM_RPN_XON_CHAR;
1563 rpn_mask ^= RFCOMM_RPN_PM_XON;
1564 }
1565 }
J. Suter3a5e9032005-08-09 20:28:46 -07001566
Al Viroe8db8c92006-11-08 00:28:44 -08001567 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_XOFF)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568 xoff_char = rpn->xoff_char;
1569 if (xoff_char != RFCOMM_RPN_XOFF_CHAR) {
1570 BT_DBG("RPN XOFF char mismatch 0x%x", xoff_char);
1571 xoff_char = RFCOMM_RPN_XOFF_CHAR;
1572 rpn_mask ^= RFCOMM_RPN_PM_XOFF;
1573 }
1574 }
1575
1576rpn_out:
J. Suter3a5e9032005-08-09 20:28:46 -07001577 rfcomm_send_rpn(s, 0, dlci, bit_rate, data_bits, stop_bits,
1578 parity, flow_ctrl, xon_char, xoff_char, rpn_mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579
1580 return 0;
1581}
1582
1583static int rfcomm_recv_rls(struct rfcomm_session *s, int cr, struct sk_buff *skb)
1584{
1585 struct rfcomm_rls *rls = (void *) skb->data;
1586 u8 dlci = __get_dlci(rls->dlci);
1587
1588 BT_DBG("dlci %d cr %d status 0x%x", dlci, cr, rls->status);
J. Suter3a5e9032005-08-09 20:28:46 -07001589
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590 if (!cr)
1591 return 0;
1592
J. Suter3a5e9032005-08-09 20:28:46 -07001593 /* We should probably do something with this information here. But
1594 * for now it's sufficient just to reply -- Bluetooth 1.1 says it's
1595 * mandatory to recognise and respond to RLS */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596
1597 rfcomm_send_rls(s, 0, dlci, rls->status);
1598
1599 return 0;
1600}
1601
1602static int rfcomm_recv_msc(struct rfcomm_session *s, int cr, struct sk_buff *skb)
1603{
1604 struct rfcomm_msc *msc = (void *) skb->data;
1605 struct rfcomm_dlc *d;
1606 u8 dlci = __get_dlci(msc->dlci);
1607
1608 BT_DBG("dlci %d cr %d v24 0x%x", dlci, cr, msc->v24_sig);
1609
1610 d = rfcomm_dlc_get(s, dlci);
J. Suter3a5e9032005-08-09 20:28:46 -07001611 if (!d)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612 return 0;
1613
1614 if (cr) {
1615 if (msc->v24_sig & RFCOMM_V24_FC && !d->cfc)
1616 set_bit(RFCOMM_TX_THROTTLED, &d->flags);
1617 else
1618 clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
J. Suter3a5e9032005-08-09 20:28:46 -07001619
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620 rfcomm_dlc_lock(d);
Marcel Holtmann8b6b3da2008-07-14 20:13:52 +02001621
1622 d->remote_v24_sig = msc->v24_sig;
1623
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624 if (d->modem_status)
1625 d->modem_status(d, msc->v24_sig);
Marcel Holtmann8b6b3da2008-07-14 20:13:52 +02001626
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 rfcomm_dlc_unlock(d);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001628
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 rfcomm_send_msc(s, 0, dlci, msc->v24_sig);
1630
1631 d->mscex |= RFCOMM_MSCEX_RX;
J. Suter3a5e9032005-08-09 20:28:46 -07001632 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001633 d->mscex |= RFCOMM_MSCEX_TX;
1634
1635 return 0;
1636}
1637
1638static int rfcomm_recv_mcc(struct rfcomm_session *s, struct sk_buff *skb)
1639{
1640 struct rfcomm_mcc *mcc = (void *) skb->data;
1641 u8 type, cr, len;
1642
1643 cr = __test_cr(mcc->type);
1644 type = __get_mcc_type(mcc->type);
1645 len = __get_mcc_len(mcc->len);
1646
1647 BT_DBG("%p type 0x%x cr %d", s, type, cr);
1648
1649 skb_pull(skb, 2);
1650
1651 switch (type) {
1652 case RFCOMM_PN:
1653 rfcomm_recv_pn(s, cr, skb);
1654 break;
1655
1656 case RFCOMM_RPN:
1657 rfcomm_recv_rpn(s, cr, len, skb);
1658 break;
1659
1660 case RFCOMM_RLS:
1661 rfcomm_recv_rls(s, cr, skb);
1662 break;
1663
1664 case RFCOMM_MSC:
1665 rfcomm_recv_msc(s, cr, skb);
1666 break;
1667
1668 case RFCOMM_FCOFF:
1669 if (cr) {
1670 set_bit(RFCOMM_TX_THROTTLED, &s->flags);
1671 rfcomm_send_fcoff(s, 0);
1672 }
1673 break;
1674
1675 case RFCOMM_FCON:
1676 if (cr) {
1677 clear_bit(RFCOMM_TX_THROTTLED, &s->flags);
1678 rfcomm_send_fcon(s, 0);
1679 }
1680 break;
1681
1682 case RFCOMM_TEST:
1683 if (cr)
1684 rfcomm_send_test(s, 0, skb->data, skb->len);
1685 break;
1686
1687 case RFCOMM_NSC:
1688 break;
1689
1690 default:
1691 BT_ERR("Unknown control type 0x%02x", type);
1692 rfcomm_send_nsc(s, cr, type);
1693 break;
1694 }
1695 return 0;
1696}
1697
1698static int rfcomm_recv_data(struct rfcomm_session *s, u8 dlci, int pf, struct sk_buff *skb)
1699{
1700 struct rfcomm_dlc *d;
1701
1702 BT_DBG("session %p state %ld dlci %d pf %d", s, s->state, dlci, pf);
1703
1704 d = rfcomm_dlc_get(s, dlci);
1705 if (!d) {
1706 rfcomm_send_dm(s, dlci);
1707 goto drop;
1708 }
1709
1710 if (pf && d->cfc) {
1711 u8 credits = *(u8 *) skb->data; skb_pull(skb, 1);
1712
1713 d->tx_credits += credits;
1714 if (d->tx_credits)
1715 clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
1716 }
1717
1718 if (skb->len && d->state == BT_CONNECTED) {
1719 rfcomm_dlc_lock(d);
1720 d->rx_credits--;
1721 d->data_ready(d, skb);
1722 rfcomm_dlc_unlock(d);
1723 return 0;
1724 }
1725
1726drop:
1727 kfree_skb(skb);
1728 return 0;
1729}
1730
1731static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
1732{
1733 struct rfcomm_hdr *hdr = (void *) skb->data;
1734 u8 type, dlci, fcs;
1735
1736 dlci = __get_dlci(hdr->addr);
1737 type = __get_type(hdr->ctrl);
1738
1739 /* Trim FCS */
1740 skb->len--; skb->tail--;
Arnaldo Carvalho de Melo27a884d2007-04-19 20:29:13 -07001741 fcs = *(u8 *)skb_tail_pointer(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742
1743 if (__check_fcs(skb->data, type, fcs)) {
1744 BT_ERR("bad checksum in packet");
1745 kfree_skb(skb);
1746 return -EILSEQ;
1747 }
1748
1749 if (__test_ea(hdr->len))
1750 skb_pull(skb, 3);
1751 else
1752 skb_pull(skb, 4);
1753
1754 switch (type) {
1755 case RFCOMM_SABM:
1756 if (__test_pf(hdr->ctrl))
1757 rfcomm_recv_sabm(s, dlci);
1758 break;
1759
1760 case RFCOMM_DISC:
1761 if (__test_pf(hdr->ctrl))
1762 rfcomm_recv_disc(s, dlci);
1763 break;
1764
1765 case RFCOMM_UA:
1766 if (__test_pf(hdr->ctrl))
1767 rfcomm_recv_ua(s, dlci);
1768 break;
1769
1770 case RFCOMM_DM:
1771 rfcomm_recv_dm(s, dlci);
1772 break;
1773
1774 case RFCOMM_UIH:
1775 if (dlci)
1776 return rfcomm_recv_data(s, dlci, __test_pf(hdr->ctrl), skb);
1777
1778 rfcomm_recv_mcc(s, skb);
1779 break;
1780
1781 default:
Andrei Emeltchenko5017d8d2010-09-08 16:26:53 +03001782 BT_ERR("Unknown packet type 0x%02x", type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783 break;
1784 }
1785 kfree_skb(skb);
1786 return 0;
1787}
1788
1789/* ---- Connection and data processing ---- */
1790
1791static void rfcomm_process_connect(struct rfcomm_session *s)
1792{
1793 struct rfcomm_dlc *d;
1794 struct list_head *p, *n;
1795
1796 BT_DBG("session %p state %ld", s, s->state);
1797
1798 list_for_each_safe(p, n, &s->dlcs) {
1799 d = list_entry(p, struct rfcomm_dlc, list);
1800 if (d->state == BT_CONFIG) {
1801 d->mtu = s->mtu;
Marcel Holtmann9f2c8a02009-01-15 21:58:40 +01001802 if (rfcomm_check_security(d)) {
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001803 rfcomm_send_pn(s, 1, d);
1804 } else {
Marcel Holtmann77db1982008-07-14 20:13:45 +02001805 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
1806 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001807 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 }
1809 }
1810}
1811
1812/* Send data queued for the DLC.
1813 * Return number of frames left in the queue.
1814 */
1815static inline int rfcomm_process_tx(struct rfcomm_dlc *d)
1816{
1817 struct sk_buff *skb;
1818 int err;
1819
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001820 BT_DBG("dlc %p state %ld cfc %d rx_credits %d tx_credits %d",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821 d, d->state, d->cfc, d->rx_credits, d->tx_credits);
1822
1823 /* Send pending MSC */
1824 if (test_and_clear_bit(RFCOMM_MSC_PENDING, &d->flags))
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001825 rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826
1827 if (d->cfc) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001828 /* CFC enabled.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829 * Give them some credits */
1830 if (!test_bit(RFCOMM_RX_THROTTLED, &d->flags) &&
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001831 d->rx_credits <= (d->cfc >> 2)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832 rfcomm_send_credits(d->session, d->addr, d->cfc - d->rx_credits);
1833 d->rx_credits = d->cfc;
1834 }
1835 } else {
1836 /* CFC disabled.
1837 * Give ourselves some credits */
1838 d->tx_credits = 5;
1839 }
1840
1841 if (test_bit(RFCOMM_TX_THROTTLED, &d->flags))
1842 return skb_queue_len(&d->tx_queue);
1843
1844 while (d->tx_credits && (skb = skb_dequeue(&d->tx_queue))) {
Gustavo F. Padovan54365382011-12-20 16:30:44 -02001845 err = rfcomm_send_frame(d->session, skb->data, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846 if (err < 0) {
1847 skb_queue_head(&d->tx_queue, skb);
1848 break;
1849 }
1850 kfree_skb(skb);
1851 d->tx_credits--;
1852 }
1853
1854 if (d->cfc && !d->tx_credits) {
1855 /* We're out of TX credits.
1856 * Set TX_THROTTLED flag to avoid unnesary wakeups by dlc_send. */
1857 set_bit(RFCOMM_TX_THROTTLED, &d->flags);
1858 }
1859
1860 return skb_queue_len(&d->tx_queue);
1861}
1862
1863static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
1864{
1865 struct rfcomm_dlc *d;
1866 struct list_head *p, *n;
1867
1868 BT_DBG("session %p state %ld", s, s->state);
1869
1870 list_for_each_safe(p, n, &s->dlcs) {
1871 d = list_entry(p, struct rfcomm_dlc, list);
1872
1873 if (test_bit(RFCOMM_TIMED_OUT, &d->flags)) {
1874 __rfcomm_dlc_close(d, ETIMEDOUT);
1875 continue;
1876 }
1877
1878 if (test_and_clear_bit(RFCOMM_AUTH_ACCEPT, &d->flags)) {
1879 rfcomm_dlc_clear_timer(d);
Marcel Holtmann77db1982008-07-14 20:13:45 +02001880 if (d->out) {
1881 rfcomm_send_pn(s, 1, d);
1882 rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT);
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001883 } else {
1884 if (d->defer_setup) {
1885 set_bit(RFCOMM_DEFER_SETUP, &d->flags);
1886 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
Marcel Holtmann8bf47942009-02-16 02:59:49 +01001887
1888 rfcomm_dlc_lock(d);
1889 d->state = BT_CONNECT2;
1890 d->state_change(d, 0);
1891 rfcomm_dlc_unlock(d);
Marcel Holtmannbb23c0a2009-01-15 21:56:48 +01001892 } else
1893 rfcomm_dlc_accept(d);
1894 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895 continue;
1896 } else if (test_and_clear_bit(RFCOMM_AUTH_REJECT, &d->flags)) {
1897 rfcomm_dlc_clear_timer(d);
Marcel Holtmann77db1982008-07-14 20:13:45 +02001898 if (!d->out)
1899 rfcomm_send_dm(s, d->dlci);
1900 else
1901 d->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902 __rfcomm_dlc_close(d, ECONNREFUSED);
1903 continue;
1904 }
1905
Jaikumar Ganesh6e1031a2009-02-02 18:03:57 -08001906 if (test_bit(RFCOMM_SEC_PENDING, &d->flags))
1907 continue;
1908
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909 if (test_bit(RFCOMM_TX_THROTTLED, &s->flags))
1910 continue;
1911
1912 if ((d->state == BT_CONNECTED || d->state == BT_DISCONN) &&
Marcel Holtmann77db1982008-07-14 20:13:45 +02001913 d->mscex == RFCOMM_MSCEX_OK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914 rfcomm_process_tx(d);
1915 }
1916}
1917
1918static inline void rfcomm_process_rx(struct rfcomm_session *s)
1919{
1920 struct socket *sock = s->sock;
1921 struct sock *sk = sock->sk;
1922 struct sk_buff *skb;
1923
1924 BT_DBG("session %p state %ld qlen %d", s, s->state, skb_queue_len(&sk->sk_receive_queue));
1925
1926 /* Get data directly from socket receive queue without copying it. */
1927 while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
1928 skb_orphan(skb);
Mat Martineau44935722011-07-22 14:53:58 -07001929 if (!skb_linearize(skb))
1930 rfcomm_recv_frame(s, skb);
1931 else
1932 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933 }
1934
1935 if (sk->sk_state == BT_CLOSED) {
1936 if (!s->initiator)
1937 rfcomm_session_put(s);
1938
1939 rfcomm_session_close(s, sk->sk_err);
1940 }
1941}
1942
1943static inline void rfcomm_accept_connection(struct rfcomm_session *s)
1944{
1945 struct socket *sock = s->sock, *nsock;
1946 int err;
1947
1948 /* Fast check for a new connection.
1949 * Avoids unnesesary socket allocations. */
1950 if (list_empty(&bt_sk(sock->sk)->accept_q))
1951 return;
1952
1953 BT_DBG("session %p", s);
1954
Marcel Holtmann48db9ca2007-05-05 00:36:06 +02001955 err = kernel_accept(sock, &nsock, O_NONBLOCK);
1956 if (err < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001957 return;
1958
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959 /* Set our callbacks */
1960 nsock->sk->sk_data_ready = rfcomm_l2data_ready;
1961 nsock->sk->sk_state_change = rfcomm_l2state_change;
1962
1963 s = rfcomm_session_add(nsock, BT_OPEN);
1964 if (s) {
1965 rfcomm_session_hold(s);
Marcel Holtmann98bcd082006-07-14 11:42:12 +02001966
1967 /* We should adjust MTU on incoming sessions.
Mallikarjuna GB2da40bf2011-09-06 17:02:36 +05301968 * L2CAP MTU minus UIH header and FCS.
1969 * Need to accomodate 1 Byte credits information */
1970 s->mtu = min(l2cap_pi(nsock->sk)->omtu,
1971 l2cap_pi(nsock->sk)->imtu) - RFCOMM_HDR_SIZE;
Marcel Holtmann98bcd082006-07-14 11:42:12 +02001972
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +03001973 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001974 } else
1975 sock_release(nsock);
1976}
1977
1978static inline void rfcomm_check_connection(struct rfcomm_session *s)
1979{
1980 struct sock *sk = s->sock->sk;
1981
1982 BT_DBG("%p state %ld", s, s->state);
1983
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +02001984 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001985 case BT_CONNECTED:
1986 s->state = BT_CONNECT;
1987
1988 /* We can adjust MTU on outgoing sessions.
Mallikarjuna GB2da40bf2011-09-06 17:02:36 +05301989 * L2CAP MTU minus UIH header, Credits and FCS. */
1990 s->mtu = min(l2cap_pi(sk)->omtu, l2cap_pi(sk)->imtu) -
1991 RFCOMM_HDR_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001992
1993 rfcomm_send_sabm(s, 0);
1994 break;
1995
1996 case BT_CLOSED:
1997 s->state = BT_CLOSED;
1998 rfcomm_session_close(s, sk->sk_err);
1999 break;
2000 }
2001}
2002
2003static inline void rfcomm_process_sessions(void)
2004{
2005 struct list_head *p, *n;
2006
2007 rfcomm_lock();
2008
2009 list_for_each_safe(p, n, &session_list) {
2010 struct rfcomm_session *s;
2011 s = list_entry(p, struct rfcomm_session, list);
2012
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -03002013 if (test_and_clear_bit(RFCOMM_TIMED_OUT, &s->flags)) {
2014 s->state = BT_DISCONN;
2015 rfcomm_send_disc(s, 0);
Marcel Holtmann485f1ef2010-02-03 15:52:18 -08002016 rfcomm_session_put(s);
Luiz Augusto von Dentz9e726b12009-07-15 13:50:58 -03002017 continue;
2018 }
2019
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020 if (s->state == BT_LISTEN) {
2021 rfcomm_accept_connection(s);
2022 continue;
2023 }
2024
2025 rfcomm_session_hold(s);
2026
2027 switch (s->state) {
2028 case BT_BOUND:
2029 rfcomm_check_connection(s);
2030 break;
2031
2032 default:
2033 rfcomm_process_rx(s);
2034 break;
2035 }
2036
2037 rfcomm_process_dlcs(s);
2038
2039 rfcomm_session_put(s);
2040 }
2041
2042 rfcomm_unlock();
2043}
2044
Linus Torvalds1da177e2005-04-16 15:20:36 -07002045static int rfcomm_add_listener(bdaddr_t *ba)
2046{
2047 struct sockaddr_l2 addr;
2048 struct socket *sock;
2049 struct sock *sk;
2050 struct rfcomm_session *s;
2051 int err = 0;
2052
2053 /* Create socket */
2054 err = rfcomm_l2sock_create(&sock);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002055 if (err < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002056 BT_ERR("Create socket failed %d", err);
2057 return err;
2058 }
2059
2060 /* Bind socket */
2061 bacpy(&addr.l2_bdaddr, ba);
2062 addr.l2_family = AF_BLUETOOTH;
Marcel Holtmannb4324b52009-06-07 18:06:51 +02002063 addr.l2_psm = cpu_to_le16(RFCOMM_PSM);
Marcel Holtmann37e62f52009-02-17 21:49:33 +01002064 addr.l2_cid = 0;
Marcel Holtmann48db9ca2007-05-05 00:36:06 +02002065 err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002066 if (err < 0) {
2067 BT_ERR("Bind failed %d", err);
2068 goto failed;
2069 }
2070
2071 /* Set L2CAP options */
2072 sk = sock->sk;
2073 lock_sock(sk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002074 l2cap_pi(sk)->imtu = l2cap_mtu;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002075 release_sock(sk);
2076
2077 /* Start listening on the socket */
Marcel Holtmann48db9ca2007-05-05 00:36:06 +02002078 err = kernel_listen(sock, 10);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002079 if (err) {
2080 BT_ERR("Listen failed %d", err);
2081 goto failed;
2082 }
2083
2084 /* Add listening session */
2085 s = rfcomm_session_add(sock, BT_LISTEN);
2086 if (!s)
2087 goto failed;
2088
2089 rfcomm_session_hold(s);
2090 return 0;
2091failed:
2092 sock_release(sock);
2093 return err;
2094}
2095
2096static void rfcomm_kill_listener(void)
2097{
2098 struct rfcomm_session *s;
2099 struct list_head *p, *n;
2100
2101 BT_DBG("");
2102
2103 list_for_each_safe(p, n, &session_list) {
2104 s = list_entry(p, struct rfcomm_session, list);
2105 rfcomm_session_del(s);
2106 }
2107}
2108
2109static int rfcomm_run(void *unused)
2110{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002111 BT_DBG("");
2112
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002113 set_user_nice(current, -10);
2114
Linus Torvalds1da177e2005-04-16 15:20:36 -07002115 rfcomm_add_listener(BDADDR_ANY);
2116
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002117 while (!kthread_should_stop()) {
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002118 set_current_state(TASK_INTERRUPTIBLE);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002119 if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) {
2120 /* No pending events. Let's sleep.
2121 * Incoming connections and data will wake us up. */
2122 schedule();
2123 }
2124 set_current_state(TASK_RUNNING);
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002125
2126 /* Process stuff */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002127 clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002128 rfcomm_process_sessions();
2129 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002130
2131 rfcomm_kill_listener();
2132
Linus Torvalds1da177e2005-04-16 15:20:36 -07002133 return 0;
2134}
2135
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01002136static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002137{
2138 struct rfcomm_session *s;
2139 struct rfcomm_dlc *d;
2140 struct list_head *p, *n;
2141
2142 BT_DBG("conn %p status 0x%02x encrypt 0x%02x", conn, status, encrypt);
2143
2144 s = rfcomm_session_get(&conn->hdev->bdaddr, &conn->dst);
2145 if (!s)
2146 return;
2147
2148 rfcomm_session_hold(s);
2149
2150 list_for_each_safe(p, n, &s->dlcs) {
2151 d = list_entry(p, struct rfcomm_dlc, list);
2152
Marcel Holtmann8c84b832009-01-16 08:17:51 +01002153 if (test_and_clear_bit(RFCOMM_SEC_PENDING, &d->flags)) {
2154 rfcomm_dlc_clear_timer(d);
2155 if (status || encrypt == 0x00) {
2156 __rfcomm_dlc_close(d, ECONNREFUSED);
2157 continue;
2158 }
2159 }
2160
2161 if (d->state == BT_CONNECTED && !status && encrypt == 0x00) {
2162 if (d->sec_level == BT_SECURITY_MEDIUM) {
2163 set_bit(RFCOMM_SEC_PENDING, &d->flags);
2164 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
2165 continue;
2166 } else if (d->sec_level == BT_SECURITY_HIGH) {
2167 __rfcomm_dlc_close(d, ECONNREFUSED);
2168 continue;
2169 }
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02002170 }
2171
Linus Torvalds1da177e2005-04-16 15:20:36 -07002172 if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags))
2173 continue;
2174
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002175 if (!status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002176 set_bit(RFCOMM_AUTH_ACCEPT, &d->flags);
2177 else
2178 set_bit(RFCOMM_AUTH_REJECT, &d->flags);
2179 }
2180
2181 rfcomm_session_put(s);
2182
Andrei Emeltchenko534c92f2010-10-01 12:05:11 +03002183 rfcomm_schedule();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002184}
2185
2186static struct hci_cb rfcomm_cb = {
2187 .name = "RFCOMM",
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01002188 .security_cfm = rfcomm_security_cfm
Linus Torvalds1da177e2005-04-16 15:20:36 -07002189};
2190
Marcel Holtmannaef7d972010-03-21 05:27:45 +01002191static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002192{
2193 struct rfcomm_session *s;
2194 struct list_head *pp, *p;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002195
2196 rfcomm_lock();
2197
2198 list_for_each(p, &session_list) {
2199 s = list_entry(p, struct rfcomm_session, list);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08002200 list_for_each(pp, &s->dlcs) {
2201 struct sock *sk = s->sock->sk;
2202 struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002203
Marcel Holtmannaef7d972010-03-21 05:27:45 +01002204 seq_printf(f, "%s %s %ld %d %d %d %d\n",
2205 batostr(&bt_sk(sk)->src),
2206 batostr(&bt_sk(sk)->dst),
2207 d->state, d->dlci, d->mtu,
2208 d->rx_credits, d->tx_credits);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002209 }
2210 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002211
Linus Torvalds1da177e2005-04-16 15:20:36 -07002212 rfcomm_unlock();
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08002213
Marcel Holtmannaef7d972010-03-21 05:27:45 +01002214 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002215}
2216
Marcel Holtmannaef7d972010-03-21 05:27:45 +01002217static int rfcomm_dlc_debugfs_open(struct inode *inode, struct file *file)
2218{
2219 return single_open(file, rfcomm_dlc_debugfs_show, inode->i_private);
2220}
2221
2222static const struct file_operations rfcomm_dlc_debugfs_fops = {
2223 .open = rfcomm_dlc_debugfs_open,
2224 .read = seq_read,
2225 .llseek = seq_lseek,
2226 .release = single_release,
2227};
2228
2229static struct dentry *rfcomm_dlc_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002230
2231/* ---- Initialization ---- */
2232static int __init rfcomm_init(void)
2233{
Marcel Holtmann52d18342009-08-22 14:49:36 -07002234 int err;
Dave Youngaf0d3b12009-08-03 04:26:16 +00002235
Linus Torvalds1da177e2005-04-16 15:20:36 -07002236 hci_register_cb(&rfcomm_cb);
2237
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002238 rfcomm_thread = kthread_run(rfcomm_run, NULL, "krfcommd");
2239 if (IS_ERR(rfcomm_thread)) {
Marcel Holtmann52d18342009-08-22 14:49:36 -07002240 err = PTR_ERR(rfcomm_thread);
2241 goto unregister;
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002242 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002243
Marcel Holtmannaef7d972010-03-21 05:27:45 +01002244 if (bt_debugfs) {
2245 rfcomm_dlc_debugfs = debugfs_create_file("rfcomm_dlc", 0444,
2246 bt_debugfs, NULL, &rfcomm_dlc_debugfs_fops);
2247 if (!rfcomm_dlc_debugfs)
2248 BT_ERR("Failed to create RFCOMM debug file");
2249 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002250
Marcel Holtmann52d18342009-08-22 14:49:36 -07002251 err = rfcomm_init_ttys();
2252 if (err < 0)
2253 goto stop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002254
Marcel Holtmann52d18342009-08-22 14:49:36 -07002255 err = rfcomm_init_sockets();
2256 if (err < 0)
2257 goto cleanup;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002258
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08002259 BT_INFO("RFCOMM ver %s", VERSION);
2260
Linus Torvalds1da177e2005-04-16 15:20:36 -07002261 return 0;
Dave Youngaf0d3b12009-08-03 04:26:16 +00002262
Marcel Holtmann52d18342009-08-22 14:49:36 -07002263cleanup:
Dave Youngaf0d3b12009-08-03 04:26:16 +00002264 rfcomm_cleanup_ttys();
Marcel Holtmann52d18342009-08-22 14:49:36 -07002265
2266stop:
Dave Youngaf0d3b12009-08-03 04:26:16 +00002267 kthread_stop(rfcomm_thread);
Marcel Holtmann52d18342009-08-22 14:49:36 -07002268
2269unregister:
Dave Youngaf0d3b12009-08-03 04:26:16 +00002270 hci_unregister_cb(&rfcomm_cb);
2271
Marcel Holtmann52d18342009-08-22 14:49:36 -07002272 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002273}
2274
2275static void __exit rfcomm_exit(void)
2276{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01002277 debugfs_remove(rfcomm_dlc_debugfs);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08002278
Linus Torvalds1da177e2005-04-16 15:20:36 -07002279 hci_unregister_cb(&rfcomm_cb);
2280
Marcel Holtmanna524ecc2007-10-20 21:37:20 +02002281 kthread_stop(rfcomm_thread);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002282
Linus Torvalds1da177e2005-04-16 15:20:36 -07002283 rfcomm_cleanup_ttys();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002284
2285 rfcomm_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002286}
2287
2288module_init(rfcomm_init);
2289module_exit(rfcomm_exit);
2290
Marcel Holtmann7c2660b2006-07-03 10:02:51 +02002291module_param(disable_cfc, bool, 0644);
2292MODULE_PARM_DESC(disable_cfc, "Disable credit based flow control");
2293
Marcel Holtmann98bcd082006-07-14 11:42:12 +02002294module_param(channel_mtu, int, 0644);
2295MODULE_PARM_DESC(channel_mtu, "Default MTU for the RFCOMM channel");
2296
Marcel Holtmann56f3a402006-02-13 11:39:57 +01002297module_param(l2cap_mtu, uint, 0644);
2298MODULE_PARM_DESC(l2cap_mtu, "Default MTU for the L2CAP connection");
2299
Marcel Holtmanneae38ee2009-10-05 12:23:48 +02002300module_param(l2cap_ertm, bool, 0644);
2301MODULE_PARM_DESC(l2cap_ertm, "Use L2CAP ERTM mode for connection");
2302
Marcel Holtmann63fbd242008-08-18 13:23:53 +02002303MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002304MODULE_DESCRIPTION("Bluetooth RFCOMM ver " VERSION);
2305MODULE_VERSION(VERSION);
2306MODULE_LICENSE("GPL");
2307MODULE_ALIAS("bt-proto-3");