blob: 530079649b4352f91867ae6bec9ca2b565f70169 [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 Holtmannb1235d72008-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 Holtmannb1235d72008-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 Holtmannb1235d72008-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 Holtmannb1235d72008-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. Padovan1c2acff2009-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. Padovan1c2acff2009-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. Padovan1c2acff2009-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. Padovan1c2acff2009-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. Padovan1c2acff2009-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. Padovan1c2acff2009-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 Holtmannb1235d72008-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 Holtmannb1235d72008-07-14 20:13:54 +0200407 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200408
Marcel Holtmannb1235d72008-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 Holtmannb1235d72008-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 Holtmannb1235d72008-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 Holtmannb1235d72008-07-14 20:13:54 +0200461 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200462
Marcel Holtmannb1235d72008-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 Holtmannb1235d72008-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 Holtmannb1235d72008-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 Holtmannb1235d72008-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;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -0300785 pi->tx_win = l2cap_pi(parent)->tx_win;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100786 pi->sec_level = l2cap_pi(parent)->sec_level;
787 pi->role_switch = l2cap_pi(parent)->role_switch;
788 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 } else {
790 pi->imtu = L2CAP_DEFAULT_MTU;
791 pi->omtu = 0;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700792 pi->mode = L2CAP_MODE_BASIC;
793 pi->fcs = L2CAP_FCS_CRC16;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -0300794 pi->tx_win = L2CAP_DEFAULT_TX_WINDOW;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100795 pi->sec_level = BT_SECURITY_LOW;
796 pi->role_switch = 0;
797 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798 }
799
800 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200801 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Dave Young45054dc2009-10-18 20:28:30 +0000803 skb_queue_head_init(TX_QUEUE(sk));
804 skb_queue_head_init(SREJ_QUEUE(sk));
805 INIT_LIST_HEAD(SREJ_LIST(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806}
807
808static struct proto l2cap_proto = {
809 .name = "L2CAP",
810 .owner = THIS_MODULE,
811 .obj_size = sizeof(struct l2cap_pinfo)
812};
813
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700814static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815{
816 struct sock *sk;
817
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700818 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819 if (!sk)
820 return NULL;
821
822 sock_init_data(sock, sk);
823 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
824
825 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200826 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827
828 sock_reset_flag(sk, SOCK_ZAPPED);
829
830 sk->sk_protocol = proto;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200831 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200833 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834
835 bt_sock_link(&l2cap_sk_list, sk);
836 return sk;
837}
838
Eric Paris3f378b62009-11-05 22:18:14 -0800839static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
840 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841{
842 struct sock *sk;
843
844 BT_DBG("sock %p", sock);
845
846 sock->state = SS_UNCONNECTED;
847
848 if (sock->type != SOCK_SEQPACKET &&
849 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
850 return -ESOCKTNOSUPPORT;
851
Eric Parisc84b3262009-11-05 20:45:52 -0800852 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853 return -EPERM;
854
855 sock->ops = &l2cap_sock_ops;
856
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700857 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858 if (!sk)
859 return -ENOMEM;
860
861 l2cap_sock_init(sk, NULL);
862 return 0;
863}
864
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100865static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100868 struct sockaddr_l2 la;
869 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100871 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872
873 if (!addr || addr->sa_family != AF_BLUETOOTH)
874 return -EINVAL;
875
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100876 memset(&la, 0, sizeof(la));
877 len = min_t(unsigned int, sizeof(la), alen);
878 memcpy(&la, addr, len);
879
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100880 if (la.l2_cid)
881 return -EINVAL;
882
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883 lock_sock(sk);
884
885 if (sk->sk_state != BT_OPEN) {
886 err = -EBADFD;
887 goto done;
888 }
889
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200890 if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
Marcel Holtmann847641d2007-01-22 22:00:45 +0100891 !capable(CAP_NET_BIND_SERVICE)) {
892 err = -EACCES;
893 goto done;
894 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900895
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896 write_lock_bh(&l2cap_sk_list.lock);
897
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100898 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700899 err = -EADDRINUSE;
900 } else {
901 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100902 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
903 l2cap_pi(sk)->psm = la.l2_psm;
904 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100906
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200907 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
908 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100909 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910 }
911
912 write_unlock_bh(&l2cap_sk_list.lock);
913
914done:
915 release_sock(sk);
916 return err;
917}
918
919static int l2cap_do_connect(struct sock *sk)
920{
921 bdaddr_t *src = &bt_sk(sk)->src;
922 bdaddr_t *dst = &bt_sk(sk)->dst;
923 struct l2cap_conn *conn;
924 struct hci_conn *hcon;
925 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200926 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +0200927 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100929 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
930 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300932 hdev = hci_get_route(dst, src);
933 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 return -EHOSTUNREACH;
935
936 hci_dev_lock_bh(hdev);
937
938 err = -ENOMEM;
939
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100940 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100941 switch (l2cap_pi(sk)->sec_level) {
942 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100943 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100944 break;
945 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100946 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100947 break;
948 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100949 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100950 break;
951 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100952 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100953 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200954 auth_type = HCI_AT_NO_BONDING_MITM;
955 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200956 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +0100957
958 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
959 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100960 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100961 switch (l2cap_pi(sk)->sec_level) {
962 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100963 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100964 break;
965 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200966 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100967 break;
968 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100969 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100970 break;
971 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200972 }
973
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100974 hcon = hci_connect(hdev, ACL_LINK, dst,
975 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700976 if (!hcon)
977 goto done;
978
979 conn = l2cap_conn_add(hcon, 0);
980 if (!conn) {
981 hci_conn_put(hcon);
982 goto done;
983 }
984
985 err = 0;
986
987 /* Update source addr of the socket */
988 bacpy(src, conn->src);
989
990 l2cap_chan_add(conn, sk, NULL);
991
992 sk->sk_state = BT_CONNECT;
993 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
994
995 if (hcon->state == BT_CONNECTED) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200996 if (sk->sk_type != SOCK_SEQPACKET) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700997 l2cap_sock_clear_timer(sk);
998 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200999 } else
1000 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001 }
1002
1003done:
1004 hci_dev_unlock_bh(hdev);
1005 hci_dev_put(hdev);
1006 return err;
1007}
1008
1009static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
1010{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001012 struct sockaddr_l2 la;
1013 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001014
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015 BT_DBG("sk %p", sk);
1016
Changli Gao6503d962010-03-31 22:58:26 +00001017 if (!addr || alen < sizeof(addr->sa_family) ||
1018 addr->sa_family != AF_BLUETOOTH)
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001019 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001021 memset(&la, 0, sizeof(la));
1022 len = min_t(unsigned int, sizeof(la), alen);
1023 memcpy(&la, addr, len);
1024
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001025 if (la.l2_cid)
1026 return -EINVAL;
1027
1028 lock_sock(sk);
1029
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001030 if (sk->sk_type == SOCK_SEQPACKET && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031 err = -EINVAL;
1032 goto done;
1033 }
1034
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001035 switch (l2cap_pi(sk)->mode) {
1036 case L2CAP_MODE_BASIC:
1037 break;
1038 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001039 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001040 if (enable_ertm)
1041 break;
1042 /* fall through */
1043 default:
1044 err = -ENOTSUPP;
1045 goto done;
1046 }
1047
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001048 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 case BT_CONNECT:
1050 case BT_CONNECT2:
1051 case BT_CONFIG:
1052 /* Already connecting */
1053 goto wait;
1054
1055 case BT_CONNECTED:
1056 /* Already connected */
1057 goto done;
1058
1059 case BT_OPEN:
1060 case BT_BOUND:
1061 /* Can connect */
1062 break;
1063
1064 default:
1065 err = -EBADFD;
1066 goto done;
1067 }
1068
1069 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001070 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1071 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001073 err = l2cap_do_connect(sk);
1074 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 goto done;
1076
1077wait:
1078 err = bt_sock_wait_state(sk, BT_CONNECTED,
1079 sock_sndtimeo(sk, flags & O_NONBLOCK));
1080done:
1081 release_sock(sk);
1082 return err;
1083}
1084
1085static int l2cap_sock_listen(struct socket *sock, int backlog)
1086{
1087 struct sock *sk = sock->sk;
1088 int err = 0;
1089
1090 BT_DBG("sk %p backlog %d", sk, backlog);
1091
1092 lock_sock(sk);
1093
1094 if (sk->sk_state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
1095 err = -EBADFD;
1096 goto done;
1097 }
1098
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001099 switch (l2cap_pi(sk)->mode) {
1100 case L2CAP_MODE_BASIC:
1101 break;
1102 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001103 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001104 if (enable_ertm)
1105 break;
1106 /* fall through */
1107 default:
1108 err = -ENOTSUPP;
1109 goto done;
1110 }
1111
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112 if (!l2cap_pi(sk)->psm) {
1113 bdaddr_t *src = &bt_sk(sk)->src;
1114 u16 psm;
1115
1116 err = -EINVAL;
1117
1118 write_lock_bh(&l2cap_sk_list.lock);
1119
1120 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001121 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1122 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1123 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124 err = 0;
1125 break;
1126 }
1127
1128 write_unlock_bh(&l2cap_sk_list.lock);
1129
1130 if (err < 0)
1131 goto done;
1132 }
1133
1134 sk->sk_max_ack_backlog = backlog;
1135 sk->sk_ack_backlog = 0;
1136 sk->sk_state = BT_LISTEN;
1137
1138done:
1139 release_sock(sk);
1140 return err;
1141}
1142
1143static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1144{
1145 DECLARE_WAITQUEUE(wait, current);
1146 struct sock *sk = sock->sk, *nsk;
1147 long timeo;
1148 int err = 0;
1149
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001150 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151
1152 if (sk->sk_state != BT_LISTEN) {
1153 err = -EBADFD;
1154 goto done;
1155 }
1156
1157 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1158
1159 BT_DBG("sk %p timeo %ld", sk, timeo);
1160
1161 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +00001162 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1164 set_current_state(TASK_INTERRUPTIBLE);
1165 if (!timeo) {
1166 err = -EAGAIN;
1167 break;
1168 }
1169
1170 release_sock(sk);
1171 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001172 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001173
1174 if (sk->sk_state != BT_LISTEN) {
1175 err = -EBADFD;
1176 break;
1177 }
1178
1179 if (signal_pending(current)) {
1180 err = sock_intr_errno(timeo);
1181 break;
1182 }
1183 }
1184 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +00001185 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186
1187 if (err)
1188 goto done;
1189
1190 newsock->state = SS_CONNECTED;
1191
1192 BT_DBG("new socket %p", nsk);
1193
1194done:
1195 release_sock(sk);
1196 return err;
1197}
1198
1199static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1200{
1201 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1202 struct sock *sk = sock->sk;
1203
1204 BT_DBG("sock %p, sk %p", sock, sk);
1205
1206 addr->sa_family = AF_BLUETOOTH;
1207 *len = sizeof(struct sockaddr_l2);
1208
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001209 if (peer) {
1210 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001212 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001213 } else {
1214 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001216 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001217 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219 return 0;
1220}
1221
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001222static void l2cap_monitor_timeout(unsigned long arg)
1223{
1224 struct sock *sk = (void *) arg;
1225 u16 control;
1226
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001227 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001228 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
1229 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001230 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001231 return;
1232 }
1233
1234 l2cap_pi(sk)->retry_count++;
1235 __mod_monitor_timer();
1236
1237 control = L2CAP_CTRL_POLL;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001238 l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001239 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001240}
1241
1242static void l2cap_retrans_timeout(unsigned long arg)
1243{
1244 struct sock *sk = (void *) arg;
1245 u16 control;
1246
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001247 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001248 l2cap_pi(sk)->retry_count = 1;
1249 __mod_monitor_timer();
1250
1251 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1252
1253 control = L2CAP_CTRL_POLL;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001254 l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001255 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001256}
1257
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001258static void l2cap_drop_acked_frames(struct sock *sk)
1259{
1260 struct sk_buff *skb;
1261
1262 while ((skb = skb_peek(TX_QUEUE(sk)))) {
1263 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1264 break;
1265
1266 skb = skb_dequeue(TX_QUEUE(sk));
1267 kfree_skb(skb);
1268
1269 l2cap_pi(sk)->unacked_frames--;
1270 }
1271
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001272 if (!l2cap_pi(sk)->unacked_frames)
1273 del_timer(&l2cap_pi(sk)->retrans_timer);
1274
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001275 return;
1276}
1277
1278static inline int l2cap_do_send(struct sock *sk, struct sk_buff *skb)
1279{
1280 struct l2cap_pinfo *pi = l2cap_pi(sk);
1281 int err;
1282
1283 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1284
1285 err = hci_send_acl(pi->conn->hcon, skb, 0);
1286 if (err < 0)
1287 kfree_skb(skb);
1288
1289 return err;
1290}
1291
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001292static int l2cap_streaming_send(struct sock *sk)
1293{
1294 struct sk_buff *skb, *tx_skb;
1295 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001296 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001297 int err;
1298
1299 while ((skb = sk->sk_send_head)) {
1300 tx_skb = skb_clone(skb, GFP_ATOMIC);
1301
1302 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1303 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1304 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1305
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001306 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001307 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1308 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1309 }
1310
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001311 err = l2cap_do_send(sk, tx_skb);
1312 if (err < 0) {
1313 l2cap_send_disconn_req(pi->conn, sk);
1314 return err;
1315 }
1316
1317 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1318
1319 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1320 sk->sk_send_head = NULL;
1321 else
1322 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1323
1324 skb = skb_dequeue(TX_QUEUE(sk));
1325 kfree_skb(skb);
1326 }
1327 return 0;
1328}
1329
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001330static int l2cap_retransmit_frame(struct sock *sk, u8 tx_seq)
1331{
1332 struct l2cap_pinfo *pi = l2cap_pi(sk);
1333 struct sk_buff *skb, *tx_skb;
1334 u16 control, fcs;
1335 int err;
1336
1337 skb = skb_peek(TX_QUEUE(sk));
1338 do {
1339 if (bt_cb(skb)->tx_seq != tx_seq) {
1340 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1341 break;
1342 skb = skb_queue_next(TX_QUEUE(sk), skb);
1343 continue;
1344 }
1345
1346 if (pi->remote_max_tx &&
1347 bt_cb(skb)->retries == pi->remote_max_tx) {
1348 l2cap_send_disconn_req(pi->conn, sk);
1349 break;
1350 }
1351
1352 tx_skb = skb_clone(skb, GFP_ATOMIC);
1353 bt_cb(skb)->retries++;
1354 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001355 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001356 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1357 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1358
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001359 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001360 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1361 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1362 }
1363
1364 err = l2cap_do_send(sk, tx_skb);
1365 if (err < 0) {
1366 l2cap_send_disconn_req(pi->conn, sk);
1367 return err;
1368 }
1369 break;
1370 } while(1);
1371 return 0;
1372}
1373
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001374static int l2cap_ertm_send(struct sock *sk)
1375{
1376 struct sk_buff *skb, *tx_skb;
1377 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001378 u16 control, fcs;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001379 int err, nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001380
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001381 if (pi->conn_state & L2CAP_CONN_WAIT_F)
1382 return 0;
1383
Joe Perchesf64f9e72009-11-29 16:55:45 -08001384 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) &&
1385 !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001386
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001387 if (pi->remote_max_tx &&
1388 bt_cb(skb)->retries == pi->remote_max_tx) {
1389 l2cap_send_disconn_req(pi->conn, sk);
1390 break;
1391 }
1392
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001393 tx_skb = skb_clone(skb, GFP_ATOMIC);
1394
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001395 bt_cb(skb)->retries++;
1396
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001397 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001398 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1399 control |= L2CAP_CTRL_FINAL;
1400 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1401 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001402 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001403 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1404 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1405
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001406
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001407 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001408 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1409 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1410 }
1411
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001412 err = l2cap_do_send(sk, tx_skb);
1413 if (err < 0) {
1414 l2cap_send_disconn_req(pi->conn, sk);
1415 return err;
1416 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001417 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001418
1419 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1420 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1421
1422 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001423 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001424
1425 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1426 sk->sk_send_head = NULL;
1427 else
1428 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001429
1430 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001431 }
1432
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001433 return nsent;
1434}
1435
1436static int l2cap_send_ack(struct l2cap_pinfo *pi)
1437{
1438 struct sock *sk = (struct sock *)pi;
1439 u16 control = 0;
1440
1441 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1442
1443 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1444 control |= L2CAP_SUPER_RCV_NOT_READY;
1445 return l2cap_send_sframe(pi, control);
1446 } else if (l2cap_ertm_send(sk) == 0) {
1447 control |= L2CAP_SUPER_RCV_READY;
1448 return l2cap_send_sframe(pi, control);
1449 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001450 return 0;
1451}
1452
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001453static int l2cap_send_srejtail(struct sock *sk)
1454{
1455 struct srej_list *tail;
1456 u16 control;
1457
1458 control = L2CAP_SUPER_SELECT_REJECT;
1459 control |= L2CAP_CTRL_FINAL;
1460
1461 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1462 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1463
1464 l2cap_send_sframe(l2cap_pi(sk), control);
1465
1466 return 0;
1467}
1468
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001469static 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 -07001470{
1471 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001472 struct sk_buff **frag;
1473 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474
1475 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001476 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001477 }
1478
1479 sent += count;
1480 len -= count;
1481
1482 /* Continuation fragments (no L2CAP header) */
1483 frag = &skb_shinfo(skb)->frag_list;
1484 while (len) {
1485 count = min_t(unsigned int, conn->mtu, len);
1486
1487 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1488 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001489 return -EFAULT;
1490 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1491 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492
1493 sent += count;
1494 len -= count;
1495
1496 frag = &(*frag)->next;
1497 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498
1499 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001500}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001501
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001502static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1503{
1504 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1505 struct sk_buff *skb;
1506 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1507 struct l2cap_hdr *lh;
1508
1509 BT_DBG("sk %p len %d", sk, (int)len);
1510
1511 count = min_t(unsigned int, (conn->mtu - hlen), len);
1512 skb = bt_skb_send_alloc(sk, count + hlen,
1513 msg->msg_flags & MSG_DONTWAIT, &err);
1514 if (!skb)
1515 return ERR_PTR(-ENOMEM);
1516
1517 /* Create L2CAP header */
1518 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1519 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1520 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1521 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1522
1523 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1524 if (unlikely(err < 0)) {
1525 kfree_skb(skb);
1526 return ERR_PTR(err);
1527 }
1528 return skb;
1529}
1530
1531static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1532{
1533 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1534 struct sk_buff *skb;
1535 int err, count, hlen = L2CAP_HDR_SIZE;
1536 struct l2cap_hdr *lh;
1537
1538 BT_DBG("sk %p len %d", sk, (int)len);
1539
1540 count = min_t(unsigned int, (conn->mtu - hlen), len);
1541 skb = bt_skb_send_alloc(sk, count + hlen,
1542 msg->msg_flags & MSG_DONTWAIT, &err);
1543 if (!skb)
1544 return ERR_PTR(-ENOMEM);
1545
1546 /* Create L2CAP header */
1547 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1548 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1549 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1550
1551 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1552 if (unlikely(err < 0)) {
1553 kfree_skb(skb);
1554 return ERR_PTR(err);
1555 }
1556 return skb;
1557}
1558
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001559static struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001560{
1561 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1562 struct sk_buff *skb;
1563 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1564 struct l2cap_hdr *lh;
1565
1566 BT_DBG("sk %p len %d", sk, (int)len);
1567
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001568 if (sdulen)
1569 hlen += 2;
1570
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001571 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1572 hlen += 2;
1573
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001574 count = min_t(unsigned int, (conn->mtu - hlen), len);
1575 skb = bt_skb_send_alloc(sk, count + hlen,
1576 msg->msg_flags & MSG_DONTWAIT, &err);
1577 if (!skb)
1578 return ERR_PTR(-ENOMEM);
1579
1580 /* Create L2CAP header */
1581 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1582 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1583 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1584 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001585 if (sdulen)
1586 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001587
1588 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1589 if (unlikely(err < 0)) {
1590 kfree_skb(skb);
1591 return ERR_PTR(err);
1592 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001593
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001594 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1595 put_unaligned_le16(0, skb_put(skb, 2));
1596
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001597 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001598 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599}
1600
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001601static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1602{
1603 struct l2cap_pinfo *pi = l2cap_pi(sk);
1604 struct sk_buff *skb;
1605 struct sk_buff_head sar_queue;
1606 u16 control;
1607 size_t size = 0;
1608
1609 __skb_queue_head_init(&sar_queue);
1610 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001611 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001612 if (IS_ERR(skb))
1613 return PTR_ERR(skb);
1614
1615 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001616 len -= pi->remote_mps;
1617 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001618 control = 0;
1619
1620 while (len > 0) {
1621 size_t buflen;
1622
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001623 if (len > pi->remote_mps) {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001624 control |= L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001625 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001626 } else {
1627 control |= L2CAP_SDU_END;
1628 buflen = len;
1629 }
1630
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001631 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001632 if (IS_ERR(skb)) {
1633 skb_queue_purge(&sar_queue);
1634 return PTR_ERR(skb);
1635 }
1636
1637 __skb_queue_tail(&sar_queue, skb);
1638 len -= buflen;
1639 size += buflen;
1640 control = 0;
1641 }
1642 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1643 if (sk->sk_send_head == NULL)
1644 sk->sk_send_head = sar_queue.next;
1645
1646 return size;
1647}
1648
Linus Torvalds1da177e2005-04-16 15:20:36 -07001649static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1650{
1651 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001652 struct l2cap_pinfo *pi = l2cap_pi(sk);
1653 struct sk_buff *skb;
1654 u16 control;
1655 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656
1657 BT_DBG("sock %p, sk %p", sock, sk);
1658
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001659 err = sock_error(sk);
1660 if (err)
1661 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662
1663 if (msg->msg_flags & MSG_OOB)
1664 return -EOPNOTSUPP;
1665
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666 lock_sock(sk);
1667
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001668 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001670 goto done;
1671 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001673 /* Connectionless channel */
1674 if (sk->sk_type == SOCK_DGRAM) {
1675 skb = l2cap_create_connless_pdu(sk, msg, len);
Dan Carpenter477fffb2010-04-21 23:52:01 +00001676 if (IS_ERR(skb))
1677 err = PTR_ERR(skb);
1678 else
1679 err = l2cap_do_send(sk, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001680 goto done;
1681 }
1682
1683 switch (pi->mode) {
1684 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001685 /* Check outgoing MTU */
1686 if (len > pi->omtu) {
1687 err = -EINVAL;
1688 goto done;
1689 }
1690
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001691 /* Create a basic PDU */
1692 skb = l2cap_create_basic_pdu(sk, msg, len);
1693 if (IS_ERR(skb)) {
1694 err = PTR_ERR(skb);
1695 goto done;
1696 }
1697
1698 err = l2cap_do_send(sk, skb);
1699 if (!err)
1700 err = len;
1701 break;
1702
1703 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001704 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001705 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001706 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001707 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001708 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001709 if (IS_ERR(skb)) {
1710 err = PTR_ERR(skb);
1711 goto done;
1712 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001713 __skb_queue_tail(TX_QUEUE(sk), skb);
1714 if (sk->sk_send_head == NULL)
1715 sk->sk_send_head = skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001716 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001717 /* Segment SDU into multiples PDUs */
1718 err = l2cap_sar_segment_sdu(sk, msg, len);
1719 if (err < 0)
1720 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001721 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001722
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001723 if (pi->mode == L2CAP_MODE_STREAMING)
1724 err = l2cap_streaming_send(sk);
1725 else
1726 err = l2cap_ertm_send(sk);
1727
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001728 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001729 err = len;
1730 break;
1731
1732 default:
1733 BT_DBG("bad state %1.1x", pi->mode);
1734 err = -EINVAL;
1735 }
1736
1737done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 release_sock(sk);
1739 return err;
1740}
1741
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001742static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1743{
1744 struct sock *sk = sock->sk;
1745
1746 lock_sock(sk);
1747
1748 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1749 struct l2cap_conn_rsp rsp;
1750
1751 sk->sk_state = BT_CONFIG;
1752
1753 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1754 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1755 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1756 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1757 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1758 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1759
1760 release_sock(sk);
1761 return 0;
1762 }
1763
1764 release_sock(sk);
1765
1766 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1767}
1768
David S. Millerb7058842009-09-30 16:12:20 -07001769static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770{
1771 struct sock *sk = sock->sk;
1772 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001773 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774 u32 opt;
1775
1776 BT_DBG("sk %p", sk);
1777
1778 lock_sock(sk);
1779
1780 switch (optname) {
1781 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001782 opts.imtu = l2cap_pi(sk)->imtu;
1783 opts.omtu = l2cap_pi(sk)->omtu;
1784 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001785 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001786 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001787 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001788
Linus Torvalds1da177e2005-04-16 15:20:36 -07001789 len = min_t(unsigned int, sizeof(opts), optlen);
1790 if (copy_from_user((char *) &opts, optval, len)) {
1791 err = -EFAULT;
1792 break;
1793 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001794
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001795 l2cap_pi(sk)->imtu = opts.imtu;
1796 l2cap_pi(sk)->omtu = opts.omtu;
1797 l2cap_pi(sk)->mode = opts.mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001798 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001799 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800 break;
1801
1802 case L2CAP_LM:
1803 if (get_user(opt, (u32 __user *) optval)) {
1804 err = -EFAULT;
1805 break;
1806 }
1807
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001808 if (opt & L2CAP_LM_AUTH)
1809 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1810 if (opt & L2CAP_LM_ENCRYPT)
1811 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1812 if (opt & L2CAP_LM_SECURE)
1813 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1814
1815 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1816 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 break;
1818
1819 default:
1820 err = -ENOPROTOOPT;
1821 break;
1822 }
1823
1824 release_sock(sk);
1825 return err;
1826}
1827
David S. Millerb7058842009-09-30 16:12:20 -07001828static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001829{
1830 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001831 struct bt_security sec;
1832 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001833 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001834
1835 BT_DBG("sk %p", sk);
1836
1837 if (level == SOL_L2CAP)
1838 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1839
Marcel Holtmann0588d942009-01-16 10:06:13 +01001840 if (level != SOL_BLUETOOTH)
1841 return -ENOPROTOOPT;
1842
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001843 lock_sock(sk);
1844
1845 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001846 case BT_SECURITY:
Marcel Holtmann2526d3d2009-02-20 20:54:06 +01001847 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001848 err = -EINVAL;
1849 break;
1850 }
1851
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001852 sec.level = BT_SECURITY_LOW;
1853
1854 len = min_t(unsigned int, sizeof(sec), optlen);
1855 if (copy_from_user((char *) &sec, optval, len)) {
1856 err = -EFAULT;
1857 break;
1858 }
1859
1860 if (sec.level < BT_SECURITY_LOW ||
1861 sec.level > BT_SECURITY_HIGH) {
1862 err = -EINVAL;
1863 break;
1864 }
1865
1866 l2cap_pi(sk)->sec_level = sec.level;
1867 break;
1868
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001869 case BT_DEFER_SETUP:
1870 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1871 err = -EINVAL;
1872 break;
1873 }
1874
1875 if (get_user(opt, (u32 __user *) optval)) {
1876 err = -EFAULT;
1877 break;
1878 }
1879
1880 bt_sk(sk)->defer_setup = opt;
1881 break;
1882
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001883 default:
1884 err = -ENOPROTOOPT;
1885 break;
1886 }
1887
1888 release_sock(sk);
1889 return err;
1890}
1891
1892static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893{
1894 struct sock *sk = sock->sk;
1895 struct l2cap_options opts;
1896 struct l2cap_conninfo cinfo;
1897 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001898 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899
1900 BT_DBG("sk %p", sk);
1901
1902 if (get_user(len, optlen))
1903 return -EFAULT;
1904
1905 lock_sock(sk);
1906
1907 switch (optname) {
1908 case L2CAP_OPTIONS:
1909 opts.imtu = l2cap_pi(sk)->imtu;
1910 opts.omtu = l2cap_pi(sk)->omtu;
1911 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001912 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001913 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001914 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915
1916 len = min_t(unsigned int, len, sizeof(opts));
1917 if (copy_to_user(optval, (char *) &opts, len))
1918 err = -EFAULT;
1919
1920 break;
1921
1922 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001923 switch (l2cap_pi(sk)->sec_level) {
1924 case BT_SECURITY_LOW:
1925 opt = L2CAP_LM_AUTH;
1926 break;
1927 case BT_SECURITY_MEDIUM:
1928 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
1929 break;
1930 case BT_SECURITY_HIGH:
1931 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
1932 L2CAP_LM_SECURE;
1933 break;
1934 default:
1935 opt = 0;
1936 break;
1937 }
1938
1939 if (l2cap_pi(sk)->role_switch)
1940 opt |= L2CAP_LM_MASTER;
1941
1942 if (l2cap_pi(sk)->force_reliable)
1943 opt |= L2CAP_LM_RELIABLE;
1944
1945 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946 err = -EFAULT;
1947 break;
1948
1949 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001950 if (sk->sk_state != BT_CONNECTED &&
1951 !(sk->sk_state == BT_CONNECT2 &&
1952 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001953 err = -ENOTCONN;
1954 break;
1955 }
1956
1957 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
1958 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
1959
1960 len = min_t(unsigned int, len, sizeof(cinfo));
1961 if (copy_to_user(optval, (char *) &cinfo, len))
1962 err = -EFAULT;
1963
1964 break;
1965
1966 default:
1967 err = -ENOPROTOOPT;
1968 break;
1969 }
1970
1971 release_sock(sk);
1972 return err;
1973}
1974
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001975static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
1976{
1977 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001978 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001979 int len, err = 0;
1980
1981 BT_DBG("sk %p", sk);
1982
1983 if (level == SOL_L2CAP)
1984 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
1985
Marcel Holtmann0588d942009-01-16 10:06:13 +01001986 if (level != SOL_BLUETOOTH)
1987 return -ENOPROTOOPT;
1988
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001989 if (get_user(len, optlen))
1990 return -EFAULT;
1991
1992 lock_sock(sk);
1993
1994 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001995 case BT_SECURITY:
Marcel Holtmann2526d3d2009-02-20 20:54:06 +01001996 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001997 err = -EINVAL;
1998 break;
1999 }
2000
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002001 sec.level = l2cap_pi(sk)->sec_level;
2002
2003 len = min_t(unsigned int, len, sizeof(sec));
2004 if (copy_to_user(optval, (char *) &sec, len))
2005 err = -EFAULT;
2006
2007 break;
2008
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002009 case BT_DEFER_SETUP:
2010 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2011 err = -EINVAL;
2012 break;
2013 }
2014
2015 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2016 err = -EFAULT;
2017
2018 break;
2019
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002020 default:
2021 err = -ENOPROTOOPT;
2022 break;
2023 }
2024
2025 release_sock(sk);
2026 return err;
2027}
2028
Linus Torvalds1da177e2005-04-16 15:20:36 -07002029static int l2cap_sock_shutdown(struct socket *sock, int how)
2030{
2031 struct sock *sk = sock->sk;
2032 int err = 0;
2033
2034 BT_DBG("sock %p, sk %p", sock, sk);
2035
2036 if (!sk)
2037 return 0;
2038
2039 lock_sock(sk);
2040 if (!sk->sk_shutdown) {
2041 sk->sk_shutdown = SHUTDOWN_MASK;
2042 l2cap_sock_clear_timer(sk);
2043 __l2cap_sock_close(sk, 0);
2044
2045 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002046 err = bt_sock_wait_state(sk, BT_CLOSED,
2047 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002048 }
2049 release_sock(sk);
2050 return err;
2051}
2052
2053static int l2cap_sock_release(struct socket *sock)
2054{
2055 struct sock *sk = sock->sk;
2056 int err;
2057
2058 BT_DBG("sock %p, sk %p", sock, sk);
2059
2060 if (!sk)
2061 return 0;
2062
2063 err = l2cap_sock_shutdown(sock, 2);
2064
2065 sock_orphan(sk);
2066 l2cap_sock_kill(sk);
2067 return err;
2068}
2069
Linus Torvalds1da177e2005-04-16 15:20:36 -07002070static void l2cap_chan_ready(struct sock *sk)
2071{
2072 struct sock *parent = bt_sk(sk)->parent;
2073
2074 BT_DBG("sk %p, parent %p", sk, parent);
2075
2076 l2cap_pi(sk)->conf_state = 0;
2077 l2cap_sock_clear_timer(sk);
2078
2079 if (!parent) {
2080 /* Outgoing channel.
2081 * Wake up socket sleeping on connect.
2082 */
2083 sk->sk_state = BT_CONNECTED;
2084 sk->sk_state_change(sk);
2085 } else {
2086 /* Incoming channel.
2087 * Wake up socket sleeping on accept.
2088 */
2089 parent->sk_data_ready(parent, 0);
2090 }
2091}
2092
2093/* Copy frame to all raw sockets on that connection */
2094static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2095{
2096 struct l2cap_chan_list *l = &conn->chan_list;
2097 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002098 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002099
2100 BT_DBG("conn %p", conn);
2101
2102 read_lock(&l->lock);
2103 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2104 if (sk->sk_type != SOCK_RAW)
2105 continue;
2106
2107 /* Don't send frame to the socket it came from */
2108 if (skb->sk == sk)
2109 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002110 nskb = skb_clone(skb, GFP_ATOMIC);
2111 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002112 continue;
2113
2114 if (sock_queue_rcv_skb(sk, nskb))
2115 kfree_skb(nskb);
2116 }
2117 read_unlock(&l->lock);
2118}
2119
2120/* ---- L2CAP signalling commands ---- */
2121static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2122 u8 code, u8 ident, u16 dlen, void *data)
2123{
2124 struct sk_buff *skb, **frag;
2125 struct l2cap_cmd_hdr *cmd;
2126 struct l2cap_hdr *lh;
2127 int len, count;
2128
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002129 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2130 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002131
2132 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2133 count = min_t(unsigned int, conn->mtu, len);
2134
2135 skb = bt_skb_alloc(count, GFP_ATOMIC);
2136 if (!skb)
2137 return NULL;
2138
2139 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002140 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002141 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002142
2143 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2144 cmd->code = code;
2145 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002146 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002147
2148 if (dlen) {
2149 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2150 memcpy(skb_put(skb, count), data, count);
2151 data += count;
2152 }
2153
2154 len -= skb->len;
2155
2156 /* Continuation fragments (no L2CAP header) */
2157 frag = &skb_shinfo(skb)->frag_list;
2158 while (len) {
2159 count = min_t(unsigned int, conn->mtu, len);
2160
2161 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2162 if (!*frag)
2163 goto fail;
2164
2165 memcpy(skb_put(*frag, count), data, count);
2166
2167 len -= count;
2168 data += count;
2169
2170 frag = &(*frag)->next;
2171 }
2172
2173 return skb;
2174
2175fail:
2176 kfree_skb(skb);
2177 return NULL;
2178}
2179
2180static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2181{
2182 struct l2cap_conf_opt *opt = *ptr;
2183 int len;
2184
2185 len = L2CAP_CONF_OPT_SIZE + opt->len;
2186 *ptr += len;
2187
2188 *type = opt->type;
2189 *olen = opt->len;
2190
2191 switch (opt->len) {
2192 case 1:
2193 *val = *((u8 *) opt->val);
2194 break;
2195
2196 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002197 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002198 break;
2199
2200 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002201 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002202 break;
2203
2204 default:
2205 *val = (unsigned long) opt->val;
2206 break;
2207 }
2208
2209 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2210 return len;
2211}
2212
Linus Torvalds1da177e2005-04-16 15:20:36 -07002213static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2214{
2215 struct l2cap_conf_opt *opt = *ptr;
2216
2217 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2218
2219 opt->type = type;
2220 opt->len = len;
2221
2222 switch (len) {
2223 case 1:
2224 *((u8 *) opt->val) = val;
2225 break;
2226
2227 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002228 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002229 break;
2230
2231 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002232 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002233 break;
2234
2235 default:
2236 memcpy(opt->val, (void *) val, len);
2237 break;
2238 }
2239
2240 *ptr += L2CAP_CONF_OPT_SIZE + len;
2241}
2242
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002243static void l2cap_ack_timeout(unsigned long arg)
2244{
2245 struct sock *sk = (void *) arg;
2246
2247 bh_lock_sock(sk);
2248 l2cap_send_ack(l2cap_pi(sk));
2249 bh_unlock_sock(sk);
2250}
2251
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002252static inline void l2cap_ertm_init(struct sock *sk)
2253{
2254 l2cap_pi(sk)->expected_ack_seq = 0;
2255 l2cap_pi(sk)->unacked_frames = 0;
2256 l2cap_pi(sk)->buffer_seq = 0;
2257 l2cap_pi(sk)->num_to_ack = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002258 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002259
2260 setup_timer(&l2cap_pi(sk)->retrans_timer,
2261 l2cap_retrans_timeout, (unsigned long) sk);
2262 setup_timer(&l2cap_pi(sk)->monitor_timer,
2263 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002264 setup_timer(&l2cap_pi(sk)->ack_timer,
2265 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002266
2267 __skb_queue_head_init(SREJ_QUEUE(sk));
2268}
2269
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002270static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2271{
2272 u32 local_feat_mask = l2cap_feat_mask;
2273 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002274 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002275
2276 switch (mode) {
2277 case L2CAP_MODE_ERTM:
2278 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2279 case L2CAP_MODE_STREAMING:
2280 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2281 default:
2282 return 0x00;
2283 }
2284}
2285
2286static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2287{
2288 switch (mode) {
2289 case L2CAP_MODE_STREAMING:
2290 case L2CAP_MODE_ERTM:
2291 if (l2cap_mode_supported(mode, remote_feat_mask))
2292 return mode;
2293 /* fall through */
2294 default:
2295 return L2CAP_MODE_BASIC;
2296 }
2297}
2298
Linus Torvalds1da177e2005-04-16 15:20:36 -07002299static int l2cap_build_conf_req(struct sock *sk, void *data)
2300{
2301 struct l2cap_pinfo *pi = l2cap_pi(sk);
2302 struct l2cap_conf_req *req = data;
Gustavo F. Padovana0e55a32009-09-29 01:42:23 -03002303 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002304 void *ptr = req->data;
2305
2306 BT_DBG("sk %p", sk);
2307
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002308 if (pi->num_conf_req || pi->num_conf_rsp)
2309 goto done;
2310
2311 switch (pi->mode) {
2312 case L2CAP_MODE_STREAMING:
2313 case L2CAP_MODE_ERTM:
2314 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002315 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2316 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002317 break;
2318 default:
2319 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2320 break;
2321 }
2322
2323done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002324 switch (pi->mode) {
2325 case L2CAP_MODE_BASIC:
2326 if (pi->imtu != L2CAP_DEFAULT_MTU)
2327 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2328 break;
2329
2330 case L2CAP_MODE_ERTM:
2331 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002332 rfc.txwin_size = pi->tx_win;
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +02002333 rfc.max_transmit = max_transmit;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002334 rfc.retrans_timeout = 0;
2335 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002336 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002337 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002338 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002339
2340 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2341 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002342
2343 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2344 break;
2345
2346 if (pi->fcs == L2CAP_FCS_NONE ||
2347 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2348 pi->fcs = L2CAP_FCS_NONE;
2349 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2350 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002351 break;
2352
2353 case L2CAP_MODE_STREAMING:
2354 rfc.mode = L2CAP_MODE_STREAMING;
2355 rfc.txwin_size = 0;
2356 rfc.max_transmit = 0;
2357 rfc.retrans_timeout = 0;
2358 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002359 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002360 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002361 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002362
2363 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2364 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002365
2366 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2367 break;
2368
2369 if (pi->fcs == L2CAP_FCS_NONE ||
2370 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2371 pi->fcs = L2CAP_FCS_NONE;
2372 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2373 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002374 break;
2375 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002376
2377 /* FIXME: Need actual value of the flush timeout */
2378 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2379 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2380
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002381 req->dcid = cpu_to_le16(pi->dcid);
2382 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002383
2384 return ptr - data;
2385}
2386
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002387static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002388{
2389 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002390 struct l2cap_conf_rsp *rsp = data;
2391 void *ptr = rsp->data;
2392 void *req = pi->conf_req;
2393 int len = pi->conf_len;
2394 int type, hint, olen;
2395 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002396 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002397 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002398 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002399
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002400 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002401
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002402 while (len >= L2CAP_CONF_OPT_SIZE) {
2403 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002404
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002405 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002406 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002407
2408 switch (type) {
2409 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002410 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002411 break;
2412
2413 case L2CAP_CONF_FLUSH_TO:
2414 pi->flush_to = val;
2415 break;
2416
2417 case L2CAP_CONF_QOS:
2418 break;
2419
Marcel Holtmann6464f352007-10-20 13:39:51 +02002420 case L2CAP_CONF_RFC:
2421 if (olen == sizeof(rfc))
2422 memcpy(&rfc, (void *) val, olen);
2423 break;
2424
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002425 case L2CAP_CONF_FCS:
2426 if (val == L2CAP_FCS_NONE)
2427 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2428
2429 break;
2430
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002431 default:
2432 if (hint)
2433 break;
2434
2435 result = L2CAP_CONF_UNKNOWN;
2436 *((u8 *) ptr++) = type;
2437 break;
2438 }
2439 }
2440
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002441 if (pi->num_conf_rsp || pi->num_conf_req)
2442 goto done;
2443
2444 switch (pi->mode) {
2445 case L2CAP_MODE_STREAMING:
2446 case L2CAP_MODE_ERTM:
2447 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2448 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2449 return -ECONNREFUSED;
2450 break;
2451 default:
2452 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2453 break;
2454 }
2455
2456done:
2457 if (pi->mode != rfc.mode) {
2458 result = L2CAP_CONF_UNACCEPT;
2459 rfc.mode = pi->mode;
2460
2461 if (pi->num_conf_rsp == 1)
2462 return -ECONNREFUSED;
2463
2464 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2465 sizeof(rfc), (unsigned long) &rfc);
2466 }
2467
2468
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002469 if (result == L2CAP_CONF_SUCCESS) {
2470 /* Configure output options and let the other side know
2471 * which ones we don't like. */
2472
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002473 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2474 result = L2CAP_CONF_UNACCEPT;
2475 else {
2476 pi->omtu = mtu;
2477 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2478 }
2479 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002480
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002481 switch (rfc.mode) {
2482 case L2CAP_MODE_BASIC:
2483 pi->fcs = L2CAP_FCS_NONE;
2484 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2485 break;
2486
2487 case L2CAP_MODE_ERTM:
2488 pi->remote_tx_win = rfc.txwin_size;
2489 pi->remote_max_tx = rfc.max_transmit;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002490 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2491 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2492
2493 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002494
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002495 rfc.retrans_timeout =
2496 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2497 rfc.monitor_timeout =
2498 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002499
2500 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002501
2502 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2503 sizeof(rfc), (unsigned long) &rfc);
2504
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002505 break;
2506
2507 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002508 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2509 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2510
2511 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002512
2513 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002514
2515 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2516 sizeof(rfc), (unsigned long) &rfc);
2517
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002518 break;
2519
2520 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002521 result = L2CAP_CONF_UNACCEPT;
2522
2523 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002524 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002525 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002526
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002527 if (result == L2CAP_CONF_SUCCESS)
2528 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2529 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002530 rsp->scid = cpu_to_le16(pi->dcid);
2531 rsp->result = cpu_to_le16(result);
2532 rsp->flags = cpu_to_le16(0x0000);
2533
2534 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002535}
2536
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002537static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2538{
2539 struct l2cap_pinfo *pi = l2cap_pi(sk);
2540 struct l2cap_conf_req *req = data;
2541 void *ptr = req->data;
2542 int type, olen;
2543 unsigned long val;
2544 struct l2cap_conf_rfc rfc;
2545
2546 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2547
2548 while (len >= L2CAP_CONF_OPT_SIZE) {
2549 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2550
2551 switch (type) {
2552 case L2CAP_CONF_MTU:
2553 if (val < L2CAP_DEFAULT_MIN_MTU) {
2554 *result = L2CAP_CONF_UNACCEPT;
2555 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2556 } else
2557 pi->omtu = val;
2558 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2559 break;
2560
2561 case L2CAP_CONF_FLUSH_TO:
2562 pi->flush_to = val;
2563 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2564 2, pi->flush_to);
2565 break;
2566
2567 case L2CAP_CONF_RFC:
2568 if (olen == sizeof(rfc))
2569 memcpy(&rfc, (void *)val, olen);
2570
2571 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2572 rfc.mode != pi->mode)
2573 return -ECONNREFUSED;
2574
2575 pi->mode = rfc.mode;
2576 pi->fcs = 0;
2577
2578 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2579 sizeof(rfc), (unsigned long) &rfc);
2580 break;
2581 }
2582 }
2583
2584 if (*result == L2CAP_CONF_SUCCESS) {
2585 switch (rfc.mode) {
2586 case L2CAP_MODE_ERTM:
2587 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002588 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2589 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002590 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002591 break;
2592 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002593 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002594 }
2595 }
2596
2597 req->dcid = cpu_to_le16(pi->dcid);
2598 req->flags = cpu_to_le16(0x0000);
2599
2600 return ptr - data;
2601}
2602
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002603static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604{
2605 struct l2cap_conf_rsp *rsp = data;
2606 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002607
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002608 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002609
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002610 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002611 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002612 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002613
2614 return ptr - data;
2615}
2616
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002617static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2618{
2619 struct l2cap_pinfo *pi = l2cap_pi(sk);
2620 int type, olen;
2621 unsigned long val;
2622 struct l2cap_conf_rfc rfc;
2623
2624 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2625
2626 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2627 return;
2628
2629 while (len >= L2CAP_CONF_OPT_SIZE) {
2630 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2631
2632 switch (type) {
2633 case L2CAP_CONF_RFC:
2634 if (olen == sizeof(rfc))
2635 memcpy(&rfc, (void *)val, olen);
2636 goto done;
2637 }
2638 }
2639
2640done:
2641 switch (rfc.mode) {
2642 case L2CAP_MODE_ERTM:
2643 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002644 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2645 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002646 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2647 break;
2648 case L2CAP_MODE_STREAMING:
2649 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2650 }
2651}
2652
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002653static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2654{
2655 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2656
2657 if (rej->reason != 0x0000)
2658 return 0;
2659
2660 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2661 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002662 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002663
2664 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002665 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002666
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002667 l2cap_conn_start(conn);
2668 }
2669
2670 return 0;
2671}
2672
Linus Torvalds1da177e2005-04-16 15:20:36 -07002673static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2674{
2675 struct l2cap_chan_list *list = &conn->chan_list;
2676 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2677 struct l2cap_conn_rsp rsp;
2678 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002679 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002680
2681 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002682 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002683
2684 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2685
2686 /* Check if we have socket listening on psm */
2687 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2688 if (!parent) {
2689 result = L2CAP_CR_BAD_PSM;
2690 goto sendresp;
2691 }
2692
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002693 /* Check if the ACL is secure enough (if not SDP) */
2694 if (psm != cpu_to_le16(0x0001) &&
2695 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002696 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002697 result = L2CAP_CR_SEC_BLOCK;
2698 goto response;
2699 }
2700
Linus Torvalds1da177e2005-04-16 15:20:36 -07002701 result = L2CAP_CR_NO_MEM;
2702
2703 /* Check for backlog size */
2704 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002705 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002706 goto response;
2707 }
2708
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002709 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710 if (!sk)
2711 goto response;
2712
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002713 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002714
2715 /* Check if we already have channel with that dcid */
2716 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002717 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002718 sock_set_flag(sk, SOCK_ZAPPED);
2719 l2cap_sock_kill(sk);
2720 goto response;
2721 }
2722
2723 hci_conn_hold(conn->hcon);
2724
2725 l2cap_sock_init(sk, parent);
2726 bacpy(&bt_sk(sk)->src, conn->src);
2727 bacpy(&bt_sk(sk)->dst, conn->dst);
2728 l2cap_pi(sk)->psm = psm;
2729 l2cap_pi(sk)->dcid = scid;
2730
2731 __l2cap_chan_add(conn, sk, parent);
2732 dcid = l2cap_pi(sk)->scid;
2733
2734 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2735
Linus Torvalds1da177e2005-04-16 15:20:36 -07002736 l2cap_pi(sk)->ident = cmd->ident;
2737
Marcel Holtmann984947d2009-02-06 23:35:19 +01002738 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002739 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002740 if (bt_sk(sk)->defer_setup) {
2741 sk->sk_state = BT_CONNECT2;
2742 result = L2CAP_CR_PEND;
2743 status = L2CAP_CS_AUTHOR_PEND;
2744 parent->sk_data_ready(parent, 0);
2745 } else {
2746 sk->sk_state = BT_CONFIG;
2747 result = L2CAP_CR_SUCCESS;
2748 status = L2CAP_CS_NO_INFO;
2749 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002750 } else {
2751 sk->sk_state = BT_CONNECT2;
2752 result = L2CAP_CR_PEND;
2753 status = L2CAP_CS_AUTHEN_PEND;
2754 }
2755 } else {
2756 sk->sk_state = BT_CONNECT2;
2757 result = L2CAP_CR_PEND;
2758 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002759 }
2760
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002761 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002762
2763response:
2764 bh_unlock_sock(parent);
2765
2766sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002767 rsp.scid = cpu_to_le16(scid);
2768 rsp.dcid = cpu_to_le16(dcid);
2769 rsp.result = cpu_to_le16(result);
2770 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002771 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002772
2773 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2774 struct l2cap_info_req info;
2775 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2776
2777 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2778 conn->info_ident = l2cap_get_ident(conn);
2779
2780 mod_timer(&conn->info_timer, jiffies +
2781 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2782
2783 l2cap_send_cmd(conn, conn->info_ident,
2784 L2CAP_INFO_REQ, sizeof(info), &info);
2785 }
2786
Linus Torvalds1da177e2005-04-16 15:20:36 -07002787 return 0;
2788}
2789
2790static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2791{
2792 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2793 u16 scid, dcid, result, status;
2794 struct sock *sk;
2795 u8 req[128];
2796
2797 scid = __le16_to_cpu(rsp->scid);
2798 dcid = __le16_to_cpu(rsp->dcid);
2799 result = __le16_to_cpu(rsp->result);
2800 status = __le16_to_cpu(rsp->status);
2801
2802 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2803
2804 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002805 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2806 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002807 return 0;
2808 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002809 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2810 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002811 return 0;
2812 }
2813
2814 switch (result) {
2815 case L2CAP_CR_SUCCESS:
2816 sk->sk_state = BT_CONFIG;
2817 l2cap_pi(sk)->ident = 0;
2818 l2cap_pi(sk)->dcid = dcid;
2819 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2820
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002821 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2822
Linus Torvalds1da177e2005-04-16 15:20:36 -07002823 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2824 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002825 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002826 break;
2827
2828 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002829 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002830 break;
2831
2832 default:
2833 l2cap_chan_del(sk, ECONNREFUSED);
2834 break;
2835 }
2836
2837 bh_unlock_sock(sk);
2838 return 0;
2839}
2840
Al Viro88219a02007-07-29 00:17:25 -07002841static 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 -07002842{
2843 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2844 u16 dcid, flags;
2845 u8 rsp[64];
2846 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002847 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002848
2849 dcid = __le16_to_cpu(req->dcid);
2850 flags = __le16_to_cpu(req->flags);
2851
2852 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2853
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002854 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2855 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002856 return -ENOENT;
2857
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002858 if (sk->sk_state == BT_DISCONN)
2859 goto unlock;
2860
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002861 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002862 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002863 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2864 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2865 l2cap_build_conf_rsp(sk, rsp,
2866 L2CAP_CONF_REJECT, flags), rsp);
2867 goto unlock;
2868 }
2869
2870 /* Store config. */
2871 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2872 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002873
2874 if (flags & 0x0001) {
2875 /* Incomplete config. Send empty response. */
2876 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002877 l2cap_build_conf_rsp(sk, rsp,
2878 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002879 goto unlock;
2880 }
2881
2882 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002883 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002884 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002885 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002886 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002887 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002888
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002889 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002890 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002891
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002892 /* Reset config buffer. */
2893 l2cap_pi(sk)->conf_len = 0;
2894
Marcel Holtmann876d9482007-10-20 13:35:42 +02002895 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2896 goto unlock;
2897
Linus Torvalds1da177e2005-04-16 15:20:36 -07002898 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002899 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
2900 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002901 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2902
Linus Torvalds1da177e2005-04-16 15:20:36 -07002903 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002904
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002905 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002906 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002907 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002908 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2909 l2cap_ertm_init(sk);
2910
Linus Torvalds1da177e2005-04-16 15:20:36 -07002911 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002912 goto unlock;
2913 }
2914
2915 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002916 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002917 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002918 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002919 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002920 }
2921
2922unlock:
2923 bh_unlock_sock(sk);
2924 return 0;
2925}
2926
2927static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2928{
2929 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2930 u16 scid, flags, result;
2931 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002932 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002933
2934 scid = __le16_to_cpu(rsp->scid);
2935 flags = __le16_to_cpu(rsp->flags);
2936 result = __le16_to_cpu(rsp->result);
2937
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002938 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2939 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002940
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002941 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2942 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002943 return 0;
2944
2945 switch (result) {
2946 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002947 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002948 break;
2949
2950 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002951 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002952 char req[64];
2953
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02002954 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
2955 l2cap_send_disconn_req(conn, sk);
2956 goto done;
2957 }
2958
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002959 /* throw out any old stored conf requests */
2960 result = L2CAP_CONF_SUCCESS;
2961 len = l2cap_parse_conf_rsp(sk, rsp->data,
2962 len, req, &result);
2963 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002964 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002965 goto done;
2966 }
2967
2968 l2cap_send_cmd(conn, l2cap_get_ident(conn),
2969 L2CAP_CONF_REQ, len, req);
2970 l2cap_pi(sk)->num_conf_req++;
2971 if (result != L2CAP_CONF_SUCCESS)
2972 goto done;
2973 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002974 }
2975
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002976 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002977 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002978 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002980 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002981 goto done;
2982 }
2983
2984 if (flags & 0x01)
2985 goto done;
2986
Linus Torvalds1da177e2005-04-16 15:20:36 -07002987 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
2988
2989 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002990 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
2991 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002992 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2993
Linus Torvalds1da177e2005-04-16 15:20:36 -07002994 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002995 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002996 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002997 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002998 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2999 l2cap_ertm_init(sk);
3000
Linus Torvalds1da177e2005-04-16 15:20:36 -07003001 l2cap_chan_ready(sk);
3002 }
3003
3004done:
3005 bh_unlock_sock(sk);
3006 return 0;
3007}
3008
3009static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3010{
3011 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3012 struct l2cap_disconn_rsp rsp;
3013 u16 dcid, scid;
3014 struct sock *sk;
3015
3016 scid = __le16_to_cpu(req->scid);
3017 dcid = __le16_to_cpu(req->dcid);
3018
3019 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3020
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003021 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3022 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003023 return 0;
3024
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003025 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3026 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003027 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3028
3029 sk->sk_shutdown = SHUTDOWN_MASK;
3030
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003031 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003032
3033 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3034 skb_queue_purge(SREJ_QUEUE(sk));
3035 del_timer(&l2cap_pi(sk)->retrans_timer);
3036 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003037 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003038 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003039
Linus Torvalds1da177e2005-04-16 15:20:36 -07003040 l2cap_chan_del(sk, ECONNRESET);
3041 bh_unlock_sock(sk);
3042
3043 l2cap_sock_kill(sk);
3044 return 0;
3045}
3046
3047static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3048{
3049 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3050 u16 dcid, scid;
3051 struct sock *sk;
3052
3053 scid = __le16_to_cpu(rsp->scid);
3054 dcid = __le16_to_cpu(rsp->dcid);
3055
3056 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3057
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003058 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3059 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003060 return 0;
3061
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003062 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003063
3064 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3065 skb_queue_purge(SREJ_QUEUE(sk));
3066 del_timer(&l2cap_pi(sk)->retrans_timer);
3067 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003068 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003069 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003070
Linus Torvalds1da177e2005-04-16 15:20:36 -07003071 l2cap_chan_del(sk, 0);
3072 bh_unlock_sock(sk);
3073
3074 l2cap_sock_kill(sk);
3075 return 0;
3076}
3077
3078static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3079{
3080 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003081 u16 type;
3082
3083 type = __le16_to_cpu(req->type);
3084
3085 BT_DBG("type 0x%4.4x", type);
3086
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003087 if (type == L2CAP_IT_FEAT_MASK) {
3088 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003089 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003090 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3091 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3092 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003093 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003094 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3095 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003096 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003097 l2cap_send_cmd(conn, cmd->ident,
3098 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003099 } else if (type == L2CAP_IT_FIXED_CHAN) {
3100 u8 buf[12];
3101 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3102 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3103 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3104 memcpy(buf + 4, l2cap_fixed_chan, 8);
3105 l2cap_send_cmd(conn, cmd->ident,
3106 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003107 } else {
3108 struct l2cap_info_rsp rsp;
3109 rsp.type = cpu_to_le16(type);
3110 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3111 l2cap_send_cmd(conn, cmd->ident,
3112 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3113 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003114
3115 return 0;
3116}
3117
3118static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3119{
3120 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3121 u16 type, result;
3122
3123 type = __le16_to_cpu(rsp->type);
3124 result = __le16_to_cpu(rsp->result);
3125
3126 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3127
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003128 del_timer(&conn->info_timer);
3129
Marcel Holtmann984947d2009-02-06 23:35:19 +01003130 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003131 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003132
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003133 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003134 struct l2cap_info_req req;
3135 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3136
3137 conn->info_ident = l2cap_get_ident(conn);
3138
3139 l2cap_send_cmd(conn, conn->info_ident,
3140 L2CAP_INFO_REQ, sizeof(req), &req);
3141 } else {
3142 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3143 conn->info_ident = 0;
3144
3145 l2cap_conn_start(conn);
3146 }
3147 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003148 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003149 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003150
3151 l2cap_conn_start(conn);
3152 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003153
Linus Torvalds1da177e2005-04-16 15:20:36 -07003154 return 0;
3155}
3156
3157static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3158{
3159 u8 *data = skb->data;
3160 int len = skb->len;
3161 struct l2cap_cmd_hdr cmd;
3162 int err = 0;
3163
3164 l2cap_raw_recv(conn, skb);
3165
3166 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003167 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003168 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3169 data += L2CAP_CMD_HDR_SIZE;
3170 len -= L2CAP_CMD_HDR_SIZE;
3171
Al Viro88219a02007-07-29 00:17:25 -07003172 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003173
Al Viro88219a02007-07-29 00:17:25 -07003174 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 -07003175
Al Viro88219a02007-07-29 00:17:25 -07003176 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003177 BT_DBG("corrupted command");
3178 break;
3179 }
3180
3181 switch (cmd.code) {
3182 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003183 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003184 break;
3185
3186 case L2CAP_CONN_REQ:
3187 err = l2cap_connect_req(conn, &cmd, data);
3188 break;
3189
3190 case L2CAP_CONN_RSP:
3191 err = l2cap_connect_rsp(conn, &cmd, data);
3192 break;
3193
3194 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003195 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003196 break;
3197
3198 case L2CAP_CONF_RSP:
3199 err = l2cap_config_rsp(conn, &cmd, data);
3200 break;
3201
3202 case L2CAP_DISCONN_REQ:
3203 err = l2cap_disconnect_req(conn, &cmd, data);
3204 break;
3205
3206 case L2CAP_DISCONN_RSP:
3207 err = l2cap_disconnect_rsp(conn, &cmd, data);
3208 break;
3209
3210 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003211 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003212 break;
3213
3214 case L2CAP_ECHO_RSP:
3215 break;
3216
3217 case L2CAP_INFO_REQ:
3218 err = l2cap_information_req(conn, &cmd, data);
3219 break;
3220
3221 case L2CAP_INFO_RSP:
3222 err = l2cap_information_rsp(conn, &cmd, data);
3223 break;
3224
3225 default:
3226 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3227 err = -EINVAL;
3228 break;
3229 }
3230
3231 if (err) {
3232 struct l2cap_cmd_rej rej;
3233 BT_DBG("error %d", err);
3234
3235 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003236 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003237 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3238 }
3239
Al Viro88219a02007-07-29 00:17:25 -07003240 data += cmd_len;
3241 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003242 }
3243
3244 kfree_skb(skb);
3245}
3246
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003247static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3248{
3249 u16 our_fcs, rcv_fcs;
3250 int hdr_size = L2CAP_HDR_SIZE + 2;
3251
3252 if (pi->fcs == L2CAP_FCS_CRC16) {
3253 skb_trim(skb, skb->len - 2);
3254 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3255 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3256
3257 if (our_fcs != rcv_fcs)
3258 return -EINVAL;
3259 }
3260 return 0;
3261}
3262
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003263static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3264{
3265 struct l2cap_pinfo *pi = l2cap_pi(sk);
3266 u16 control = 0;
3267
3268 pi->frames_sent = 0;
3269 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3270
3271 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3272
3273 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3274 control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL;
3275 l2cap_send_sframe(pi, control);
3276 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
3277 }
3278
3279 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0)
3280 __mod_retrans_timer();
3281
3282 l2cap_ertm_send(sk);
3283
3284 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3285 pi->frames_sent == 0) {
3286 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003287 l2cap_send_sframe(pi, control);
3288 }
3289}
3290
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003291static void l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
3292{
3293 struct sk_buff *next_skb;
3294
3295 bt_cb(skb)->tx_seq = tx_seq;
3296 bt_cb(skb)->sar = sar;
3297
3298 next_skb = skb_peek(SREJ_QUEUE(sk));
3299 if (!next_skb) {
3300 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3301 return;
3302 }
3303
3304 do {
3305 if (bt_cb(next_skb)->tx_seq > tx_seq) {
3306 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
3307 return;
3308 }
3309
3310 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3311 break;
3312
3313 } while((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
3314
3315 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3316}
3317
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003318static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3319{
3320 struct l2cap_pinfo *pi = l2cap_pi(sk);
3321 struct sk_buff *_skb;
3322 int err = -EINVAL;
3323
3324 switch (control & L2CAP_CTRL_SAR) {
3325 case L2CAP_SDU_UNSEGMENTED:
3326 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3327 kfree_skb(pi->sdu);
3328 break;
3329 }
3330
3331 err = sock_queue_rcv_skb(sk, skb);
3332 if (!err)
3333 return 0;
3334
3335 break;
3336
3337 case L2CAP_SDU_START:
3338 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3339 kfree_skb(pi->sdu);
3340 break;
3341 }
3342
3343 pi->sdu_len = get_unaligned_le16(skb->data);
3344 skb_pull(skb, 2);
3345
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003346 if (pi->sdu_len > pi->imtu) {
3347 err = -EMSGSIZE;
3348 break;
3349 }
3350
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003351 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3352 if (!pi->sdu) {
3353 err = -ENOMEM;
3354 break;
3355 }
3356
3357 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3358
3359 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3360 pi->partial_sdu_len = skb->len;
3361 err = 0;
3362 break;
3363
3364 case L2CAP_SDU_CONTINUE:
3365 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3366 break;
3367
3368 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3369
3370 pi->partial_sdu_len += skb->len;
3371 if (pi->partial_sdu_len > pi->sdu_len)
3372 kfree_skb(pi->sdu);
3373 else
3374 err = 0;
3375
3376 break;
3377
3378 case L2CAP_SDU_END:
3379 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3380 break;
3381
3382 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3383
3384 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3385 pi->partial_sdu_len += skb->len;
3386
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003387 if (pi->partial_sdu_len > pi->imtu)
3388 goto drop;
3389
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003390 if (pi->partial_sdu_len == pi->sdu_len) {
3391 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3392 err = sock_queue_rcv_skb(sk, _skb);
3393 if (err < 0)
3394 kfree_skb(_skb);
3395 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003396 err = 0;
3397
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003398drop:
3399 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003400 break;
3401 }
3402
3403 kfree_skb(skb);
3404 return err;
3405}
3406
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003407static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3408{
3409 struct sk_buff *skb;
3410 u16 control = 0;
3411
3412 while((skb = skb_peek(SREJ_QUEUE(sk)))) {
3413 if (bt_cb(skb)->tx_seq != tx_seq)
3414 break;
3415
3416 skb = skb_dequeue(SREJ_QUEUE(sk));
3417 control |= bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3418 l2cap_sar_reassembly_sdu(sk, skb, control);
3419 l2cap_pi(sk)->buffer_seq_srej =
3420 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
3421 tx_seq++;
3422 }
3423}
3424
3425static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3426{
3427 struct l2cap_pinfo *pi = l2cap_pi(sk);
3428 struct srej_list *l, *tmp;
3429 u16 control;
3430
3431 list_for_each_entry_safe(l,tmp, SREJ_LIST(sk), list) {
3432 if (l->tx_seq == tx_seq) {
3433 list_del(&l->list);
3434 kfree(l);
3435 return;
3436 }
3437 control = L2CAP_SUPER_SELECT_REJECT;
3438 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3439 l2cap_send_sframe(pi, control);
3440 list_del(&l->list);
3441 list_add_tail(&l->list, SREJ_LIST(sk));
3442 }
3443}
3444
3445static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3446{
3447 struct l2cap_pinfo *pi = l2cap_pi(sk);
3448 struct srej_list *new;
3449 u16 control;
3450
3451 while (tx_seq != pi->expected_tx_seq) {
3452 control = L2CAP_SUPER_SELECT_REJECT;
3453 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3454 l2cap_send_sframe(pi, control);
3455
3456 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
3457 new->tx_seq = pi->expected_tx_seq++;
3458 list_add_tail(&new->list, SREJ_LIST(sk));
3459 }
3460 pi->expected_tx_seq++;
3461}
3462
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003463static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3464{
3465 struct l2cap_pinfo *pi = l2cap_pi(sk);
3466 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003467 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003468 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003469 int err = 0;
3470
3471 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3472
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003473 if (L2CAP_CTRL_FINAL & rx_control) {
3474 del_timer(&pi->monitor_timer);
3475 if (pi->unacked_frames > 0)
3476 __mod_retrans_timer();
3477 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3478 }
3479
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003480 pi->expected_ack_seq = req_seq;
3481 l2cap_drop_acked_frames(sk);
3482
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003483 if (tx_seq == pi->expected_tx_seq)
3484 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003485
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003486 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3487 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003488
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003489 first = list_first_entry(SREJ_LIST(sk),
3490 struct srej_list, list);
3491 if (tx_seq == first->tx_seq) {
3492 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3493 l2cap_check_srej_gap(sk, tx_seq);
3494
3495 list_del(&first->list);
3496 kfree(first);
3497
3498 if (list_empty(SREJ_LIST(sk))) {
3499 pi->buffer_seq = pi->buffer_seq_srej;
3500 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666cc2010-05-01 16:15:40 -03003501 l2cap_send_ack(pi);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003502 }
3503 } else {
3504 struct srej_list *l;
3505 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3506
3507 list_for_each_entry(l, SREJ_LIST(sk), list) {
3508 if (l->tx_seq == tx_seq) {
3509 l2cap_resend_srejframe(sk, tx_seq);
3510 return 0;
3511 }
3512 }
3513 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003514 }
3515 } else {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003516 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003517
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003518 INIT_LIST_HEAD(SREJ_LIST(sk));
3519 pi->buffer_seq_srej = pi->buffer_seq;
3520
3521 __skb_queue_head_init(SREJ_QUEUE(sk));
3522 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3523
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003524 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3525
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003526 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003527 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003528 return 0;
3529
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003530expected:
3531 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3532
3533 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3534 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3535 return 0;
3536 }
3537
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003538 if (rx_control & L2CAP_CTRL_FINAL) {
3539 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3540 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3541 else {
3542 sk->sk_send_head = TX_QUEUE(sk)->next;
3543 pi->next_tx_seq = pi->expected_ack_seq;
3544 l2cap_ertm_send(sk);
3545 }
3546 }
3547
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003548 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3549
3550 err = l2cap_sar_reassembly_sdu(sk, skb, rx_control);
3551 if (err < 0)
3552 return err;
3553
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003554 __mod_ack_timer();
3555
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003556 pi->num_to_ack = (pi->num_to_ack + 1) % L2CAP_DEFAULT_NUM_TO_ACK;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003557 if (pi->num_to_ack == L2CAP_DEFAULT_NUM_TO_ACK - 1)
3558 l2cap_send_ack(pi);
3559
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003560 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003561}
3562
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003563static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003564{
3565 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003566
3567 pi->expected_ack_seq = __get_reqseq(rx_control);
3568 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003569
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003570 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003571 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3572 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3573 (pi->unacked_frames > 0))
3574 __mod_retrans_timer();
3575
3576 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3577 l2cap_send_srejtail(sk);
3578 } else {
3579 l2cap_send_i_or_rr_or_rnr(sk);
3580 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3581 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003582
3583 } else if (rx_control & L2CAP_CTRL_FINAL) {
3584 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003585
3586 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3587 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3588 else {
3589 sk->sk_send_head = TX_QUEUE(sk)->next;
3590 pi->next_tx_seq = pi->expected_ack_seq;
3591 l2cap_ertm_send(sk);
3592 }
3593
3594 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003595 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3596 (pi->unacked_frames > 0))
3597 __mod_retrans_timer();
3598
3599 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3600 if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
3601 l2cap_send_ack(pi);
3602 else
3603 l2cap_ertm_send(sk);
3604 }
3605}
3606
3607static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3608{
3609 struct l2cap_pinfo *pi = l2cap_pi(sk);
3610 u8 tx_seq = __get_reqseq(rx_control);
3611
3612 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3613
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03003614 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003615 l2cap_drop_acked_frames(sk);
3616
3617 if (rx_control & L2CAP_CTRL_FINAL) {
3618 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3619 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3620 else {
3621 sk->sk_send_head = TX_QUEUE(sk)->next;
3622 pi->next_tx_seq = pi->expected_ack_seq;
3623 l2cap_ertm_send(sk);
3624 }
3625 } else {
3626 sk->sk_send_head = TX_QUEUE(sk)->next;
3627 pi->next_tx_seq = pi->expected_ack_seq;
3628 l2cap_ertm_send(sk);
3629
3630 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3631 pi->srej_save_reqseq = tx_seq;
3632 pi->conn_state |= L2CAP_CONN_REJ_ACT;
3633 }
3634 }
3635}
3636static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
3637{
3638 struct l2cap_pinfo *pi = l2cap_pi(sk);
3639 u8 tx_seq = __get_reqseq(rx_control);
3640
3641 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3642
3643 if (rx_control & L2CAP_CTRL_POLL) {
3644 pi->expected_ack_seq = tx_seq;
3645 l2cap_drop_acked_frames(sk);
3646 l2cap_retransmit_frame(sk, tx_seq);
3647 l2cap_ertm_send(sk);
3648 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3649 pi->srej_save_reqseq = tx_seq;
3650 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3651 }
3652 } else if (rx_control & L2CAP_CTRL_FINAL) {
3653 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3654 pi->srej_save_reqseq == tx_seq)
3655 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
3656 else
3657 l2cap_retransmit_frame(sk, tx_seq);
3658 } else {
3659 l2cap_retransmit_frame(sk, tx_seq);
3660 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3661 pi->srej_save_reqseq = tx_seq;
3662 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3663 }
3664 }
3665}
3666
3667static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
3668{
3669 struct l2cap_pinfo *pi = l2cap_pi(sk);
3670 u8 tx_seq = __get_reqseq(rx_control);
3671
3672 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
3673 pi->expected_ack_seq = tx_seq;
3674 l2cap_drop_acked_frames(sk);
3675
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003676 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
3677 del_timer(&pi->retrans_timer);
3678 if (rx_control & L2CAP_CTRL_POLL) {
3679 u16 control = L2CAP_CTRL_FINAL;
3680 l2cap_send_rr_or_rnr(pi, control);
3681 }
3682 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003683 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003684
3685 if (rx_control & L2CAP_CTRL_POLL)
3686 l2cap_send_srejtail(sk);
3687 else
3688 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003689}
3690
3691static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3692{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003693 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3694
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003695 if (L2CAP_CTRL_FINAL & rx_control) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003696 del_timer(&l2cap_pi(sk)->monitor_timer);
3697 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003698 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003699 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003700 }
3701
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003702 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
3703 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003704 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003705 break;
3706
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003707 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003708 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003709 break;
3710
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003711 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003712 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003713 break;
3714
3715 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003716 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003717 break;
3718 }
3719
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03003720 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003721 return 0;
3722}
3723
Linus Torvalds1da177e2005-04-16 15:20:36 -07003724static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
3725{
3726 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003727 struct l2cap_pinfo *pi;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003728 u16 control, len;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003729 u8 tx_seq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003730
3731 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3732 if (!sk) {
3733 BT_DBG("unknown cid 0x%4.4x", cid);
3734 goto drop;
3735 }
3736
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003737 pi = l2cap_pi(sk);
3738
Linus Torvalds1da177e2005-04-16 15:20:36 -07003739 BT_DBG("sk %p, len %d", sk, skb->len);
3740
3741 if (sk->sk_state != BT_CONNECTED)
3742 goto drop;
3743
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003744 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003745 case L2CAP_MODE_BASIC:
3746 /* If socket recv buffers overflows we drop data here
3747 * which is *bad* because L2CAP has to be reliable.
3748 * But we don't have any other choice. L2CAP doesn't
3749 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003750
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003751 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003752 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003753
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003754 if (!sock_queue_rcv_skb(sk, skb))
3755 goto done;
3756 break;
3757
3758 case L2CAP_MODE_ERTM:
3759 control = get_unaligned_le16(skb->data);
3760 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003761 len = skb->len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003762
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003763 if (__is_sar_start(control))
3764 len -= 2;
3765
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003766 if (pi->fcs == L2CAP_FCS_CRC16)
3767 len -= 2;
3768
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003769 /*
3770 * We can just drop the corrupted I-frame here.
3771 * Receiver will miss it and start proper recovery
3772 * procedures and ask retransmission.
3773 */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03003774 if (len > pi->mps)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003775 goto drop;
3776
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003777 if (l2cap_check_fcs(pi, skb))
3778 goto drop;
3779
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003780 if (__is_iframe(control)) {
3781 if (len < 4)
3782 goto drop;
3783
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003784 l2cap_data_channel_iframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003785 } else {
3786 if (len != 0)
3787 goto drop;
3788
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003789 l2cap_data_channel_sframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003790 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003791
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003792 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003793
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003794 case L2CAP_MODE_STREAMING:
3795 control = get_unaligned_le16(skb->data);
3796 skb_pull(skb, 2);
3797 len = skb->len;
3798
3799 if (__is_sar_start(control))
3800 len -= 2;
3801
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003802 if (pi->fcs == L2CAP_FCS_CRC16)
3803 len -= 2;
3804
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03003805 if (len > pi->mps || len < 4 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003806 goto drop;
3807
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003808 if (l2cap_check_fcs(pi, skb))
3809 goto drop;
3810
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003811 tx_seq = __get_txseq(control);
3812
3813 if (pi->expected_tx_seq == tx_seq)
3814 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3815 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03003816 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003817
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003818 l2cap_sar_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003819
3820 goto done;
3821
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003822 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03003823 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003824 break;
3825 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003826
3827drop:
3828 kfree_skb(skb);
3829
3830done:
Marcel Holtmann01394182006-07-03 10:02:46 +02003831 if (sk)
3832 bh_unlock_sock(sk);
3833
Linus Torvalds1da177e2005-04-16 15:20:36 -07003834 return 0;
3835}
3836
Al Viro8e036fc2007-07-29 00:16:36 -07003837static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003838{
3839 struct sock *sk;
3840
3841 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
3842 if (!sk)
3843 goto drop;
3844
3845 BT_DBG("sk %p, len %d", sk, skb->len);
3846
3847 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
3848 goto drop;
3849
3850 if (l2cap_pi(sk)->imtu < skb->len)
3851 goto drop;
3852
3853 if (!sock_queue_rcv_skb(sk, skb))
3854 goto done;
3855
3856drop:
3857 kfree_skb(skb);
3858
3859done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003860 if (sk)
3861 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003862 return 0;
3863}
3864
3865static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
3866{
3867 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07003868 u16 cid, len;
3869 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003870
3871 skb_pull(skb, L2CAP_HDR_SIZE);
3872 cid = __le16_to_cpu(lh->cid);
3873 len = __le16_to_cpu(lh->len);
3874
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003875 if (len != skb->len) {
3876 kfree_skb(skb);
3877 return;
3878 }
3879
Linus Torvalds1da177e2005-04-16 15:20:36 -07003880 BT_DBG("len %d, cid 0x%4.4x", len, cid);
3881
3882 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003883 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003884 l2cap_sig_channel(conn, skb);
3885 break;
3886
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003887 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003888 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003889 skb_pull(skb, 2);
3890 l2cap_conless_channel(conn, psm, skb);
3891 break;
3892
3893 default:
3894 l2cap_data_channel(conn, cid, skb);
3895 break;
3896 }
3897}
3898
3899/* ---- L2CAP interface with lower layer (HCI) ---- */
3900
3901static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3902{
3903 int exact = 0, lm1 = 0, lm2 = 0;
3904 register struct sock *sk;
3905 struct hlist_node *node;
3906
3907 if (type != ACL_LINK)
3908 return 0;
3909
3910 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
3911
3912 /* Find listening sockets and check their link_mode */
3913 read_lock(&l2cap_sk_list.lock);
3914 sk_for_each(sk, node, &l2cap_sk_list.head) {
3915 if (sk->sk_state != BT_LISTEN)
3916 continue;
3917
3918 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003919 lm1 |= HCI_LM_ACCEPT;
3920 if (l2cap_pi(sk)->role_switch)
3921 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003922 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003923 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
3924 lm2 |= HCI_LM_ACCEPT;
3925 if (l2cap_pi(sk)->role_switch)
3926 lm2 |= HCI_LM_MASTER;
3927 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003928 }
3929 read_unlock(&l2cap_sk_list.lock);
3930
3931 return exact ? lm1 : lm2;
3932}
3933
3934static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
3935{
Marcel Holtmann01394182006-07-03 10:02:46 +02003936 struct l2cap_conn *conn;
3937
Linus Torvalds1da177e2005-04-16 15:20:36 -07003938 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
3939
3940 if (hcon->type != ACL_LINK)
3941 return 0;
3942
3943 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003944 conn = l2cap_conn_add(hcon, status);
3945 if (conn)
3946 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02003947 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003948 l2cap_conn_del(hcon, bt_err(status));
3949
3950 return 0;
3951}
3952
Marcel Holtmann2950f212009-02-12 14:02:50 +01003953static int l2cap_disconn_ind(struct hci_conn *hcon)
3954{
3955 struct l2cap_conn *conn = hcon->l2cap_data;
3956
3957 BT_DBG("hcon %p", hcon);
3958
3959 if (hcon->type != ACL_LINK || !conn)
3960 return 0x13;
3961
3962 return conn->disc_reason;
3963}
3964
3965static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003966{
3967 BT_DBG("hcon %p reason %d", hcon, reason);
3968
3969 if (hcon->type != ACL_LINK)
3970 return 0;
3971
3972 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02003973
Linus Torvalds1da177e2005-04-16 15:20:36 -07003974 return 0;
3975}
3976
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003977static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
3978{
Marcel Holtmann255c7602009-02-04 21:07:19 +01003979 if (sk->sk_type != SOCK_SEQPACKET)
3980 return;
3981
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003982 if (encrypt == 0x00) {
3983 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
3984 l2cap_sock_clear_timer(sk);
3985 l2cap_sock_set_timer(sk, HZ * 5);
3986 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
3987 __l2cap_sock_close(sk, ECONNREFUSED);
3988 } else {
3989 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
3990 l2cap_sock_clear_timer(sk);
3991 }
3992}
3993
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003994static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003995{
3996 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02003997 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003998 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003999
Marcel Holtmann01394182006-07-03 10:02:46 +02004000 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004001 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004002
Linus Torvalds1da177e2005-04-16 15:20:36 -07004003 l = &conn->chan_list;
4004
4005 BT_DBG("conn %p", conn);
4006
4007 read_lock(&l->lock);
4008
4009 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4010 bh_lock_sock(sk);
4011
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004012 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4013 bh_unlock_sock(sk);
4014 continue;
4015 }
4016
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004017 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004018 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004019 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004020 bh_unlock_sock(sk);
4021 continue;
4022 }
4023
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004024 if (sk->sk_state == BT_CONNECT) {
4025 if (!status) {
4026 struct l2cap_conn_req req;
4027 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4028 req.psm = l2cap_pi(sk)->psm;
4029
4030 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
4031
4032 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4033 L2CAP_CONN_REQ, sizeof(req), &req);
4034 } else {
4035 l2cap_sock_clear_timer(sk);
4036 l2cap_sock_set_timer(sk, HZ / 10);
4037 }
4038 } else if (sk->sk_state == BT_CONNECT2) {
4039 struct l2cap_conn_rsp rsp;
4040 __u16 result;
4041
4042 if (!status) {
4043 sk->sk_state = BT_CONFIG;
4044 result = L2CAP_CR_SUCCESS;
4045 } else {
4046 sk->sk_state = BT_DISCONN;
4047 l2cap_sock_set_timer(sk, HZ / 10);
4048 result = L2CAP_CR_SEC_BLOCK;
4049 }
4050
4051 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4052 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4053 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004054 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004055 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4056 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004057 }
4058
Linus Torvalds1da177e2005-04-16 15:20:36 -07004059 bh_unlock_sock(sk);
4060 }
4061
4062 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004063
Linus Torvalds1da177e2005-04-16 15:20:36 -07004064 return 0;
4065}
4066
4067static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4068{
4069 struct l2cap_conn *conn = hcon->l2cap_data;
4070
4071 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4072 goto drop;
4073
4074 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4075
4076 if (flags & ACL_START) {
4077 struct l2cap_hdr *hdr;
4078 int len;
4079
4080 if (conn->rx_len) {
4081 BT_ERR("Unexpected start frame (len %d)", skb->len);
4082 kfree_skb(conn->rx_skb);
4083 conn->rx_skb = NULL;
4084 conn->rx_len = 0;
4085 l2cap_conn_unreliable(conn, ECOMM);
4086 }
4087
4088 if (skb->len < 2) {
4089 BT_ERR("Frame is too short (len %d)", skb->len);
4090 l2cap_conn_unreliable(conn, ECOMM);
4091 goto drop;
4092 }
4093
4094 hdr = (struct l2cap_hdr *) skb->data;
4095 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4096
4097 if (len == skb->len) {
4098 /* Complete frame received */
4099 l2cap_recv_frame(conn, skb);
4100 return 0;
4101 }
4102
4103 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4104
4105 if (skb->len > len) {
4106 BT_ERR("Frame is too long (len %d, expected len %d)",
4107 skb->len, len);
4108 l2cap_conn_unreliable(conn, ECOMM);
4109 goto drop;
4110 }
4111
4112 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004113 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4114 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004115 goto drop;
4116
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004117 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004118 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004119 conn->rx_len = len - skb->len;
4120 } else {
4121 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4122
4123 if (!conn->rx_len) {
4124 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4125 l2cap_conn_unreliable(conn, ECOMM);
4126 goto drop;
4127 }
4128
4129 if (skb->len > conn->rx_len) {
4130 BT_ERR("Fragment is too long (len %d, expected %d)",
4131 skb->len, conn->rx_len);
4132 kfree_skb(conn->rx_skb);
4133 conn->rx_skb = NULL;
4134 conn->rx_len = 0;
4135 l2cap_conn_unreliable(conn, ECOMM);
4136 goto drop;
4137 }
4138
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004139 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004140 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004141 conn->rx_len -= skb->len;
4142
4143 if (!conn->rx_len) {
4144 /* Complete frame received */
4145 l2cap_recv_frame(conn, conn->rx_skb);
4146 conn->rx_skb = NULL;
4147 }
4148 }
4149
4150drop:
4151 kfree_skb(skb);
4152 return 0;
4153}
4154
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004155static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004156{
4157 struct sock *sk;
4158 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004159
4160 read_lock_bh(&l2cap_sk_list.lock);
4161
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004162 sk_for_each(sk, node, &l2cap_sk_list.head) {
4163 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004164
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004165 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4166 batostr(&bt_sk(sk)->src),
4167 batostr(&bt_sk(sk)->dst),
4168 sk->sk_state, __le16_to_cpu(pi->psm),
4169 pi->scid, pi->dcid,
4170 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004171 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004172
Linus Torvalds1da177e2005-04-16 15:20:36 -07004173 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004174
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004175 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004176}
4177
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004178static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4179{
4180 return single_open(file, l2cap_debugfs_show, inode->i_private);
4181}
4182
4183static const struct file_operations l2cap_debugfs_fops = {
4184 .open = l2cap_debugfs_open,
4185 .read = seq_read,
4186 .llseek = seq_lseek,
4187 .release = single_release,
4188};
4189
4190static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004191
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004192static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004193 .family = PF_BLUETOOTH,
4194 .owner = THIS_MODULE,
4195 .release = l2cap_sock_release,
4196 .bind = l2cap_sock_bind,
4197 .connect = l2cap_sock_connect,
4198 .listen = l2cap_sock_listen,
4199 .accept = l2cap_sock_accept,
4200 .getname = l2cap_sock_getname,
4201 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004202 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004203 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004204 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004205 .mmap = sock_no_mmap,
4206 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004207 .shutdown = l2cap_sock_shutdown,
4208 .setsockopt = l2cap_sock_setsockopt,
4209 .getsockopt = l2cap_sock_getsockopt
4210};
4211
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004212static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004213 .family = PF_BLUETOOTH,
4214 .owner = THIS_MODULE,
4215 .create = l2cap_sock_create,
4216};
4217
4218static struct hci_proto l2cap_hci_proto = {
4219 .name = "L2CAP",
4220 .id = HCI_PROTO_L2CAP,
4221 .connect_ind = l2cap_connect_ind,
4222 .connect_cfm = l2cap_connect_cfm,
4223 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004224 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004225 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004226 .recv_acldata = l2cap_recv_acldata
4227};
4228
4229static int __init l2cap_init(void)
4230{
4231 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004232
Linus Torvalds1da177e2005-04-16 15:20:36 -07004233 err = proto_register(&l2cap_proto, 0);
4234 if (err < 0)
4235 return err;
4236
4237 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4238 if (err < 0) {
4239 BT_ERR("L2CAP socket registration failed");
4240 goto error;
4241 }
4242
4243 err = hci_register_proto(&l2cap_hci_proto);
4244 if (err < 0) {
4245 BT_ERR("L2CAP protocol registration failed");
4246 bt_sock_unregister(BTPROTO_L2CAP);
4247 goto error;
4248 }
4249
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004250 if (bt_debugfs) {
4251 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4252 bt_debugfs, NULL, &l2cap_debugfs_fops);
4253 if (!l2cap_debugfs)
4254 BT_ERR("Failed to create L2CAP debug file");
4255 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004256
4257 BT_INFO("L2CAP ver %s", VERSION);
4258 BT_INFO("L2CAP socket layer initialized");
4259
4260 return 0;
4261
4262error:
4263 proto_unregister(&l2cap_proto);
4264 return err;
4265}
4266
4267static void __exit l2cap_exit(void)
4268{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004269 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004270
4271 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4272 BT_ERR("L2CAP socket unregistration failed");
4273
4274 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4275 BT_ERR("L2CAP protocol unregistration failed");
4276
4277 proto_unregister(&l2cap_proto);
4278}
4279
4280void l2cap_load(void)
4281{
4282 /* Dummy function to trigger automatic L2CAP module loading by
4283 * other modules that use L2CAP sockets but don't use any other
4284 * symbols from it. */
4285 return;
4286}
4287EXPORT_SYMBOL(l2cap_load);
4288
4289module_init(l2cap_init);
4290module_exit(l2cap_exit);
4291
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004292module_param(enable_ertm, bool, 0644);
4293MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4294
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +02004295module_param(max_transmit, uint, 0644);
4296MODULE_PARM_DESC(max_transmit, "Max transmit value (default = 3)");
4297
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004298MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004299MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4300MODULE_VERSION(VERSION);
4301MODULE_LICENSE("GPL");
4302MODULE_ALIAS("bt-proto-0");