blob: 675614e38e149c7d28d13903763b966b3c37e5f8 [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
Gustavo F. Padovance5706b2010-07-13 11:57:11 -03004 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
Gustavo F. Padovan5d8868f2010-07-16 16:18:39 -03005 Copyright (C) 2010 Google Inc.
Linus Torvalds1da177e2005-04-16 15:20:36 -07006
7 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License version 2 as
11 published by the Free Software Foundation;
12
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
16 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090017 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
18 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070020 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090022 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
23 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070024 SOFTWARE IS DISCLAIMED.
25*/
26
27/* Bluetooth L2CAP core and sockets. */
28
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#include <linux/module.h>
30
31#include <linux/types.h>
Randy Dunlap4fc268d2006-01-11 12:17:47 -080032#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/errno.h>
34#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035#include <linux/sched.h>
36#include <linux/slab.h>
37#include <linux/poll.h>
38#include <linux/fcntl.h>
39#include <linux/init.h>
40#include <linux/interrupt.h>
41#include <linux/socket.h>
42#include <linux/skbuff.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#include <linux/list.h>
Marcel Holtmannbe9d1222005-11-08 09:57:38 -080044#include <linux/device.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010045#include <linux/debugfs.h>
46#include <linux/seq_file.h>
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -030047#include <linux/uaccess.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030048#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070049#include <net/sock.h>
50
51#include <asm/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070052#include <asm/unaligned.h>
53
54#include <net/bluetooth/bluetooth.h>
55#include <net/bluetooth/hci_core.h>
56#include <net/bluetooth/l2cap.h>
57
Gustavo F. Padovandd135242010-07-13 11:57:12 -030058#define VERSION "2.15"
Marcel Holtmann44dd46d2009-05-02 19:09:01 -070059
Andrei Emeltchenko894718a2010-12-01 16:58:24 +020060static int disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020061
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070062static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Marcel Holtmanne1027a72009-02-09 09:18:02 +010063static u8 l2cap_fixed_chan[8] = { 0x02, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070064
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080065static const struct proto_ops l2cap_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070066
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030067static struct workqueue_struct *_busy_wq;
68
Linus Torvalds1da177e2005-04-16 15:20:36 -070069static struct bt_sock_list l2cap_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070070 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070071};
72
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030073static void l2cap_busy_work(struct work_struct *work);
74
Linus Torvalds1da177e2005-04-16 15:20:36 -070075static void __l2cap_sock_close(struct sock *sk, int reason);
76static void l2cap_sock_close(struct sock *sk);
77static void l2cap_sock_kill(struct sock *sk);
78
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -030079static int l2cap_build_conf_req(struct sock *sk, void *data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070080static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
81 u8 code, u8 ident, u16 dlen, void *data);
82
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -030083static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
84
Linus Torvalds1da177e2005-04-16 15:20:36 -070085/* ---- L2CAP timers ---- */
Andrei Emeltchenko940a9ee2010-11-03 12:32:45 +020086static void l2cap_sock_set_timer(struct sock *sk, long timeout)
87{
88 BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
89 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
90}
91
92static void l2cap_sock_clear_timer(struct sock *sk)
93{
94 BT_DBG("sock %p state %d", sk, sk->sk_state);
95 sk_stop_timer(sk, &sk->sk_timer);
96}
97
Linus Torvalds1da177e2005-04-16 15:20:36 -070098static void l2cap_sock_timeout(unsigned long arg)
99{
100 struct sock *sk = (struct sock *) arg;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200101 int reason;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
103 BT_DBG("sock %p state %d", sk, sk->sk_state);
104
105 bh_lock_sock(sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200106
Andrei Emeltchenko940a9ee2010-11-03 12:32:45 +0200107 if (sock_owned_by_user(sk)) {
108 /* sk is owned by user. Try again later */
109 l2cap_sock_set_timer(sk, HZ / 5);
110 bh_unlock_sock(sk);
111 sock_put(sk);
112 return;
113 }
114
Marcel Holtmannf62e4322009-01-15 21:58:44 +0100115 if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
116 reason = ECONNREFUSED;
117 else if (sk->sk_state == BT_CONNECT &&
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100118 l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200119 reason = ECONNREFUSED;
120 else
121 reason = ETIMEDOUT;
122
123 __l2cap_sock_close(sk, reason);
124
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125 bh_unlock_sock(sk);
126
127 l2cap_sock_kill(sk);
128 sock_put(sk);
129}
130
Marcel Holtmann01394182006-07-03 10:02:46 +0200131/* ---- L2CAP channels ---- */
132static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
133{
134 struct sock *s;
135 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
136 if (l2cap_pi(s)->dcid == cid)
137 break;
138 }
139 return s;
140}
141
142static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
143{
144 struct sock *s;
145 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
146 if (l2cap_pi(s)->scid == cid)
147 break;
148 }
149 return s;
150}
151
152/* Find channel with given SCID.
153 * Returns locked socket */
154static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
155{
156 struct sock *s;
157 read_lock(&l->lock);
158 s = __l2cap_get_chan_by_scid(l, cid);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300159 if (s)
160 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200161 read_unlock(&l->lock);
162 return s;
163}
164
165static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
166{
167 struct sock *s;
168 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
169 if (l2cap_pi(s)->ident == ident)
170 break;
171 }
172 return s;
173}
174
175static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
176{
177 struct sock *s;
178 read_lock(&l->lock);
179 s = __l2cap_get_chan_by_ident(l, ident);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300180 if (s)
181 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200182 read_unlock(&l->lock);
183 return s;
184}
185
186static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
187{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300188 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200189
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300190 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300191 if (!__l2cap_get_chan_by_scid(l, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200192 return cid;
193 }
194
195 return 0;
196}
197
198static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
199{
200 sock_hold(sk);
201
202 if (l->head)
203 l2cap_pi(l->head)->prev_c = sk;
204
205 l2cap_pi(sk)->next_c = l->head;
206 l2cap_pi(sk)->prev_c = NULL;
207 l->head = sk;
208}
209
210static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
211{
212 struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
213
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200214 write_lock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200215 if (sk == l->head)
216 l->head = next;
217
218 if (next)
219 l2cap_pi(next)->prev_c = prev;
220 if (prev)
221 l2cap_pi(prev)->next_c = next;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200222 write_unlock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200223
224 __sock_put(sk);
225}
226
227static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
228{
229 struct l2cap_chan_list *l = &conn->chan_list;
230
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300231 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
232 l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200233
Marcel Holtmann2950f212009-02-12 14:02:50 +0100234 conn->disc_reason = 0x13;
235
Marcel Holtmann01394182006-07-03 10:02:46 +0200236 l2cap_pi(sk)->conn = conn;
237
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300238 if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200239 /* Alloc CID for connection-oriented socket */
240 l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
241 } else if (sk->sk_type == SOCK_DGRAM) {
242 /* Connectionless socket */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300243 l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
244 l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
Marcel Holtmann01394182006-07-03 10:02:46 +0200245 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
246 } else {
247 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300248 l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
249 l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
Marcel Holtmann01394182006-07-03 10:02:46 +0200250 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
251 }
252
253 __l2cap_chan_link(l, sk);
254
255 if (parent)
256 bt_accept_enqueue(parent, sk);
257}
258
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900259/* Delete channel.
Marcel Holtmann01394182006-07-03 10:02:46 +0200260 * Must be called on the locked socket. */
261static void l2cap_chan_del(struct sock *sk, int err)
262{
263 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
264 struct sock *parent = bt_sk(sk)->parent;
265
266 l2cap_sock_clear_timer(sk);
267
268 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
269
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900270 if (conn) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200271 /* Unlink from channel list */
272 l2cap_chan_unlink(&conn->chan_list, sk);
273 l2cap_pi(sk)->conn = NULL;
274 hci_conn_put(conn->hcon);
275 }
276
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200277 sk->sk_state = BT_CLOSED;
Marcel Holtmann01394182006-07-03 10:02:46 +0200278 sock_set_flag(sk, SOCK_ZAPPED);
279
280 if (err)
281 sk->sk_err = err;
282
283 if (parent) {
284 bt_accept_unlink(sk);
285 parent->sk_data_ready(parent, 0);
286 } else
287 sk->sk_state_change(sk);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300288
289 skb_queue_purge(TX_QUEUE(sk));
290
291 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
292 struct srej_list *l, *tmp;
293
294 del_timer(&l2cap_pi(sk)->retrans_timer);
295 del_timer(&l2cap_pi(sk)->monitor_timer);
296 del_timer(&l2cap_pi(sk)->ack_timer);
297
298 skb_queue_purge(SREJ_QUEUE(sk));
299 skb_queue_purge(BUSY_QUEUE(sk));
300
301 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
302 list_del(&l->list);
303 kfree(l);
304 }
305 }
Marcel Holtmann01394182006-07-03 10:02:46 +0200306}
307
Johan Hedberg8556edd32011-01-19 12:06:50 +0530308static inline u8 l2cap_get_auth_type(struct sock *sk)
309{
310 if (sk->sk_type == SOCK_RAW) {
311 switch (l2cap_pi(sk)->sec_level) {
312 case BT_SECURITY_HIGH:
313 return HCI_AT_DEDICATED_BONDING_MITM;
314 case BT_SECURITY_MEDIUM:
315 return HCI_AT_DEDICATED_BONDING;
316 default:
317 return HCI_AT_NO_BONDING;
318 }
319 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
320 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
321 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
322
323 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
324 return HCI_AT_NO_BONDING_MITM;
325 else
326 return HCI_AT_NO_BONDING;
327 } else {
328 switch (l2cap_pi(sk)->sec_level) {
329 case BT_SECURITY_HIGH:
330 return HCI_AT_GENERAL_BONDING_MITM;
331 case BT_SECURITY_MEDIUM:
332 return HCI_AT_GENERAL_BONDING;
333 default:
334 return HCI_AT_NO_BONDING;
335 }
336 }
337}
338
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200339/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100340static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200341{
342 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100343 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200344
Johan Hedberg8556edd32011-01-19 12:06:50 +0530345 auth_type = l2cap_get_auth_type(sk);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100346
347 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
348 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200349}
350
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200351static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
352{
353 u8 id;
354
355 /* Get next available identificator.
356 * 1 - 128 are used by kernel.
357 * 129 - 199 are reserved.
358 * 200 - 254 are used by utilities like l2ping, etc.
359 */
360
361 spin_lock_bh(&conn->lock);
362
363 if (++conn->tx_ident > 128)
364 conn->tx_ident = 1;
365
366 id = conn->tx_ident;
367
368 spin_unlock_bh(&conn->lock);
369
370 return id;
371}
372
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300373static inline void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200374{
375 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
376
377 BT_DBG("code 0x%2.2x", code);
378
379 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300380 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200381
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300382 hci_send_acl(conn->hcon, skb, 0);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200383}
384
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300385static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300386{
387 struct sk_buff *skb;
388 struct l2cap_hdr *lh;
389 struct l2cap_conn *conn = pi->conn;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300390 struct sock *sk = (struct sock *)pi;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300391 int count, hlen = L2CAP_HDR_SIZE + 2;
392
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300393 if (sk->sk_state != BT_CONNECTED)
394 return;
395
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300396 if (pi->fcs == L2CAP_FCS_CRC16)
397 hlen += 2;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300398
399 BT_DBG("pi %p, control 0x%2.2x", pi, control);
400
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300401 count = min_t(unsigned int, conn->mtu, hlen);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300402 control |= L2CAP_CTRL_FRAME_TYPE;
403
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -0300404 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
405 control |= L2CAP_CTRL_FINAL;
406 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
407 }
408
Gustavo F. Padovanf0946cc2010-05-01 16:15:37 -0300409 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
410 control |= L2CAP_CTRL_POLL;
411 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
412 }
413
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300414 skb = bt_skb_alloc(count, GFP_ATOMIC);
415 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300416 return;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300417
418 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300419 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300420 lh->cid = cpu_to_le16(pi->dcid);
421 put_unaligned_le16(control, skb_put(skb, 2));
422
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300423 if (pi->fcs == L2CAP_FCS_CRC16) {
424 u16 fcs = crc16(0, (u8 *)lh, count - 2);
425 put_unaligned_le16(fcs, skb_put(skb, 2));
426 }
427
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300428 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300429}
430
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300431static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300432{
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300433 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300434 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300435 pi->conn_state |= L2CAP_CONN_RNR_SENT;
436 } else
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300437 control |= L2CAP_SUPER_RCV_READY;
438
Gustavo F. Padovan2ab25cd2009-10-03 02:34:40 -0300439 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
440
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300441 l2cap_send_sframe(pi, control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300442}
443
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300444static inline int __l2cap_no_conn_pending(struct sock *sk)
445{
446 return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND);
447}
448
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200449static void l2cap_do_start(struct sock *sk)
450{
451 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
452
453 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100454 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
455 return;
456
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300457 if (l2cap_check_security(sk) && __l2cap_no_conn_pending(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200458 struct l2cap_conn_req req;
459 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
460 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200461
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200462 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300463 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200464
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200465 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200466 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200467 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200468 } else {
469 struct l2cap_info_req req;
470 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
471
472 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
473 conn->info_ident = l2cap_get_ident(conn);
474
475 mod_timer(&conn->info_timer, jiffies +
476 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
477
478 l2cap_send_cmd(conn, conn->info_ident,
479 L2CAP_INFO_REQ, sizeof(req), &req);
480 }
481}
482
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300483static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
484{
485 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -0300486 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300487 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
488
489 switch (mode) {
490 case L2CAP_MODE_ERTM:
491 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
492 case L2CAP_MODE_STREAMING:
493 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
494 default:
495 return 0x00;
496 }
497}
498
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300499static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300500{
501 struct l2cap_disconn_req req;
502
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300503 if (!conn)
504 return;
505
506 skb_queue_purge(TX_QUEUE(sk));
507
508 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
509 del_timer(&l2cap_pi(sk)->retrans_timer);
510 del_timer(&l2cap_pi(sk)->monitor_timer);
511 del_timer(&l2cap_pi(sk)->ack_timer);
512 }
513
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300514 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
515 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
516 l2cap_send_cmd(conn, l2cap_get_ident(conn),
517 L2CAP_DISCONN_REQ, sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300518
519 sk->sk_state = BT_DISCONN;
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300520 sk->sk_err = err;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300521}
522
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200524static void l2cap_conn_start(struct l2cap_conn *conn)
525{
526 struct l2cap_chan_list *l = &conn->chan_list;
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300527 struct sock_del_list del, *tmp1, *tmp2;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200528 struct sock *sk;
529
530 BT_DBG("conn %p", conn);
531
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300532 INIT_LIST_HEAD(&del.list);
533
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200534 read_lock(&l->lock);
535
536 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
537 bh_lock_sock(sk);
538
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300539 if (sk->sk_type != SOCK_SEQPACKET &&
540 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200541 bh_unlock_sock(sk);
542 continue;
543 }
544
545 if (sk->sk_state == BT_CONNECT) {
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300546 struct l2cap_conn_req req;
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300547
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300548 if (!l2cap_check_security(sk) ||
549 !__l2cap_no_conn_pending(sk)) {
550 bh_unlock_sock(sk);
551 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200552 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300553
554 if (!l2cap_mode_supported(l2cap_pi(sk)->mode,
555 conn->feat_mask)
556 && l2cap_pi(sk)->conf_state &
557 L2CAP_CONF_STATE2_DEVICE) {
558 tmp1 = kzalloc(sizeof(struct sock_del_list),
559 GFP_ATOMIC);
560 tmp1->sk = sk;
561 list_add_tail(&tmp1->list, &del.list);
562 bh_unlock_sock(sk);
563 continue;
564 }
565
566 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
567 req.psm = l2cap_pi(sk)->psm;
568
569 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
570 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
571
572 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
573 L2CAP_CONN_REQ, sizeof(req), &req);
574
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200575 } else if (sk->sk_state == BT_CONNECT2) {
576 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -0300577 char buf[128];
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200578 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
579 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
580
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100581 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100582 if (bt_sk(sk)->defer_setup) {
583 struct sock *parent = bt_sk(sk)->parent;
584 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
585 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
586 parent->sk_data_ready(parent, 0);
587
588 } else {
589 sk->sk_state = BT_CONFIG;
590 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
591 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
592 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200593 } else {
594 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
595 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
596 }
597
598 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
599 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -0300600
601 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT ||
602 rsp.result != L2CAP_CR_SUCCESS) {
603 bh_unlock_sock(sk);
604 continue;
605 }
606
607 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
608 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
609 l2cap_build_conf_req(sk, buf), buf);
610 l2cap_pi(sk)->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200611 }
612
613 bh_unlock_sock(sk);
614 }
615
616 read_unlock(&l->lock);
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300617
618 list_for_each_entry_safe(tmp1, tmp2, &del.list, list) {
619 bh_lock_sock(tmp1->sk);
620 __l2cap_sock_close(tmp1->sk, ECONNRESET);
621 bh_unlock_sock(tmp1->sk);
622 list_del(&tmp1->list);
623 kfree(tmp1);
624 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200625}
626
627static void l2cap_conn_ready(struct l2cap_conn *conn)
628{
629 struct l2cap_chan_list *l = &conn->chan_list;
630 struct sock *sk;
631
632 BT_DBG("conn %p", conn);
633
634 read_lock(&l->lock);
635
636 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
637 bh_lock_sock(sk);
638
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300639 if (sk->sk_type != SOCK_SEQPACKET &&
640 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200641 l2cap_sock_clear_timer(sk);
642 sk->sk_state = BT_CONNECTED;
643 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200644 } else if (sk->sk_state == BT_CONNECT)
645 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200646
647 bh_unlock_sock(sk);
648 }
649
650 read_unlock(&l->lock);
651}
652
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200653/* Notify sockets that we cannot guaranty reliability anymore */
654static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
655{
656 struct l2cap_chan_list *l = &conn->chan_list;
657 struct sock *sk;
658
659 BT_DBG("conn %p", conn);
660
661 read_lock(&l->lock);
662
663 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100664 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200665 sk->sk_err = err;
666 }
667
668 read_unlock(&l->lock);
669}
670
671static void l2cap_info_timeout(unsigned long arg)
672{
673 struct l2cap_conn *conn = (void *) arg;
674
Marcel Holtmann984947d2009-02-06 23:35:19 +0100675 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100676 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100677
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200678 l2cap_conn_start(conn);
679}
680
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
682{
Marcel Holtmann01394182006-07-03 10:02:46 +0200683 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684
Marcel Holtmann01394182006-07-03 10:02:46 +0200685 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 return conn;
687
Marcel Holtmann01394182006-07-03 10:02:46 +0200688 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
689 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691
692 hcon->l2cap_data = conn;
693 conn->hcon = hcon;
694
Marcel Holtmann01394182006-07-03 10:02:46 +0200695 BT_DBG("hcon %p conn %p", hcon, conn);
696
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697 conn->mtu = hcon->hdev->acl_mtu;
698 conn->src = &hcon->hdev->bdaddr;
699 conn->dst = &hcon->dst;
700
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200701 conn->feat_mask = 0;
702
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703 spin_lock_init(&conn->lock);
704 rwlock_init(&conn->chan_list.lock);
705
Dave Young45054dc2009-10-18 20:28:30 +0000706 setup_timer(&conn->info_timer, l2cap_info_timeout,
707 (unsigned long) conn);
708
Marcel Holtmann2950f212009-02-12 14:02:50 +0100709 conn->disc_reason = 0x13;
710
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711 return conn;
712}
713
Marcel Holtmann01394182006-07-03 10:02:46 +0200714static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715{
Marcel Holtmann01394182006-07-03 10:02:46 +0200716 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 struct sock *sk;
718
Marcel Holtmann01394182006-07-03 10:02:46 +0200719 if (!conn)
720 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721
722 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
723
Wei Yongjun7585b972009-02-25 18:29:52 +0800724 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725
726 /* Kill channels */
727 while ((sk = conn->chan_list.head)) {
728 bh_lock_sock(sk);
729 l2cap_chan_del(sk, err);
730 bh_unlock_sock(sk);
731 l2cap_sock_kill(sk);
732 }
733
Dave Young8e8440f2008-03-03 12:18:55 -0800734 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
735 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800736
Linus Torvalds1da177e2005-04-16 15:20:36 -0700737 hcon->l2cap_data = NULL;
738 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739}
740
741static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
742{
743 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200744 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200746 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747}
748
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700750static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751{
752 struct sock *sk;
753 struct hlist_node *node;
754 sk_for_each(sk, node, &l2cap_sk_list.head)
755 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
756 goto found;
757 sk = NULL;
758found:
759 return sk;
760}
761
762/* Find socket with psm and source bdaddr.
763 * Returns closest match.
764 */
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +0000765static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766{
767 struct sock *sk = NULL, *sk1 = NULL;
768 struct hlist_node *node;
769
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +0000770 read_lock(&l2cap_sk_list.lock);
771
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772 sk_for_each(sk, node, &l2cap_sk_list.head) {
773 if (state && sk->sk_state != state)
774 continue;
775
776 if (l2cap_pi(sk)->psm == psm) {
777 /* Exact match. */
778 if (!bacmp(&bt_sk(sk)->src, src))
779 break;
780
781 /* Closest match */
782 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
783 sk1 = sk;
784 }
785 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787 read_unlock(&l2cap_sk_list.lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +0000788
789 return node ? sk : sk1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790}
791
792static void l2cap_sock_destruct(struct sock *sk)
793{
794 BT_DBG("sk %p", sk);
795
796 skb_queue_purge(&sk->sk_receive_queue);
797 skb_queue_purge(&sk->sk_write_queue);
798}
799
800static void l2cap_sock_cleanup_listen(struct sock *parent)
801{
802 struct sock *sk;
803
804 BT_DBG("parent %p", parent);
805
806 /* Close not yet accepted channels */
807 while ((sk = bt_accept_dequeue(parent, NULL)))
808 l2cap_sock_close(sk);
809
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200810 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811 sock_set_flag(parent, SOCK_ZAPPED);
812}
813
814/* Kill socket (only if zapped and orphan)
815 * Must be called on unlocked socket.
816 */
817static void l2cap_sock_kill(struct sock *sk)
818{
819 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
820 return;
821
822 BT_DBG("sk %p state %d", sk, sk->sk_state);
823
824 /* Kill poor orphan */
825 bt_sock_unlink(&l2cap_sk_list, sk);
826 sock_set_flag(sk, SOCK_DEAD);
827 sock_put(sk);
828}
829
830static void __l2cap_sock_close(struct sock *sk, int reason)
831{
832 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
833
834 switch (sk->sk_state) {
835 case BT_LISTEN:
836 l2cap_sock_cleanup_listen(sk);
837 break;
838
839 case BT_CONNECTED:
840 case BT_CONFIG:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300841 if (sk->sk_type == SOCK_SEQPACKET ||
842 sk->sk_type == SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700844
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300846 l2cap_send_disconn_req(conn, sk, reason);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200847 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849 break;
850
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100851 case BT_CONNECT2:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300852 if (sk->sk_type == SOCK_SEQPACKET ||
853 sk->sk_type == SOCK_STREAM) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100854 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
855 struct l2cap_conn_rsp rsp;
856 __u16 result;
857
858 if (bt_sk(sk)->defer_setup)
859 result = L2CAP_CR_SEC_BLOCK;
860 else
861 result = L2CAP_CR_BAD_PSM;
Bao Liange733fb62011-01-29 21:39:37 +0800862 sk->sk_state = BT_DISCONN;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100863
864 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
865 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
866 rsp.result = cpu_to_le16(result);
867 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
868 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
869 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
870 } else
871 l2cap_chan_del(sk, reason);
872 break;
873
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 case BT_CONNECT:
875 case BT_DISCONN:
876 l2cap_chan_del(sk, reason);
877 break;
878
879 default:
880 sock_set_flag(sk, SOCK_ZAPPED);
881 break;
882 }
883}
884
885/* Must be called on unlocked socket. */
886static void l2cap_sock_close(struct sock *sk)
887{
888 l2cap_sock_clear_timer(sk);
889 lock_sock(sk);
890 __l2cap_sock_close(sk, ECONNRESET);
891 release_sock(sk);
892 l2cap_sock_kill(sk);
893}
894
895static void l2cap_sock_init(struct sock *sk, struct sock *parent)
896{
897 struct l2cap_pinfo *pi = l2cap_pi(sk);
898
899 BT_DBG("sk %p", sk);
900
901 if (parent) {
902 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100903 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
904
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 pi->imtu = l2cap_pi(parent)->imtu;
906 pi->omtu = l2cap_pi(parent)->omtu;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300907 pi->conf_state = l2cap_pi(parent)->conf_state;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700908 pi->mode = l2cap_pi(parent)->mode;
909 pi->fcs = l2cap_pi(parent)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -0300910 pi->max_tx = l2cap_pi(parent)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -0300911 pi->tx_win = l2cap_pi(parent)->tx_win;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100912 pi->sec_level = l2cap_pi(parent)->sec_level;
913 pi->role_switch = l2cap_pi(parent)->role_switch;
914 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700915 } else {
916 pi->imtu = L2CAP_DEFAULT_MTU;
917 pi->omtu = 0;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -0300918 if (!disable_ertm && sk->sk_type == SOCK_STREAM) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300919 pi->mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300920 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
921 } else {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300922 pi->mode = L2CAP_MODE_BASIC;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300923 }
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300924 pi->max_tx = L2CAP_DEFAULT_MAX_TX;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700925 pi->fcs = L2CAP_FCS_CRC16;
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300926 pi->tx_win = L2CAP_DEFAULT_TX_WINDOW;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100927 pi->sec_level = BT_SECURITY_LOW;
928 pi->role_switch = 0;
929 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930 }
931
932 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200933 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Dave Young45054dc2009-10-18 20:28:30 +0000935 skb_queue_head_init(TX_QUEUE(sk));
936 skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300937 skb_queue_head_init(BUSY_QUEUE(sk));
Dave Young45054dc2009-10-18 20:28:30 +0000938 INIT_LIST_HEAD(SREJ_LIST(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939}
940
941static struct proto l2cap_proto = {
942 .name = "L2CAP",
943 .owner = THIS_MODULE,
944 .obj_size = sizeof(struct l2cap_pinfo)
945};
946
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700947static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948{
949 struct sock *sk;
950
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700951 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952 if (!sk)
953 return NULL;
954
955 sock_init_data(sock, sk);
956 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
957
958 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200959 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960
961 sock_reset_flag(sk, SOCK_ZAPPED);
962
963 sk->sk_protocol = proto;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200964 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200966 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967
968 bt_sock_link(&l2cap_sk_list, sk);
969 return sk;
970}
971
Eric Paris3f378b62009-11-05 22:18:14 -0800972static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
973 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974{
975 struct sock *sk;
976
977 BT_DBG("sock %p", sock);
978
979 sock->state = SS_UNCONNECTED;
980
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300981 if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
983 return -ESOCKTNOSUPPORT;
984
Eric Parisc84b3262009-11-05 20:45:52 -0800985 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986 return -EPERM;
987
988 sock->ops = &l2cap_sock_ops;
989
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700990 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991 if (!sk)
992 return -ENOMEM;
993
994 l2cap_sock_init(sk, NULL);
995 return 0;
996}
997
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100998static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700999{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001001 struct sockaddr_l2 la;
1002 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001004 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005
1006 if (!addr || addr->sa_family != AF_BLUETOOTH)
1007 return -EINVAL;
1008
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001009 memset(&la, 0, sizeof(la));
1010 len = min_t(unsigned int, sizeof(la), alen);
1011 memcpy(&la, addr, len);
1012
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001013 if (la.l2_cid)
1014 return -EINVAL;
1015
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 lock_sock(sk);
1017
1018 if (sk->sk_state != BT_OPEN) {
1019 err = -EBADFD;
1020 goto done;
1021 }
1022
Mat Martineau0fba2552010-09-08 10:05:26 -07001023 if (la.l2_psm) {
1024 __u16 psm = __le16_to_cpu(la.l2_psm);
1025
1026 /* PSM must be odd and lsb of upper byte must be 0 */
1027 if ((psm & 0x0101) != 0x0001) {
1028 err = -EINVAL;
1029 goto done;
1030 }
1031
1032 /* Restrict usage of well-known PSMs */
1033 if (psm < 0x1001 && !capable(CAP_NET_BIND_SERVICE)) {
1034 err = -EACCES;
1035 goto done;
1036 }
Marcel Holtmann847641d2007-01-22 22:00:45 +01001037 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001038
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039 write_lock_bh(&l2cap_sk_list.lock);
1040
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001041 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042 err = -EADDRINUSE;
1043 } else {
1044 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001045 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
1046 l2cap_pi(sk)->psm = la.l2_psm;
1047 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001049
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001050 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
1051 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001052 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053 }
1054
1055 write_unlock_bh(&l2cap_sk_list.lock);
1056
1057done:
1058 release_sock(sk);
1059 return err;
1060}
1061
1062static int l2cap_do_connect(struct sock *sk)
1063{
1064 bdaddr_t *src = &bt_sk(sk)->src;
1065 bdaddr_t *dst = &bt_sk(sk)->dst;
1066 struct l2cap_conn *conn;
1067 struct hci_conn *hcon;
1068 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001069 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001070 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001072 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
1073 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001075 hdev = hci_get_route(dst, src);
1076 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 return -EHOSTUNREACH;
1078
1079 hci_dev_lock_bh(hdev);
1080
1081 err = -ENOMEM;
1082
Johan Hedberg8556edd32011-01-19 12:06:50 +05301083 auth_type = l2cap_get_auth_type(sk);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001084
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001085 hcon = hci_connect(hdev, ACL_LINK, dst,
1086 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087 if (!hcon)
1088 goto done;
1089
1090 conn = l2cap_conn_add(hcon, 0);
1091 if (!conn) {
1092 hci_conn_put(hcon);
1093 goto done;
1094 }
1095
1096 err = 0;
1097
1098 /* Update source addr of the socket */
1099 bacpy(src, conn->src);
1100
1101 l2cap_chan_add(conn, sk, NULL);
1102
1103 sk->sk_state = BT_CONNECT;
1104 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
1105
1106 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001107 if (sk->sk_type != SOCK_SEQPACKET &&
1108 sk->sk_type != SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109 l2cap_sock_clear_timer(sk);
Johan Hedbergd00ef242011-01-19 12:06:51 +05301110 if (l2cap_check_security(sk))
1111 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001112 } else
1113 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 }
1115
1116done:
1117 hci_dev_unlock_bh(hdev);
1118 hci_dev_put(hdev);
1119 return err;
1120}
1121
1122static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
1123{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001125 struct sockaddr_l2 la;
1126 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128 BT_DBG("sk %p", sk);
1129
Changli Gao6503d962010-03-31 22:58:26 +00001130 if (!addr || alen < sizeof(addr->sa_family) ||
1131 addr->sa_family != AF_BLUETOOTH)
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001132 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001134 memset(&la, 0, sizeof(la));
1135 len = min_t(unsigned int, sizeof(la), alen);
1136 memcpy(&la, addr, len);
1137
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001138 if (la.l2_cid)
1139 return -EINVAL;
1140
1141 lock_sock(sk);
1142
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001143 if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
1144 && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145 err = -EINVAL;
1146 goto done;
1147 }
1148
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001149 switch (l2cap_pi(sk)->mode) {
1150 case L2CAP_MODE_BASIC:
1151 break;
1152 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001153 case L2CAP_MODE_STREAMING:
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001154 if (!disable_ertm)
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001155 break;
1156 /* fall through */
1157 default:
1158 err = -ENOTSUPP;
1159 goto done;
1160 }
1161
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001162 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163 case BT_CONNECT:
1164 case BT_CONNECT2:
1165 case BT_CONFIG:
1166 /* Already connecting */
1167 goto wait;
1168
1169 case BT_CONNECTED:
1170 /* Already connected */
João Paulo Rechi Vita8b0dc6d2010-06-22 13:56:22 -03001171 err = -EISCONN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001172 goto done;
1173
1174 case BT_OPEN:
1175 case BT_BOUND:
1176 /* Can connect */
1177 break;
1178
1179 default:
1180 err = -EBADFD;
1181 goto done;
1182 }
1183
Mat Martineau0fba2552010-09-08 10:05:26 -07001184 /* PSM must be odd and lsb of upper byte must be 0 */
1185 if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 &&
1186 sk->sk_type != SOCK_RAW) {
1187 err = -EINVAL;
1188 goto done;
1189 }
1190
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001192 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1193 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001195 err = l2cap_do_connect(sk);
1196 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197 goto done;
1198
1199wait:
1200 err = bt_sock_wait_state(sk, BT_CONNECTED,
1201 sock_sndtimeo(sk, flags & O_NONBLOCK));
1202done:
1203 release_sock(sk);
1204 return err;
1205}
1206
1207static int l2cap_sock_listen(struct socket *sock, int backlog)
1208{
1209 struct sock *sk = sock->sk;
1210 int err = 0;
1211
1212 BT_DBG("sk %p backlog %d", sk, backlog);
1213
1214 lock_sock(sk);
1215
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001216 if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
1217 || sk->sk_state != BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 err = -EBADFD;
1219 goto done;
1220 }
1221
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001222 switch (l2cap_pi(sk)->mode) {
1223 case L2CAP_MODE_BASIC:
1224 break;
1225 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001226 case L2CAP_MODE_STREAMING:
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001227 if (!disable_ertm)
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001228 break;
1229 /* fall through */
1230 default:
1231 err = -ENOTSUPP;
1232 goto done;
1233 }
1234
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235 if (!l2cap_pi(sk)->psm) {
1236 bdaddr_t *src = &bt_sk(sk)->src;
1237 u16 psm;
1238
1239 err = -EINVAL;
1240
1241 write_lock_bh(&l2cap_sk_list.lock);
1242
1243 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001244 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1245 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1246 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247 err = 0;
1248 break;
1249 }
1250
1251 write_unlock_bh(&l2cap_sk_list.lock);
1252
1253 if (err < 0)
1254 goto done;
1255 }
1256
1257 sk->sk_max_ack_backlog = backlog;
1258 sk->sk_ack_backlog = 0;
1259 sk->sk_state = BT_LISTEN;
1260
1261done:
1262 release_sock(sk);
1263 return err;
1264}
1265
1266static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1267{
1268 DECLARE_WAITQUEUE(wait, current);
1269 struct sock *sk = sock->sk, *nsk;
1270 long timeo;
1271 int err = 0;
1272
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001273 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274
1275 if (sk->sk_state != BT_LISTEN) {
1276 err = -EBADFD;
1277 goto done;
1278 }
1279
1280 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1281
1282 BT_DBG("sk %p timeo %ld", sk, timeo);
1283
1284 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +00001285 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001286 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1287 set_current_state(TASK_INTERRUPTIBLE);
1288 if (!timeo) {
1289 err = -EAGAIN;
1290 break;
1291 }
1292
1293 release_sock(sk);
1294 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001295 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296
1297 if (sk->sk_state != BT_LISTEN) {
1298 err = -EBADFD;
1299 break;
1300 }
1301
1302 if (signal_pending(current)) {
1303 err = sock_intr_errno(timeo);
1304 break;
1305 }
1306 }
1307 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +00001308 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001309
1310 if (err)
1311 goto done;
1312
1313 newsock->state = SS_CONNECTED;
1314
1315 BT_DBG("new socket %p", nsk);
1316
1317done:
1318 release_sock(sk);
1319 return err;
1320}
1321
1322static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1323{
1324 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1325 struct sock *sk = sock->sk;
1326
1327 BT_DBG("sock %p, sk %p", sock, sk);
1328
1329 addr->sa_family = AF_BLUETOOTH;
1330 *len = sizeof(struct sockaddr_l2);
1331
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001332 if (peer) {
1333 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001335 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001336 } else {
1337 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001338 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001339 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001340 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342 return 0;
1343}
1344
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001345static int __l2cap_wait_ack(struct sock *sk)
1346{
1347 DECLARE_WAITQUEUE(wait, current);
1348 int err = 0;
1349 int timeo = HZ/5;
1350
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001351 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001352 while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
1353 set_current_state(TASK_INTERRUPTIBLE);
1354
1355 if (!timeo)
1356 timeo = HZ/5;
1357
1358 if (signal_pending(current)) {
1359 err = sock_intr_errno(timeo);
1360 break;
1361 }
1362
1363 release_sock(sk);
1364 timeo = schedule_timeout(timeo);
1365 lock_sock(sk);
1366
1367 err = sock_error(sk);
1368 if (err)
1369 break;
1370 }
1371 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001372 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001373 return err;
1374}
1375
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001376static void l2cap_monitor_timeout(unsigned long arg)
1377{
1378 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001379
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001380 BT_DBG("sk %p", sk);
1381
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001382 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001383 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001384 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001385 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001386 return;
1387 }
1388
1389 l2cap_pi(sk)->retry_count++;
1390 __mod_monitor_timer();
1391
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001392 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001393 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001394}
1395
1396static void l2cap_retrans_timeout(unsigned long arg)
1397{
1398 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001399
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001400 BT_DBG("sk %p", sk);
1401
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001402 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001403 l2cap_pi(sk)->retry_count = 1;
1404 __mod_monitor_timer();
1405
1406 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1407
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001408 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001409 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001410}
1411
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001412static void l2cap_drop_acked_frames(struct sock *sk)
1413{
1414 struct sk_buff *skb;
1415
Gustavo F. Padovan812e7372010-05-01 16:15:42 -03001416 while ((skb = skb_peek(TX_QUEUE(sk))) &&
1417 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001418 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1419 break;
1420
1421 skb = skb_dequeue(TX_QUEUE(sk));
1422 kfree_skb(skb);
1423
1424 l2cap_pi(sk)->unacked_frames--;
1425 }
1426
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001427 if (!l2cap_pi(sk)->unacked_frames)
1428 del_timer(&l2cap_pi(sk)->retrans_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001429}
1430
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001431static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001432{
1433 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001434
1435 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1436
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001437 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001438}
1439
João Paulo Rechi Vita305682e2010-06-22 13:56:23 -03001440static void l2cap_streaming_send(struct sock *sk)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001441{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001442 struct sk_buff *skb;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001443 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001444 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001445
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001446 while ((skb = skb_dequeue(TX_QUEUE(sk)))) {
1447 control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001448 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001449 put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001450
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001451 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001452 fcs = crc16(0, (u8 *)skb->data, skb->len - 2);
1453 put_unaligned_le16(fcs, skb->data + skb->len - 2);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001454 }
1455
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001456 l2cap_do_send(sk, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001457
1458 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001459 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001460}
1461
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001462static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001463{
1464 struct l2cap_pinfo *pi = l2cap_pi(sk);
1465 struct sk_buff *skb, *tx_skb;
1466 u16 control, fcs;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001467
1468 skb = skb_peek(TX_QUEUE(sk));
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001469 if (!skb)
1470 return;
1471
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001472 do {
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001473 if (bt_cb(skb)->tx_seq == tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001474 break;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001475
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001476 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1477 return;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001478
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001479 } while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001480
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001481 if (pi->remote_max_tx &&
1482 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001483 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001484 return;
1485 }
1486
1487 tx_skb = skb_clone(skb, GFP_ATOMIC);
1488 bt_cb(skb)->retries++;
1489 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001490
1491 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1492 control |= L2CAP_CTRL_FINAL;
1493 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1494 }
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001495
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001496 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1497 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001498
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001499 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1500
1501 if (pi->fcs == L2CAP_FCS_CRC16) {
1502 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1503 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1504 }
1505
1506 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001507}
1508
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001509static int l2cap_ertm_send(struct sock *sk)
1510{
1511 struct sk_buff *skb, *tx_skb;
1512 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001513 u16 control, fcs;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001514 int nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001515
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001516 if (sk->sk_state != BT_CONNECTED)
1517 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001518
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001519 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001520
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001521 if (pi->remote_max_tx &&
1522 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001523 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001524 break;
1525 }
1526
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001527 tx_skb = skb_clone(skb, GFP_ATOMIC);
1528
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001529 bt_cb(skb)->retries++;
1530
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001531 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001532 control &= L2CAP_CTRL_SAR;
1533
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001534 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1535 control |= L2CAP_CTRL_FINAL;
1536 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1537 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001538 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001539 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1540 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1541
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001542
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001543 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001544 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1545 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1546 }
1547
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001548 l2cap_do_send(sk, tx_skb);
1549
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001550 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001551
1552 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1553 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1554
1555 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001556 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001557
1558 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1559 sk->sk_send_head = NULL;
1560 else
1561 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001562
1563 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001564 }
1565
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001566 return nsent;
1567}
1568
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001569static int l2cap_retransmit_frames(struct sock *sk)
1570{
1571 struct l2cap_pinfo *pi = l2cap_pi(sk);
1572 int ret;
1573
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001574 if (!skb_queue_empty(TX_QUEUE(sk)))
1575 sk->sk_send_head = TX_QUEUE(sk)->next;
1576
1577 pi->next_tx_seq = pi->expected_ack_seq;
1578 ret = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001579 return ret;
1580}
1581
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001582static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001583{
1584 struct sock *sk = (struct sock *)pi;
1585 u16 control = 0;
1586
1587 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1588
1589 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1590 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001591 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001592 l2cap_send_sframe(pi, control);
1593 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001594 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001595
Gustavo F. Padovane0f66212010-06-21 18:50:49 -03001596 if (l2cap_ertm_send(sk) > 0)
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001597 return;
1598
1599 control |= L2CAP_SUPER_RCV_READY;
1600 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001601}
1602
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001603static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001604{
1605 struct srej_list *tail;
1606 u16 control;
1607
1608 control = L2CAP_SUPER_SELECT_REJECT;
1609 control |= L2CAP_CTRL_FINAL;
1610
1611 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1612 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1613
1614 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001615}
1616
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001617static 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 -07001618{
1619 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001620 struct sk_buff **frag;
1621 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001623 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001624 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625
1626 sent += count;
1627 len -= count;
1628
1629 /* Continuation fragments (no L2CAP header) */
1630 frag = &skb_shinfo(skb)->frag_list;
1631 while (len) {
1632 count = min_t(unsigned int, conn->mtu, len);
1633
1634 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1635 if (!*frag)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001636 return err;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001637 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1638 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639
1640 sent += count;
1641 len -= count;
1642
1643 frag = &(*frag)->next;
1644 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001645
1646 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001647}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001649static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1650{
1651 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1652 struct sk_buff *skb;
1653 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1654 struct l2cap_hdr *lh;
1655
1656 BT_DBG("sk %p len %d", sk, (int)len);
1657
1658 count = min_t(unsigned int, (conn->mtu - hlen), len);
1659 skb = bt_skb_send_alloc(sk, count + hlen,
1660 msg->msg_flags & MSG_DONTWAIT, &err);
1661 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001662 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001663
1664 /* Create L2CAP header */
1665 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1666 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1667 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1668 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1669
1670 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1671 if (unlikely(err < 0)) {
1672 kfree_skb(skb);
1673 return ERR_PTR(err);
1674 }
1675 return skb;
1676}
1677
1678static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1679{
1680 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1681 struct sk_buff *skb;
1682 int err, count, hlen = L2CAP_HDR_SIZE;
1683 struct l2cap_hdr *lh;
1684
1685 BT_DBG("sk %p len %d", sk, (int)len);
1686
1687 count = min_t(unsigned int, (conn->mtu - hlen), len);
1688 skb = bt_skb_send_alloc(sk, count + hlen,
1689 msg->msg_flags & MSG_DONTWAIT, &err);
1690 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001691 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001692
1693 /* Create L2CAP header */
1694 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1695 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1696 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1697
1698 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1699 if (unlikely(err < 0)) {
1700 kfree_skb(skb);
1701 return ERR_PTR(err);
1702 }
1703 return skb;
1704}
1705
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001706static 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 -03001707{
1708 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1709 struct sk_buff *skb;
1710 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1711 struct l2cap_hdr *lh;
1712
1713 BT_DBG("sk %p len %d", sk, (int)len);
1714
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001715 if (!conn)
1716 return ERR_PTR(-ENOTCONN);
1717
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001718 if (sdulen)
1719 hlen += 2;
1720
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001721 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1722 hlen += 2;
1723
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001724 count = min_t(unsigned int, (conn->mtu - hlen), len);
1725 skb = bt_skb_send_alloc(sk, count + hlen,
1726 msg->msg_flags & MSG_DONTWAIT, &err);
1727 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001728 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001729
1730 /* Create L2CAP header */
1731 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1732 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1733 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1734 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001735 if (sdulen)
1736 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001737
1738 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1739 if (unlikely(err < 0)) {
1740 kfree_skb(skb);
1741 return ERR_PTR(err);
1742 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001743
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001744 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1745 put_unaligned_le16(0, skb_put(skb, 2));
1746
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001747 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001748 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749}
1750
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001751static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1752{
1753 struct l2cap_pinfo *pi = l2cap_pi(sk);
1754 struct sk_buff *skb;
1755 struct sk_buff_head sar_queue;
1756 u16 control;
1757 size_t size = 0;
1758
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001759 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001760 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001761 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001762 if (IS_ERR(skb))
1763 return PTR_ERR(skb);
1764
1765 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001766 len -= pi->remote_mps;
1767 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001768
1769 while (len > 0) {
1770 size_t buflen;
1771
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001772 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001773 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001774 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001775 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001776 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001777 buflen = len;
1778 }
1779
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001780 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001781 if (IS_ERR(skb)) {
1782 skb_queue_purge(&sar_queue);
1783 return PTR_ERR(skb);
1784 }
1785
1786 __skb_queue_tail(&sar_queue, skb);
1787 len -= buflen;
1788 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001789 }
1790 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1791 if (sk->sk_send_head == NULL)
1792 sk->sk_send_head = sar_queue.next;
1793
1794 return size;
1795}
1796
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1798{
1799 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001800 struct l2cap_pinfo *pi = l2cap_pi(sk);
1801 struct sk_buff *skb;
1802 u16 control;
1803 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804
1805 BT_DBG("sock %p, sk %p", sock, sk);
1806
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001807 err = sock_error(sk);
1808 if (err)
1809 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810
1811 if (msg->msg_flags & MSG_OOB)
1812 return -EOPNOTSUPP;
1813
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 lock_sock(sk);
1815
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001816 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001818 goto done;
1819 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001821 /* Connectionless channel */
1822 if (sk->sk_type == SOCK_DGRAM) {
1823 skb = l2cap_create_connless_pdu(sk, msg, len);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001824 if (IS_ERR(skb)) {
Dan Carpenter477fffb2010-04-21 23:52:01 +00001825 err = PTR_ERR(skb);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001826 } else {
1827 l2cap_do_send(sk, skb);
1828 err = len;
1829 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001830 goto done;
1831 }
1832
1833 switch (pi->mode) {
1834 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001835 /* Check outgoing MTU */
1836 if (len > pi->omtu) {
João Paulo Rechi Vitaf9dd11b2010-06-22 13:56:24 -03001837 err = -EMSGSIZE;
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001838 goto done;
1839 }
1840
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001841 /* Create a basic PDU */
1842 skb = l2cap_create_basic_pdu(sk, msg, len);
1843 if (IS_ERR(skb)) {
1844 err = PTR_ERR(skb);
1845 goto done;
1846 }
1847
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001848 l2cap_do_send(sk, skb);
1849 err = len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001850 break;
1851
1852 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001853 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001854 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001855 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001856 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001857 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001858 if (IS_ERR(skb)) {
1859 err = PTR_ERR(skb);
1860 goto done;
1861 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001862 __skb_queue_tail(TX_QUEUE(sk), skb);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001863
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001864 if (sk->sk_send_head == NULL)
1865 sk->sk_send_head = skb;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001866
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001867 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001868 /* Segment SDU into multiples PDUs */
1869 err = l2cap_sar_segment_sdu(sk, msg, len);
1870 if (err < 0)
1871 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001872 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001873
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001874 if (pi->mode == L2CAP_MODE_STREAMING) {
João Paulo Rechi Vita305682e2010-06-22 13:56:23 -03001875 l2cap_streaming_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001876 } else {
David Sterba45719282011-01-14 14:59:44 +01001877 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
1878 (pi->conn_state & L2CAP_CONN_WAIT_F)) {
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001879 err = len;
1880 break;
1881 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001882 err = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001883 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001884
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001885 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001886 err = len;
1887 break;
1888
1889 default:
1890 BT_DBG("bad state %1.1x", pi->mode);
João Paulo Rechi Vitabc766db22010-06-22 13:56:25 -03001891 err = -EBADFD;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001892 }
1893
1894done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895 release_sock(sk);
1896 return err;
1897}
1898
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001899static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1900{
1901 struct sock *sk = sock->sk;
1902
1903 lock_sock(sk);
1904
1905 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1906 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001907 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1908 u8 buf[128];
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001909
1910 sk->sk_state = BT_CONFIG;
1911
1912 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1913 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1914 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1915 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1916 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1917 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1918
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001919 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) {
1920 release_sock(sk);
1921 return 0;
1922 }
1923
1924 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
1925 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
1926 l2cap_build_conf_req(sk, buf), buf);
1927 l2cap_pi(sk)->num_conf_req++;
1928
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001929 release_sock(sk);
1930 return 0;
1931 }
1932
1933 release_sock(sk);
1934
Mat Martineau6fdf4822010-09-08 10:05:29 -07001935 if (sock->type == SOCK_STREAM)
1936 return bt_sock_stream_recvmsg(iocb, sock, msg, len, flags);
1937
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001938 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1939}
1940
David S. Millerb7058842009-09-30 16:12:20 -07001941static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001942{
1943 struct sock *sk = sock->sk;
1944 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001945 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946 u32 opt;
1947
1948 BT_DBG("sk %p", sk);
1949
1950 lock_sock(sk);
1951
1952 switch (optname) {
1953 case L2CAP_OPTIONS:
Gustavo F. Padovaneaa71b32010-10-04 19:28:52 -03001954 if (sk->sk_state == BT_CONNECTED) {
1955 err = -EINVAL;
1956 break;
1957 }
1958
Marcel Holtmann0878b662007-05-05 00:35:59 +02001959 opts.imtu = l2cap_pi(sk)->imtu;
1960 opts.omtu = l2cap_pi(sk)->omtu;
1961 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001962 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001963 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001964 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001965 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001966
Linus Torvalds1da177e2005-04-16 15:20:36 -07001967 len = min_t(unsigned int, sizeof(opts), optlen);
1968 if (copy_from_user((char *) &opts, optval, len)) {
1969 err = -EFAULT;
1970 break;
1971 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001972
Gustavo F. Padovan45d65c42010-06-07 19:21:30 -03001973 if (opts.txwin_size > L2CAP_DEFAULT_TX_WINDOW) {
1974 err = -EINVAL;
1975 break;
1976 }
1977
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001978 l2cap_pi(sk)->mode = opts.mode;
1979 switch (l2cap_pi(sk)->mode) {
1980 case L2CAP_MODE_BASIC:
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03001981 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_STATE2_DEVICE;
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001982 break;
1983 case L2CAP_MODE_ERTM:
1984 case L2CAP_MODE_STREAMING:
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001985 if (!disable_ertm)
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001986 break;
1987 /* fall through */
1988 default:
1989 err = -EINVAL;
1990 break;
1991 }
1992
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001993 l2cap_pi(sk)->imtu = opts.imtu;
1994 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001995 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001996 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001997 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001998 break;
1999
2000 case L2CAP_LM:
2001 if (get_user(opt, (u32 __user *) optval)) {
2002 err = -EFAULT;
2003 break;
2004 }
2005
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002006 if (opt & L2CAP_LM_AUTH)
2007 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
2008 if (opt & L2CAP_LM_ENCRYPT)
2009 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
2010 if (opt & L2CAP_LM_SECURE)
2011 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
2012
2013 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
2014 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002015 break;
2016
2017 default:
2018 err = -ENOPROTOOPT;
2019 break;
2020 }
2021
2022 release_sock(sk);
2023 return err;
2024}
2025
David S. Millerb7058842009-09-30 16:12:20 -07002026static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002027{
2028 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002029 struct bt_security sec;
2030 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002031 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002032
2033 BT_DBG("sk %p", sk);
2034
2035 if (level == SOL_L2CAP)
2036 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
2037
Marcel Holtmann0588d942009-01-16 10:06:13 +01002038 if (level != SOL_BLUETOOTH)
2039 return -ENOPROTOOPT;
2040
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002041 lock_sock(sk);
2042
2043 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002044 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002045 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2046 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002047 err = -EINVAL;
2048 break;
2049 }
2050
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002051 sec.level = BT_SECURITY_LOW;
2052
2053 len = min_t(unsigned int, sizeof(sec), optlen);
2054 if (copy_from_user((char *) &sec, optval, len)) {
2055 err = -EFAULT;
2056 break;
2057 }
2058
2059 if (sec.level < BT_SECURITY_LOW ||
2060 sec.level > BT_SECURITY_HIGH) {
2061 err = -EINVAL;
2062 break;
2063 }
2064
2065 l2cap_pi(sk)->sec_level = sec.level;
2066 break;
2067
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002068 case BT_DEFER_SETUP:
2069 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2070 err = -EINVAL;
2071 break;
2072 }
2073
2074 if (get_user(opt, (u32 __user *) optval)) {
2075 err = -EFAULT;
2076 break;
2077 }
2078
2079 bt_sk(sk)->defer_setup = opt;
2080 break;
2081
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002082 default:
2083 err = -ENOPROTOOPT;
2084 break;
2085 }
2086
2087 release_sock(sk);
2088 return err;
2089}
2090
2091static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002092{
2093 struct sock *sk = sock->sk;
2094 struct l2cap_options opts;
2095 struct l2cap_conninfo cinfo;
2096 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002097 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002098
2099 BT_DBG("sk %p", sk);
2100
2101 if (get_user(len, optlen))
2102 return -EFAULT;
2103
2104 lock_sock(sk);
2105
2106 switch (optname) {
2107 case L2CAP_OPTIONS:
2108 opts.imtu = l2cap_pi(sk)->imtu;
2109 opts.omtu = l2cap_pi(sk)->omtu;
2110 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07002111 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002112 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002113 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002114 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002115
2116 len = min_t(unsigned int, len, sizeof(opts));
2117 if (copy_to_user(optval, (char *) &opts, len))
2118 err = -EFAULT;
2119
2120 break;
2121
2122 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002123 switch (l2cap_pi(sk)->sec_level) {
2124 case BT_SECURITY_LOW:
2125 opt = L2CAP_LM_AUTH;
2126 break;
2127 case BT_SECURITY_MEDIUM:
2128 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
2129 break;
2130 case BT_SECURITY_HIGH:
2131 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
2132 L2CAP_LM_SECURE;
2133 break;
2134 default:
2135 opt = 0;
2136 break;
2137 }
2138
2139 if (l2cap_pi(sk)->role_switch)
2140 opt |= L2CAP_LM_MASTER;
2141
2142 if (l2cap_pi(sk)->force_reliable)
2143 opt |= L2CAP_LM_RELIABLE;
2144
2145 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002146 err = -EFAULT;
2147 break;
2148
2149 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002150 if (sk->sk_state != BT_CONNECTED &&
2151 !(sk->sk_state == BT_CONNECT2 &&
2152 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002153 err = -ENOTCONN;
2154 break;
2155 }
2156
2157 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
2158 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
2159
2160 len = min_t(unsigned int, len, sizeof(cinfo));
2161 if (copy_to_user(optval, (char *) &cinfo, len))
2162 err = -EFAULT;
2163
2164 break;
2165
2166 default:
2167 err = -ENOPROTOOPT;
2168 break;
2169 }
2170
2171 release_sock(sk);
2172 return err;
2173}
2174
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002175static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
2176{
2177 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002178 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002179 int len, err = 0;
2180
2181 BT_DBG("sk %p", sk);
2182
2183 if (level == SOL_L2CAP)
2184 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
2185
Marcel Holtmann0588d942009-01-16 10:06:13 +01002186 if (level != SOL_BLUETOOTH)
2187 return -ENOPROTOOPT;
2188
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002189 if (get_user(len, optlen))
2190 return -EFAULT;
2191
2192 lock_sock(sk);
2193
2194 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002195 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002196 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2197 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002198 err = -EINVAL;
2199 break;
2200 }
2201
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002202 sec.level = l2cap_pi(sk)->sec_level;
2203
2204 len = min_t(unsigned int, len, sizeof(sec));
2205 if (copy_to_user(optval, (char *) &sec, len))
2206 err = -EFAULT;
2207
2208 break;
2209
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002210 case BT_DEFER_SETUP:
2211 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2212 err = -EINVAL;
2213 break;
2214 }
2215
2216 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2217 err = -EFAULT;
2218
2219 break;
2220
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002221 default:
2222 err = -ENOPROTOOPT;
2223 break;
2224 }
2225
2226 release_sock(sk);
2227 return err;
2228}
2229
Linus Torvalds1da177e2005-04-16 15:20:36 -07002230static int l2cap_sock_shutdown(struct socket *sock, int how)
2231{
2232 struct sock *sk = sock->sk;
2233 int err = 0;
2234
2235 BT_DBG("sock %p, sk %p", sock, sk);
2236
2237 if (!sk)
2238 return 0;
2239
2240 lock_sock(sk);
2241 if (!sk->sk_shutdown) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03002242 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2243 err = __l2cap_wait_ack(sk);
2244
Linus Torvalds1da177e2005-04-16 15:20:36 -07002245 sk->sk_shutdown = SHUTDOWN_MASK;
2246 l2cap_sock_clear_timer(sk);
2247 __l2cap_sock_close(sk, 0);
2248
2249 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002250 err = bt_sock_wait_state(sk, BT_CLOSED,
2251 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252 }
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002253
2254 if (!err && sk->sk_err)
2255 err = -sk->sk_err;
2256
Linus Torvalds1da177e2005-04-16 15:20:36 -07002257 release_sock(sk);
2258 return err;
2259}
2260
2261static int l2cap_sock_release(struct socket *sock)
2262{
2263 struct sock *sk = sock->sk;
2264 int err;
2265
2266 BT_DBG("sock %p, sk %p", sock, sk);
2267
2268 if (!sk)
2269 return 0;
2270
2271 err = l2cap_sock_shutdown(sock, 2);
2272
2273 sock_orphan(sk);
2274 l2cap_sock_kill(sk);
2275 return err;
2276}
2277
Linus Torvalds1da177e2005-04-16 15:20:36 -07002278static void l2cap_chan_ready(struct sock *sk)
2279{
2280 struct sock *parent = bt_sk(sk)->parent;
2281
2282 BT_DBG("sk %p, parent %p", sk, parent);
2283
2284 l2cap_pi(sk)->conf_state = 0;
2285 l2cap_sock_clear_timer(sk);
2286
2287 if (!parent) {
2288 /* Outgoing channel.
2289 * Wake up socket sleeping on connect.
2290 */
2291 sk->sk_state = BT_CONNECTED;
2292 sk->sk_state_change(sk);
2293 } else {
2294 /* Incoming channel.
2295 * Wake up socket sleeping on accept.
2296 */
2297 parent->sk_data_ready(parent, 0);
2298 }
2299}
2300
2301/* Copy frame to all raw sockets on that connection */
2302static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2303{
2304 struct l2cap_chan_list *l = &conn->chan_list;
2305 struct sk_buff *nskb;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002306 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002307
2308 BT_DBG("conn %p", conn);
2309
2310 read_lock(&l->lock);
2311 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2312 if (sk->sk_type != SOCK_RAW)
2313 continue;
2314
2315 /* Don't send frame to the socket it came from */
2316 if (skb->sk == sk)
2317 continue;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002318 nskb = skb_clone(skb, GFP_ATOMIC);
2319 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002320 continue;
2321
2322 if (sock_queue_rcv_skb(sk, nskb))
2323 kfree_skb(nskb);
2324 }
2325 read_unlock(&l->lock);
2326}
2327
2328/* ---- L2CAP signalling commands ---- */
2329static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2330 u8 code, u8 ident, u16 dlen, void *data)
2331{
2332 struct sk_buff *skb, **frag;
2333 struct l2cap_cmd_hdr *cmd;
2334 struct l2cap_hdr *lh;
2335 int len, count;
2336
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002337 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2338 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002339
2340 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2341 count = min_t(unsigned int, conn->mtu, len);
2342
2343 skb = bt_skb_alloc(count, GFP_ATOMIC);
2344 if (!skb)
2345 return NULL;
2346
2347 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002348 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002349 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002350
2351 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2352 cmd->code = code;
2353 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002354 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002355
2356 if (dlen) {
2357 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2358 memcpy(skb_put(skb, count), data, count);
2359 data += count;
2360 }
2361
2362 len -= skb->len;
2363
2364 /* Continuation fragments (no L2CAP header) */
2365 frag = &skb_shinfo(skb)->frag_list;
2366 while (len) {
2367 count = min_t(unsigned int, conn->mtu, len);
2368
2369 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2370 if (!*frag)
2371 goto fail;
2372
2373 memcpy(skb_put(*frag, count), data, count);
2374
2375 len -= count;
2376 data += count;
2377
2378 frag = &(*frag)->next;
2379 }
2380
2381 return skb;
2382
2383fail:
2384 kfree_skb(skb);
2385 return NULL;
2386}
2387
2388static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2389{
2390 struct l2cap_conf_opt *opt = *ptr;
2391 int len;
2392
2393 len = L2CAP_CONF_OPT_SIZE + opt->len;
2394 *ptr += len;
2395
2396 *type = opt->type;
2397 *olen = opt->len;
2398
2399 switch (opt->len) {
2400 case 1:
2401 *val = *((u8 *) opt->val);
2402 break;
2403
2404 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002405 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002406 break;
2407
2408 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002409 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002410 break;
2411
2412 default:
2413 *val = (unsigned long) opt->val;
2414 break;
2415 }
2416
2417 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2418 return len;
2419}
2420
Linus Torvalds1da177e2005-04-16 15:20:36 -07002421static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2422{
2423 struct l2cap_conf_opt *opt = *ptr;
2424
2425 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2426
2427 opt->type = type;
2428 opt->len = len;
2429
2430 switch (len) {
2431 case 1:
2432 *((u8 *) opt->val) = val;
2433 break;
2434
2435 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002436 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002437 break;
2438
2439 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002440 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002441 break;
2442
2443 default:
2444 memcpy(opt->val, (void *) val, len);
2445 break;
2446 }
2447
2448 *ptr += L2CAP_CONF_OPT_SIZE + len;
2449}
2450
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002451static void l2cap_ack_timeout(unsigned long arg)
2452{
2453 struct sock *sk = (void *) arg;
2454
2455 bh_lock_sock(sk);
2456 l2cap_send_ack(l2cap_pi(sk));
2457 bh_unlock_sock(sk);
2458}
2459
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002460static inline void l2cap_ertm_init(struct sock *sk)
2461{
2462 l2cap_pi(sk)->expected_ack_seq = 0;
2463 l2cap_pi(sk)->unacked_frames = 0;
2464 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002465 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002466 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002467
2468 setup_timer(&l2cap_pi(sk)->retrans_timer,
2469 l2cap_retrans_timeout, (unsigned long) sk);
2470 setup_timer(&l2cap_pi(sk)->monitor_timer,
2471 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002472 setup_timer(&l2cap_pi(sk)->ack_timer,
2473 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002474
2475 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002476 __skb_queue_head_init(BUSY_QUEUE(sk));
2477
2478 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03002479
2480 sk->sk_backlog_rcv = l2cap_ertm_data_rcv;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002481}
2482
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002483static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2484{
2485 switch (mode) {
2486 case L2CAP_MODE_STREAMING:
2487 case L2CAP_MODE_ERTM:
2488 if (l2cap_mode_supported(mode, remote_feat_mask))
2489 return mode;
2490 /* fall through */
2491 default:
2492 return L2CAP_MODE_BASIC;
2493 }
2494}
2495
Linus Torvalds1da177e2005-04-16 15:20:36 -07002496static int l2cap_build_conf_req(struct sock *sk, void *data)
2497{
2498 struct l2cap_pinfo *pi = l2cap_pi(sk);
2499 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002500 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002501 void *ptr = req->data;
2502
2503 BT_DBG("sk %p", sk);
2504
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002505 if (pi->num_conf_req || pi->num_conf_rsp)
2506 goto done;
2507
2508 switch (pi->mode) {
2509 case L2CAP_MODE_STREAMING:
2510 case L2CAP_MODE_ERTM:
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002511 if (pi->conf_state & L2CAP_CONF_STATE2_DEVICE)
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002512 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002513
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002514 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002515 default:
2516 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2517 break;
2518 }
2519
2520done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002521 switch (pi->mode) {
2522 case L2CAP_MODE_BASIC:
2523 if (pi->imtu != L2CAP_DEFAULT_MTU)
2524 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002525
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002526 if (!(pi->conn->feat_mask & L2CAP_FEAT_ERTM) &&
2527 !(pi->conn->feat_mask & L2CAP_FEAT_STREAMING))
2528 break;
2529
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002530 rfc.mode = L2CAP_MODE_BASIC;
2531 rfc.txwin_size = 0;
2532 rfc.max_transmit = 0;
2533 rfc.retrans_timeout = 0;
2534 rfc.monitor_timeout = 0;
2535 rfc.max_pdu_size = 0;
2536
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002537 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2538 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002539 break;
2540
2541 case L2CAP_MODE_ERTM:
2542 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002543 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002544 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002545 rfc.retrans_timeout = 0;
2546 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002547 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002548 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002549 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002550
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002551 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2552 (unsigned long) &rfc);
2553
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002554 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2555 break;
2556
2557 if (pi->fcs == L2CAP_FCS_NONE ||
2558 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2559 pi->fcs = L2CAP_FCS_NONE;
2560 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2561 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002562 break;
2563
2564 case L2CAP_MODE_STREAMING:
2565 rfc.mode = L2CAP_MODE_STREAMING;
2566 rfc.txwin_size = 0;
2567 rfc.max_transmit = 0;
2568 rfc.retrans_timeout = 0;
2569 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002570 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002571 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002572 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002573
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002574 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2575 (unsigned long) &rfc);
2576
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002577 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2578 break;
2579
2580 if (pi->fcs == L2CAP_FCS_NONE ||
2581 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2582 pi->fcs = L2CAP_FCS_NONE;
2583 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2584 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002585 break;
2586 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002587
2588 /* FIXME: Need actual value of the flush timeout */
2589 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2590 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2591
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002592 req->dcid = cpu_to_le16(pi->dcid);
2593 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002594
2595 return ptr - data;
2596}
2597
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002598static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002599{
2600 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002601 struct l2cap_conf_rsp *rsp = data;
2602 void *ptr = rsp->data;
2603 void *req = pi->conf_req;
2604 int len = pi->conf_len;
2605 int type, hint, olen;
2606 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002607 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002608 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002609 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002610
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002611 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002612
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002613 while (len >= L2CAP_CONF_OPT_SIZE) {
2614 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002615
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002616 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002617 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002618
2619 switch (type) {
2620 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002621 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002622 break;
2623
2624 case L2CAP_CONF_FLUSH_TO:
2625 pi->flush_to = val;
2626 break;
2627
2628 case L2CAP_CONF_QOS:
2629 break;
2630
Marcel Holtmann6464f352007-10-20 13:39:51 +02002631 case L2CAP_CONF_RFC:
2632 if (olen == sizeof(rfc))
2633 memcpy(&rfc, (void *) val, olen);
2634 break;
2635
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002636 case L2CAP_CONF_FCS:
2637 if (val == L2CAP_FCS_NONE)
2638 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2639
2640 break;
2641
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002642 default:
2643 if (hint)
2644 break;
2645
2646 result = L2CAP_CONF_UNKNOWN;
2647 *((u8 *) ptr++) = type;
2648 break;
2649 }
2650 }
2651
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002652 if (pi->num_conf_rsp || pi->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002653 goto done;
2654
2655 switch (pi->mode) {
2656 case L2CAP_MODE_STREAMING:
2657 case L2CAP_MODE_ERTM:
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002658 if (!(pi->conf_state & L2CAP_CONF_STATE2_DEVICE)) {
2659 pi->mode = l2cap_select_mode(rfc.mode,
2660 pi->conn->feat_mask);
2661 break;
2662 }
2663
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03002664 if (pi->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002665 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03002666
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002667 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002668 }
2669
2670done:
2671 if (pi->mode != rfc.mode) {
2672 result = L2CAP_CONF_UNACCEPT;
2673 rfc.mode = pi->mode;
2674
2675 if (pi->num_conf_rsp == 1)
2676 return -ECONNREFUSED;
2677
2678 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2679 sizeof(rfc), (unsigned long) &rfc);
2680 }
2681
2682
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002683 if (result == L2CAP_CONF_SUCCESS) {
2684 /* Configure output options and let the other side know
2685 * which ones we don't like. */
2686
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002687 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2688 result = L2CAP_CONF_UNACCEPT;
2689 else {
2690 pi->omtu = mtu;
2691 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2692 }
2693 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002694
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002695 switch (rfc.mode) {
2696 case L2CAP_MODE_BASIC:
2697 pi->fcs = L2CAP_FCS_NONE;
2698 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2699 break;
2700
2701 case L2CAP_MODE_ERTM:
2702 pi->remote_tx_win = rfc.txwin_size;
2703 pi->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07002704
2705 if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
2706 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002707
2708 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002709
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002710 rfc.retrans_timeout =
2711 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2712 rfc.monitor_timeout =
2713 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002714
2715 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002716
2717 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2718 sizeof(rfc), (unsigned long) &rfc);
2719
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002720 break;
2721
2722 case L2CAP_MODE_STREAMING:
Mat Martineau86b1b262010-08-05 15:54:22 -07002723 if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
2724 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002725
2726 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002727
2728 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002729
2730 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2731 sizeof(rfc), (unsigned long) &rfc);
2732
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002733 break;
2734
2735 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002736 result = L2CAP_CONF_UNACCEPT;
2737
2738 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002739 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002740 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002741
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002742 if (result == L2CAP_CONF_SUCCESS)
2743 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2744 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002745 rsp->scid = cpu_to_le16(pi->dcid);
2746 rsp->result = cpu_to_le16(result);
2747 rsp->flags = cpu_to_le16(0x0000);
2748
2749 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002750}
2751
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002752static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2753{
2754 struct l2cap_pinfo *pi = l2cap_pi(sk);
2755 struct l2cap_conf_req *req = data;
2756 void *ptr = req->data;
2757 int type, olen;
2758 unsigned long val;
2759 struct l2cap_conf_rfc rfc;
2760
2761 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2762
2763 while (len >= L2CAP_CONF_OPT_SIZE) {
2764 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2765
2766 switch (type) {
2767 case L2CAP_CONF_MTU:
2768 if (val < L2CAP_DEFAULT_MIN_MTU) {
2769 *result = L2CAP_CONF_UNACCEPT;
Andrei Emeltchenko8183b772010-09-01 15:17:25 +03002770 pi->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002771 } else
Andrei Emeltchenko8183b772010-09-01 15:17:25 +03002772 pi->imtu = val;
2773 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002774 break;
2775
2776 case L2CAP_CONF_FLUSH_TO:
2777 pi->flush_to = val;
2778 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2779 2, pi->flush_to);
2780 break;
2781
2782 case L2CAP_CONF_RFC:
2783 if (olen == sizeof(rfc))
2784 memcpy(&rfc, (void *)val, olen);
2785
2786 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2787 rfc.mode != pi->mode)
2788 return -ECONNREFUSED;
2789
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002790 pi->fcs = 0;
2791
2792 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2793 sizeof(rfc), (unsigned long) &rfc);
2794 break;
2795 }
2796 }
2797
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03002798 if (pi->mode == L2CAP_MODE_BASIC && pi->mode != rfc.mode)
2799 return -ECONNREFUSED;
2800
2801 pi->mode = rfc.mode;
2802
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002803 if (*result == L2CAP_CONF_SUCCESS) {
2804 switch (rfc.mode) {
2805 case L2CAP_MODE_ERTM:
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002806 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2807 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002808 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002809 break;
2810 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002811 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002812 }
2813 }
2814
2815 req->dcid = cpu_to_le16(pi->dcid);
2816 req->flags = cpu_to_le16(0x0000);
2817
2818 return ptr - data;
2819}
2820
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002821static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002822{
2823 struct l2cap_conf_rsp *rsp = data;
2824 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002825
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002826 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002827
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002828 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002829 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002830 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002831
2832 return ptr - data;
2833}
2834
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002835static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2836{
2837 struct l2cap_pinfo *pi = l2cap_pi(sk);
2838 int type, olen;
2839 unsigned long val;
2840 struct l2cap_conf_rfc rfc;
2841
2842 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2843
2844 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2845 return;
2846
2847 while (len >= L2CAP_CONF_OPT_SIZE) {
2848 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2849
2850 switch (type) {
2851 case L2CAP_CONF_RFC:
2852 if (olen == sizeof(rfc))
2853 memcpy(&rfc, (void *)val, olen);
2854 goto done;
2855 }
2856 }
2857
2858done:
2859 switch (rfc.mode) {
2860 case L2CAP_MODE_ERTM:
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002861 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2862 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002863 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2864 break;
2865 case L2CAP_MODE_STREAMING:
2866 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2867 }
2868}
2869
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002870static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2871{
2872 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2873
2874 if (rej->reason != 0x0000)
2875 return 0;
2876
2877 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2878 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002879 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002880
2881 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002882 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002883
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002884 l2cap_conn_start(conn);
2885 }
2886
2887 return 0;
2888}
2889
Linus Torvalds1da177e2005-04-16 15:20:36 -07002890static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2891{
2892 struct l2cap_chan_list *list = &conn->chan_list;
2893 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2894 struct l2cap_conn_rsp rsp;
Nathan Holsteind793fe82010-10-15 11:54:02 -04002895 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002896 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002897
2898 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002899 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002900
2901 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2902
2903 /* Check if we have socket listening on psm */
2904 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2905 if (!parent) {
2906 result = L2CAP_CR_BAD_PSM;
2907 goto sendresp;
2908 }
2909
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00002910 bh_lock_sock(parent);
2911
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002912 /* Check if the ACL is secure enough (if not SDP) */
2913 if (psm != cpu_to_le16(0x0001) &&
2914 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002915 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002916 result = L2CAP_CR_SEC_BLOCK;
2917 goto response;
2918 }
2919
Linus Torvalds1da177e2005-04-16 15:20:36 -07002920 result = L2CAP_CR_NO_MEM;
2921
2922 /* Check for backlog size */
2923 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002924 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002925 goto response;
2926 }
2927
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002928 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002929 if (!sk)
2930 goto response;
2931
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002932 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002933
2934 /* Check if we already have channel with that dcid */
2935 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002936 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002937 sock_set_flag(sk, SOCK_ZAPPED);
2938 l2cap_sock_kill(sk);
2939 goto response;
2940 }
2941
2942 hci_conn_hold(conn->hcon);
2943
2944 l2cap_sock_init(sk, parent);
2945 bacpy(&bt_sk(sk)->src, conn->src);
2946 bacpy(&bt_sk(sk)->dst, conn->dst);
2947 l2cap_pi(sk)->psm = psm;
2948 l2cap_pi(sk)->dcid = scid;
2949
2950 __l2cap_chan_add(conn, sk, parent);
2951 dcid = l2cap_pi(sk)->scid;
2952
2953 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2954
Linus Torvalds1da177e2005-04-16 15:20:36 -07002955 l2cap_pi(sk)->ident = cmd->ident;
2956
Marcel Holtmann984947d2009-02-06 23:35:19 +01002957 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002958 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002959 if (bt_sk(sk)->defer_setup) {
2960 sk->sk_state = BT_CONNECT2;
2961 result = L2CAP_CR_PEND;
2962 status = L2CAP_CS_AUTHOR_PEND;
2963 parent->sk_data_ready(parent, 0);
2964 } else {
2965 sk->sk_state = BT_CONFIG;
2966 result = L2CAP_CR_SUCCESS;
2967 status = L2CAP_CS_NO_INFO;
2968 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002969 } else {
2970 sk->sk_state = BT_CONNECT2;
2971 result = L2CAP_CR_PEND;
2972 status = L2CAP_CS_AUTHEN_PEND;
2973 }
2974 } else {
2975 sk->sk_state = BT_CONNECT2;
2976 result = L2CAP_CR_PEND;
2977 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002978 }
2979
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002980 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002981
2982response:
2983 bh_unlock_sock(parent);
2984
2985sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002986 rsp.scid = cpu_to_le16(scid);
2987 rsp.dcid = cpu_to_le16(dcid);
2988 rsp.result = cpu_to_le16(result);
2989 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002990 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002991
2992 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2993 struct l2cap_info_req info;
2994 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2995
2996 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2997 conn->info_ident = l2cap_get_ident(conn);
2998
2999 mod_timer(&conn->info_timer, jiffies +
3000 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
3001
3002 l2cap_send_cmd(conn, conn->info_ident,
3003 L2CAP_INFO_REQ, sizeof(info), &info);
3004 }
3005
Nathan Holsteind793fe82010-10-15 11:54:02 -04003006 if (sk && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) &&
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003007 result == L2CAP_CR_SUCCESS) {
3008 u8 buf[128];
3009 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
3010 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3011 l2cap_build_conf_req(sk, buf), buf);
3012 l2cap_pi(sk)->num_conf_req++;
3013 }
3014
Linus Torvalds1da177e2005-04-16 15:20:36 -07003015 return 0;
3016}
3017
3018static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3019{
3020 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3021 u16 scid, dcid, result, status;
3022 struct sock *sk;
3023 u8 req[128];
3024
3025 scid = __le16_to_cpu(rsp->scid);
3026 dcid = __le16_to_cpu(rsp->dcid);
3027 result = __le16_to_cpu(rsp->result);
3028 status = __le16_to_cpu(rsp->status);
3029
3030 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
3031
3032 if (scid) {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003033 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3034 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03003035 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003036 } else {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003037 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
3038 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03003039 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003040 }
3041
3042 switch (result) {
3043 case L2CAP_CR_SUCCESS:
3044 sk->sk_state = BT_CONFIG;
3045 l2cap_pi(sk)->ident = 0;
3046 l2cap_pi(sk)->dcid = dcid;
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003047 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
3048
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003049 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)
3050 break;
3051
3052 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
3053
Linus Torvalds1da177e2005-04-16 15:20:36 -07003054 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3055 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003056 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003057 break;
3058
3059 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003060 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003061 break;
3062
3063 default:
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02003064 /* don't delete l2cap channel if sk is owned by user */
3065 if (sock_owned_by_user(sk)) {
3066 sk->sk_state = BT_DISCONN;
3067 l2cap_sock_clear_timer(sk);
3068 l2cap_sock_set_timer(sk, HZ / 5);
3069 break;
3070 }
3071
Linus Torvalds1da177e2005-04-16 15:20:36 -07003072 l2cap_chan_del(sk, ECONNREFUSED);
3073 break;
3074 }
3075
3076 bh_unlock_sock(sk);
3077 return 0;
3078}
3079
Mat Martineau8c462b62010-08-24 15:35:42 -07003080static inline void set_default_fcs(struct l2cap_pinfo *pi)
3081{
3082 /* FCS is enabled only in ERTM or streaming mode, if one or both
3083 * sides request it.
3084 */
3085 if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING)
3086 pi->fcs = L2CAP_FCS_NONE;
3087 else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV))
3088 pi->fcs = L2CAP_FCS_CRC16;
3089}
3090
Al Viro88219a02007-07-29 00:17:25 -07003091static 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 -07003092{
3093 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3094 u16 dcid, flags;
3095 u8 rsp[64];
3096 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003097 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003098
3099 dcid = __le16_to_cpu(req->dcid);
3100 flags = __le16_to_cpu(req->flags);
3101
3102 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3103
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003104 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3105 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003106 return -ENOENT;
3107
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003108 if (sk->sk_state != BT_CONFIG) {
3109 struct l2cap_cmd_rej rej;
3110
3111 rej.reason = cpu_to_le16(0x0002);
3112 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
3113 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003114 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003115 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003116
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003117 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003118 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003119 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
3120 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
3121 l2cap_build_conf_rsp(sk, rsp,
3122 L2CAP_CONF_REJECT, flags), rsp);
3123 goto unlock;
3124 }
3125
3126 /* Store config. */
3127 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
3128 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003129
3130 if (flags & 0x0001) {
3131 /* Incomplete config. Send empty response. */
3132 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003133 l2cap_build_conf_rsp(sk, rsp,
3134 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003135 goto unlock;
3136 }
3137
3138 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003139 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003140 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003141 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003142 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003143 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003144
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003145 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003146 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003147
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003148 /* Reset config buffer. */
3149 l2cap_pi(sk)->conf_len = 0;
3150
Marcel Holtmann876d9482007-10-20 13:35:42 +02003151 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
3152 goto unlock;
3153
Linus Torvalds1da177e2005-04-16 15:20:36 -07003154 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Mat Martineau8c462b62010-08-24 15:35:42 -07003155 set_default_fcs(l2cap_pi(sk));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003156
Linus Torvalds1da177e2005-04-16 15:20:36 -07003157 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003158
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003159 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003160 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003161 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003162 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3163 l2cap_ertm_init(sk);
3164
Linus Torvalds1da177e2005-04-16 15:20:36 -07003165 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02003166 goto unlock;
3167 }
3168
3169 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003170 u8 buf[64];
Haijun Liuab3e5712010-09-30 16:52:40 +08003171 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003172 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003173 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003174 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003175 }
3176
3177unlock:
3178 bh_unlock_sock(sk);
3179 return 0;
3180}
3181
3182static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3183{
3184 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3185 u16 scid, flags, result;
3186 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003187 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003188
3189 scid = __le16_to_cpu(rsp->scid);
3190 flags = __le16_to_cpu(rsp->flags);
3191 result = __le16_to_cpu(rsp->result);
3192
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003193 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
3194 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003195
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003196 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3197 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003198 return 0;
3199
3200 switch (result) {
3201 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003202 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003203 break;
3204
3205 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003206 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003207 char req[64];
3208
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003209 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003210 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003211 goto done;
3212 }
3213
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003214 /* throw out any old stored conf requests */
3215 result = L2CAP_CONF_SUCCESS;
3216 len = l2cap_parse_conf_rsp(sk, rsp->data,
3217 len, req, &result);
3218 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003219 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003220 goto done;
3221 }
3222
3223 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3224 L2CAP_CONF_REQ, len, req);
3225 l2cap_pi(sk)->num_conf_req++;
3226 if (result != L2CAP_CONF_SUCCESS)
3227 goto done;
3228 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003229 }
3230
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003231 default:
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003232 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003233 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003234 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003235 goto done;
3236 }
3237
3238 if (flags & 0x01)
3239 goto done;
3240
Linus Torvalds1da177e2005-04-16 15:20:36 -07003241 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3242
3243 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Mat Martineau8c462b62010-08-24 15:35:42 -07003244 set_default_fcs(l2cap_pi(sk));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003245
Linus Torvalds1da177e2005-04-16 15:20:36 -07003246 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003247 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003248 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003249 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003250 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3251 l2cap_ertm_init(sk);
3252
Linus Torvalds1da177e2005-04-16 15:20:36 -07003253 l2cap_chan_ready(sk);
3254 }
3255
3256done:
3257 bh_unlock_sock(sk);
3258 return 0;
3259}
3260
3261static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3262{
3263 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3264 struct l2cap_disconn_rsp rsp;
3265 u16 dcid, scid;
3266 struct sock *sk;
3267
3268 scid = __le16_to_cpu(req->scid);
3269 dcid = __le16_to_cpu(req->dcid);
3270
3271 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3272
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003273 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3274 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003275 return 0;
3276
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003277 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3278 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003279 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3280
3281 sk->sk_shutdown = SHUTDOWN_MASK;
3282
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02003283 /* don't delete l2cap channel if sk is owned by user */
3284 if (sock_owned_by_user(sk)) {
3285 sk->sk_state = BT_DISCONN;
3286 l2cap_sock_clear_timer(sk);
3287 l2cap_sock_set_timer(sk, HZ / 5);
3288 bh_unlock_sock(sk);
3289 return 0;
3290 }
3291
Linus Torvalds1da177e2005-04-16 15:20:36 -07003292 l2cap_chan_del(sk, ECONNRESET);
3293 bh_unlock_sock(sk);
3294
3295 l2cap_sock_kill(sk);
3296 return 0;
3297}
3298
3299static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3300{
3301 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3302 u16 dcid, scid;
3303 struct sock *sk;
3304
3305 scid = __le16_to_cpu(rsp->scid);
3306 dcid = __le16_to_cpu(rsp->dcid);
3307
3308 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3309
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003310 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3311 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003312 return 0;
3313
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02003314 /* don't delete l2cap channel if sk is owned by user */
3315 if (sock_owned_by_user(sk)) {
3316 sk->sk_state = BT_DISCONN;
3317 l2cap_sock_clear_timer(sk);
3318 l2cap_sock_set_timer(sk, HZ / 5);
3319 bh_unlock_sock(sk);
3320 return 0;
3321 }
3322
Linus Torvalds1da177e2005-04-16 15:20:36 -07003323 l2cap_chan_del(sk, 0);
3324 bh_unlock_sock(sk);
3325
3326 l2cap_sock_kill(sk);
3327 return 0;
3328}
3329
3330static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3331{
3332 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003333 u16 type;
3334
3335 type = __le16_to_cpu(req->type);
3336
3337 BT_DBG("type 0x%4.4x", type);
3338
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003339 if (type == L2CAP_IT_FEAT_MASK) {
3340 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003341 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003342 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3343 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3344 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03003345 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003346 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3347 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003348 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003349 l2cap_send_cmd(conn, cmd->ident,
3350 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003351 } else if (type == L2CAP_IT_FIXED_CHAN) {
3352 u8 buf[12];
3353 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3354 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3355 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3356 memcpy(buf + 4, l2cap_fixed_chan, 8);
3357 l2cap_send_cmd(conn, cmd->ident,
3358 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003359 } else {
3360 struct l2cap_info_rsp rsp;
3361 rsp.type = cpu_to_le16(type);
3362 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3363 l2cap_send_cmd(conn, cmd->ident,
3364 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3365 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003366
3367 return 0;
3368}
3369
3370static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3371{
3372 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3373 u16 type, result;
3374
3375 type = __le16_to_cpu(rsp->type);
3376 result = __le16_to_cpu(rsp->result);
3377
3378 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3379
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003380 del_timer(&conn->info_timer);
3381
Ville Tervoadb08ed2010-08-04 09:43:33 +03003382 if (result != L2CAP_IR_SUCCESS) {
3383 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3384 conn->info_ident = 0;
3385
3386 l2cap_conn_start(conn);
3387
3388 return 0;
3389 }
3390
Marcel Holtmann984947d2009-02-06 23:35:19 +01003391 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003392 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003393
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003394 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003395 struct l2cap_info_req req;
3396 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3397
3398 conn->info_ident = l2cap_get_ident(conn);
3399
3400 l2cap_send_cmd(conn, conn->info_ident,
3401 L2CAP_INFO_REQ, sizeof(req), &req);
3402 } else {
3403 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3404 conn->info_ident = 0;
3405
3406 l2cap_conn_start(conn);
3407 }
3408 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003409 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003410 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003411
3412 l2cap_conn_start(conn);
3413 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003414
Linus Torvalds1da177e2005-04-16 15:20:36 -07003415 return 0;
3416}
3417
3418static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3419{
3420 u8 *data = skb->data;
3421 int len = skb->len;
3422 struct l2cap_cmd_hdr cmd;
3423 int err = 0;
3424
3425 l2cap_raw_recv(conn, skb);
3426
3427 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003428 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003429 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3430 data += L2CAP_CMD_HDR_SIZE;
3431 len -= L2CAP_CMD_HDR_SIZE;
3432
Al Viro88219a02007-07-29 00:17:25 -07003433 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003434
Al Viro88219a02007-07-29 00:17:25 -07003435 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 -07003436
Al Viro88219a02007-07-29 00:17:25 -07003437 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003438 BT_DBG("corrupted command");
3439 break;
3440 }
3441
3442 switch (cmd.code) {
3443 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003444 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003445 break;
3446
3447 case L2CAP_CONN_REQ:
3448 err = l2cap_connect_req(conn, &cmd, data);
3449 break;
3450
3451 case L2CAP_CONN_RSP:
3452 err = l2cap_connect_rsp(conn, &cmd, data);
3453 break;
3454
3455 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003456 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003457 break;
3458
3459 case L2CAP_CONF_RSP:
3460 err = l2cap_config_rsp(conn, &cmd, data);
3461 break;
3462
3463 case L2CAP_DISCONN_REQ:
3464 err = l2cap_disconnect_req(conn, &cmd, data);
3465 break;
3466
3467 case L2CAP_DISCONN_RSP:
3468 err = l2cap_disconnect_rsp(conn, &cmd, data);
3469 break;
3470
3471 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003472 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003473 break;
3474
3475 case L2CAP_ECHO_RSP:
3476 break;
3477
3478 case L2CAP_INFO_REQ:
3479 err = l2cap_information_req(conn, &cmd, data);
3480 break;
3481
3482 case L2CAP_INFO_RSP:
3483 err = l2cap_information_rsp(conn, &cmd, data);
3484 break;
3485
3486 default:
3487 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3488 err = -EINVAL;
3489 break;
3490 }
3491
3492 if (err) {
3493 struct l2cap_cmd_rej rej;
3494 BT_DBG("error %d", err);
3495
3496 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003497 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003498 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3499 }
3500
Al Viro88219a02007-07-29 00:17:25 -07003501 data += cmd_len;
3502 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003503 }
3504
3505 kfree_skb(skb);
3506}
3507
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003508static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3509{
3510 u16 our_fcs, rcv_fcs;
3511 int hdr_size = L2CAP_HDR_SIZE + 2;
3512
3513 if (pi->fcs == L2CAP_FCS_CRC16) {
3514 skb_trim(skb, skb->len - 2);
3515 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3516 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3517
3518 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03003519 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003520 }
3521 return 0;
3522}
3523
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003524static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3525{
3526 struct l2cap_pinfo *pi = l2cap_pi(sk);
3527 u16 control = 0;
3528
3529 pi->frames_sent = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003530
3531 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3532
3533 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan64988862010-05-10 14:54:14 -03003534 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003535 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003536 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003537 }
3538
Gustavo F. Padovan4ea727e2010-06-03 16:34:20 -03003539 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY)
3540 l2cap_retransmit_frames(sk);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003541
3542 l2cap_ertm_send(sk);
3543
3544 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3545 pi->frames_sent == 0) {
3546 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003547 l2cap_send_sframe(pi, control);
3548 }
3549}
3550
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003551static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003552{
3553 struct sk_buff *next_skb;
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003554 struct l2cap_pinfo *pi = l2cap_pi(sk);
3555 int tx_seq_offset, next_tx_seq_offset;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003556
3557 bt_cb(skb)->tx_seq = tx_seq;
3558 bt_cb(skb)->sar = sar;
3559
3560 next_skb = skb_peek(SREJ_QUEUE(sk));
3561 if (!next_skb) {
3562 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003563 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003564 }
3565
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003566 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3567 if (tx_seq_offset < 0)
3568 tx_seq_offset += 64;
3569
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003570 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003571 if (bt_cb(next_skb)->tx_seq == tx_seq)
3572 return -EINVAL;
3573
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003574 next_tx_seq_offset = (bt_cb(next_skb)->tx_seq -
3575 pi->buffer_seq) % 64;
3576 if (next_tx_seq_offset < 0)
3577 next_tx_seq_offset += 64;
3578
3579 if (next_tx_seq_offset > tx_seq_offset) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003580 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003581 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003582 }
3583
3584 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3585 break;
3586
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003587 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003588
3589 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003590
3591 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003592}
3593
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003594static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3595{
3596 struct l2cap_pinfo *pi = l2cap_pi(sk);
3597 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003598 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003599
3600 switch (control & L2CAP_CTRL_SAR) {
3601 case L2CAP_SDU_UNSEGMENTED:
3602 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3603 goto drop;
3604
3605 err = sock_queue_rcv_skb(sk, skb);
3606 if (!err)
3607 return err;
3608
3609 break;
3610
3611 case L2CAP_SDU_START:
3612 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3613 goto drop;
3614
3615 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003616
3617 if (pi->sdu_len > pi->imtu)
3618 goto disconnect;
3619
3620 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003621 if (!pi->sdu)
3622 return -ENOMEM;
3623
3624 /* pull sdu_len bytes only after alloc, because of Local Busy
3625 * condition we have to be sure that this will be executed
3626 * only once, i.e., when alloc does not fail */
3627 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003628
3629 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3630
3631 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3632 pi->partial_sdu_len = skb->len;
3633 break;
3634
3635 case L2CAP_SDU_CONTINUE:
3636 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3637 goto disconnect;
3638
3639 if (!pi->sdu)
3640 goto disconnect;
3641
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003642 pi->partial_sdu_len += skb->len;
3643 if (pi->partial_sdu_len > pi->sdu_len)
3644 goto drop;
3645
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003646 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3647
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003648 break;
3649
3650 case L2CAP_SDU_END:
3651 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3652 goto disconnect;
3653
3654 if (!pi->sdu)
3655 goto disconnect;
3656
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003657 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003658 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003659
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003660 if (pi->partial_sdu_len > pi->imtu)
3661 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003662
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003663 if (pi->partial_sdu_len != pi->sdu_len)
3664 goto drop;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003665
3666 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003667 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003668
3669 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003670 if (!_skb) {
3671 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3672 return -ENOMEM;
3673 }
3674
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003675 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003676 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003677 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003678 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3679 return err;
3680 }
3681
3682 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
3683 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003684
3685 kfree_skb(pi->sdu);
3686 break;
3687 }
3688
3689 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003690 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003691
3692drop:
3693 kfree_skb(pi->sdu);
3694 pi->sdu = NULL;
3695
3696disconnect:
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003697 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003698 kfree_skb(skb);
3699 return 0;
3700}
3701
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003702static int l2cap_try_push_rx_skb(struct sock *sk)
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003703{
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003704 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003705 struct sk_buff *skb;
3706 u16 control;
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003707 int err;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003708
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003709 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
3710 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3711 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3712 if (err < 0) {
3713 skb_queue_head(BUSY_QUEUE(sk), skb);
3714 return -EBUSY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003715 }
3716
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003717 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003718 }
3719
3720 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
3721 goto done;
3722
3723 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3724 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
3725 l2cap_send_sframe(pi, control);
3726 l2cap_pi(sk)->retry_count = 1;
3727
3728 del_timer(&pi->retrans_timer);
3729 __mod_monitor_timer();
3730
3731 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
3732
3733done:
3734 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
3735 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
3736
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003737 BT_DBG("sk %p, Exit local busy", sk);
3738
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003739 return 0;
3740}
3741
3742static void l2cap_busy_work(struct work_struct *work)
3743{
3744 DECLARE_WAITQUEUE(wait, current);
3745 struct l2cap_pinfo *pi =
3746 container_of(work, struct l2cap_pinfo, busy_work);
3747 struct sock *sk = (struct sock *)pi;
3748 int n_tries = 0, timeo = HZ/5, err;
3749 struct sk_buff *skb;
3750
3751 lock_sock(sk);
3752
3753 add_wait_queue(sk_sleep(sk), &wait);
3754 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
3755 set_current_state(TASK_INTERRUPTIBLE);
3756
3757 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
3758 err = -EBUSY;
3759 l2cap_send_disconn_req(pi->conn, sk, EBUSY);
3760 break;
3761 }
3762
3763 if (!timeo)
3764 timeo = HZ/5;
3765
3766 if (signal_pending(current)) {
3767 err = sock_intr_errno(timeo);
3768 break;
3769 }
3770
3771 release_sock(sk);
3772 timeo = schedule_timeout(timeo);
3773 lock_sock(sk);
3774
3775 err = sock_error(sk);
3776 if (err)
3777 break;
3778
3779 if (l2cap_try_push_rx_skb(sk) == 0)
3780 break;
3781 }
3782
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003783 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003784 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003785
3786 release_sock(sk);
3787}
3788
3789static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
3790{
3791 struct l2cap_pinfo *pi = l2cap_pi(sk);
3792 int sctrl, err;
3793
3794 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3795 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3796 __skb_queue_tail(BUSY_QUEUE(sk), skb);
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003797 return l2cap_try_push_rx_skb(sk);
3798
3799
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003800 }
3801
3802 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3803 if (err >= 0) {
3804 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3805 return err;
3806 }
3807
3808 /* Busy Condition */
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003809 BT_DBG("sk %p, Enter local busy", sk);
3810
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003811 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
3812 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3813 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3814
3815 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3816 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
3817 l2cap_send_sframe(pi, sctrl);
3818
3819 pi->conn_state |= L2CAP_CONN_RNR_SENT;
3820
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03003821 del_timer(&pi->ack_timer);
3822
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003823 queue_work(_busy_wq, &pi->busy_work);
3824
3825 return err;
3826}
3827
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003828static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003829{
3830 struct l2cap_pinfo *pi = l2cap_pi(sk);
3831 struct sk_buff *_skb;
3832 int err = -EINVAL;
3833
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003834 /*
3835 * TODO: We have to notify the userland if some data is lost with the
3836 * Streaming Mode.
3837 */
3838
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003839 switch (control & L2CAP_CTRL_SAR) {
3840 case L2CAP_SDU_UNSEGMENTED:
3841 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3842 kfree_skb(pi->sdu);
3843 break;
3844 }
3845
3846 err = sock_queue_rcv_skb(sk, skb);
3847 if (!err)
3848 return 0;
3849
3850 break;
3851
3852 case L2CAP_SDU_START:
3853 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3854 kfree_skb(pi->sdu);
3855 break;
3856 }
3857
3858 pi->sdu_len = get_unaligned_le16(skb->data);
3859 skb_pull(skb, 2);
3860
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003861 if (pi->sdu_len > pi->imtu) {
3862 err = -EMSGSIZE;
3863 break;
3864 }
3865
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003866 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3867 if (!pi->sdu) {
3868 err = -ENOMEM;
3869 break;
3870 }
3871
3872 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3873
3874 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3875 pi->partial_sdu_len = skb->len;
3876 err = 0;
3877 break;
3878
3879 case L2CAP_SDU_CONTINUE:
3880 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3881 break;
3882
3883 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3884
3885 pi->partial_sdu_len += skb->len;
3886 if (pi->partial_sdu_len > pi->sdu_len)
3887 kfree_skb(pi->sdu);
3888 else
3889 err = 0;
3890
3891 break;
3892
3893 case L2CAP_SDU_END:
3894 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3895 break;
3896
3897 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3898
3899 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3900 pi->partial_sdu_len += skb->len;
3901
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003902 if (pi->partial_sdu_len > pi->imtu)
3903 goto drop;
3904
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003905 if (pi->partial_sdu_len == pi->sdu_len) {
3906 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3907 err = sock_queue_rcv_skb(sk, _skb);
3908 if (err < 0)
3909 kfree_skb(_skb);
3910 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003911 err = 0;
3912
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003913drop:
3914 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003915 break;
3916 }
3917
3918 kfree_skb(skb);
3919 return err;
3920}
3921
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003922static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3923{
3924 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003925 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003926
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003927 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003928 if (bt_cb(skb)->tx_seq != tx_seq)
3929 break;
3930
3931 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003932 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003933 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003934 l2cap_pi(sk)->buffer_seq_srej =
3935 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003936 tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003937 }
3938}
3939
3940static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3941{
3942 struct l2cap_pinfo *pi = l2cap_pi(sk);
3943 struct srej_list *l, *tmp;
3944 u16 control;
3945
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003946 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003947 if (l->tx_seq == tx_seq) {
3948 list_del(&l->list);
3949 kfree(l);
3950 return;
3951 }
3952 control = L2CAP_SUPER_SELECT_REJECT;
3953 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3954 l2cap_send_sframe(pi, control);
3955 list_del(&l->list);
3956 list_add_tail(&l->list, SREJ_LIST(sk));
3957 }
3958}
3959
3960static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3961{
3962 struct l2cap_pinfo *pi = l2cap_pi(sk);
3963 struct srej_list *new;
3964 u16 control;
3965
3966 while (tx_seq != pi->expected_tx_seq) {
3967 control = L2CAP_SUPER_SELECT_REJECT;
3968 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3969 l2cap_send_sframe(pi, control);
3970
3971 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003972 new->tx_seq = pi->expected_tx_seq;
3973 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003974 list_add_tail(&new->list, SREJ_LIST(sk));
3975 }
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003976 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003977}
3978
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003979static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3980{
3981 struct l2cap_pinfo *pi = l2cap_pi(sk);
3982 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003983 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003984 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03003985 int tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003986 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003987 int err = 0;
3988
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003989 BT_DBG("sk %p len %d tx_seq %d rx_control 0x%4.4x", sk, skb->len, tx_seq,
3990 rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003991
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003992 if (L2CAP_CTRL_FINAL & rx_control &&
3993 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003994 del_timer(&pi->monitor_timer);
3995 if (pi->unacked_frames > 0)
3996 __mod_retrans_timer();
3997 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3998 }
3999
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03004000 pi->expected_ack_seq = req_seq;
4001 l2cap_drop_acked_frames(sk);
4002
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004003 if (tx_seq == pi->expected_tx_seq)
4004 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004005
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03004006 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
4007 if (tx_seq_offset < 0)
4008 tx_seq_offset += 64;
4009
4010 /* invalid tx_seq */
4011 if (tx_seq_offset >= pi->tx_win) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03004012 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03004013 goto drop;
4014 }
4015
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004016 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
4017 goto drop;
4018
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004019 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
4020 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004021
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004022 first = list_first_entry(SREJ_LIST(sk),
4023 struct srej_list, list);
4024 if (tx_seq == first->tx_seq) {
4025 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
4026 l2cap_check_srej_gap(sk, tx_seq);
4027
4028 list_del(&first->list);
4029 kfree(first);
4030
4031 if (list_empty(SREJ_LIST(sk))) {
4032 pi->buffer_seq = pi->buffer_seq_srej;
4033 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666c2010-05-01 16:15:40 -03004034 l2cap_send_ack(pi);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004035 BT_DBG("sk %p, Exit SREJ_SENT", sk);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004036 }
4037 } else {
4038 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03004039
4040 /* duplicated tx_seq */
4041 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
4042 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004043
4044 list_for_each_entry(l, SREJ_LIST(sk), list) {
4045 if (l->tx_seq == tx_seq) {
4046 l2cap_resend_srejframe(sk, tx_seq);
4047 return 0;
4048 }
4049 }
4050 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004051 }
4052 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03004053 expected_tx_seq_offset =
4054 (pi->expected_tx_seq - pi->buffer_seq) % 64;
4055 if (expected_tx_seq_offset < 0)
4056 expected_tx_seq_offset += 64;
4057
4058 /* duplicated tx_seq */
4059 if (tx_seq_offset < expected_tx_seq_offset)
4060 goto drop;
4061
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004062 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004063
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004064 BT_DBG("sk %p, Enter SREJ", sk);
4065
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004066 INIT_LIST_HEAD(SREJ_LIST(sk));
4067 pi->buffer_seq_srej = pi->buffer_seq;
4068
4069 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004070 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004071 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
4072
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03004073 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
4074
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004075 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03004076
4077 del_timer(&pi->ack_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004078 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004079 return 0;
4080
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004081expected:
4082 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4083
4084 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03004085 bt_cb(skb)->tx_seq = tx_seq;
4086 bt_cb(skb)->sar = sar;
4087 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004088 return 0;
4089 }
4090
Gustavo F. Padovan2ece3682010-06-16 17:21:44 -03004091 err = l2cap_push_rx_skb(sk, skb, rx_control);
4092 if (err < 0)
4093 return 0;
4094
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03004095 if (rx_control & L2CAP_CTRL_FINAL) {
4096 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4097 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004098 else
4099 l2cap_retransmit_frames(sk);
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03004100 }
4101
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03004102 __mod_ack_timer();
4103
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03004104 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
4105 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03004106 l2cap_send_ack(pi);
4107
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004108 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03004109
4110drop:
4111 kfree_skb(skb);
4112 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004113}
4114
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004115static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004116{
4117 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03004118
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004119 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control),
4120 rx_control);
4121
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03004122 pi->expected_ack_seq = __get_reqseq(rx_control);
4123 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004124
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004125 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004126 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03004127 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
4128 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
4129 (pi->unacked_frames > 0))
4130 __mod_retrans_timer();
4131
4132 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4133 l2cap_send_srejtail(sk);
4134 } else {
4135 l2cap_send_i_or_rr_or_rnr(sk);
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03004136 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004137
4138 } else if (rx_control & L2CAP_CTRL_FINAL) {
4139 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004140
4141 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4142 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004143 else
4144 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004145
4146 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004147 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
4148 (pi->unacked_frames > 0))
4149 __mod_retrans_timer();
4150
4151 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Andrei Emeltchenko894718a2010-12-01 16:58:24 +02004152 if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004153 l2cap_send_ack(pi);
Andrei Emeltchenko894718a2010-12-01 16:58:24 +02004154 else
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004155 l2cap_ertm_send(sk);
4156 }
4157}
4158
4159static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
4160{
4161 struct l2cap_pinfo *pi = l2cap_pi(sk);
4162 u8 tx_seq = __get_reqseq(rx_control);
4163
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004164 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4165
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004166 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4167
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03004168 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004169 l2cap_drop_acked_frames(sk);
4170
4171 if (rx_control & L2CAP_CTRL_FINAL) {
4172 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4173 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004174 else
4175 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004176 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004177 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004178
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03004179 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004180 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004181 }
4182}
4183static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
4184{
4185 struct l2cap_pinfo *pi = l2cap_pi(sk);
4186 u8 tx_seq = __get_reqseq(rx_control);
4187
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004188 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4189
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004190 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4191
4192 if (rx_control & L2CAP_CTRL_POLL) {
4193 pi->expected_ack_seq = tx_seq;
4194 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004195
4196 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004197 l2cap_retransmit_one_frame(sk, tx_seq);
4198
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004199 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004200
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004201 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4202 pi->srej_save_reqseq = tx_seq;
4203 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4204 }
4205 } else if (rx_control & L2CAP_CTRL_FINAL) {
4206 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
4207 pi->srej_save_reqseq == tx_seq)
4208 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
4209 else
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004210 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004211 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004212 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004213 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4214 pi->srej_save_reqseq = tx_seq;
4215 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4216 }
4217 }
4218}
4219
4220static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
4221{
4222 struct l2cap_pinfo *pi = l2cap_pi(sk);
4223 u8 tx_seq = __get_reqseq(rx_control);
4224
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004225 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4226
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004227 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
4228 pi->expected_ack_seq = tx_seq;
4229 l2cap_drop_acked_frames(sk);
4230
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004231 if (rx_control & L2CAP_CTRL_POLL)
4232 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
4233
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004234 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
4235 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03004236 if (rx_control & L2CAP_CTRL_POLL)
4237 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004238 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004239 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004240
4241 if (rx_control & L2CAP_CTRL_POLL)
4242 l2cap_send_srejtail(sk);
4243 else
4244 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004245}
4246
4247static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
4248{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004249 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
4250
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03004251 if (L2CAP_CTRL_FINAL & rx_control &&
4252 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004253 del_timer(&l2cap_pi(sk)->monitor_timer);
4254 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004255 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004256 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004257 }
4258
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004259 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
4260 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004261 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004262 break;
4263
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004264 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004265 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004266 break;
4267
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004268 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004269 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004270 break;
4271
4272 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004273 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004274 break;
4275 }
4276
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03004277 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004278 return 0;
4279}
4280
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004281static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
4282{
4283 struct l2cap_pinfo *pi = l2cap_pi(sk);
4284 u16 control;
4285 u8 req_seq;
4286 int len, next_tx_seq_offset, req_seq_offset;
4287
4288 control = get_unaligned_le16(skb->data);
4289 skb_pull(skb, 2);
4290 len = skb->len;
4291
4292 /*
4293 * We can just drop the corrupted I-frame here.
4294 * Receiver will miss it and start proper recovery
4295 * procedures and ask retransmission.
4296 */
4297 if (l2cap_check_fcs(pi, skb))
4298 goto drop;
4299
4300 if (__is_sar_start(control) && __is_iframe(control))
4301 len -= 2;
4302
4303 if (pi->fcs == L2CAP_FCS_CRC16)
4304 len -= 2;
4305
4306 if (len > pi->mps) {
4307 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4308 goto drop;
4309 }
4310
4311 req_seq = __get_reqseq(control);
4312 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
4313 if (req_seq_offset < 0)
4314 req_seq_offset += 64;
4315
4316 next_tx_seq_offset =
4317 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
4318 if (next_tx_seq_offset < 0)
4319 next_tx_seq_offset += 64;
4320
4321 /* check for invalid req-seq */
4322 if (req_seq_offset > next_tx_seq_offset) {
4323 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4324 goto drop;
4325 }
4326
4327 if (__is_iframe(control)) {
4328 if (len < 0) {
4329 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4330 goto drop;
4331 }
4332
4333 l2cap_data_channel_iframe(sk, control, skb);
4334 } else {
4335 if (len != 0) {
4336 BT_ERR("%d", len);
4337 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4338 goto drop;
4339 }
4340
4341 l2cap_data_channel_sframe(sk, control, skb);
4342 }
4343
4344 return 0;
4345
4346drop:
4347 kfree_skb(skb);
4348 return 0;
4349}
4350
Linus Torvalds1da177e2005-04-16 15:20:36 -07004351static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
4352{
4353 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004354 struct l2cap_pinfo *pi;
Nathan Holstein51893f82010-06-09 15:46:25 -04004355 u16 control;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004356 u8 tx_seq;
4357 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004358
4359 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
4360 if (!sk) {
4361 BT_DBG("unknown cid 0x%4.4x", cid);
4362 goto drop;
4363 }
4364
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004365 pi = l2cap_pi(sk);
4366
Linus Torvalds1da177e2005-04-16 15:20:36 -07004367 BT_DBG("sk %p, len %d", sk, skb->len);
4368
4369 if (sk->sk_state != BT_CONNECTED)
4370 goto drop;
4371
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004372 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004373 case L2CAP_MODE_BASIC:
4374 /* If socket recv buffers overflows we drop data here
4375 * which is *bad* because L2CAP has to be reliable.
4376 * But we don't have any other choice. L2CAP doesn't
4377 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004378
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004379 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004380 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004381
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004382 if (!sock_queue_rcv_skb(sk, skb))
4383 goto done;
4384 break;
4385
4386 case L2CAP_MODE_ERTM:
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004387 if (!sock_owned_by_user(sk)) {
4388 l2cap_ertm_data_rcv(sk, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004389 } else {
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004390 if (sk_add_backlog(sk, skb))
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004391 goto drop;
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004392 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004393
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004394 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004395
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004396 case L2CAP_MODE_STREAMING:
4397 control = get_unaligned_le16(skb->data);
4398 skb_pull(skb, 2);
4399 len = skb->len;
4400
Gustavo F. Padovan26000082010-05-11 22:02:00 -03004401 if (l2cap_check_fcs(pi, skb))
4402 goto drop;
4403
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004404 if (__is_sar_start(control))
4405 len -= 2;
4406
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004407 if (pi->fcs == L2CAP_FCS_CRC16)
4408 len -= 2;
4409
Nathan Holstein51893f82010-06-09 15:46:25 -04004410 if (len > pi->mps || len < 0 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004411 goto drop;
4412
4413 tx_seq = __get_txseq(control);
4414
4415 if (pi->expected_tx_seq == tx_seq)
4416 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4417 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03004418 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004419
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004420 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004421
4422 goto done;
4423
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004424 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03004425 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004426 break;
4427 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004428
4429drop:
4430 kfree_skb(skb);
4431
4432done:
Marcel Holtmann01394182006-07-03 10:02:46 +02004433 if (sk)
4434 bh_unlock_sock(sk);
4435
Linus Torvalds1da177e2005-04-16 15:20:36 -07004436 return 0;
4437}
4438
Al Viro8e036fc2007-07-29 00:16:36 -07004439static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004440{
4441 struct sock *sk;
4442
4443 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
4444 if (!sk)
4445 goto drop;
4446
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00004447 bh_lock_sock(sk);
4448
Linus Torvalds1da177e2005-04-16 15:20:36 -07004449 BT_DBG("sk %p, len %d", sk, skb->len);
4450
4451 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
4452 goto drop;
4453
4454 if (l2cap_pi(sk)->imtu < skb->len)
4455 goto drop;
4456
4457 if (!sock_queue_rcv_skb(sk, skb))
4458 goto done;
4459
4460drop:
4461 kfree_skb(skb);
4462
4463done:
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03004464 if (sk)
4465 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004466 return 0;
4467}
4468
4469static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
4470{
4471 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07004472 u16 cid, len;
4473 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004474
4475 skb_pull(skb, L2CAP_HDR_SIZE);
4476 cid = __le16_to_cpu(lh->cid);
4477 len = __le16_to_cpu(lh->len);
4478
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004479 if (len != skb->len) {
4480 kfree_skb(skb);
4481 return;
4482 }
4483
Linus Torvalds1da177e2005-04-16 15:20:36 -07004484 BT_DBG("len %d, cid 0x%4.4x", len, cid);
4485
4486 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004487 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004488 l2cap_sig_channel(conn, skb);
4489 break;
4490
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004491 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004492 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004493 skb_pull(skb, 2);
4494 l2cap_conless_channel(conn, psm, skb);
4495 break;
4496
4497 default:
4498 l2cap_data_channel(conn, cid, skb);
4499 break;
4500 }
4501}
4502
4503/* ---- L2CAP interface with lower layer (HCI) ---- */
4504
4505static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
4506{
4507 int exact = 0, lm1 = 0, lm2 = 0;
4508 register struct sock *sk;
4509 struct hlist_node *node;
4510
4511 if (type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03004512 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004513
4514 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
4515
4516 /* Find listening sockets and check their link_mode */
4517 read_lock(&l2cap_sk_list.lock);
4518 sk_for_each(sk, node, &l2cap_sk_list.head) {
4519 if (sk->sk_state != BT_LISTEN)
4520 continue;
4521
4522 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004523 lm1 |= HCI_LM_ACCEPT;
4524 if (l2cap_pi(sk)->role_switch)
4525 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004526 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004527 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
4528 lm2 |= HCI_LM_ACCEPT;
4529 if (l2cap_pi(sk)->role_switch)
4530 lm2 |= HCI_LM_MASTER;
4531 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004532 }
4533 read_unlock(&l2cap_sk_list.lock);
4534
4535 return exact ? lm1 : lm2;
4536}
4537
4538static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
4539{
Marcel Holtmann01394182006-07-03 10:02:46 +02004540 struct l2cap_conn *conn;
4541
Linus Torvalds1da177e2005-04-16 15:20:36 -07004542 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
4543
4544 if (hcon->type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03004545 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004546
4547 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004548 conn = l2cap_conn_add(hcon, status);
4549 if (conn)
4550 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02004551 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004552 l2cap_conn_del(hcon, bt_err(status));
4553
4554 return 0;
4555}
4556
Marcel Holtmann2950f212009-02-12 14:02:50 +01004557static int l2cap_disconn_ind(struct hci_conn *hcon)
4558{
4559 struct l2cap_conn *conn = hcon->l2cap_data;
4560
4561 BT_DBG("hcon %p", hcon);
4562
4563 if (hcon->type != ACL_LINK || !conn)
4564 return 0x13;
4565
4566 return conn->disc_reason;
4567}
4568
4569static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004570{
4571 BT_DBG("hcon %p reason %d", hcon, reason);
4572
4573 if (hcon->type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03004574 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004575
4576 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004577
Linus Torvalds1da177e2005-04-16 15:20:36 -07004578 return 0;
4579}
4580
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004581static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4582{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004583 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004584 return;
4585
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004586 if (encrypt == 0x00) {
4587 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4588 l2cap_sock_clear_timer(sk);
4589 l2cap_sock_set_timer(sk, HZ * 5);
4590 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4591 __l2cap_sock_close(sk, ECONNREFUSED);
4592 } else {
4593 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4594 l2cap_sock_clear_timer(sk);
4595 }
4596}
4597
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004598static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004599{
4600 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004601 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004602 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004603
Marcel Holtmann01394182006-07-03 10:02:46 +02004604 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004605 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004606
Linus Torvalds1da177e2005-04-16 15:20:36 -07004607 l = &conn->chan_list;
4608
4609 BT_DBG("conn %p", conn);
4610
4611 read_lock(&l->lock);
4612
4613 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4614 bh_lock_sock(sk);
4615
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004616 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4617 bh_unlock_sock(sk);
4618 continue;
4619 }
4620
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004621 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004622 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004623 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004624 bh_unlock_sock(sk);
4625 continue;
4626 }
4627
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004628 if (sk->sk_state == BT_CONNECT) {
4629 if (!status) {
4630 struct l2cap_conn_req req;
4631 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4632 req.psm = l2cap_pi(sk)->psm;
4633
4634 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03004635 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004636
4637 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4638 L2CAP_CONN_REQ, sizeof(req), &req);
4639 } else {
4640 l2cap_sock_clear_timer(sk);
4641 l2cap_sock_set_timer(sk, HZ / 10);
4642 }
4643 } else if (sk->sk_state == BT_CONNECT2) {
4644 struct l2cap_conn_rsp rsp;
4645 __u16 result;
4646
4647 if (!status) {
4648 sk->sk_state = BT_CONFIG;
4649 result = L2CAP_CR_SUCCESS;
4650 } else {
4651 sk->sk_state = BT_DISCONN;
4652 l2cap_sock_set_timer(sk, HZ / 10);
4653 result = L2CAP_CR_SEC_BLOCK;
4654 }
4655
4656 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4657 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4658 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004659 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004660 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4661 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004662 }
4663
Linus Torvalds1da177e2005-04-16 15:20:36 -07004664 bh_unlock_sock(sk);
4665 }
4666
4667 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004668
Linus Torvalds1da177e2005-04-16 15:20:36 -07004669 return 0;
4670}
4671
4672static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4673{
4674 struct l2cap_conn *conn = hcon->l2cap_data;
4675
4676 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4677 goto drop;
4678
4679 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4680
4681 if (flags & ACL_START) {
4682 struct l2cap_hdr *hdr;
Andrei Emeltchenko89794812010-09-15 14:28:44 +03004683 struct sock *sk;
4684 u16 cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004685 int len;
4686
4687 if (conn->rx_len) {
4688 BT_ERR("Unexpected start frame (len %d)", skb->len);
4689 kfree_skb(conn->rx_skb);
4690 conn->rx_skb = NULL;
4691 conn->rx_len = 0;
4692 l2cap_conn_unreliable(conn, ECOMM);
4693 }
4694
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03004695 /* Start fragment always begin with Basic L2CAP header */
4696 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004697 BT_ERR("Frame is too short (len %d)", skb->len);
4698 l2cap_conn_unreliable(conn, ECOMM);
4699 goto drop;
4700 }
4701
4702 hdr = (struct l2cap_hdr *) skb->data;
4703 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
Andrei Emeltchenko89794812010-09-15 14:28:44 +03004704 cid = __le16_to_cpu(hdr->cid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004705
4706 if (len == skb->len) {
4707 /* Complete frame received */
4708 l2cap_recv_frame(conn, skb);
4709 return 0;
4710 }
4711
4712 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4713
4714 if (skb->len > len) {
4715 BT_ERR("Frame is too long (len %d, expected len %d)",
4716 skb->len, len);
4717 l2cap_conn_unreliable(conn, ECOMM);
4718 goto drop;
4719 }
4720
Andrei Emeltchenko89794812010-09-15 14:28:44 +03004721 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
4722
4723 if (sk && l2cap_pi(sk)->imtu < len - L2CAP_HDR_SIZE) {
4724 BT_ERR("Frame exceeding recv MTU (len %d, MTU %d)",
4725 len, l2cap_pi(sk)->imtu);
4726 bh_unlock_sock(sk);
4727 l2cap_conn_unreliable(conn, ECOMM);
4728 goto drop;
4729 }
4730
4731 if (sk)
4732 bh_unlock_sock(sk);
4733
Linus Torvalds1da177e2005-04-16 15:20:36 -07004734 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03004735 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4736 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004737 goto drop;
4738
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004739 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004740 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004741 conn->rx_len = len - skb->len;
4742 } else {
4743 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4744
4745 if (!conn->rx_len) {
4746 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4747 l2cap_conn_unreliable(conn, ECOMM);
4748 goto drop;
4749 }
4750
4751 if (skb->len > conn->rx_len) {
4752 BT_ERR("Fragment is too long (len %d, expected %d)",
4753 skb->len, conn->rx_len);
4754 kfree_skb(conn->rx_skb);
4755 conn->rx_skb = NULL;
4756 conn->rx_len = 0;
4757 l2cap_conn_unreliable(conn, ECOMM);
4758 goto drop;
4759 }
4760
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004761 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004762 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004763 conn->rx_len -= skb->len;
4764
4765 if (!conn->rx_len) {
4766 /* Complete frame received */
4767 l2cap_recv_frame(conn, conn->rx_skb);
4768 conn->rx_skb = NULL;
4769 }
4770 }
4771
4772drop:
4773 kfree_skb(skb);
4774 return 0;
4775}
4776
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004777static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004778{
4779 struct sock *sk;
4780 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004781
4782 read_lock_bh(&l2cap_sk_list.lock);
4783
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004784 sk_for_each(sk, node, &l2cap_sk_list.head) {
4785 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004786
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004787 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4788 batostr(&bt_sk(sk)->src),
4789 batostr(&bt_sk(sk)->dst),
4790 sk->sk_state, __le16_to_cpu(pi->psm),
4791 pi->scid, pi->dcid,
4792 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004793 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004794
Linus Torvalds1da177e2005-04-16 15:20:36 -07004795 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004796
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004797 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004798}
4799
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004800static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4801{
4802 return single_open(file, l2cap_debugfs_show, inode->i_private);
4803}
4804
4805static const struct file_operations l2cap_debugfs_fops = {
4806 .open = l2cap_debugfs_open,
4807 .read = seq_read,
4808 .llseek = seq_lseek,
4809 .release = single_release,
4810};
4811
4812static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004813
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004814static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004815 .family = PF_BLUETOOTH,
4816 .owner = THIS_MODULE,
4817 .release = l2cap_sock_release,
4818 .bind = l2cap_sock_bind,
4819 .connect = l2cap_sock_connect,
4820 .listen = l2cap_sock_listen,
4821 .accept = l2cap_sock_accept,
4822 .getname = l2cap_sock_getname,
4823 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004824 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004825 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004826 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004827 .mmap = sock_no_mmap,
4828 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004829 .shutdown = l2cap_sock_shutdown,
4830 .setsockopt = l2cap_sock_setsockopt,
4831 .getsockopt = l2cap_sock_getsockopt
4832};
4833
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004834static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004835 .family = PF_BLUETOOTH,
4836 .owner = THIS_MODULE,
4837 .create = l2cap_sock_create,
4838};
4839
4840static struct hci_proto l2cap_hci_proto = {
4841 .name = "L2CAP",
4842 .id = HCI_PROTO_L2CAP,
4843 .connect_ind = l2cap_connect_ind,
4844 .connect_cfm = l2cap_connect_cfm,
4845 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004846 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004847 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004848 .recv_acldata = l2cap_recv_acldata
4849};
4850
4851static int __init l2cap_init(void)
4852{
4853 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004854
Linus Torvalds1da177e2005-04-16 15:20:36 -07004855 err = proto_register(&l2cap_proto, 0);
4856 if (err < 0)
4857 return err;
4858
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004859 _busy_wq = create_singlethread_workqueue("l2cap");
Anderson Lizardob78d7b4f2010-11-29 12:15:50 -04004860 if (!_busy_wq) {
4861 proto_unregister(&l2cap_proto);
4862 return -ENOMEM;
4863 }
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004864
Linus Torvalds1da177e2005-04-16 15:20:36 -07004865 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4866 if (err < 0) {
4867 BT_ERR("L2CAP socket registration failed");
4868 goto error;
4869 }
4870
4871 err = hci_register_proto(&l2cap_hci_proto);
4872 if (err < 0) {
4873 BT_ERR("L2CAP protocol registration failed");
4874 bt_sock_unregister(BTPROTO_L2CAP);
4875 goto error;
4876 }
4877
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004878 if (bt_debugfs) {
4879 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4880 bt_debugfs, NULL, &l2cap_debugfs_fops);
4881 if (!l2cap_debugfs)
4882 BT_ERR("Failed to create L2CAP debug file");
4883 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004884
4885 BT_INFO("L2CAP ver %s", VERSION);
4886 BT_INFO("L2CAP socket layer initialized");
4887
4888 return 0;
4889
4890error:
Anderson Lizardob78d7b4f2010-11-29 12:15:50 -04004891 destroy_workqueue(_busy_wq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004892 proto_unregister(&l2cap_proto);
4893 return err;
4894}
4895
4896static void __exit l2cap_exit(void)
4897{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004898 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004899
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004900 flush_workqueue(_busy_wq);
4901 destroy_workqueue(_busy_wq);
4902
Linus Torvalds1da177e2005-04-16 15:20:36 -07004903 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4904 BT_ERR("L2CAP socket unregistration failed");
4905
4906 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4907 BT_ERR("L2CAP protocol unregistration failed");
4908
4909 proto_unregister(&l2cap_proto);
4910}
4911
4912void l2cap_load(void)
4913{
4914 /* Dummy function to trigger automatic L2CAP module loading by
4915 * other modules that use L2CAP sockets but don't use any other
4916 * symbols from it. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004917}
4918EXPORT_SYMBOL(l2cap_load);
4919
4920module_init(l2cap_init);
4921module_exit(l2cap_exit);
4922
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004923module_param(disable_ertm, bool, 0644);
4924MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004925
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004926MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004927MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4928MODULE_VERSION(VERSION);
4929MODULE_LICENSE("GPL");
4930MODULE_ALIAS("bt-proto-0");