blob: 852c1400d069f923ebe6cda5f6ac7a1a6b1182d1 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth L2CAP core and sockets. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
Randy Dunlap4fc268d2006-01-11 12:17:47 -080030#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/errno.h>
32#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/sched.h>
34#include <linux/slab.h>
35#include <linux/poll.h>
36#include <linux/fcntl.h>
37#include <linux/init.h>
38#include <linux/interrupt.h>
39#include <linux/socket.h>
40#include <linux/skbuff.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <linux/list.h>
Marcel Holtmannbe9d1222005-11-08 09:57:38 -080042#include <linux/device.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010043#include <linux/debugfs.h>
44#include <linux/seq_file.h>
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -030045#include <linux/uaccess.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030046#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070047#include <net/sock.h>
48
49#include <asm/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070050#include <asm/unaligned.h>
51
52#include <net/bluetooth/bluetooth.h>
53#include <net/bluetooth/hci_core.h>
54#include <net/bluetooth/l2cap.h>
55
Marcel Holtmann44dd46d2009-05-02 19:09:01 -070056#define VERSION "2.14"
57
58static int enable_ertm = 0;
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +020059static int max_transmit = L2CAP_DEFAULT_MAX_TX;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020060
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070061static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Marcel Holtmanne1027a72009-02-09 09:18:02 +010062static u8 l2cap_fixed_chan[8] = { 0x02, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070063
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080064static const struct proto_ops l2cap_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070065
66static struct bt_sock_list l2cap_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070067 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070068};
69
Linus Torvalds1da177e2005-04-16 15:20:36 -070070static void __l2cap_sock_close(struct sock *sk, int reason);
71static void l2cap_sock_close(struct sock *sk);
72static void l2cap_sock_kill(struct sock *sk);
73
74static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
75 u8 code, u8 ident, u16 dlen, void *data);
76
77/* ---- L2CAP timers ---- */
78static void l2cap_sock_timeout(unsigned long arg)
79{
80 struct sock *sk = (struct sock *) arg;
Marcel Holtmannb1235d7962008-07-14 20:13:54 +020081 int reason;
Linus Torvalds1da177e2005-04-16 15:20:36 -070082
83 BT_DBG("sock %p state %d", sk, sk->sk_state);
84
85 bh_lock_sock(sk);
Marcel Holtmannb1235d7962008-07-14 20:13:54 +020086
Marcel Holtmannf62e4322009-01-15 21:58:44 +010087 if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
88 reason = ECONNREFUSED;
89 else if (sk->sk_state == BT_CONNECT &&
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +010090 l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
Marcel Holtmannb1235d7962008-07-14 20:13:54 +020091 reason = ECONNREFUSED;
92 else
93 reason = ETIMEDOUT;
94
95 __l2cap_sock_close(sk, reason);
96
Linus Torvalds1da177e2005-04-16 15:20:36 -070097 bh_unlock_sock(sk);
98
99 l2cap_sock_kill(sk);
100 sock_put(sk);
101}
102
103static void l2cap_sock_set_timer(struct sock *sk, long timeout)
104{
105 BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
106 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
107}
108
109static void l2cap_sock_clear_timer(struct sock *sk)
110{
111 BT_DBG("sock %p state %d", sk, sk->sk_state);
112 sk_stop_timer(sk, &sk->sk_timer);
113}
114
Marcel Holtmann01394182006-07-03 10:02:46 +0200115/* ---- L2CAP channels ---- */
116static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
117{
118 struct sock *s;
119 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
120 if (l2cap_pi(s)->dcid == cid)
121 break;
122 }
123 return s;
124}
125
126static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
127{
128 struct sock *s;
129 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
130 if (l2cap_pi(s)->scid == cid)
131 break;
132 }
133 return s;
134}
135
136/* Find channel with given SCID.
137 * Returns locked socket */
138static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
139{
140 struct sock *s;
141 read_lock(&l->lock);
142 s = __l2cap_get_chan_by_scid(l, cid);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300143 if (s)
144 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200145 read_unlock(&l->lock);
146 return s;
147}
148
149static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
150{
151 struct sock *s;
152 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
153 if (l2cap_pi(s)->ident == ident)
154 break;
155 }
156 return s;
157}
158
159static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
160{
161 struct sock *s;
162 read_lock(&l->lock);
163 s = __l2cap_get_chan_by_ident(l, ident);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300164 if (s)
165 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200166 read_unlock(&l->lock);
167 return s;
168}
169
170static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
171{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300172 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200173
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300174 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300175 if (!__l2cap_get_chan_by_scid(l, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200176 return cid;
177 }
178
179 return 0;
180}
181
182static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
183{
184 sock_hold(sk);
185
186 if (l->head)
187 l2cap_pi(l->head)->prev_c = sk;
188
189 l2cap_pi(sk)->next_c = l->head;
190 l2cap_pi(sk)->prev_c = NULL;
191 l->head = sk;
192}
193
194static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
195{
196 struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
197
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200198 write_lock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200199 if (sk == l->head)
200 l->head = next;
201
202 if (next)
203 l2cap_pi(next)->prev_c = prev;
204 if (prev)
205 l2cap_pi(prev)->next_c = next;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200206 write_unlock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200207
208 __sock_put(sk);
209}
210
211static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
212{
213 struct l2cap_chan_list *l = &conn->chan_list;
214
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300215 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
216 l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200217
Marcel Holtmann2950f212009-02-12 14:02:50 +0100218 conn->disc_reason = 0x13;
219
Marcel Holtmann01394182006-07-03 10:02:46 +0200220 l2cap_pi(sk)->conn = conn;
221
222 if (sk->sk_type == SOCK_SEQPACKET) {
223 /* Alloc CID for connection-oriented socket */
224 l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
225 } else if (sk->sk_type == SOCK_DGRAM) {
226 /* Connectionless socket */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300227 l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
228 l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
Marcel Holtmann01394182006-07-03 10:02:46 +0200229 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
230 } else {
231 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300232 l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
233 l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
Marcel Holtmann01394182006-07-03 10:02:46 +0200234 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
235 }
236
237 __l2cap_chan_link(l, sk);
238
239 if (parent)
240 bt_accept_enqueue(parent, sk);
241}
242
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900243/* Delete channel.
Marcel Holtmann01394182006-07-03 10:02:46 +0200244 * Must be called on the locked socket. */
245static void l2cap_chan_del(struct sock *sk, int err)
246{
247 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
248 struct sock *parent = bt_sk(sk)->parent;
249
250 l2cap_sock_clear_timer(sk);
251
252 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
253
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900254 if (conn) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200255 /* Unlink from channel list */
256 l2cap_chan_unlink(&conn->chan_list, sk);
257 l2cap_pi(sk)->conn = NULL;
258 hci_conn_put(conn->hcon);
259 }
260
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200261 sk->sk_state = BT_CLOSED;
Marcel Holtmann01394182006-07-03 10:02:46 +0200262 sock_set_flag(sk, SOCK_ZAPPED);
263
264 if (err)
265 sk->sk_err = err;
266
267 if (parent) {
268 bt_accept_unlink(sk);
269 parent->sk_data_ready(parent, 0);
270 } else
271 sk->sk_state_change(sk);
272}
273
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200274/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100275static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200276{
277 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100278 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200279
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100280 if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
281 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
282 auth_type = HCI_AT_NO_BONDING_MITM;
283 else
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300284 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100285
286 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
287 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
288 } else {
289 switch (l2cap_pi(sk)->sec_level) {
290 case BT_SECURITY_HIGH:
291 auth_type = HCI_AT_GENERAL_BONDING_MITM;
292 break;
293 case BT_SECURITY_MEDIUM:
294 auth_type = HCI_AT_GENERAL_BONDING;
295 break;
296 default:
297 auth_type = HCI_AT_NO_BONDING;
298 break;
299 }
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100300 }
301
302 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
303 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200304}
305
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200306static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
307{
308 u8 id;
309
310 /* Get next available identificator.
311 * 1 - 128 are used by kernel.
312 * 129 - 199 are reserved.
313 * 200 - 254 are used by utilities like l2ping, etc.
314 */
315
316 spin_lock_bh(&conn->lock);
317
318 if (++conn->tx_ident > 128)
319 conn->tx_ident = 1;
320
321 id = conn->tx_ident;
322
323 spin_unlock_bh(&conn->lock);
324
325 return id;
326}
327
328static inline int l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
329{
330 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
331
332 BT_DBG("code 0x%2.2x", code);
333
334 if (!skb)
335 return -ENOMEM;
336
337 return hci_send_acl(conn->hcon, skb, 0);
338}
339
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -0300340static inline int l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
341{
342 struct sk_buff *skb;
343 struct l2cap_hdr *lh;
344 struct l2cap_conn *conn = pi->conn;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300345 int count, hlen = L2CAP_HDR_SIZE + 2;
346
347 if (pi->fcs == L2CAP_FCS_CRC16)
348 hlen += 2;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -0300349
350 BT_DBG("pi %p, control 0x%2.2x", pi, control);
351
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300352 count = min_t(unsigned int, conn->mtu, hlen);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -0300353 control |= L2CAP_CTRL_FRAME_TYPE;
354
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -0300355 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
356 control |= L2CAP_CTRL_FINAL;
357 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
358 }
359
Gustavo F. Padovanf0946cc2010-05-01 16:15:37 -0300360 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
361 control |= L2CAP_CTRL_POLL;
362 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
363 }
364
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -0300365 skb = bt_skb_alloc(count, GFP_ATOMIC);
366 if (!skb)
367 return -ENOMEM;
368
369 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300370 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -0300371 lh->cid = cpu_to_le16(pi->dcid);
372 put_unaligned_le16(control, skb_put(skb, 2));
373
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300374 if (pi->fcs == L2CAP_FCS_CRC16) {
375 u16 fcs = crc16(0, (u8 *)lh, count - 2);
376 put_unaligned_le16(fcs, skb_put(skb, 2));
377 }
378
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -0300379 return hci_send_acl(pi->conn->hcon, skb, 0);
380}
381
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300382static inline int l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
383{
384 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY)
385 control |= L2CAP_SUPER_RCV_NOT_READY;
386 else
387 control |= L2CAP_SUPER_RCV_READY;
388
Gustavo F. Padovan2ab25cd2009-10-03 02:34:40 -0300389 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
390
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300391 return l2cap_send_sframe(pi, control);
392}
393
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200394static void l2cap_do_start(struct sock *sk)
395{
396 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
397
398 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100399 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
400 return;
401
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100402 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200403 struct l2cap_conn_req req;
404 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
405 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200406
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200407 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200408
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200409 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200410 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200411 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200412 } else {
413 struct l2cap_info_req req;
414 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
415
416 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
417 conn->info_ident = l2cap_get_ident(conn);
418
419 mod_timer(&conn->info_timer, jiffies +
420 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
421
422 l2cap_send_cmd(conn, conn->info_ident,
423 L2CAP_INFO_REQ, sizeof(req), &req);
424 }
425}
426
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300427static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk)
428{
429 struct l2cap_disconn_req req;
430
431 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
432 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
433 l2cap_send_cmd(conn, l2cap_get_ident(conn),
434 L2CAP_DISCONN_REQ, sizeof(req), &req);
435}
436
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200438static void l2cap_conn_start(struct l2cap_conn *conn)
439{
440 struct l2cap_chan_list *l = &conn->chan_list;
441 struct sock *sk;
442
443 BT_DBG("conn %p", conn);
444
445 read_lock(&l->lock);
446
447 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
448 bh_lock_sock(sk);
449
450 if (sk->sk_type != SOCK_SEQPACKET) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200451 bh_unlock_sock(sk);
452 continue;
453 }
454
455 if (sk->sk_state == BT_CONNECT) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100456 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200457 struct l2cap_conn_req req;
458 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
459 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200460
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200461 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200462
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200463 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200464 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200465 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200466 } else if (sk->sk_state == BT_CONNECT2) {
467 struct l2cap_conn_rsp rsp;
468 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
469 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
470
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100471 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100472 if (bt_sk(sk)->defer_setup) {
473 struct sock *parent = bt_sk(sk)->parent;
474 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
475 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
476 parent->sk_data_ready(parent, 0);
477
478 } else {
479 sk->sk_state = BT_CONFIG;
480 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
481 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
482 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200483 } else {
484 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
485 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
486 }
487
488 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
489 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
490 }
491
492 bh_unlock_sock(sk);
493 }
494
495 read_unlock(&l->lock);
496}
497
498static void l2cap_conn_ready(struct l2cap_conn *conn)
499{
500 struct l2cap_chan_list *l = &conn->chan_list;
501 struct sock *sk;
502
503 BT_DBG("conn %p", conn);
504
505 read_lock(&l->lock);
506
507 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
508 bh_lock_sock(sk);
509
510 if (sk->sk_type != SOCK_SEQPACKET) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200511 l2cap_sock_clear_timer(sk);
512 sk->sk_state = BT_CONNECTED;
513 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200514 } else if (sk->sk_state == BT_CONNECT)
515 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200516
517 bh_unlock_sock(sk);
518 }
519
520 read_unlock(&l->lock);
521}
522
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200523/* Notify sockets that we cannot guaranty reliability anymore */
524static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
525{
526 struct l2cap_chan_list *l = &conn->chan_list;
527 struct sock *sk;
528
529 BT_DBG("conn %p", conn);
530
531 read_lock(&l->lock);
532
533 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100534 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200535 sk->sk_err = err;
536 }
537
538 read_unlock(&l->lock);
539}
540
541static void l2cap_info_timeout(unsigned long arg)
542{
543 struct l2cap_conn *conn = (void *) arg;
544
Marcel Holtmann984947d2009-02-06 23:35:19 +0100545 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100546 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100547
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200548 l2cap_conn_start(conn);
549}
550
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
552{
Marcel Holtmann01394182006-07-03 10:02:46 +0200553 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554
Marcel Holtmann01394182006-07-03 10:02:46 +0200555 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 return conn;
557
Marcel Holtmann01394182006-07-03 10:02:46 +0200558 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
559 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561
562 hcon->l2cap_data = conn;
563 conn->hcon = hcon;
564
Marcel Holtmann01394182006-07-03 10:02:46 +0200565 BT_DBG("hcon %p conn %p", hcon, conn);
566
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 conn->mtu = hcon->hdev->acl_mtu;
568 conn->src = &hcon->hdev->bdaddr;
569 conn->dst = &hcon->dst;
570
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200571 conn->feat_mask = 0;
572
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573 spin_lock_init(&conn->lock);
574 rwlock_init(&conn->chan_list.lock);
575
Dave Young45054dc2009-10-18 20:28:30 +0000576 setup_timer(&conn->info_timer, l2cap_info_timeout,
577 (unsigned long) conn);
578
Marcel Holtmann2950f212009-02-12 14:02:50 +0100579 conn->disc_reason = 0x13;
580
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 return conn;
582}
583
Marcel Holtmann01394182006-07-03 10:02:46 +0200584static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585{
Marcel Holtmann01394182006-07-03 10:02:46 +0200586 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587 struct sock *sk;
588
Marcel Holtmann01394182006-07-03 10:02:46 +0200589 if (!conn)
590 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591
592 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
593
Wei Yongjun7585b972009-02-25 18:29:52 +0800594 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595
596 /* Kill channels */
597 while ((sk = conn->chan_list.head)) {
598 bh_lock_sock(sk);
599 l2cap_chan_del(sk, err);
600 bh_unlock_sock(sk);
601 l2cap_sock_kill(sk);
602 }
603
Dave Young8e8440f2008-03-03 12:18:55 -0800604 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
605 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800606
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 hcon->l2cap_data = NULL;
608 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609}
610
611static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
612{
613 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200614 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200616 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617}
618
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700620static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621{
622 struct sock *sk;
623 struct hlist_node *node;
624 sk_for_each(sk, node, &l2cap_sk_list.head)
625 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
626 goto found;
627 sk = NULL;
628found:
629 return sk;
630}
631
632/* Find socket with psm and source bdaddr.
633 * Returns closest match.
634 */
Al Viro8e036fc2007-07-29 00:16:36 -0700635static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636{
637 struct sock *sk = NULL, *sk1 = NULL;
638 struct hlist_node *node;
639
640 sk_for_each(sk, node, &l2cap_sk_list.head) {
641 if (state && sk->sk_state != state)
642 continue;
643
644 if (l2cap_pi(sk)->psm == psm) {
645 /* Exact match. */
646 if (!bacmp(&bt_sk(sk)->src, src))
647 break;
648
649 /* Closest match */
650 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
651 sk1 = sk;
652 }
653 }
654 return node ? sk : sk1;
655}
656
657/* Find socket with given address (psm, src).
658 * Returns locked socket */
Al Viro8e036fc2007-07-29 00:16:36 -0700659static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660{
661 struct sock *s;
662 read_lock(&l2cap_sk_list.lock);
663 s = __l2cap_get_sock_by_psm(state, psm, src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300664 if (s)
665 bh_lock_sock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666 read_unlock(&l2cap_sk_list.lock);
667 return s;
668}
669
670static void l2cap_sock_destruct(struct sock *sk)
671{
672 BT_DBG("sk %p", sk);
673
674 skb_queue_purge(&sk->sk_receive_queue);
675 skb_queue_purge(&sk->sk_write_queue);
676}
677
678static void l2cap_sock_cleanup_listen(struct sock *parent)
679{
680 struct sock *sk;
681
682 BT_DBG("parent %p", parent);
683
684 /* Close not yet accepted channels */
685 while ((sk = bt_accept_dequeue(parent, NULL)))
686 l2cap_sock_close(sk);
687
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200688 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689 sock_set_flag(parent, SOCK_ZAPPED);
690}
691
692/* Kill socket (only if zapped and orphan)
693 * Must be called on unlocked socket.
694 */
695static void l2cap_sock_kill(struct sock *sk)
696{
697 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
698 return;
699
700 BT_DBG("sk %p state %d", sk, sk->sk_state);
701
702 /* Kill poor orphan */
703 bt_sock_unlink(&l2cap_sk_list, sk);
704 sock_set_flag(sk, SOCK_DEAD);
705 sock_put(sk);
706}
707
708static void __l2cap_sock_close(struct sock *sk, int reason)
709{
710 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
711
712 switch (sk->sk_state) {
713 case BT_LISTEN:
714 l2cap_sock_cleanup_listen(sk);
715 break;
716
717 case BT_CONNECTED:
718 case BT_CONFIG:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719 if (sk->sk_type == SOCK_SEQPACKET) {
720 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721
722 sk->sk_state = BT_DISCONN;
723 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300724 l2cap_send_disconn_req(conn, sk);
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200725 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727 break;
728
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100729 case BT_CONNECT2:
730 if (sk->sk_type == SOCK_SEQPACKET) {
731 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
732 struct l2cap_conn_rsp rsp;
733 __u16 result;
734
735 if (bt_sk(sk)->defer_setup)
736 result = L2CAP_CR_SEC_BLOCK;
737 else
738 result = L2CAP_CR_BAD_PSM;
739
740 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
741 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
742 rsp.result = cpu_to_le16(result);
743 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
744 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
745 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
746 } else
747 l2cap_chan_del(sk, reason);
748 break;
749
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750 case BT_CONNECT:
751 case BT_DISCONN:
752 l2cap_chan_del(sk, reason);
753 break;
754
755 default:
756 sock_set_flag(sk, SOCK_ZAPPED);
757 break;
758 }
759}
760
761/* Must be called on unlocked socket. */
762static void l2cap_sock_close(struct sock *sk)
763{
764 l2cap_sock_clear_timer(sk);
765 lock_sock(sk);
766 __l2cap_sock_close(sk, ECONNRESET);
767 release_sock(sk);
768 l2cap_sock_kill(sk);
769}
770
771static void l2cap_sock_init(struct sock *sk, struct sock *parent)
772{
773 struct l2cap_pinfo *pi = l2cap_pi(sk);
774
775 BT_DBG("sk %p", sk);
776
777 if (parent) {
778 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100779 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
780
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781 pi->imtu = l2cap_pi(parent)->imtu;
782 pi->omtu = l2cap_pi(parent)->omtu;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700783 pi->mode = l2cap_pi(parent)->mode;
784 pi->fcs = l2cap_pi(parent)->fcs;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100785 pi->sec_level = l2cap_pi(parent)->sec_level;
786 pi->role_switch = l2cap_pi(parent)->role_switch;
787 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788 } else {
789 pi->imtu = L2CAP_DEFAULT_MTU;
790 pi->omtu = 0;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700791 pi->mode = L2CAP_MODE_BASIC;
792 pi->fcs = L2CAP_FCS_CRC16;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100793 pi->sec_level = BT_SECURITY_LOW;
794 pi->role_switch = 0;
795 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796 }
797
798 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200799 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Dave Young45054dc2009-10-18 20:28:30 +0000801 skb_queue_head_init(TX_QUEUE(sk));
802 skb_queue_head_init(SREJ_QUEUE(sk));
803 INIT_LIST_HEAD(SREJ_LIST(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804}
805
806static struct proto l2cap_proto = {
807 .name = "L2CAP",
808 .owner = THIS_MODULE,
809 .obj_size = sizeof(struct l2cap_pinfo)
810};
811
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700812static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813{
814 struct sock *sk;
815
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700816 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817 if (!sk)
818 return NULL;
819
820 sock_init_data(sock, sk);
821 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
822
823 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200824 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825
826 sock_reset_flag(sk, SOCK_ZAPPED);
827
828 sk->sk_protocol = proto;
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200829 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200831 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832
833 bt_sock_link(&l2cap_sk_list, sk);
834 return sk;
835}
836
Eric Paris3f378b62009-11-05 22:18:14 -0800837static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
838 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839{
840 struct sock *sk;
841
842 BT_DBG("sock %p", sock);
843
844 sock->state = SS_UNCONNECTED;
845
846 if (sock->type != SOCK_SEQPACKET &&
847 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
848 return -ESOCKTNOSUPPORT;
849
Eric Parisc84b3262009-11-05 20:45:52 -0800850 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 return -EPERM;
852
853 sock->ops = &l2cap_sock_ops;
854
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700855 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 if (!sk)
857 return -ENOMEM;
858
859 l2cap_sock_init(sk, NULL);
860 return 0;
861}
862
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100863static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100866 struct sockaddr_l2 la;
867 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100869 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870
871 if (!addr || addr->sa_family != AF_BLUETOOTH)
872 return -EINVAL;
873
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100874 memset(&la, 0, sizeof(la));
875 len = min_t(unsigned int, sizeof(la), alen);
876 memcpy(&la, addr, len);
877
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100878 if (la.l2_cid)
879 return -EINVAL;
880
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881 lock_sock(sk);
882
883 if (sk->sk_state != BT_OPEN) {
884 err = -EBADFD;
885 goto done;
886 }
887
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200888 if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
Marcel Holtmann847641d2007-01-22 22:00:45 +0100889 !capable(CAP_NET_BIND_SERVICE)) {
890 err = -EACCES;
891 goto done;
892 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900893
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894 write_lock_bh(&l2cap_sk_list.lock);
895
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100896 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897 err = -EADDRINUSE;
898 } else {
899 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100900 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
901 l2cap_pi(sk)->psm = la.l2_psm;
902 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100904
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200905 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
906 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100907 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908 }
909
910 write_unlock_bh(&l2cap_sk_list.lock);
911
912done:
913 release_sock(sk);
914 return err;
915}
916
917static int l2cap_do_connect(struct sock *sk)
918{
919 bdaddr_t *src = &bt_sk(sk)->src;
920 bdaddr_t *dst = &bt_sk(sk)->dst;
921 struct l2cap_conn *conn;
922 struct hci_conn *hcon;
923 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200924 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +0200925 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100927 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
928 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300930 hdev = hci_get_route(dst, src);
931 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700932 return -EHOSTUNREACH;
933
934 hci_dev_lock_bh(hdev);
935
936 err = -ENOMEM;
937
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100938 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100939 switch (l2cap_pi(sk)->sec_level) {
940 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100941 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100942 break;
943 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100944 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100945 break;
946 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100947 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100948 break;
949 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100950 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100951 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200952 auth_type = HCI_AT_NO_BONDING_MITM;
953 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200954 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +0100955
956 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
957 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100958 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100959 switch (l2cap_pi(sk)->sec_level) {
960 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100961 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100962 break;
963 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200964 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100965 break;
966 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100967 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100968 break;
969 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200970 }
971
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100972 hcon = hci_connect(hdev, ACL_LINK, dst,
973 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974 if (!hcon)
975 goto done;
976
977 conn = l2cap_conn_add(hcon, 0);
978 if (!conn) {
979 hci_conn_put(hcon);
980 goto done;
981 }
982
983 err = 0;
984
985 /* Update source addr of the socket */
986 bacpy(src, conn->src);
987
988 l2cap_chan_add(conn, sk, NULL);
989
990 sk->sk_state = BT_CONNECT;
991 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
992
993 if (hcon->state == BT_CONNECTED) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200994 if (sk->sk_type != SOCK_SEQPACKET) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995 l2cap_sock_clear_timer(sk);
996 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200997 } else
998 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700999 }
1000
1001done:
1002 hci_dev_unlock_bh(hdev);
1003 hci_dev_put(hdev);
1004 return err;
1005}
1006
1007static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
1008{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001010 struct sockaddr_l2 la;
1011 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 BT_DBG("sk %p", sk);
1014
Changli Gao6503d962010-03-31 22:58:26 +00001015 if (!addr || alen < sizeof(addr->sa_family) ||
1016 addr->sa_family != AF_BLUETOOTH)
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001017 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001019 memset(&la, 0, sizeof(la));
1020 len = min_t(unsigned int, sizeof(la), alen);
1021 memcpy(&la, addr, len);
1022
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001023 if (la.l2_cid)
1024 return -EINVAL;
1025
1026 lock_sock(sk);
1027
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001028 if (sk->sk_type == SOCK_SEQPACKET && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029 err = -EINVAL;
1030 goto done;
1031 }
1032
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001033 switch (l2cap_pi(sk)->mode) {
1034 case L2CAP_MODE_BASIC:
1035 break;
1036 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001037 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001038 if (enable_ertm)
1039 break;
1040 /* fall through */
1041 default:
1042 err = -ENOTSUPP;
1043 goto done;
1044 }
1045
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001046 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 case BT_CONNECT:
1048 case BT_CONNECT2:
1049 case BT_CONFIG:
1050 /* Already connecting */
1051 goto wait;
1052
1053 case BT_CONNECTED:
1054 /* Already connected */
1055 goto done;
1056
1057 case BT_OPEN:
1058 case BT_BOUND:
1059 /* Can connect */
1060 break;
1061
1062 default:
1063 err = -EBADFD;
1064 goto done;
1065 }
1066
1067 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001068 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1069 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001071 err = l2cap_do_connect(sk);
1072 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 goto done;
1074
1075wait:
1076 err = bt_sock_wait_state(sk, BT_CONNECTED,
1077 sock_sndtimeo(sk, flags & O_NONBLOCK));
1078done:
1079 release_sock(sk);
1080 return err;
1081}
1082
1083static int l2cap_sock_listen(struct socket *sock, int backlog)
1084{
1085 struct sock *sk = sock->sk;
1086 int err = 0;
1087
1088 BT_DBG("sk %p backlog %d", sk, backlog);
1089
1090 lock_sock(sk);
1091
1092 if (sk->sk_state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
1093 err = -EBADFD;
1094 goto done;
1095 }
1096
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001097 switch (l2cap_pi(sk)->mode) {
1098 case L2CAP_MODE_BASIC:
1099 break;
1100 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001101 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001102 if (enable_ertm)
1103 break;
1104 /* fall through */
1105 default:
1106 err = -ENOTSUPP;
1107 goto done;
1108 }
1109
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110 if (!l2cap_pi(sk)->psm) {
1111 bdaddr_t *src = &bt_sk(sk)->src;
1112 u16 psm;
1113
1114 err = -EINVAL;
1115
1116 write_lock_bh(&l2cap_sk_list.lock);
1117
1118 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001119 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1120 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1121 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122 err = 0;
1123 break;
1124 }
1125
1126 write_unlock_bh(&l2cap_sk_list.lock);
1127
1128 if (err < 0)
1129 goto done;
1130 }
1131
1132 sk->sk_max_ack_backlog = backlog;
1133 sk->sk_ack_backlog = 0;
1134 sk->sk_state = BT_LISTEN;
1135
1136done:
1137 release_sock(sk);
1138 return err;
1139}
1140
1141static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1142{
1143 DECLARE_WAITQUEUE(wait, current);
1144 struct sock *sk = sock->sk, *nsk;
1145 long timeo;
1146 int err = 0;
1147
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001148 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149
1150 if (sk->sk_state != BT_LISTEN) {
1151 err = -EBADFD;
1152 goto done;
1153 }
1154
1155 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1156
1157 BT_DBG("sk %p timeo %ld", sk, timeo);
1158
1159 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +00001160 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1162 set_current_state(TASK_INTERRUPTIBLE);
1163 if (!timeo) {
1164 err = -EAGAIN;
1165 break;
1166 }
1167
1168 release_sock(sk);
1169 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001170 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171
1172 if (sk->sk_state != BT_LISTEN) {
1173 err = -EBADFD;
1174 break;
1175 }
1176
1177 if (signal_pending(current)) {
1178 err = sock_intr_errno(timeo);
1179 break;
1180 }
1181 }
1182 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +00001183 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001184
1185 if (err)
1186 goto done;
1187
1188 newsock->state = SS_CONNECTED;
1189
1190 BT_DBG("new socket %p", nsk);
1191
1192done:
1193 release_sock(sk);
1194 return err;
1195}
1196
1197static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1198{
1199 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1200 struct sock *sk = sock->sk;
1201
1202 BT_DBG("sock %p, sk %p", sock, sk);
1203
1204 addr->sa_family = AF_BLUETOOTH;
1205 *len = sizeof(struct sockaddr_l2);
1206
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001207 if (peer) {
1208 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001210 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001211 } else {
1212 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001214 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001215 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217 return 0;
1218}
1219
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001220static void l2cap_monitor_timeout(unsigned long arg)
1221{
1222 struct sock *sk = (void *) arg;
1223 u16 control;
1224
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001225 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001226 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
1227 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001228 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001229 return;
1230 }
1231
1232 l2cap_pi(sk)->retry_count++;
1233 __mod_monitor_timer();
1234
1235 control = L2CAP_CTRL_POLL;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001236 l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001237 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001238}
1239
1240static void l2cap_retrans_timeout(unsigned long arg)
1241{
1242 struct sock *sk = (void *) arg;
1243 u16 control;
1244
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001245 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001246 l2cap_pi(sk)->retry_count = 1;
1247 __mod_monitor_timer();
1248
1249 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1250
1251 control = L2CAP_CTRL_POLL;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001252 l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001253 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001254}
1255
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001256static void l2cap_drop_acked_frames(struct sock *sk)
1257{
1258 struct sk_buff *skb;
1259
1260 while ((skb = skb_peek(TX_QUEUE(sk)))) {
1261 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1262 break;
1263
1264 skb = skb_dequeue(TX_QUEUE(sk));
1265 kfree_skb(skb);
1266
1267 l2cap_pi(sk)->unacked_frames--;
1268 }
1269
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001270 if (!l2cap_pi(sk)->unacked_frames)
1271 del_timer(&l2cap_pi(sk)->retrans_timer);
1272
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001273 return;
1274}
1275
1276static inline int l2cap_do_send(struct sock *sk, struct sk_buff *skb)
1277{
1278 struct l2cap_pinfo *pi = l2cap_pi(sk);
1279 int err;
1280
1281 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1282
1283 err = hci_send_acl(pi->conn->hcon, skb, 0);
1284 if (err < 0)
1285 kfree_skb(skb);
1286
1287 return err;
1288}
1289
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001290static int l2cap_streaming_send(struct sock *sk)
1291{
1292 struct sk_buff *skb, *tx_skb;
1293 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001294 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001295 int err;
1296
1297 while ((skb = sk->sk_send_head)) {
1298 tx_skb = skb_clone(skb, GFP_ATOMIC);
1299
1300 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1301 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1302 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1303
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001304 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001305 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1306 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1307 }
1308
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001309 err = l2cap_do_send(sk, tx_skb);
1310 if (err < 0) {
1311 l2cap_send_disconn_req(pi->conn, sk);
1312 return err;
1313 }
1314
1315 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1316
1317 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1318 sk->sk_send_head = NULL;
1319 else
1320 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1321
1322 skb = skb_dequeue(TX_QUEUE(sk));
1323 kfree_skb(skb);
1324 }
1325 return 0;
1326}
1327
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001328static int l2cap_retransmit_frame(struct sock *sk, u8 tx_seq)
1329{
1330 struct l2cap_pinfo *pi = l2cap_pi(sk);
1331 struct sk_buff *skb, *tx_skb;
1332 u16 control, fcs;
1333 int err;
1334
1335 skb = skb_peek(TX_QUEUE(sk));
1336 do {
1337 if (bt_cb(skb)->tx_seq != tx_seq) {
1338 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1339 break;
1340 skb = skb_queue_next(TX_QUEUE(sk), skb);
1341 continue;
1342 }
1343
1344 if (pi->remote_max_tx &&
1345 bt_cb(skb)->retries == pi->remote_max_tx) {
1346 l2cap_send_disconn_req(pi->conn, sk);
1347 break;
1348 }
1349
1350 tx_skb = skb_clone(skb, GFP_ATOMIC);
1351 bt_cb(skb)->retries++;
1352 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001353 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001354 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1355 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1356
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001357 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001358 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1359 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1360 }
1361
1362 err = l2cap_do_send(sk, tx_skb);
1363 if (err < 0) {
1364 l2cap_send_disconn_req(pi->conn, sk);
1365 return err;
1366 }
1367 break;
1368 } while(1);
1369 return 0;
1370}
1371
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001372static int l2cap_ertm_send(struct sock *sk)
1373{
1374 struct sk_buff *skb, *tx_skb;
1375 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001376 u16 control, fcs;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001377 int err, nsent = 0;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001378
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001379 if (pi->conn_state & L2CAP_CONN_WAIT_F)
1380 return 0;
1381
Joe Perchesf64f9e72009-11-29 16:55:45 -08001382 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) &&
1383 !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) {
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001384
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001385 if (pi->remote_max_tx &&
1386 bt_cb(skb)->retries == pi->remote_max_tx) {
1387 l2cap_send_disconn_req(pi->conn, sk);
1388 break;
1389 }
1390
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001391 tx_skb = skb_clone(skb, GFP_ATOMIC);
1392
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001393 bt_cb(skb)->retries++;
1394
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001395 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001396 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1397 control |= L2CAP_CTRL_FINAL;
1398 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1399 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001400 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001401 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1402 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1403
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001404
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001405 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001406 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1407 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1408 }
1409
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001410 err = l2cap_do_send(sk, tx_skb);
1411 if (err < 0) {
1412 l2cap_send_disconn_req(pi->conn, sk);
1413 return err;
1414 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001415 __mod_retrans_timer();
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001416
1417 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1418 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1419
1420 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001421 pi->frames_sent++;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001422
1423 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1424 sk->sk_send_head = NULL;
1425 else
1426 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001427
1428 nsent++;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001429 }
1430
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001431 return nsent;
1432}
1433
1434static int l2cap_send_ack(struct l2cap_pinfo *pi)
1435{
1436 struct sock *sk = (struct sock *)pi;
1437 u16 control = 0;
1438
1439 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1440
1441 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1442 control |= L2CAP_SUPER_RCV_NOT_READY;
1443 return l2cap_send_sframe(pi, control);
1444 } else if (l2cap_ertm_send(sk) == 0) {
1445 control |= L2CAP_SUPER_RCV_READY;
1446 return l2cap_send_sframe(pi, control);
1447 }
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001448 return 0;
1449}
1450
1451static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, int len, int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452{
1453 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001454 struct sk_buff **frag;
1455 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456
1457 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001458 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459 }
1460
1461 sent += count;
1462 len -= count;
1463
1464 /* Continuation fragments (no L2CAP header) */
1465 frag = &skb_shinfo(skb)->frag_list;
1466 while (len) {
1467 count = min_t(unsigned int, conn->mtu, len);
1468
1469 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1470 if (!*frag)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001471 return -EFAULT;
1472 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1473 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474
1475 sent += count;
1476 len -= count;
1477
1478 frag = &(*frag)->next;
1479 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480
1481 return sent;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001482}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001483
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001484static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1485{
1486 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1487 struct sk_buff *skb;
1488 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1489 struct l2cap_hdr *lh;
1490
1491 BT_DBG("sk %p len %d", sk, (int)len);
1492
1493 count = min_t(unsigned int, (conn->mtu - hlen), len);
1494 skb = bt_skb_send_alloc(sk, count + hlen,
1495 msg->msg_flags & MSG_DONTWAIT, &err);
1496 if (!skb)
1497 return ERR_PTR(-ENOMEM);
1498
1499 /* Create L2CAP header */
1500 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1501 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1502 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1503 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1504
1505 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1506 if (unlikely(err < 0)) {
1507 kfree_skb(skb);
1508 return ERR_PTR(err);
1509 }
1510 return skb;
1511}
1512
1513static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1514{
1515 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1516 struct sk_buff *skb;
1517 int err, count, hlen = L2CAP_HDR_SIZE;
1518 struct l2cap_hdr *lh;
1519
1520 BT_DBG("sk %p len %d", sk, (int)len);
1521
1522 count = min_t(unsigned int, (conn->mtu - hlen), len);
1523 skb = bt_skb_send_alloc(sk, count + hlen,
1524 msg->msg_flags & MSG_DONTWAIT, &err);
1525 if (!skb)
1526 return ERR_PTR(-ENOMEM);
1527
1528 /* Create L2CAP header */
1529 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1530 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1531 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1532
1533 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1534 if (unlikely(err < 0)) {
1535 kfree_skb(skb);
1536 return ERR_PTR(err);
1537 }
1538 return skb;
1539}
1540
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001541static struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001542{
1543 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1544 struct sk_buff *skb;
1545 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1546 struct l2cap_hdr *lh;
1547
1548 BT_DBG("sk %p len %d", sk, (int)len);
1549
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001550 if (sdulen)
1551 hlen += 2;
1552
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001553 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1554 hlen += 2;
1555
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001556 count = min_t(unsigned int, (conn->mtu - hlen), len);
1557 skb = bt_skb_send_alloc(sk, count + hlen,
1558 msg->msg_flags & MSG_DONTWAIT, &err);
1559 if (!skb)
1560 return ERR_PTR(-ENOMEM);
1561
1562 /* Create L2CAP header */
1563 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1564 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1565 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1566 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001567 if (sdulen)
1568 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001569
1570 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1571 if (unlikely(err < 0)) {
1572 kfree_skb(skb);
1573 return ERR_PTR(err);
1574 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001575
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001576 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1577 put_unaligned_le16(0, skb_put(skb, 2));
1578
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001579 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001580 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581}
1582
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001583static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1584{
1585 struct l2cap_pinfo *pi = l2cap_pi(sk);
1586 struct sk_buff *skb;
1587 struct sk_buff_head sar_queue;
1588 u16 control;
1589 size_t size = 0;
1590
1591 __skb_queue_head_init(&sar_queue);
1592 control = L2CAP_SDU_START;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001593 skb = l2cap_create_iframe_pdu(sk, msg, pi->max_pdu_size, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001594 if (IS_ERR(skb))
1595 return PTR_ERR(skb);
1596
1597 __skb_queue_tail(&sar_queue, skb);
1598 len -= pi->max_pdu_size;
1599 size +=pi->max_pdu_size;
1600 control = 0;
1601
1602 while (len > 0) {
1603 size_t buflen;
1604
1605 if (len > pi->max_pdu_size) {
1606 control |= L2CAP_SDU_CONTINUE;
1607 buflen = pi->max_pdu_size;
1608 } else {
1609 control |= L2CAP_SDU_END;
1610 buflen = len;
1611 }
1612
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001613 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001614 if (IS_ERR(skb)) {
1615 skb_queue_purge(&sar_queue);
1616 return PTR_ERR(skb);
1617 }
1618
1619 __skb_queue_tail(&sar_queue, skb);
1620 len -= buflen;
1621 size += buflen;
1622 control = 0;
1623 }
1624 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1625 if (sk->sk_send_head == NULL)
1626 sk->sk_send_head = sar_queue.next;
1627
1628 return size;
1629}
1630
Linus Torvalds1da177e2005-04-16 15:20:36 -07001631static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1632{
1633 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001634 struct l2cap_pinfo *pi = l2cap_pi(sk);
1635 struct sk_buff *skb;
1636 u16 control;
1637 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638
1639 BT_DBG("sock %p, sk %p", sock, sk);
1640
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001641 err = sock_error(sk);
1642 if (err)
1643 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644
1645 if (msg->msg_flags & MSG_OOB)
1646 return -EOPNOTSUPP;
1647
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648 lock_sock(sk);
1649
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001650 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651 err = -ENOTCONN;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001652 goto done;
1653 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001655 /* Connectionless channel */
1656 if (sk->sk_type == SOCK_DGRAM) {
1657 skb = l2cap_create_connless_pdu(sk, msg, len);
Dan Carpenter477fffb2010-04-21 23:52:01 +00001658 if (IS_ERR(skb))
1659 err = PTR_ERR(skb);
1660 else
1661 err = l2cap_do_send(sk, skb);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001662 goto done;
1663 }
1664
1665 switch (pi->mode) {
1666 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001667 /* Check outgoing MTU */
1668 if (len > pi->omtu) {
1669 err = -EINVAL;
1670 goto done;
1671 }
1672
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001673 /* Create a basic PDU */
1674 skb = l2cap_create_basic_pdu(sk, msg, len);
1675 if (IS_ERR(skb)) {
1676 err = PTR_ERR(skb);
1677 goto done;
1678 }
1679
1680 err = l2cap_do_send(sk, skb);
1681 if (!err)
1682 err = len;
1683 break;
1684
1685 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001686 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001687 /* Entire SDU fits into one PDU */
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001688 if (len <= pi->max_pdu_size) {
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001689 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001690 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001691 if (IS_ERR(skb)) {
1692 err = PTR_ERR(skb);
1693 goto done;
1694 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001695 __skb_queue_tail(TX_QUEUE(sk), skb);
1696 if (sk->sk_send_head == NULL)
1697 sk->sk_send_head = skb;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001698 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001699 /* Segment SDU into multiples PDUs */
1700 err = l2cap_sar_segment_sdu(sk, msg, len);
1701 if (err < 0)
1702 goto done;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001703 }
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001704
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001705 if (pi->mode == L2CAP_MODE_STREAMING)
1706 err = l2cap_streaming_send(sk);
1707 else
1708 err = l2cap_ertm_send(sk);
1709
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001710 if (err >= 0)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001711 err = len;
1712 break;
1713
1714 default:
1715 BT_DBG("bad state %1.1x", pi->mode);
1716 err = -EINVAL;
1717 }
1718
1719done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 release_sock(sk);
1721 return err;
1722}
1723
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001724static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1725{
1726 struct sock *sk = sock->sk;
1727
1728 lock_sock(sk);
1729
1730 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1731 struct l2cap_conn_rsp rsp;
1732
1733 sk->sk_state = BT_CONFIG;
1734
1735 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1736 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1737 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1738 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1739 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1740 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1741
1742 release_sock(sk);
1743 return 0;
1744 }
1745
1746 release_sock(sk);
1747
1748 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1749}
1750
David S. Millerb7058842009-09-30 16:12:20 -07001751static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752{
1753 struct sock *sk = sock->sk;
1754 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001755 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 u32 opt;
1757
1758 BT_DBG("sk %p", sk);
1759
1760 lock_sock(sk);
1761
1762 switch (optname) {
1763 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001764 opts.imtu = l2cap_pi(sk)->imtu;
1765 opts.omtu = l2cap_pi(sk)->omtu;
1766 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001767 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001768 opts.fcs = l2cap_pi(sk)->fcs;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001769
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770 len = min_t(unsigned int, sizeof(opts), optlen);
1771 if (copy_from_user((char *) &opts, optval, len)) {
1772 err = -EFAULT;
1773 break;
1774 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001775
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001776 l2cap_pi(sk)->imtu = opts.imtu;
1777 l2cap_pi(sk)->omtu = opts.omtu;
1778 l2cap_pi(sk)->mode = opts.mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001779 l2cap_pi(sk)->fcs = opts.fcs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780 break;
1781
1782 case L2CAP_LM:
1783 if (get_user(opt, (u32 __user *) optval)) {
1784 err = -EFAULT;
1785 break;
1786 }
1787
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001788 if (opt & L2CAP_LM_AUTH)
1789 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1790 if (opt & L2CAP_LM_ENCRYPT)
1791 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1792 if (opt & L2CAP_LM_SECURE)
1793 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1794
1795 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1796 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797 break;
1798
1799 default:
1800 err = -ENOPROTOOPT;
1801 break;
1802 }
1803
1804 release_sock(sk);
1805 return err;
1806}
1807
David S. Millerb7058842009-09-30 16:12:20 -07001808static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001809{
1810 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001811 struct bt_security sec;
1812 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001813 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001814
1815 BT_DBG("sk %p", sk);
1816
1817 if (level == SOL_L2CAP)
1818 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1819
Marcel Holtmann0588d942009-01-16 10:06:13 +01001820 if (level != SOL_BLUETOOTH)
1821 return -ENOPROTOOPT;
1822
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001823 lock_sock(sk);
1824
1825 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001826 case BT_SECURITY:
Marcel Holtmann2526d3d2009-02-20 20:54:06 +01001827 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001828 err = -EINVAL;
1829 break;
1830 }
1831
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001832 sec.level = BT_SECURITY_LOW;
1833
1834 len = min_t(unsigned int, sizeof(sec), optlen);
1835 if (copy_from_user((char *) &sec, optval, len)) {
1836 err = -EFAULT;
1837 break;
1838 }
1839
1840 if (sec.level < BT_SECURITY_LOW ||
1841 sec.level > BT_SECURITY_HIGH) {
1842 err = -EINVAL;
1843 break;
1844 }
1845
1846 l2cap_pi(sk)->sec_level = sec.level;
1847 break;
1848
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001849 case BT_DEFER_SETUP:
1850 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1851 err = -EINVAL;
1852 break;
1853 }
1854
1855 if (get_user(opt, (u32 __user *) optval)) {
1856 err = -EFAULT;
1857 break;
1858 }
1859
1860 bt_sk(sk)->defer_setup = opt;
1861 break;
1862
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001863 default:
1864 err = -ENOPROTOOPT;
1865 break;
1866 }
1867
1868 release_sock(sk);
1869 return err;
1870}
1871
1872static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873{
1874 struct sock *sk = sock->sk;
1875 struct l2cap_options opts;
1876 struct l2cap_conninfo cinfo;
1877 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001878 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879
1880 BT_DBG("sk %p", sk);
1881
1882 if (get_user(len, optlen))
1883 return -EFAULT;
1884
1885 lock_sock(sk);
1886
1887 switch (optname) {
1888 case L2CAP_OPTIONS:
1889 opts.imtu = l2cap_pi(sk)->imtu;
1890 opts.omtu = l2cap_pi(sk)->omtu;
1891 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001892 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001893 opts.fcs = l2cap_pi(sk)->fcs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894
1895 len = min_t(unsigned int, len, sizeof(opts));
1896 if (copy_to_user(optval, (char *) &opts, len))
1897 err = -EFAULT;
1898
1899 break;
1900
1901 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001902 switch (l2cap_pi(sk)->sec_level) {
1903 case BT_SECURITY_LOW:
1904 opt = L2CAP_LM_AUTH;
1905 break;
1906 case BT_SECURITY_MEDIUM:
1907 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
1908 break;
1909 case BT_SECURITY_HIGH:
1910 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
1911 L2CAP_LM_SECURE;
1912 break;
1913 default:
1914 opt = 0;
1915 break;
1916 }
1917
1918 if (l2cap_pi(sk)->role_switch)
1919 opt |= L2CAP_LM_MASTER;
1920
1921 if (l2cap_pi(sk)->force_reliable)
1922 opt |= L2CAP_LM_RELIABLE;
1923
1924 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925 err = -EFAULT;
1926 break;
1927
1928 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001929 if (sk->sk_state != BT_CONNECTED &&
1930 !(sk->sk_state == BT_CONNECT2 &&
1931 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001932 err = -ENOTCONN;
1933 break;
1934 }
1935
1936 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
1937 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
1938
1939 len = min_t(unsigned int, len, sizeof(cinfo));
1940 if (copy_to_user(optval, (char *) &cinfo, len))
1941 err = -EFAULT;
1942
1943 break;
1944
1945 default:
1946 err = -ENOPROTOOPT;
1947 break;
1948 }
1949
1950 release_sock(sk);
1951 return err;
1952}
1953
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001954static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
1955{
1956 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001957 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001958 int len, err = 0;
1959
1960 BT_DBG("sk %p", sk);
1961
1962 if (level == SOL_L2CAP)
1963 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
1964
Marcel Holtmann0588d942009-01-16 10:06:13 +01001965 if (level != SOL_BLUETOOTH)
1966 return -ENOPROTOOPT;
1967
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001968 if (get_user(len, optlen))
1969 return -EFAULT;
1970
1971 lock_sock(sk);
1972
1973 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001974 case BT_SECURITY:
Marcel Holtmann2526d3d2009-02-20 20:54:06 +01001975 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001976 err = -EINVAL;
1977 break;
1978 }
1979
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001980 sec.level = l2cap_pi(sk)->sec_level;
1981
1982 len = min_t(unsigned int, len, sizeof(sec));
1983 if (copy_to_user(optval, (char *) &sec, len))
1984 err = -EFAULT;
1985
1986 break;
1987
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001988 case BT_DEFER_SETUP:
1989 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1990 err = -EINVAL;
1991 break;
1992 }
1993
1994 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
1995 err = -EFAULT;
1996
1997 break;
1998
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001999 default:
2000 err = -ENOPROTOOPT;
2001 break;
2002 }
2003
2004 release_sock(sk);
2005 return err;
2006}
2007
Linus Torvalds1da177e2005-04-16 15:20:36 -07002008static int l2cap_sock_shutdown(struct socket *sock, int how)
2009{
2010 struct sock *sk = sock->sk;
2011 int err = 0;
2012
2013 BT_DBG("sock %p, sk %p", sock, sk);
2014
2015 if (!sk)
2016 return 0;
2017
2018 lock_sock(sk);
2019 if (!sk->sk_shutdown) {
2020 sk->sk_shutdown = SHUTDOWN_MASK;
2021 l2cap_sock_clear_timer(sk);
2022 __l2cap_sock_close(sk, 0);
2023
2024 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02002025 err = bt_sock_wait_state(sk, BT_CLOSED,
2026 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002027 }
2028 release_sock(sk);
2029 return err;
2030}
2031
2032static int l2cap_sock_release(struct socket *sock)
2033{
2034 struct sock *sk = sock->sk;
2035 int err;
2036
2037 BT_DBG("sock %p, sk %p", sock, sk);
2038
2039 if (!sk)
2040 return 0;
2041
2042 err = l2cap_sock_shutdown(sock, 2);
2043
2044 sock_orphan(sk);
2045 l2cap_sock_kill(sk);
2046 return err;
2047}
2048
Linus Torvalds1da177e2005-04-16 15:20:36 -07002049static void l2cap_chan_ready(struct sock *sk)
2050{
2051 struct sock *parent = bt_sk(sk)->parent;
2052
2053 BT_DBG("sk %p, parent %p", sk, parent);
2054
2055 l2cap_pi(sk)->conf_state = 0;
2056 l2cap_sock_clear_timer(sk);
2057
2058 if (!parent) {
2059 /* Outgoing channel.
2060 * Wake up socket sleeping on connect.
2061 */
2062 sk->sk_state = BT_CONNECTED;
2063 sk->sk_state_change(sk);
2064 } else {
2065 /* Incoming channel.
2066 * Wake up socket sleeping on accept.
2067 */
2068 parent->sk_data_ready(parent, 0);
2069 }
2070}
2071
2072/* Copy frame to all raw sockets on that connection */
2073static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2074{
2075 struct l2cap_chan_list *l = &conn->chan_list;
2076 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002077 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002078
2079 BT_DBG("conn %p", conn);
2080
2081 read_lock(&l->lock);
2082 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2083 if (sk->sk_type != SOCK_RAW)
2084 continue;
2085
2086 /* Don't send frame to the socket it came from */
2087 if (skb->sk == sk)
2088 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002089 nskb = skb_clone(skb, GFP_ATOMIC);
2090 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002091 continue;
2092
2093 if (sock_queue_rcv_skb(sk, nskb))
2094 kfree_skb(nskb);
2095 }
2096 read_unlock(&l->lock);
2097}
2098
2099/* ---- L2CAP signalling commands ---- */
2100static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2101 u8 code, u8 ident, u16 dlen, void *data)
2102{
2103 struct sk_buff *skb, **frag;
2104 struct l2cap_cmd_hdr *cmd;
2105 struct l2cap_hdr *lh;
2106 int len, count;
2107
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002108 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2109 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002110
2111 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2112 count = min_t(unsigned int, conn->mtu, len);
2113
2114 skb = bt_skb_alloc(count, GFP_ATOMIC);
2115 if (!skb)
2116 return NULL;
2117
2118 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002119 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002120 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002121
2122 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2123 cmd->code = code;
2124 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002125 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002126
2127 if (dlen) {
2128 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2129 memcpy(skb_put(skb, count), data, count);
2130 data += count;
2131 }
2132
2133 len -= skb->len;
2134
2135 /* Continuation fragments (no L2CAP header) */
2136 frag = &skb_shinfo(skb)->frag_list;
2137 while (len) {
2138 count = min_t(unsigned int, conn->mtu, len);
2139
2140 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2141 if (!*frag)
2142 goto fail;
2143
2144 memcpy(skb_put(*frag, count), data, count);
2145
2146 len -= count;
2147 data += count;
2148
2149 frag = &(*frag)->next;
2150 }
2151
2152 return skb;
2153
2154fail:
2155 kfree_skb(skb);
2156 return NULL;
2157}
2158
2159static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2160{
2161 struct l2cap_conf_opt *opt = *ptr;
2162 int len;
2163
2164 len = L2CAP_CONF_OPT_SIZE + opt->len;
2165 *ptr += len;
2166
2167 *type = opt->type;
2168 *olen = opt->len;
2169
2170 switch (opt->len) {
2171 case 1:
2172 *val = *((u8 *) opt->val);
2173 break;
2174
2175 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002176 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002177 break;
2178
2179 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002180 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002181 break;
2182
2183 default:
2184 *val = (unsigned long) opt->val;
2185 break;
2186 }
2187
2188 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2189 return len;
2190}
2191
Linus Torvalds1da177e2005-04-16 15:20:36 -07002192static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2193{
2194 struct l2cap_conf_opt *opt = *ptr;
2195
2196 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2197
2198 opt->type = type;
2199 opt->len = len;
2200
2201 switch (len) {
2202 case 1:
2203 *((u8 *) opt->val) = val;
2204 break;
2205
2206 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002207 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002208 break;
2209
2210 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002211 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002212 break;
2213
2214 default:
2215 memcpy(opt->val, (void *) val, len);
2216 break;
2217 }
2218
2219 *ptr += L2CAP_CONF_OPT_SIZE + len;
2220}
2221
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002222static inline void l2cap_ertm_init(struct sock *sk)
2223{
2224 l2cap_pi(sk)->expected_ack_seq = 0;
2225 l2cap_pi(sk)->unacked_frames = 0;
2226 l2cap_pi(sk)->buffer_seq = 0;
2227 l2cap_pi(sk)->num_to_ack = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002228 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002229
2230 setup_timer(&l2cap_pi(sk)->retrans_timer,
2231 l2cap_retrans_timeout, (unsigned long) sk);
2232 setup_timer(&l2cap_pi(sk)->monitor_timer,
2233 l2cap_monitor_timeout, (unsigned long) sk);
2234
2235 __skb_queue_head_init(SREJ_QUEUE(sk));
2236}
2237
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002238static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2239{
2240 u32 local_feat_mask = l2cap_feat_mask;
2241 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002242 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002243
2244 switch (mode) {
2245 case L2CAP_MODE_ERTM:
2246 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2247 case L2CAP_MODE_STREAMING:
2248 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2249 default:
2250 return 0x00;
2251 }
2252}
2253
2254static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2255{
2256 switch (mode) {
2257 case L2CAP_MODE_STREAMING:
2258 case L2CAP_MODE_ERTM:
2259 if (l2cap_mode_supported(mode, remote_feat_mask))
2260 return mode;
2261 /* fall through */
2262 default:
2263 return L2CAP_MODE_BASIC;
2264 }
2265}
2266
Linus Torvalds1da177e2005-04-16 15:20:36 -07002267static int l2cap_build_conf_req(struct sock *sk, void *data)
2268{
2269 struct l2cap_pinfo *pi = l2cap_pi(sk);
2270 struct l2cap_conf_req *req = data;
Gustavo F. Padovana0e55a32009-09-29 01:42:23 -03002271 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002272 void *ptr = req->data;
2273
2274 BT_DBG("sk %p", sk);
2275
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002276 if (pi->num_conf_req || pi->num_conf_rsp)
2277 goto done;
2278
2279 switch (pi->mode) {
2280 case L2CAP_MODE_STREAMING:
2281 case L2CAP_MODE_ERTM:
2282 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002283 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2284 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002285 break;
2286 default:
2287 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2288 break;
2289 }
2290
2291done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002292 switch (pi->mode) {
2293 case L2CAP_MODE_BASIC:
2294 if (pi->imtu != L2CAP_DEFAULT_MTU)
2295 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2296 break;
2297
2298 case L2CAP_MODE_ERTM:
2299 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002300 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +02002301 rfc.max_transmit = max_transmit;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002302 rfc.retrans_timeout = 0;
2303 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002304 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002305 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
2306 rfc.max_pdu_size = pi->conn->mtu - 10;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002307
2308 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2309 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002310
2311 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2312 break;
2313
2314 if (pi->fcs == L2CAP_FCS_NONE ||
2315 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2316 pi->fcs = L2CAP_FCS_NONE;
2317 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2318 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002319 break;
2320
2321 case L2CAP_MODE_STREAMING:
2322 rfc.mode = L2CAP_MODE_STREAMING;
2323 rfc.txwin_size = 0;
2324 rfc.max_transmit = 0;
2325 rfc.retrans_timeout = 0;
2326 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002327 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002328 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
2329 rfc.max_pdu_size = pi->conn->mtu - 10;
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002330
2331 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2332 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002333
2334 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2335 break;
2336
2337 if (pi->fcs == L2CAP_FCS_NONE ||
2338 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2339 pi->fcs = L2CAP_FCS_NONE;
2340 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2341 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002342 break;
2343 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002344
2345 /* FIXME: Need actual value of the flush timeout */
2346 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2347 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2348
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002349 req->dcid = cpu_to_le16(pi->dcid);
2350 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002351
2352 return ptr - data;
2353}
2354
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002355static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002356{
2357 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002358 struct l2cap_conf_rsp *rsp = data;
2359 void *ptr = rsp->data;
2360 void *req = pi->conf_req;
2361 int len = pi->conf_len;
2362 int type, hint, olen;
2363 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002364 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002365 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002366 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002367
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002368 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002369
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002370 while (len >= L2CAP_CONF_OPT_SIZE) {
2371 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002372
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002373 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002374 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002375
2376 switch (type) {
2377 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002378 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002379 break;
2380
2381 case L2CAP_CONF_FLUSH_TO:
2382 pi->flush_to = val;
2383 break;
2384
2385 case L2CAP_CONF_QOS:
2386 break;
2387
Marcel Holtmann6464f352007-10-20 13:39:51 +02002388 case L2CAP_CONF_RFC:
2389 if (olen == sizeof(rfc))
2390 memcpy(&rfc, (void *) val, olen);
2391 break;
2392
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002393 case L2CAP_CONF_FCS:
2394 if (val == L2CAP_FCS_NONE)
2395 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2396
2397 break;
2398
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002399 default:
2400 if (hint)
2401 break;
2402
2403 result = L2CAP_CONF_UNKNOWN;
2404 *((u8 *) ptr++) = type;
2405 break;
2406 }
2407 }
2408
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002409 if (pi->num_conf_rsp || pi->num_conf_req)
2410 goto done;
2411
2412 switch (pi->mode) {
2413 case L2CAP_MODE_STREAMING:
2414 case L2CAP_MODE_ERTM:
2415 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2416 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2417 return -ECONNREFUSED;
2418 break;
2419 default:
2420 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2421 break;
2422 }
2423
2424done:
2425 if (pi->mode != rfc.mode) {
2426 result = L2CAP_CONF_UNACCEPT;
2427 rfc.mode = pi->mode;
2428
2429 if (pi->num_conf_rsp == 1)
2430 return -ECONNREFUSED;
2431
2432 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2433 sizeof(rfc), (unsigned long) &rfc);
2434 }
2435
2436
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002437 if (result == L2CAP_CONF_SUCCESS) {
2438 /* Configure output options and let the other side know
2439 * which ones we don't like. */
2440
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002441 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2442 result = L2CAP_CONF_UNACCEPT;
2443 else {
2444 pi->omtu = mtu;
2445 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2446 }
2447 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002448
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002449 switch (rfc.mode) {
2450 case L2CAP_MODE_BASIC:
2451 pi->fcs = L2CAP_FCS_NONE;
2452 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2453 break;
2454
2455 case L2CAP_MODE_ERTM:
2456 pi->remote_tx_win = rfc.txwin_size;
2457 pi->remote_max_tx = rfc.max_transmit;
2458 pi->max_pdu_size = rfc.max_pdu_size;
2459
2460 rfc.retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
2461 rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
2462
2463 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002464
2465 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2466 sizeof(rfc), (unsigned long) &rfc);
2467
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002468 break;
2469
2470 case L2CAP_MODE_STREAMING:
2471 pi->remote_tx_win = rfc.txwin_size;
2472 pi->max_pdu_size = rfc.max_pdu_size;
2473
2474 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002475
2476 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2477 sizeof(rfc), (unsigned long) &rfc);
2478
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002479 break;
2480
2481 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002482 result = L2CAP_CONF_UNACCEPT;
2483
2484 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002485 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002486 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002487
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002488 if (result == L2CAP_CONF_SUCCESS)
2489 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2490 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002491 rsp->scid = cpu_to_le16(pi->dcid);
2492 rsp->result = cpu_to_le16(result);
2493 rsp->flags = cpu_to_le16(0x0000);
2494
2495 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002496}
2497
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002498static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2499{
2500 struct l2cap_pinfo *pi = l2cap_pi(sk);
2501 struct l2cap_conf_req *req = data;
2502 void *ptr = req->data;
2503 int type, olen;
2504 unsigned long val;
2505 struct l2cap_conf_rfc rfc;
2506
2507 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2508
2509 while (len >= L2CAP_CONF_OPT_SIZE) {
2510 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2511
2512 switch (type) {
2513 case L2CAP_CONF_MTU:
2514 if (val < L2CAP_DEFAULT_MIN_MTU) {
2515 *result = L2CAP_CONF_UNACCEPT;
2516 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2517 } else
2518 pi->omtu = val;
2519 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2520 break;
2521
2522 case L2CAP_CONF_FLUSH_TO:
2523 pi->flush_to = val;
2524 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2525 2, pi->flush_to);
2526 break;
2527
2528 case L2CAP_CONF_RFC:
2529 if (olen == sizeof(rfc))
2530 memcpy(&rfc, (void *)val, olen);
2531
2532 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2533 rfc.mode != pi->mode)
2534 return -ECONNREFUSED;
2535
2536 pi->mode = rfc.mode;
2537 pi->fcs = 0;
2538
2539 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2540 sizeof(rfc), (unsigned long) &rfc);
2541 break;
2542 }
2543 }
2544
2545 if (*result == L2CAP_CONF_SUCCESS) {
2546 switch (rfc.mode) {
2547 case L2CAP_MODE_ERTM:
2548 pi->remote_tx_win = rfc.txwin_size;
2549 pi->retrans_timeout = rfc.retrans_timeout;
2550 pi->monitor_timeout = rfc.monitor_timeout;
2551 pi->max_pdu_size = le16_to_cpu(rfc.max_pdu_size);
2552 break;
2553 case L2CAP_MODE_STREAMING:
2554 pi->max_pdu_size = le16_to_cpu(rfc.max_pdu_size);
2555 break;
2556 }
2557 }
2558
2559 req->dcid = cpu_to_le16(pi->dcid);
2560 req->flags = cpu_to_le16(0x0000);
2561
2562 return ptr - data;
2563}
2564
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002565static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002566{
2567 struct l2cap_conf_rsp *rsp = data;
2568 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002569
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002570 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002571
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002572 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002573 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002574 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002575
2576 return ptr - data;
2577}
2578
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002579static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2580{
2581 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2582
2583 if (rej->reason != 0x0000)
2584 return 0;
2585
2586 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2587 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002588 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002589
2590 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002591 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002592
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002593 l2cap_conn_start(conn);
2594 }
2595
2596 return 0;
2597}
2598
Linus Torvalds1da177e2005-04-16 15:20:36 -07002599static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2600{
2601 struct l2cap_chan_list *list = &conn->chan_list;
2602 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2603 struct l2cap_conn_rsp rsp;
2604 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002605 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002606
2607 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002608 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002609
2610 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2611
2612 /* Check if we have socket listening on psm */
2613 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2614 if (!parent) {
2615 result = L2CAP_CR_BAD_PSM;
2616 goto sendresp;
2617 }
2618
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002619 /* Check if the ACL is secure enough (if not SDP) */
2620 if (psm != cpu_to_le16(0x0001) &&
2621 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002622 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002623 result = L2CAP_CR_SEC_BLOCK;
2624 goto response;
2625 }
2626
Linus Torvalds1da177e2005-04-16 15:20:36 -07002627 result = L2CAP_CR_NO_MEM;
2628
2629 /* Check for backlog size */
2630 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002631 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002632 goto response;
2633 }
2634
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002635 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636 if (!sk)
2637 goto response;
2638
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002639 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002640
2641 /* Check if we already have channel with that dcid */
2642 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002643 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002644 sock_set_flag(sk, SOCK_ZAPPED);
2645 l2cap_sock_kill(sk);
2646 goto response;
2647 }
2648
2649 hci_conn_hold(conn->hcon);
2650
2651 l2cap_sock_init(sk, parent);
2652 bacpy(&bt_sk(sk)->src, conn->src);
2653 bacpy(&bt_sk(sk)->dst, conn->dst);
2654 l2cap_pi(sk)->psm = psm;
2655 l2cap_pi(sk)->dcid = scid;
2656
2657 __l2cap_chan_add(conn, sk, parent);
2658 dcid = l2cap_pi(sk)->scid;
2659
2660 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2661
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662 l2cap_pi(sk)->ident = cmd->ident;
2663
Marcel Holtmann984947d2009-02-06 23:35:19 +01002664 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002665 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002666 if (bt_sk(sk)->defer_setup) {
2667 sk->sk_state = BT_CONNECT2;
2668 result = L2CAP_CR_PEND;
2669 status = L2CAP_CS_AUTHOR_PEND;
2670 parent->sk_data_ready(parent, 0);
2671 } else {
2672 sk->sk_state = BT_CONFIG;
2673 result = L2CAP_CR_SUCCESS;
2674 status = L2CAP_CS_NO_INFO;
2675 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002676 } else {
2677 sk->sk_state = BT_CONNECT2;
2678 result = L2CAP_CR_PEND;
2679 status = L2CAP_CS_AUTHEN_PEND;
2680 }
2681 } else {
2682 sk->sk_state = BT_CONNECT2;
2683 result = L2CAP_CR_PEND;
2684 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002685 }
2686
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002687 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002688
2689response:
2690 bh_unlock_sock(parent);
2691
2692sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002693 rsp.scid = cpu_to_le16(scid);
2694 rsp.dcid = cpu_to_le16(dcid);
2695 rsp.result = cpu_to_le16(result);
2696 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002697 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002698
2699 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2700 struct l2cap_info_req info;
2701 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2702
2703 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2704 conn->info_ident = l2cap_get_ident(conn);
2705
2706 mod_timer(&conn->info_timer, jiffies +
2707 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2708
2709 l2cap_send_cmd(conn, conn->info_ident,
2710 L2CAP_INFO_REQ, sizeof(info), &info);
2711 }
2712
Linus Torvalds1da177e2005-04-16 15:20:36 -07002713 return 0;
2714}
2715
2716static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2717{
2718 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2719 u16 scid, dcid, result, status;
2720 struct sock *sk;
2721 u8 req[128];
2722
2723 scid = __le16_to_cpu(rsp->scid);
2724 dcid = __le16_to_cpu(rsp->dcid);
2725 result = __le16_to_cpu(rsp->result);
2726 status = __le16_to_cpu(rsp->status);
2727
2728 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2729
2730 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002731 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2732 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002733 return 0;
2734 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002735 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2736 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002737 return 0;
2738 }
2739
2740 switch (result) {
2741 case L2CAP_CR_SUCCESS:
2742 sk->sk_state = BT_CONFIG;
2743 l2cap_pi(sk)->ident = 0;
2744 l2cap_pi(sk)->dcid = dcid;
2745 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2746
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002747 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2748
Linus Torvalds1da177e2005-04-16 15:20:36 -07002749 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2750 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002751 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002752 break;
2753
2754 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002755 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002756 break;
2757
2758 default:
2759 l2cap_chan_del(sk, ECONNREFUSED);
2760 break;
2761 }
2762
2763 bh_unlock_sock(sk);
2764 return 0;
2765}
2766
Al Viro88219a02007-07-29 00:17:25 -07002767static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002768{
2769 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2770 u16 dcid, flags;
2771 u8 rsp[64];
2772 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002773 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002774
2775 dcid = __le16_to_cpu(req->dcid);
2776 flags = __le16_to_cpu(req->flags);
2777
2778 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2779
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002780 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2781 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002782 return -ENOENT;
2783
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002784 if (sk->sk_state == BT_DISCONN)
2785 goto unlock;
2786
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002787 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002788 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002789 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2790 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2791 l2cap_build_conf_rsp(sk, rsp,
2792 L2CAP_CONF_REJECT, flags), rsp);
2793 goto unlock;
2794 }
2795
2796 /* Store config. */
2797 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2798 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002799
2800 if (flags & 0x0001) {
2801 /* Incomplete config. Send empty response. */
2802 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002803 l2cap_build_conf_rsp(sk, rsp,
2804 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002805 goto unlock;
2806 }
2807
2808 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002809 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002810 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002811 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002812 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002813 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002814
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002815 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002816 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002817
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002818 /* Reset config buffer. */
2819 l2cap_pi(sk)->conf_len = 0;
2820
Marcel Holtmann876d9482007-10-20 13:35:42 +02002821 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2822 goto unlock;
2823
Linus Torvalds1da177e2005-04-16 15:20:36 -07002824 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002825 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
2826 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002827 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2828
Linus Torvalds1da177e2005-04-16 15:20:36 -07002829 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002830
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002831 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002832 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002833 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002834 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2835 l2cap_ertm_init(sk);
2836
Linus Torvalds1da177e2005-04-16 15:20:36 -07002837 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002838 goto unlock;
2839 }
2840
2841 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002842 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002843 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002844 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002845 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002846 }
2847
2848unlock:
2849 bh_unlock_sock(sk);
2850 return 0;
2851}
2852
2853static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2854{
2855 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2856 u16 scid, flags, result;
2857 struct sock *sk;
2858
2859 scid = __le16_to_cpu(rsp->scid);
2860 flags = __le16_to_cpu(rsp->flags);
2861 result = __le16_to_cpu(rsp->result);
2862
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002863 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2864 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002865
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002866 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2867 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002868 return 0;
2869
2870 switch (result) {
2871 case L2CAP_CONF_SUCCESS:
2872 break;
2873
2874 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002875 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
2876 int len = cmd->len - sizeof(*rsp);
2877 char req[64];
2878
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02002879 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
2880 l2cap_send_disconn_req(conn, sk);
2881 goto done;
2882 }
2883
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002884 /* throw out any old stored conf requests */
2885 result = L2CAP_CONF_SUCCESS;
2886 len = l2cap_parse_conf_rsp(sk, rsp->data,
2887 len, req, &result);
2888 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002889 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002890 goto done;
2891 }
2892
2893 l2cap_send_cmd(conn, l2cap_get_ident(conn),
2894 L2CAP_CONF_REQ, len, req);
2895 l2cap_pi(sk)->num_conf_req++;
2896 if (result != L2CAP_CONF_SUCCESS)
2897 goto done;
2898 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002899 }
2900
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002901 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002902 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02002903 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002904 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002905 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002906 goto done;
2907 }
2908
2909 if (flags & 0x01)
2910 goto done;
2911
Linus Torvalds1da177e2005-04-16 15:20:36 -07002912 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
2913
2914 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002915 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
2916 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002917 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2918
Linus Torvalds1da177e2005-04-16 15:20:36 -07002919 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002920 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002921 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002922 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002923 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2924 l2cap_ertm_init(sk);
2925
Linus Torvalds1da177e2005-04-16 15:20:36 -07002926 l2cap_chan_ready(sk);
2927 }
2928
2929done:
2930 bh_unlock_sock(sk);
2931 return 0;
2932}
2933
2934static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2935{
2936 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
2937 struct l2cap_disconn_rsp rsp;
2938 u16 dcid, scid;
2939 struct sock *sk;
2940
2941 scid = __le16_to_cpu(req->scid);
2942 dcid = __le16_to_cpu(req->dcid);
2943
2944 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
2945
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002946 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2947 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002948 return 0;
2949
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002950 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
2951 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002952 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
2953
2954 sk->sk_shutdown = SHUTDOWN_MASK;
2955
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002956 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002957
2958 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
2959 skb_queue_purge(SREJ_QUEUE(sk));
2960 del_timer(&l2cap_pi(sk)->retrans_timer);
2961 del_timer(&l2cap_pi(sk)->monitor_timer);
2962 }
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002963
Linus Torvalds1da177e2005-04-16 15:20:36 -07002964 l2cap_chan_del(sk, ECONNRESET);
2965 bh_unlock_sock(sk);
2966
2967 l2cap_sock_kill(sk);
2968 return 0;
2969}
2970
2971static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2972{
2973 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
2974 u16 dcid, scid;
2975 struct sock *sk;
2976
2977 scid = __le16_to_cpu(rsp->scid);
2978 dcid = __le16_to_cpu(rsp->dcid);
2979
2980 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
2981
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002982 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2983 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002984 return 0;
2985
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002986 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002987
2988 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
2989 skb_queue_purge(SREJ_QUEUE(sk));
2990 del_timer(&l2cap_pi(sk)->retrans_timer);
2991 del_timer(&l2cap_pi(sk)->monitor_timer);
2992 }
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002993
Linus Torvalds1da177e2005-04-16 15:20:36 -07002994 l2cap_chan_del(sk, 0);
2995 bh_unlock_sock(sk);
2996
2997 l2cap_sock_kill(sk);
2998 return 0;
2999}
3000
3001static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3002{
3003 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003004 u16 type;
3005
3006 type = __le16_to_cpu(req->type);
3007
3008 BT_DBG("type 0x%4.4x", type);
3009
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003010 if (type == L2CAP_IT_FEAT_MASK) {
3011 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003012 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003013 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3014 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3015 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003016 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003017 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3018 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003019 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003020 l2cap_send_cmd(conn, cmd->ident,
3021 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003022 } else if (type == L2CAP_IT_FIXED_CHAN) {
3023 u8 buf[12];
3024 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3025 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3026 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3027 memcpy(buf + 4, l2cap_fixed_chan, 8);
3028 l2cap_send_cmd(conn, cmd->ident,
3029 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003030 } else {
3031 struct l2cap_info_rsp rsp;
3032 rsp.type = cpu_to_le16(type);
3033 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3034 l2cap_send_cmd(conn, cmd->ident,
3035 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3036 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003037
3038 return 0;
3039}
3040
3041static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3042{
3043 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3044 u16 type, result;
3045
3046 type = __le16_to_cpu(rsp->type);
3047 result = __le16_to_cpu(rsp->result);
3048
3049 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3050
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003051 del_timer(&conn->info_timer);
3052
Marcel Holtmann984947d2009-02-06 23:35:19 +01003053 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003054 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003055
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003056 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003057 struct l2cap_info_req req;
3058 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3059
3060 conn->info_ident = l2cap_get_ident(conn);
3061
3062 l2cap_send_cmd(conn, conn->info_ident,
3063 L2CAP_INFO_REQ, sizeof(req), &req);
3064 } else {
3065 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3066 conn->info_ident = 0;
3067
3068 l2cap_conn_start(conn);
3069 }
3070 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003071 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003072 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003073
3074 l2cap_conn_start(conn);
3075 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003076
Linus Torvalds1da177e2005-04-16 15:20:36 -07003077 return 0;
3078}
3079
3080static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3081{
3082 u8 *data = skb->data;
3083 int len = skb->len;
3084 struct l2cap_cmd_hdr cmd;
3085 int err = 0;
3086
3087 l2cap_raw_recv(conn, skb);
3088
3089 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003090 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003091 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3092 data += L2CAP_CMD_HDR_SIZE;
3093 len -= L2CAP_CMD_HDR_SIZE;
3094
Al Viro88219a02007-07-29 00:17:25 -07003095 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003096
Al Viro88219a02007-07-29 00:17:25 -07003097 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len, cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003098
Al Viro88219a02007-07-29 00:17:25 -07003099 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003100 BT_DBG("corrupted command");
3101 break;
3102 }
3103
3104 switch (cmd.code) {
3105 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003106 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003107 break;
3108
3109 case L2CAP_CONN_REQ:
3110 err = l2cap_connect_req(conn, &cmd, data);
3111 break;
3112
3113 case L2CAP_CONN_RSP:
3114 err = l2cap_connect_rsp(conn, &cmd, data);
3115 break;
3116
3117 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003118 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003119 break;
3120
3121 case L2CAP_CONF_RSP:
3122 err = l2cap_config_rsp(conn, &cmd, data);
3123 break;
3124
3125 case L2CAP_DISCONN_REQ:
3126 err = l2cap_disconnect_req(conn, &cmd, data);
3127 break;
3128
3129 case L2CAP_DISCONN_RSP:
3130 err = l2cap_disconnect_rsp(conn, &cmd, data);
3131 break;
3132
3133 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003134 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003135 break;
3136
3137 case L2CAP_ECHO_RSP:
3138 break;
3139
3140 case L2CAP_INFO_REQ:
3141 err = l2cap_information_req(conn, &cmd, data);
3142 break;
3143
3144 case L2CAP_INFO_RSP:
3145 err = l2cap_information_rsp(conn, &cmd, data);
3146 break;
3147
3148 default:
3149 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3150 err = -EINVAL;
3151 break;
3152 }
3153
3154 if (err) {
3155 struct l2cap_cmd_rej rej;
3156 BT_DBG("error %d", err);
3157
3158 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003159 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003160 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3161 }
3162
Al Viro88219a02007-07-29 00:17:25 -07003163 data += cmd_len;
3164 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003165 }
3166
3167 kfree_skb(skb);
3168}
3169
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003170static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3171{
3172 u16 our_fcs, rcv_fcs;
3173 int hdr_size = L2CAP_HDR_SIZE + 2;
3174
3175 if (pi->fcs == L2CAP_FCS_CRC16) {
3176 skb_trim(skb, skb->len - 2);
3177 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3178 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3179
3180 if (our_fcs != rcv_fcs)
3181 return -EINVAL;
3182 }
3183 return 0;
3184}
3185
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003186static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3187{
3188 struct l2cap_pinfo *pi = l2cap_pi(sk);
3189 u16 control = 0;
3190
3191 pi->frames_sent = 0;
3192 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3193
3194 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3195
3196 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3197 control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL;
3198 l2cap_send_sframe(pi, control);
3199 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
3200 }
3201
3202 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0)
3203 __mod_retrans_timer();
3204
3205 l2cap_ertm_send(sk);
3206
3207 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3208 pi->frames_sent == 0) {
3209 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003210 l2cap_send_sframe(pi, control);
3211 }
3212}
3213
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003214static void l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
3215{
3216 struct sk_buff *next_skb;
3217
3218 bt_cb(skb)->tx_seq = tx_seq;
3219 bt_cb(skb)->sar = sar;
3220
3221 next_skb = skb_peek(SREJ_QUEUE(sk));
3222 if (!next_skb) {
3223 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3224 return;
3225 }
3226
3227 do {
3228 if (bt_cb(next_skb)->tx_seq > tx_seq) {
3229 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
3230 return;
3231 }
3232
3233 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3234 break;
3235
3236 } while((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
3237
3238 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3239}
3240
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003241static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3242{
3243 struct l2cap_pinfo *pi = l2cap_pi(sk);
3244 struct sk_buff *_skb;
3245 int err = -EINVAL;
3246
3247 switch (control & L2CAP_CTRL_SAR) {
3248 case L2CAP_SDU_UNSEGMENTED:
3249 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3250 kfree_skb(pi->sdu);
3251 break;
3252 }
3253
3254 err = sock_queue_rcv_skb(sk, skb);
3255 if (!err)
3256 return 0;
3257
3258 break;
3259
3260 case L2CAP_SDU_START:
3261 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3262 kfree_skb(pi->sdu);
3263 break;
3264 }
3265
3266 pi->sdu_len = get_unaligned_le16(skb->data);
3267 skb_pull(skb, 2);
3268
3269 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3270 if (!pi->sdu) {
3271 err = -ENOMEM;
3272 break;
3273 }
3274
3275 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3276
3277 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3278 pi->partial_sdu_len = skb->len;
3279 err = 0;
3280 break;
3281
3282 case L2CAP_SDU_CONTINUE:
3283 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3284 break;
3285
3286 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3287
3288 pi->partial_sdu_len += skb->len;
3289 if (pi->partial_sdu_len > pi->sdu_len)
3290 kfree_skb(pi->sdu);
3291 else
3292 err = 0;
3293
3294 break;
3295
3296 case L2CAP_SDU_END:
3297 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3298 break;
3299
3300 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3301
3302 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3303 pi->partial_sdu_len += skb->len;
3304
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003305 if (pi->partial_sdu_len > pi->imtu)
3306 goto drop;
3307
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003308 if (pi->partial_sdu_len == pi->sdu_len) {
3309 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3310 err = sock_queue_rcv_skb(sk, _skb);
3311 if (err < 0)
3312 kfree_skb(_skb);
3313 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003314 err = 0;
3315
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003316drop:
3317 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003318 break;
3319 }
3320
3321 kfree_skb(skb);
3322 return err;
3323}
3324
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003325static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3326{
3327 struct sk_buff *skb;
3328 u16 control = 0;
3329
3330 while((skb = skb_peek(SREJ_QUEUE(sk)))) {
3331 if (bt_cb(skb)->tx_seq != tx_seq)
3332 break;
3333
3334 skb = skb_dequeue(SREJ_QUEUE(sk));
3335 control |= bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3336 l2cap_sar_reassembly_sdu(sk, skb, control);
3337 l2cap_pi(sk)->buffer_seq_srej =
3338 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
3339 tx_seq++;
3340 }
3341}
3342
3343static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3344{
3345 struct l2cap_pinfo *pi = l2cap_pi(sk);
3346 struct srej_list *l, *tmp;
3347 u16 control;
3348
3349 list_for_each_entry_safe(l,tmp, SREJ_LIST(sk), list) {
3350 if (l->tx_seq == tx_seq) {
3351 list_del(&l->list);
3352 kfree(l);
3353 return;
3354 }
3355 control = L2CAP_SUPER_SELECT_REJECT;
3356 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3357 l2cap_send_sframe(pi, control);
3358 list_del(&l->list);
3359 list_add_tail(&l->list, SREJ_LIST(sk));
3360 }
3361}
3362
3363static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3364{
3365 struct l2cap_pinfo *pi = l2cap_pi(sk);
3366 struct srej_list *new;
3367 u16 control;
3368
3369 while (tx_seq != pi->expected_tx_seq) {
3370 control = L2CAP_SUPER_SELECT_REJECT;
3371 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3372 l2cap_send_sframe(pi, control);
3373
3374 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
3375 new->tx_seq = pi->expected_tx_seq++;
3376 list_add_tail(&new->list, SREJ_LIST(sk));
3377 }
3378 pi->expected_tx_seq++;
3379}
3380
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003381static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3382{
3383 struct l2cap_pinfo *pi = l2cap_pi(sk);
3384 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003385 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003386 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003387 int err = 0;
3388
3389 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3390
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003391 if (L2CAP_CTRL_FINAL & rx_control) {
3392 del_timer(&pi->monitor_timer);
3393 if (pi->unacked_frames > 0)
3394 __mod_retrans_timer();
3395 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3396 }
3397
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003398 pi->expected_ack_seq = req_seq;
3399 l2cap_drop_acked_frames(sk);
3400
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003401 if (tx_seq == pi->expected_tx_seq)
3402 goto expected;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003403
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003404 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3405 struct srej_list *first;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003406
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003407 first = list_first_entry(SREJ_LIST(sk),
3408 struct srej_list, list);
3409 if (tx_seq == first->tx_seq) {
3410 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3411 l2cap_check_srej_gap(sk, tx_seq);
3412
3413 list_del(&first->list);
3414 kfree(first);
3415
3416 if (list_empty(SREJ_LIST(sk))) {
3417 pi->buffer_seq = pi->buffer_seq_srej;
3418 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
3419 }
3420 } else {
3421 struct srej_list *l;
3422 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3423
3424 list_for_each_entry(l, SREJ_LIST(sk), list) {
3425 if (l->tx_seq == tx_seq) {
3426 l2cap_resend_srejframe(sk, tx_seq);
3427 return 0;
3428 }
3429 }
3430 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003431 }
3432 } else {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003433 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003434
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003435 INIT_LIST_HEAD(SREJ_LIST(sk));
3436 pi->buffer_seq_srej = pi->buffer_seq;
3437
3438 __skb_queue_head_init(SREJ_QUEUE(sk));
3439 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3440
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003441 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3442
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003443 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003444 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003445 return 0;
3446
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003447expected:
3448 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3449
3450 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3451 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3452 return 0;
3453 }
3454
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003455 if (rx_control & L2CAP_CTRL_FINAL) {
3456 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3457 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3458 else {
3459 sk->sk_send_head = TX_QUEUE(sk)->next;
3460 pi->next_tx_seq = pi->expected_ack_seq;
3461 l2cap_ertm_send(sk);
3462 }
3463 }
3464
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003465 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3466
3467 err = l2cap_sar_reassembly_sdu(sk, skb, rx_control);
3468 if (err < 0)
3469 return err;
3470
3471 pi->num_to_ack = (pi->num_to_ack + 1) % L2CAP_DEFAULT_NUM_TO_ACK;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003472 if (pi->num_to_ack == L2CAP_DEFAULT_NUM_TO_ACK - 1)
3473 l2cap_send_ack(pi);
3474
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003475 return 0;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003476}
3477
3478static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3479{
3480 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003481 u8 tx_seq = __get_reqseq(rx_control);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003482
3483 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3484
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003485 if (L2CAP_CTRL_FINAL & rx_control) {
3486 del_timer(&pi->monitor_timer);
3487 if (pi->unacked_frames > 0)
3488 __mod_retrans_timer();
3489 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3490 }
3491
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003492 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
3493 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003494 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003495 l2cap_send_i_or_rr_or_rnr(sk);
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003496 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3497
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003498 } else if (rx_control & L2CAP_CTRL_FINAL) {
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003499 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovanca42a612009-08-26 04:04:01 -03003500 pi->expected_ack_seq = tx_seq;
3501 l2cap_drop_acked_frames(sk);
3502
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003503 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3504 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3505 else {
3506 sk->sk_send_head = TX_QUEUE(sk)->next;
3507 pi->next_tx_seq = pi->expected_ack_seq;
3508 l2cap_ertm_send(sk);
3509 }
3510
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003511 } else {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003512 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003513 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003514
Joe Perchesf64f9e72009-11-29 16:55:45 -08003515 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3516 (pi->unacked_frames > 0))
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003517 __mod_retrans_timer();
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003518
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003519 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovan186de9a2009-12-15 15:56:34 -02003520 l2cap_ertm_send(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003521 }
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003522 break;
3523
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003524 case L2CAP_SUPER_REJECT:
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003525 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3526
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003527 pi->expected_ack_seq = __get_reqseq(rx_control);
3528 l2cap_drop_acked_frames(sk);
3529
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003530 if (rx_control & L2CAP_CTRL_FINAL) {
3531 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3532 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3533 else {
3534 sk->sk_send_head = TX_QUEUE(sk)->next;
3535 pi->next_tx_seq = pi->expected_ack_seq;
3536 l2cap_ertm_send(sk);
3537 }
3538 } else {
3539 sk->sk_send_head = TX_QUEUE(sk)->next;
3540 pi->next_tx_seq = pi->expected_ack_seq;
3541 l2cap_ertm_send(sk);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003542
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003543 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3544 pi->srej_save_reqseq = tx_seq;
3545 pi->conn_state |= L2CAP_CONN_REJ_ACT;
3546 }
3547 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003548
3549 break;
3550
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003551 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003552 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3553
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003554 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003555 pi->expected_ack_seq = tx_seq;
3556 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan186ee8cf2009-12-15 20:13:27 -02003557 l2cap_retransmit_frame(sk, tx_seq);
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003558 l2cap_ertm_send(sk);
3559 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3560 pi->srej_save_reqseq = tx_seq;
3561 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3562 }
3563 } else if (rx_control & L2CAP_CTRL_FINAL) {
3564 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3565 pi->srej_save_reqseq == tx_seq)
Gustavo F. Padovan889a3ca2009-10-03 02:34:37 -03003566 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003567 else
3568 l2cap_retransmit_frame(sk, tx_seq);
3569 }
3570 else {
3571 l2cap_retransmit_frame(sk, tx_seq);
3572 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3573 pi->srej_save_reqseq = tx_seq;
3574 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3575 }
3576 }
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003577 break;
3578
3579 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003580 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
3581 pi->expected_ack_seq = tx_seq;
3582 l2cap_drop_acked_frames(sk);
3583
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03003584 del_timer(&pi->retrans_timer);
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003585 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03003586 u16 control = L2CAP_CTRL_FINAL;
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03003587 l2cap_send_rr_or_rnr(pi, control);
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003588 }
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003589 break;
3590 }
3591
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03003592 kfree_skb(skb);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003593 return 0;
3594}
3595
Linus Torvalds1da177e2005-04-16 15:20:36 -07003596static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
3597{
3598 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003599 struct l2cap_pinfo *pi;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003600 u16 control, len;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003601 u8 tx_seq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003602
3603 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3604 if (!sk) {
3605 BT_DBG("unknown cid 0x%4.4x", cid);
3606 goto drop;
3607 }
3608
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003609 pi = l2cap_pi(sk);
3610
Linus Torvalds1da177e2005-04-16 15:20:36 -07003611 BT_DBG("sk %p, len %d", sk, skb->len);
3612
3613 if (sk->sk_state != BT_CONNECTED)
3614 goto drop;
3615
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003616 switch (pi->mode) {
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003617 case L2CAP_MODE_BASIC:
3618 /* If socket recv buffers overflows we drop data here
3619 * which is *bad* because L2CAP has to be reliable.
3620 * But we don't have any other choice. L2CAP doesn't
3621 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003622
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003623 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003624 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003625
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003626 if (!sock_queue_rcv_skb(sk, skb))
3627 goto done;
3628 break;
3629
3630 case L2CAP_MODE_ERTM:
3631 control = get_unaligned_le16(skb->data);
3632 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003633 len = skb->len;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003634
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003635 if (__is_sar_start(control))
3636 len -= 2;
3637
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003638 if (pi->fcs == L2CAP_FCS_CRC16)
3639 len -= 2;
3640
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003641 /*
3642 * We can just drop the corrupted I-frame here.
3643 * Receiver will miss it and start proper recovery
3644 * procedures and ask retransmission.
3645 */
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003646 if (len > L2CAP_DEFAULT_MAX_PDU_SIZE)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003647 goto drop;
3648
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003649 if (l2cap_check_fcs(pi, skb))
3650 goto drop;
3651
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003652 if (__is_iframe(control)) {
3653 if (len < 4)
3654 goto drop;
3655
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003656 l2cap_data_channel_iframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003657 } else {
3658 if (len != 0)
3659 goto drop;
3660
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003661 l2cap_data_channel_sframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003662 }
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003663
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003664 goto done;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003665
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003666 case L2CAP_MODE_STREAMING:
3667 control = get_unaligned_le16(skb->data);
3668 skb_pull(skb, 2);
3669 len = skb->len;
3670
3671 if (__is_sar_start(control))
3672 len -= 2;
3673
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003674 if (pi->fcs == L2CAP_FCS_CRC16)
3675 len -= 2;
3676
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003677 if (len > L2CAP_DEFAULT_MAX_PDU_SIZE || len < 4
3678 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003679 goto drop;
3680
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003681 if (l2cap_check_fcs(pi, skb))
3682 goto drop;
3683
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003684 tx_seq = __get_txseq(control);
3685
3686 if (pi->expected_tx_seq == tx_seq)
3687 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3688 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03003689 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003690
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003691 l2cap_sar_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003692
3693 goto done;
3694
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003695 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03003696 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003697 break;
3698 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003699
3700drop:
3701 kfree_skb(skb);
3702
3703done:
Marcel Holtmann01394182006-07-03 10:02:46 +02003704 if (sk)
3705 bh_unlock_sock(sk);
3706
Linus Torvalds1da177e2005-04-16 15:20:36 -07003707 return 0;
3708}
3709
Al Viro8e036fc2007-07-29 00:16:36 -07003710static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003711{
3712 struct sock *sk;
3713
3714 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
3715 if (!sk)
3716 goto drop;
3717
3718 BT_DBG("sk %p, len %d", sk, skb->len);
3719
3720 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
3721 goto drop;
3722
3723 if (l2cap_pi(sk)->imtu < skb->len)
3724 goto drop;
3725
3726 if (!sock_queue_rcv_skb(sk, skb))
3727 goto done;
3728
3729drop:
3730 kfree_skb(skb);
3731
3732done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003733 if (sk)
3734 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003735 return 0;
3736}
3737
3738static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
3739{
3740 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07003741 u16 cid, len;
3742 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003743
3744 skb_pull(skb, L2CAP_HDR_SIZE);
3745 cid = __le16_to_cpu(lh->cid);
3746 len = __le16_to_cpu(lh->len);
3747
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003748 if (len != skb->len) {
3749 kfree_skb(skb);
3750 return;
3751 }
3752
Linus Torvalds1da177e2005-04-16 15:20:36 -07003753 BT_DBG("len %d, cid 0x%4.4x", len, cid);
3754
3755 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003756 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003757 l2cap_sig_channel(conn, skb);
3758 break;
3759
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003760 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003761 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003762 skb_pull(skb, 2);
3763 l2cap_conless_channel(conn, psm, skb);
3764 break;
3765
3766 default:
3767 l2cap_data_channel(conn, cid, skb);
3768 break;
3769 }
3770}
3771
3772/* ---- L2CAP interface with lower layer (HCI) ---- */
3773
3774static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3775{
3776 int exact = 0, lm1 = 0, lm2 = 0;
3777 register struct sock *sk;
3778 struct hlist_node *node;
3779
3780 if (type != ACL_LINK)
3781 return 0;
3782
3783 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
3784
3785 /* Find listening sockets and check their link_mode */
3786 read_lock(&l2cap_sk_list.lock);
3787 sk_for_each(sk, node, &l2cap_sk_list.head) {
3788 if (sk->sk_state != BT_LISTEN)
3789 continue;
3790
3791 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003792 lm1 |= HCI_LM_ACCEPT;
3793 if (l2cap_pi(sk)->role_switch)
3794 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003795 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003796 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
3797 lm2 |= HCI_LM_ACCEPT;
3798 if (l2cap_pi(sk)->role_switch)
3799 lm2 |= HCI_LM_MASTER;
3800 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003801 }
3802 read_unlock(&l2cap_sk_list.lock);
3803
3804 return exact ? lm1 : lm2;
3805}
3806
3807static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
3808{
Marcel Holtmann01394182006-07-03 10:02:46 +02003809 struct l2cap_conn *conn;
3810
Linus Torvalds1da177e2005-04-16 15:20:36 -07003811 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
3812
3813 if (hcon->type != ACL_LINK)
3814 return 0;
3815
3816 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003817 conn = l2cap_conn_add(hcon, status);
3818 if (conn)
3819 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02003820 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003821 l2cap_conn_del(hcon, bt_err(status));
3822
3823 return 0;
3824}
3825
Marcel Holtmann2950f212009-02-12 14:02:50 +01003826static int l2cap_disconn_ind(struct hci_conn *hcon)
3827{
3828 struct l2cap_conn *conn = hcon->l2cap_data;
3829
3830 BT_DBG("hcon %p", hcon);
3831
3832 if (hcon->type != ACL_LINK || !conn)
3833 return 0x13;
3834
3835 return conn->disc_reason;
3836}
3837
3838static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003839{
3840 BT_DBG("hcon %p reason %d", hcon, reason);
3841
3842 if (hcon->type != ACL_LINK)
3843 return 0;
3844
3845 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02003846
Linus Torvalds1da177e2005-04-16 15:20:36 -07003847 return 0;
3848}
3849
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003850static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
3851{
Marcel Holtmann255c7602009-02-04 21:07:19 +01003852 if (sk->sk_type != SOCK_SEQPACKET)
3853 return;
3854
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003855 if (encrypt == 0x00) {
3856 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
3857 l2cap_sock_clear_timer(sk);
3858 l2cap_sock_set_timer(sk, HZ * 5);
3859 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
3860 __l2cap_sock_close(sk, ECONNREFUSED);
3861 } else {
3862 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
3863 l2cap_sock_clear_timer(sk);
3864 }
3865}
3866
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003867static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003868{
3869 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02003870 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003871 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003872
Marcel Holtmann01394182006-07-03 10:02:46 +02003873 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003874 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02003875
Linus Torvalds1da177e2005-04-16 15:20:36 -07003876 l = &conn->chan_list;
3877
3878 BT_DBG("conn %p", conn);
3879
3880 read_lock(&l->lock);
3881
3882 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
3883 bh_lock_sock(sk);
3884
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003885 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
3886 bh_unlock_sock(sk);
3887 continue;
3888 }
3889
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003890 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003891 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003892 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02003893 bh_unlock_sock(sk);
3894 continue;
3895 }
3896
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02003897 if (sk->sk_state == BT_CONNECT) {
3898 if (!status) {
3899 struct l2cap_conn_req req;
3900 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
3901 req.psm = l2cap_pi(sk)->psm;
3902
3903 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
3904
3905 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3906 L2CAP_CONN_REQ, sizeof(req), &req);
3907 } else {
3908 l2cap_sock_clear_timer(sk);
3909 l2cap_sock_set_timer(sk, HZ / 10);
3910 }
3911 } else if (sk->sk_state == BT_CONNECT2) {
3912 struct l2cap_conn_rsp rsp;
3913 __u16 result;
3914
3915 if (!status) {
3916 sk->sk_state = BT_CONFIG;
3917 result = L2CAP_CR_SUCCESS;
3918 } else {
3919 sk->sk_state = BT_DISCONN;
3920 l2cap_sock_set_timer(sk, HZ / 10);
3921 result = L2CAP_CR_SEC_BLOCK;
3922 }
3923
3924 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
3925 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3926 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003927 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02003928 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3929 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003930 }
3931
Linus Torvalds1da177e2005-04-16 15:20:36 -07003932 bh_unlock_sock(sk);
3933 }
3934
3935 read_unlock(&l->lock);
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02003936
Linus Torvalds1da177e2005-04-16 15:20:36 -07003937 return 0;
3938}
3939
3940static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
3941{
3942 struct l2cap_conn *conn = hcon->l2cap_data;
3943
3944 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
3945 goto drop;
3946
3947 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
3948
3949 if (flags & ACL_START) {
3950 struct l2cap_hdr *hdr;
3951 int len;
3952
3953 if (conn->rx_len) {
3954 BT_ERR("Unexpected start frame (len %d)", skb->len);
3955 kfree_skb(conn->rx_skb);
3956 conn->rx_skb = NULL;
3957 conn->rx_len = 0;
3958 l2cap_conn_unreliable(conn, ECOMM);
3959 }
3960
3961 if (skb->len < 2) {
3962 BT_ERR("Frame is too short (len %d)", skb->len);
3963 l2cap_conn_unreliable(conn, ECOMM);
3964 goto drop;
3965 }
3966
3967 hdr = (struct l2cap_hdr *) skb->data;
3968 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
3969
3970 if (len == skb->len) {
3971 /* Complete frame received */
3972 l2cap_recv_frame(conn, skb);
3973 return 0;
3974 }
3975
3976 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
3977
3978 if (skb->len > len) {
3979 BT_ERR("Frame is too long (len %d, expected len %d)",
3980 skb->len, len);
3981 l2cap_conn_unreliable(conn, ECOMM);
3982 goto drop;
3983 }
3984
3985 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003986 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
3987 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003988 goto drop;
3989
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03003990 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003991 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003992 conn->rx_len = len - skb->len;
3993 } else {
3994 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
3995
3996 if (!conn->rx_len) {
3997 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
3998 l2cap_conn_unreliable(conn, ECOMM);
3999 goto drop;
4000 }
4001
4002 if (skb->len > conn->rx_len) {
4003 BT_ERR("Fragment is too long (len %d, expected %d)",
4004 skb->len, conn->rx_len);
4005 kfree_skb(conn->rx_skb);
4006 conn->rx_skb = NULL;
4007 conn->rx_len = 0;
4008 l2cap_conn_unreliable(conn, ECOMM);
4009 goto drop;
4010 }
4011
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004012 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004013 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004014 conn->rx_len -= skb->len;
4015
4016 if (!conn->rx_len) {
4017 /* Complete frame received */
4018 l2cap_recv_frame(conn, conn->rx_skb);
4019 conn->rx_skb = NULL;
4020 }
4021 }
4022
4023drop:
4024 kfree_skb(skb);
4025 return 0;
4026}
4027
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004028static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004029{
4030 struct sock *sk;
4031 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004032
4033 read_lock_bh(&l2cap_sk_list.lock);
4034
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004035 sk_for_each(sk, node, &l2cap_sk_list.head) {
4036 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004037
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004038 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4039 batostr(&bt_sk(sk)->src),
4040 batostr(&bt_sk(sk)->dst),
4041 sk->sk_state, __le16_to_cpu(pi->psm),
4042 pi->scid, pi->dcid,
4043 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004044 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004045
Linus Torvalds1da177e2005-04-16 15:20:36 -07004046 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004047
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004048 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004049}
4050
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004051static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4052{
4053 return single_open(file, l2cap_debugfs_show, inode->i_private);
4054}
4055
4056static const struct file_operations l2cap_debugfs_fops = {
4057 .open = l2cap_debugfs_open,
4058 .read = seq_read,
4059 .llseek = seq_lseek,
4060 .release = single_release,
4061};
4062
4063static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004064
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004065static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004066 .family = PF_BLUETOOTH,
4067 .owner = THIS_MODULE,
4068 .release = l2cap_sock_release,
4069 .bind = l2cap_sock_bind,
4070 .connect = l2cap_sock_connect,
4071 .listen = l2cap_sock_listen,
4072 .accept = l2cap_sock_accept,
4073 .getname = l2cap_sock_getname,
4074 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004075 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004076 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004077 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004078 .mmap = sock_no_mmap,
4079 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004080 .shutdown = l2cap_sock_shutdown,
4081 .setsockopt = l2cap_sock_setsockopt,
4082 .getsockopt = l2cap_sock_getsockopt
4083};
4084
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004085static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004086 .family = PF_BLUETOOTH,
4087 .owner = THIS_MODULE,
4088 .create = l2cap_sock_create,
4089};
4090
4091static struct hci_proto l2cap_hci_proto = {
4092 .name = "L2CAP",
4093 .id = HCI_PROTO_L2CAP,
4094 .connect_ind = l2cap_connect_ind,
4095 .connect_cfm = l2cap_connect_cfm,
4096 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004097 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004098 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004099 .recv_acldata = l2cap_recv_acldata
4100};
4101
4102static int __init l2cap_init(void)
4103{
4104 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004105
Linus Torvalds1da177e2005-04-16 15:20:36 -07004106 err = proto_register(&l2cap_proto, 0);
4107 if (err < 0)
4108 return err;
4109
4110 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4111 if (err < 0) {
4112 BT_ERR("L2CAP socket registration failed");
4113 goto error;
4114 }
4115
4116 err = hci_register_proto(&l2cap_hci_proto);
4117 if (err < 0) {
4118 BT_ERR("L2CAP protocol registration failed");
4119 bt_sock_unregister(BTPROTO_L2CAP);
4120 goto error;
4121 }
4122
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004123 if (bt_debugfs) {
4124 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4125 bt_debugfs, NULL, &l2cap_debugfs_fops);
4126 if (!l2cap_debugfs)
4127 BT_ERR("Failed to create L2CAP debug file");
4128 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004129
4130 BT_INFO("L2CAP ver %s", VERSION);
4131 BT_INFO("L2CAP socket layer initialized");
4132
4133 return 0;
4134
4135error:
4136 proto_unregister(&l2cap_proto);
4137 return err;
4138}
4139
4140static void __exit l2cap_exit(void)
4141{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004142 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004143
4144 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4145 BT_ERR("L2CAP socket unregistration failed");
4146
4147 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4148 BT_ERR("L2CAP protocol unregistration failed");
4149
4150 proto_unregister(&l2cap_proto);
4151}
4152
4153void l2cap_load(void)
4154{
4155 /* Dummy function to trigger automatic L2CAP module loading by
4156 * other modules that use L2CAP sockets but don't use any other
4157 * symbols from it. */
4158 return;
4159}
4160EXPORT_SYMBOL(l2cap_load);
4161
4162module_init(l2cap_init);
4163module_exit(l2cap_exit);
4164
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004165module_param(enable_ertm, bool, 0644);
4166MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4167
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +02004168module_param(max_transmit, uint, 0644);
4169MODULE_PARM_DESC(max_transmit, "Max transmit value (default = 3)");
4170
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004171MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004172MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4173MODULE_VERSION(VERSION);
4174MODULE_LICENSE("GPL");
4175MODULE_ALIAS("bt-proto-0");