blob: ae227bf2556364bc91a2bcdb14f95b48ecf6d44f [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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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;
862
863 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
864 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
865 rsp.result = cpu_to_le16(result);
866 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
867 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
868 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
869 } else
870 l2cap_chan_del(sk, reason);
871 break;
872
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873 case BT_CONNECT:
874 case BT_DISCONN:
875 l2cap_chan_del(sk, reason);
876 break;
877
878 default:
879 sock_set_flag(sk, SOCK_ZAPPED);
880 break;
881 }
882}
883
884/* Must be called on unlocked socket. */
885static void l2cap_sock_close(struct sock *sk)
886{
887 l2cap_sock_clear_timer(sk);
888 lock_sock(sk);
889 __l2cap_sock_close(sk, ECONNRESET);
890 release_sock(sk);
891 l2cap_sock_kill(sk);
892}
893
894static void l2cap_sock_init(struct sock *sk, struct sock *parent)
895{
896 struct l2cap_pinfo *pi = l2cap_pi(sk);
897
898 BT_DBG("sk %p", sk);
899
900 if (parent) {
901 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100902 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
903
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904 pi->imtu = l2cap_pi(parent)->imtu;
905 pi->omtu = l2cap_pi(parent)->omtu;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300906 pi->conf_state = l2cap_pi(parent)->conf_state;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700907 pi->mode = l2cap_pi(parent)->mode;
908 pi->fcs = l2cap_pi(parent)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -0300909 pi->max_tx = l2cap_pi(parent)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -0300910 pi->tx_win = l2cap_pi(parent)->tx_win;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100911 pi->sec_level = l2cap_pi(parent)->sec_level;
912 pi->role_switch = l2cap_pi(parent)->role_switch;
913 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914 } else {
915 pi->imtu = L2CAP_DEFAULT_MTU;
916 pi->omtu = 0;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -0300917 if (!disable_ertm && sk->sk_type == SOCK_STREAM) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300918 pi->mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300919 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
920 } else {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300921 pi->mode = L2CAP_MODE_BASIC;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300922 }
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300923 pi->max_tx = L2CAP_DEFAULT_MAX_TX;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700924 pi->fcs = L2CAP_FCS_CRC16;
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300925 pi->tx_win = L2CAP_DEFAULT_TX_WINDOW;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100926 pi->sec_level = BT_SECURITY_LOW;
927 pi->role_switch = 0;
928 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929 }
930
931 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200932 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700933 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Dave Young45054dc2009-10-18 20:28:30 +0000934 skb_queue_head_init(TX_QUEUE(sk));
935 skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300936 skb_queue_head_init(BUSY_QUEUE(sk));
Dave Young45054dc2009-10-18 20:28:30 +0000937 INIT_LIST_HEAD(SREJ_LIST(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938}
939
940static struct proto l2cap_proto = {
941 .name = "L2CAP",
942 .owner = THIS_MODULE,
943 .obj_size = sizeof(struct l2cap_pinfo)
944};
945
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700946static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947{
948 struct sock *sk;
949
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700950 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951 if (!sk)
952 return NULL;
953
954 sock_init_data(sock, sk);
955 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
956
957 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200958 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959
960 sock_reset_flag(sk, SOCK_ZAPPED);
961
962 sk->sk_protocol = proto;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200963 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700964
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200965 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966
967 bt_sock_link(&l2cap_sk_list, sk);
968 return sk;
969}
970
Eric Paris3f378b62009-11-05 22:18:14 -0800971static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
972 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973{
974 struct sock *sk;
975
976 BT_DBG("sock %p", sock);
977
978 sock->state = SS_UNCONNECTED;
979
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300980 if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
982 return -ESOCKTNOSUPPORT;
983
Eric Parisc84b3262009-11-05 20:45:52 -0800984 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985 return -EPERM;
986
987 sock->ops = &l2cap_sock_ops;
988
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700989 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990 if (!sk)
991 return -ENOMEM;
992
993 l2cap_sock_init(sk, NULL);
994 return 0;
995}
996
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100997static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700999 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001000 struct sockaddr_l2 la;
1001 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001003 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004
1005 if (!addr || addr->sa_family != AF_BLUETOOTH)
1006 return -EINVAL;
1007
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001008 memset(&la, 0, sizeof(la));
1009 len = min_t(unsigned int, sizeof(la), alen);
1010 memcpy(&la, addr, len);
1011
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001012 if (la.l2_cid)
1013 return -EINVAL;
1014
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015 lock_sock(sk);
1016
1017 if (sk->sk_state != BT_OPEN) {
1018 err = -EBADFD;
1019 goto done;
1020 }
1021
Mat Martineau0fba2552010-09-08 10:05:26 -07001022 if (la.l2_psm) {
1023 __u16 psm = __le16_to_cpu(la.l2_psm);
1024
1025 /* PSM must be odd and lsb of upper byte must be 0 */
1026 if ((psm & 0x0101) != 0x0001) {
1027 err = -EINVAL;
1028 goto done;
1029 }
1030
1031 /* Restrict usage of well-known PSMs */
1032 if (psm < 0x1001 && !capable(CAP_NET_BIND_SERVICE)) {
1033 err = -EACCES;
1034 goto done;
1035 }
Marcel Holtmann847641d2007-01-22 22:00:45 +01001036 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001037
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038 write_lock_bh(&l2cap_sk_list.lock);
1039
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001040 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 err = -EADDRINUSE;
1042 } else {
1043 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001044 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
1045 l2cap_pi(sk)->psm = la.l2_psm;
1046 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001048
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001049 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
1050 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001051 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052 }
1053
1054 write_unlock_bh(&l2cap_sk_list.lock);
1055
1056done:
1057 release_sock(sk);
1058 return err;
1059}
1060
1061static int l2cap_do_connect(struct sock *sk)
1062{
1063 bdaddr_t *src = &bt_sk(sk)->src;
1064 bdaddr_t *dst = &bt_sk(sk)->dst;
1065 struct l2cap_conn *conn;
1066 struct hci_conn *hcon;
1067 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001068 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001069 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001071 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
1072 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001074 hdev = hci_get_route(dst, src);
1075 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076 return -EHOSTUNREACH;
1077
1078 hci_dev_lock_bh(hdev);
1079
1080 err = -ENOMEM;
1081
Johan Hedberg8556edd32011-01-19 12:06:50 +05301082 auth_type = l2cap_get_auth_type(sk);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001083
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001084 hcon = hci_connect(hdev, ACL_LINK, dst,
1085 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001086 if (!hcon)
1087 goto done;
1088
1089 conn = l2cap_conn_add(hcon, 0);
1090 if (!conn) {
1091 hci_conn_put(hcon);
1092 goto done;
1093 }
1094
1095 err = 0;
1096
1097 /* Update source addr of the socket */
1098 bacpy(src, conn->src);
1099
1100 l2cap_chan_add(conn, sk, NULL);
1101
1102 sk->sk_state = BT_CONNECT;
1103 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
1104
1105 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001106 if (sk->sk_type != SOCK_SEQPACKET &&
1107 sk->sk_type != SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108 l2cap_sock_clear_timer(sk);
1109 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001110 } else
1111 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112 }
1113
1114done:
1115 hci_dev_unlock_bh(hdev);
1116 hci_dev_put(hdev);
1117 return err;
1118}
1119
1120static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
1121{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001123 struct sockaddr_l2 la;
1124 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126 BT_DBG("sk %p", sk);
1127
Changli Gao6503d962010-03-31 22:58:26 +00001128 if (!addr || alen < sizeof(addr->sa_family) ||
1129 addr->sa_family != AF_BLUETOOTH)
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001130 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001132 memset(&la, 0, sizeof(la));
1133 len = min_t(unsigned int, sizeof(la), alen);
1134 memcpy(&la, addr, len);
1135
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001136 if (la.l2_cid)
1137 return -EINVAL;
1138
1139 lock_sock(sk);
1140
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001141 if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
1142 && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001143 err = -EINVAL;
1144 goto done;
1145 }
1146
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001147 switch (l2cap_pi(sk)->mode) {
1148 case L2CAP_MODE_BASIC:
1149 break;
1150 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001151 case L2CAP_MODE_STREAMING:
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001152 if (!disable_ertm)
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001153 break;
1154 /* fall through */
1155 default:
1156 err = -ENOTSUPP;
1157 goto done;
1158 }
1159
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001160 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161 case BT_CONNECT:
1162 case BT_CONNECT2:
1163 case BT_CONFIG:
1164 /* Already connecting */
1165 goto wait;
1166
1167 case BT_CONNECTED:
1168 /* Already connected */
João Paulo Rechi Vita8b0dc6d2010-06-22 13:56:22 -03001169 err = -EISCONN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170 goto done;
1171
1172 case BT_OPEN:
1173 case BT_BOUND:
1174 /* Can connect */
1175 break;
1176
1177 default:
1178 err = -EBADFD;
1179 goto done;
1180 }
1181
Mat Martineau0fba2552010-09-08 10:05:26 -07001182 /* PSM must be odd and lsb of upper byte must be 0 */
1183 if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 &&
1184 sk->sk_type != SOCK_RAW) {
1185 err = -EINVAL;
1186 goto done;
1187 }
1188
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001190 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1191 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001193 err = l2cap_do_connect(sk);
1194 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195 goto done;
1196
1197wait:
1198 err = bt_sock_wait_state(sk, BT_CONNECTED,
1199 sock_sndtimeo(sk, flags & O_NONBLOCK));
1200done:
1201 release_sock(sk);
1202 return err;
1203}
1204
1205static int l2cap_sock_listen(struct socket *sock, int backlog)
1206{
1207 struct sock *sk = sock->sk;
1208 int err = 0;
1209
1210 BT_DBG("sk %p backlog %d", sk, backlog);
1211
1212 lock_sock(sk);
1213
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001214 if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
1215 || sk->sk_state != BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216 err = -EBADFD;
1217 goto done;
1218 }
1219
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001220 switch (l2cap_pi(sk)->mode) {
1221 case L2CAP_MODE_BASIC:
1222 break;
1223 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001224 case L2CAP_MODE_STREAMING:
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001225 if (!disable_ertm)
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001226 break;
1227 /* fall through */
1228 default:
1229 err = -ENOTSUPP;
1230 goto done;
1231 }
1232
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233 if (!l2cap_pi(sk)->psm) {
1234 bdaddr_t *src = &bt_sk(sk)->src;
1235 u16 psm;
1236
1237 err = -EINVAL;
1238
1239 write_lock_bh(&l2cap_sk_list.lock);
1240
1241 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001242 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1243 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1244 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245 err = 0;
1246 break;
1247 }
1248
1249 write_unlock_bh(&l2cap_sk_list.lock);
1250
1251 if (err < 0)
1252 goto done;
1253 }
1254
1255 sk->sk_max_ack_backlog = backlog;
1256 sk->sk_ack_backlog = 0;
1257 sk->sk_state = BT_LISTEN;
1258
1259done:
1260 release_sock(sk);
1261 return err;
1262}
1263
1264static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1265{
1266 DECLARE_WAITQUEUE(wait, current);
1267 struct sock *sk = sock->sk, *nsk;
1268 long timeo;
1269 int err = 0;
1270
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001271 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001272
1273 if (sk->sk_state != BT_LISTEN) {
1274 err = -EBADFD;
1275 goto done;
1276 }
1277
1278 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1279
1280 BT_DBG("sk %p timeo %ld", sk, timeo);
1281
1282 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +00001283 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1285 set_current_state(TASK_INTERRUPTIBLE);
1286 if (!timeo) {
1287 err = -EAGAIN;
1288 break;
1289 }
1290
1291 release_sock(sk);
1292 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001293 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001294
1295 if (sk->sk_state != BT_LISTEN) {
1296 err = -EBADFD;
1297 break;
1298 }
1299
1300 if (signal_pending(current)) {
1301 err = sock_intr_errno(timeo);
1302 break;
1303 }
1304 }
1305 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +00001306 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307
1308 if (err)
1309 goto done;
1310
1311 newsock->state = SS_CONNECTED;
1312
1313 BT_DBG("new socket %p", nsk);
1314
1315done:
1316 release_sock(sk);
1317 return err;
1318}
1319
1320static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1321{
1322 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1323 struct sock *sk = sock->sk;
1324
1325 BT_DBG("sock %p, sk %p", sock, sk);
1326
1327 addr->sa_family = AF_BLUETOOTH;
1328 *len = sizeof(struct sockaddr_l2);
1329
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001330 if (peer) {
1331 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001333 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001334 } else {
1335 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001337 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001338 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340 return 0;
1341}
1342
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001343static int __l2cap_wait_ack(struct sock *sk)
1344{
1345 DECLARE_WAITQUEUE(wait, current);
1346 int err = 0;
1347 int timeo = HZ/5;
1348
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001349 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001350 while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
1351 set_current_state(TASK_INTERRUPTIBLE);
1352
1353 if (!timeo)
1354 timeo = HZ/5;
1355
1356 if (signal_pending(current)) {
1357 err = sock_intr_errno(timeo);
1358 break;
1359 }
1360
1361 release_sock(sk);
1362 timeo = schedule_timeout(timeo);
1363 lock_sock(sk);
1364
1365 err = sock_error(sk);
1366 if (err)
1367 break;
1368 }
1369 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001370 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001371 return err;
1372}
1373
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001374static void l2cap_monitor_timeout(unsigned long arg)
1375{
1376 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001377
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001378 BT_DBG("sk %p", sk);
1379
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001380 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001381 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001382 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001383 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001384 return;
1385 }
1386
1387 l2cap_pi(sk)->retry_count++;
1388 __mod_monitor_timer();
1389
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001390 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001391 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001392}
1393
1394static void l2cap_retrans_timeout(unsigned long arg)
1395{
1396 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001397
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001398 BT_DBG("sk %p", sk);
1399
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001400 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001401 l2cap_pi(sk)->retry_count = 1;
1402 __mod_monitor_timer();
1403
1404 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1405
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001406 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001407 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001408}
1409
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001410static void l2cap_drop_acked_frames(struct sock *sk)
1411{
1412 struct sk_buff *skb;
1413
Gustavo F. Padovan812e7372010-05-01 16:15:42 -03001414 while ((skb = skb_peek(TX_QUEUE(sk))) &&
1415 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001416 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1417 break;
1418
1419 skb = skb_dequeue(TX_QUEUE(sk));
1420 kfree_skb(skb);
1421
1422 l2cap_pi(sk)->unacked_frames--;
1423 }
1424
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001425 if (!l2cap_pi(sk)->unacked_frames)
1426 del_timer(&l2cap_pi(sk)->retrans_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001427}
1428
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001429static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001430{
1431 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001432
1433 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1434
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001435 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001436}
1437
João Paulo Rechi Vita305682e2010-06-22 13:56:23 -03001438static void l2cap_streaming_send(struct sock *sk)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001439{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001440 struct sk_buff *skb;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001441 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001442 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001443
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001444 while ((skb = skb_dequeue(TX_QUEUE(sk)))) {
1445 control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001446 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001447 put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001448
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001449 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001450 fcs = crc16(0, (u8 *)skb->data, skb->len - 2);
1451 put_unaligned_le16(fcs, skb->data + skb->len - 2);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001452 }
1453
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001454 l2cap_do_send(sk, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001455
1456 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001457 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001458}
1459
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001460static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001461{
1462 struct l2cap_pinfo *pi = l2cap_pi(sk);
1463 struct sk_buff *skb, *tx_skb;
1464 u16 control, fcs;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001465
1466 skb = skb_peek(TX_QUEUE(sk));
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001467 if (!skb)
1468 return;
1469
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001470 do {
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001471 if (bt_cb(skb)->tx_seq == tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001472 break;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001473
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001474 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1475 return;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001476
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001477 } while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001478
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001479 if (pi->remote_max_tx &&
1480 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001481 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001482 return;
1483 }
1484
1485 tx_skb = skb_clone(skb, GFP_ATOMIC);
1486 bt_cb(skb)->retries++;
1487 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001488
1489 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1490 control |= L2CAP_CTRL_FINAL;
1491 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1492 }
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001493
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001494 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1495 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001496
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001497 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1498
1499 if (pi->fcs == L2CAP_FCS_CRC16) {
1500 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1501 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1502 }
1503
1504 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001505}
1506
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001507static int l2cap_ertm_send(struct sock *sk)
1508{
1509 struct sk_buff *skb, *tx_skb;
1510 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001511 u16 control, fcs;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001512 int nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001513
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001514 if (sk->sk_state != BT_CONNECTED)
1515 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001516
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001517 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001518
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001519 if (pi->remote_max_tx &&
1520 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001521 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001522 break;
1523 }
1524
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001525 tx_skb = skb_clone(skb, GFP_ATOMIC);
1526
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001527 bt_cb(skb)->retries++;
1528
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001529 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001530 control &= L2CAP_CTRL_SAR;
1531
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001532 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1533 control |= L2CAP_CTRL_FINAL;
1534 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1535 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001536 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001537 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1538 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1539
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001540
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001541 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001542 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1543 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1544 }
1545
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001546 l2cap_do_send(sk, tx_skb);
1547
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001548 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001549
1550 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1551 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1552
1553 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001554 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001555
1556 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1557 sk->sk_send_head = NULL;
1558 else
1559 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001560
1561 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001562 }
1563
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001564 return nsent;
1565}
1566
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001567static int l2cap_retransmit_frames(struct sock *sk)
1568{
1569 struct l2cap_pinfo *pi = l2cap_pi(sk);
1570 int ret;
1571
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001572 if (!skb_queue_empty(TX_QUEUE(sk)))
1573 sk->sk_send_head = TX_QUEUE(sk)->next;
1574
1575 pi->next_tx_seq = pi->expected_ack_seq;
1576 ret = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001577 return ret;
1578}
1579
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001580static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001581{
1582 struct sock *sk = (struct sock *)pi;
1583 u16 control = 0;
1584
1585 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1586
1587 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1588 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001589 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001590 l2cap_send_sframe(pi, control);
1591 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001592 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001593
Gustavo F. Padovane0f66212010-06-21 18:50:49 -03001594 if (l2cap_ertm_send(sk) > 0)
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001595 return;
1596
1597 control |= L2CAP_SUPER_RCV_READY;
1598 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001599}
1600
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001601static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001602{
1603 struct srej_list *tail;
1604 u16 control;
1605
1606 control = L2CAP_SUPER_SELECT_REJECT;
1607 control |= L2CAP_CTRL_FINAL;
1608
1609 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1610 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1611
1612 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001613}
1614
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001615static 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 -07001616{
1617 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001618 struct sk_buff **frag;
1619 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001621 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001622 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623
1624 sent += count;
1625 len -= count;
1626
1627 /* Continuation fragments (no L2CAP header) */
1628 frag = &skb_shinfo(skb)->frag_list;
1629 while (len) {
1630 count = min_t(unsigned int, conn->mtu, len);
1631
1632 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1633 if (!*frag)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001634 return err;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001635 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1636 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637
1638 sent += count;
1639 len -= count;
1640
1641 frag = &(*frag)->next;
1642 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643
1644 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001645}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001646
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001647static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1648{
1649 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1650 struct sk_buff *skb;
1651 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1652 struct l2cap_hdr *lh;
1653
1654 BT_DBG("sk %p len %d", sk, (int)len);
1655
1656 count = min_t(unsigned int, (conn->mtu - hlen), len);
1657 skb = bt_skb_send_alloc(sk, count + hlen,
1658 msg->msg_flags & MSG_DONTWAIT, &err);
1659 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001660 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001661
1662 /* Create L2CAP header */
1663 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1664 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1665 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1666 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1667
1668 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1669 if (unlikely(err < 0)) {
1670 kfree_skb(skb);
1671 return ERR_PTR(err);
1672 }
1673 return skb;
1674}
1675
1676static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1677{
1678 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1679 struct sk_buff *skb;
1680 int err, count, hlen = L2CAP_HDR_SIZE;
1681 struct l2cap_hdr *lh;
1682
1683 BT_DBG("sk %p len %d", sk, (int)len);
1684
1685 count = min_t(unsigned int, (conn->mtu - hlen), len);
1686 skb = bt_skb_send_alloc(sk, count + hlen,
1687 msg->msg_flags & MSG_DONTWAIT, &err);
1688 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001689 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001690
1691 /* Create L2CAP header */
1692 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1693 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1694 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1695
1696 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1697 if (unlikely(err < 0)) {
1698 kfree_skb(skb);
1699 return ERR_PTR(err);
1700 }
1701 return skb;
1702}
1703
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001704static 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 -03001705{
1706 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1707 struct sk_buff *skb;
1708 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1709 struct l2cap_hdr *lh;
1710
1711 BT_DBG("sk %p len %d", sk, (int)len);
1712
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001713 if (!conn)
1714 return ERR_PTR(-ENOTCONN);
1715
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001716 if (sdulen)
1717 hlen += 2;
1718
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001719 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1720 hlen += 2;
1721
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001722 count = min_t(unsigned int, (conn->mtu - hlen), len);
1723 skb = bt_skb_send_alloc(sk, count + hlen,
1724 msg->msg_flags & MSG_DONTWAIT, &err);
1725 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001726 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001727
1728 /* Create L2CAP header */
1729 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1730 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1731 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1732 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001733 if (sdulen)
1734 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001735
1736 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1737 if (unlikely(err < 0)) {
1738 kfree_skb(skb);
1739 return ERR_PTR(err);
1740 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001741
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001742 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1743 put_unaligned_le16(0, skb_put(skb, 2));
1744
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001745 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001746 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747}
1748
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001749static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1750{
1751 struct l2cap_pinfo *pi = l2cap_pi(sk);
1752 struct sk_buff *skb;
1753 struct sk_buff_head sar_queue;
1754 u16 control;
1755 size_t size = 0;
1756
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001757 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001758 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001759 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001760 if (IS_ERR(skb))
1761 return PTR_ERR(skb);
1762
1763 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001764 len -= pi->remote_mps;
1765 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001766
1767 while (len > 0) {
1768 size_t buflen;
1769
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001770 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001771 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001772 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001773 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001774 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001775 buflen = len;
1776 }
1777
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001778 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001779 if (IS_ERR(skb)) {
1780 skb_queue_purge(&sar_queue);
1781 return PTR_ERR(skb);
1782 }
1783
1784 __skb_queue_tail(&sar_queue, skb);
1785 len -= buflen;
1786 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001787 }
1788 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1789 if (sk->sk_send_head == NULL)
1790 sk->sk_send_head = sar_queue.next;
1791
1792 return size;
1793}
1794
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1796{
1797 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001798 struct l2cap_pinfo *pi = l2cap_pi(sk);
1799 struct sk_buff *skb;
1800 u16 control;
1801 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802
1803 BT_DBG("sock %p, sk %p", sock, sk);
1804
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001805 err = sock_error(sk);
1806 if (err)
1807 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808
1809 if (msg->msg_flags & MSG_OOB)
1810 return -EOPNOTSUPP;
1811
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812 lock_sock(sk);
1813
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001814 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001816 goto done;
1817 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001819 /* Connectionless channel */
1820 if (sk->sk_type == SOCK_DGRAM) {
1821 skb = l2cap_create_connless_pdu(sk, msg, len);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001822 if (IS_ERR(skb)) {
Dan Carpenter477fffb2010-04-21 23:52:01 +00001823 err = PTR_ERR(skb);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001824 } else {
1825 l2cap_do_send(sk, skb);
1826 err = len;
1827 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001828 goto done;
1829 }
1830
1831 switch (pi->mode) {
1832 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001833 /* Check outgoing MTU */
1834 if (len > pi->omtu) {
João Paulo Rechi Vitaf9dd11b2010-06-22 13:56:24 -03001835 err = -EMSGSIZE;
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001836 goto done;
1837 }
1838
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001839 /* Create a basic PDU */
1840 skb = l2cap_create_basic_pdu(sk, msg, len);
1841 if (IS_ERR(skb)) {
1842 err = PTR_ERR(skb);
1843 goto done;
1844 }
1845
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001846 l2cap_do_send(sk, skb);
1847 err = len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001848 break;
1849
1850 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001851 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001852 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001853 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001854 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001855 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001856 if (IS_ERR(skb)) {
1857 err = PTR_ERR(skb);
1858 goto done;
1859 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001860 __skb_queue_tail(TX_QUEUE(sk), skb);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001861
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001862 if (sk->sk_send_head == NULL)
1863 sk->sk_send_head = skb;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001864
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001865 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001866 /* Segment SDU into multiples PDUs */
1867 err = l2cap_sar_segment_sdu(sk, msg, len);
1868 if (err < 0)
1869 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001870 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001871
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001872 if (pi->mode == L2CAP_MODE_STREAMING) {
João Paulo Rechi Vita305682e2010-06-22 13:56:23 -03001873 l2cap_streaming_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001874 } else {
David Sterba45719282011-01-14 14:59:44 +01001875 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
1876 (pi->conn_state & L2CAP_CONN_WAIT_F)) {
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001877 err = len;
1878 break;
1879 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001880 err = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001881 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001882
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001883 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001884 err = len;
1885 break;
1886
1887 default:
1888 BT_DBG("bad state %1.1x", pi->mode);
João Paulo Rechi Vitabc766db22010-06-22 13:56:25 -03001889 err = -EBADFD;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001890 }
1891
1892done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893 release_sock(sk);
1894 return err;
1895}
1896
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001897static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1898{
1899 struct sock *sk = sock->sk;
1900
1901 lock_sock(sk);
1902
1903 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1904 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001905 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1906 u8 buf[128];
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001907
1908 sk->sk_state = BT_CONFIG;
1909
1910 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1911 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1912 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1913 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1914 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1915 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1916
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001917 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) {
1918 release_sock(sk);
1919 return 0;
1920 }
1921
1922 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
1923 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
1924 l2cap_build_conf_req(sk, buf), buf);
1925 l2cap_pi(sk)->num_conf_req++;
1926
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001927 release_sock(sk);
1928 return 0;
1929 }
1930
1931 release_sock(sk);
1932
Mat Martineau6fdf4822010-09-08 10:05:29 -07001933 if (sock->type == SOCK_STREAM)
1934 return bt_sock_stream_recvmsg(iocb, sock, msg, len, flags);
1935
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001936 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1937}
1938
David S. Millerb7058842009-09-30 16:12:20 -07001939static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940{
1941 struct sock *sk = sock->sk;
1942 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001943 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944 u32 opt;
1945
1946 BT_DBG("sk %p", sk);
1947
1948 lock_sock(sk);
1949
1950 switch (optname) {
1951 case L2CAP_OPTIONS:
Gustavo F. Padovaneaa71b32010-10-04 19:28:52 -03001952 if (sk->sk_state == BT_CONNECTED) {
1953 err = -EINVAL;
1954 break;
1955 }
1956
Marcel Holtmann0878b662007-05-05 00:35:59 +02001957 opts.imtu = l2cap_pi(sk)->imtu;
1958 opts.omtu = l2cap_pi(sk)->omtu;
1959 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001960 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001961 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001962 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001963 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001964
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965 len = min_t(unsigned int, sizeof(opts), optlen);
1966 if (copy_from_user((char *) &opts, optval, len)) {
1967 err = -EFAULT;
1968 break;
1969 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001970
Gustavo F. Padovan45d65c42010-06-07 19:21:30 -03001971 if (opts.txwin_size > L2CAP_DEFAULT_TX_WINDOW) {
1972 err = -EINVAL;
1973 break;
1974 }
1975
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001976 l2cap_pi(sk)->mode = opts.mode;
1977 switch (l2cap_pi(sk)->mode) {
1978 case L2CAP_MODE_BASIC:
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03001979 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_STATE2_DEVICE;
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001980 break;
1981 case L2CAP_MODE_ERTM:
1982 case L2CAP_MODE_STREAMING:
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001983 if (!disable_ertm)
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001984 break;
1985 /* fall through */
1986 default:
1987 err = -EINVAL;
1988 break;
1989 }
1990
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001991 l2cap_pi(sk)->imtu = opts.imtu;
1992 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001993 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001994 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001995 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001996 break;
1997
1998 case L2CAP_LM:
1999 if (get_user(opt, (u32 __user *) optval)) {
2000 err = -EFAULT;
2001 break;
2002 }
2003
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002004 if (opt & L2CAP_LM_AUTH)
2005 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
2006 if (opt & L2CAP_LM_ENCRYPT)
2007 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
2008 if (opt & L2CAP_LM_SECURE)
2009 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
2010
2011 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
2012 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002013 break;
2014
2015 default:
2016 err = -ENOPROTOOPT;
2017 break;
2018 }
2019
2020 release_sock(sk);
2021 return err;
2022}
2023
David S. Millerb7058842009-09-30 16:12:20 -07002024static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002025{
2026 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002027 struct bt_security sec;
2028 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002029 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002030
2031 BT_DBG("sk %p", sk);
2032
2033 if (level == SOL_L2CAP)
2034 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
2035
Marcel Holtmann0588d942009-01-16 10:06:13 +01002036 if (level != SOL_BLUETOOTH)
2037 return -ENOPROTOOPT;
2038
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002039 lock_sock(sk);
2040
2041 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002042 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002043 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2044 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002045 err = -EINVAL;
2046 break;
2047 }
2048
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002049 sec.level = BT_SECURITY_LOW;
2050
2051 len = min_t(unsigned int, sizeof(sec), optlen);
2052 if (copy_from_user((char *) &sec, optval, len)) {
2053 err = -EFAULT;
2054 break;
2055 }
2056
2057 if (sec.level < BT_SECURITY_LOW ||
2058 sec.level > BT_SECURITY_HIGH) {
2059 err = -EINVAL;
2060 break;
2061 }
2062
2063 l2cap_pi(sk)->sec_level = sec.level;
2064 break;
2065
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002066 case BT_DEFER_SETUP:
2067 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2068 err = -EINVAL;
2069 break;
2070 }
2071
2072 if (get_user(opt, (u32 __user *) optval)) {
2073 err = -EFAULT;
2074 break;
2075 }
2076
2077 bt_sk(sk)->defer_setup = opt;
2078 break;
2079
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002080 default:
2081 err = -ENOPROTOOPT;
2082 break;
2083 }
2084
2085 release_sock(sk);
2086 return err;
2087}
2088
2089static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002090{
2091 struct sock *sk = sock->sk;
2092 struct l2cap_options opts;
2093 struct l2cap_conninfo cinfo;
2094 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002095 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002096
2097 BT_DBG("sk %p", sk);
2098
2099 if (get_user(len, optlen))
2100 return -EFAULT;
2101
2102 lock_sock(sk);
2103
2104 switch (optname) {
2105 case L2CAP_OPTIONS:
2106 opts.imtu = l2cap_pi(sk)->imtu;
2107 opts.omtu = l2cap_pi(sk)->omtu;
2108 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07002109 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002110 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002111 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002112 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002113
2114 len = min_t(unsigned int, len, sizeof(opts));
2115 if (copy_to_user(optval, (char *) &opts, len))
2116 err = -EFAULT;
2117
2118 break;
2119
2120 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002121 switch (l2cap_pi(sk)->sec_level) {
2122 case BT_SECURITY_LOW:
2123 opt = L2CAP_LM_AUTH;
2124 break;
2125 case BT_SECURITY_MEDIUM:
2126 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
2127 break;
2128 case BT_SECURITY_HIGH:
2129 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
2130 L2CAP_LM_SECURE;
2131 break;
2132 default:
2133 opt = 0;
2134 break;
2135 }
2136
2137 if (l2cap_pi(sk)->role_switch)
2138 opt |= L2CAP_LM_MASTER;
2139
2140 if (l2cap_pi(sk)->force_reliable)
2141 opt |= L2CAP_LM_RELIABLE;
2142
2143 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002144 err = -EFAULT;
2145 break;
2146
2147 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002148 if (sk->sk_state != BT_CONNECTED &&
2149 !(sk->sk_state == BT_CONNECT2 &&
2150 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002151 err = -ENOTCONN;
2152 break;
2153 }
2154
2155 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
2156 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
2157
2158 len = min_t(unsigned int, len, sizeof(cinfo));
2159 if (copy_to_user(optval, (char *) &cinfo, len))
2160 err = -EFAULT;
2161
2162 break;
2163
2164 default:
2165 err = -ENOPROTOOPT;
2166 break;
2167 }
2168
2169 release_sock(sk);
2170 return err;
2171}
2172
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002173static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
2174{
2175 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002176 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002177 int len, err = 0;
2178
2179 BT_DBG("sk %p", sk);
2180
2181 if (level == SOL_L2CAP)
2182 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
2183
Marcel Holtmann0588d942009-01-16 10:06:13 +01002184 if (level != SOL_BLUETOOTH)
2185 return -ENOPROTOOPT;
2186
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002187 if (get_user(len, optlen))
2188 return -EFAULT;
2189
2190 lock_sock(sk);
2191
2192 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002193 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002194 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2195 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002196 err = -EINVAL;
2197 break;
2198 }
2199
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002200 sec.level = l2cap_pi(sk)->sec_level;
2201
2202 len = min_t(unsigned int, len, sizeof(sec));
2203 if (copy_to_user(optval, (char *) &sec, len))
2204 err = -EFAULT;
2205
2206 break;
2207
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002208 case BT_DEFER_SETUP:
2209 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2210 err = -EINVAL;
2211 break;
2212 }
2213
2214 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2215 err = -EFAULT;
2216
2217 break;
2218
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002219 default:
2220 err = -ENOPROTOOPT;
2221 break;
2222 }
2223
2224 release_sock(sk);
2225 return err;
2226}
2227
Linus Torvalds1da177e2005-04-16 15:20:36 -07002228static int l2cap_sock_shutdown(struct socket *sock, int how)
2229{
2230 struct sock *sk = sock->sk;
2231 int err = 0;
2232
2233 BT_DBG("sock %p, sk %p", sock, sk);
2234
2235 if (!sk)
2236 return 0;
2237
2238 lock_sock(sk);
2239 if (!sk->sk_shutdown) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03002240 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2241 err = __l2cap_wait_ack(sk);
2242
Linus Torvalds1da177e2005-04-16 15:20:36 -07002243 sk->sk_shutdown = SHUTDOWN_MASK;
2244 l2cap_sock_clear_timer(sk);
2245 __l2cap_sock_close(sk, 0);
2246
2247 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002248 err = bt_sock_wait_state(sk, BT_CLOSED,
2249 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002250 }
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002251
2252 if (!err && sk->sk_err)
2253 err = -sk->sk_err;
2254
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255 release_sock(sk);
2256 return err;
2257}
2258
2259static int l2cap_sock_release(struct socket *sock)
2260{
2261 struct sock *sk = sock->sk;
2262 int err;
2263
2264 BT_DBG("sock %p, sk %p", sock, sk);
2265
2266 if (!sk)
2267 return 0;
2268
2269 err = l2cap_sock_shutdown(sock, 2);
2270
2271 sock_orphan(sk);
2272 l2cap_sock_kill(sk);
2273 return err;
2274}
2275
Linus Torvalds1da177e2005-04-16 15:20:36 -07002276static void l2cap_chan_ready(struct sock *sk)
2277{
2278 struct sock *parent = bt_sk(sk)->parent;
2279
2280 BT_DBG("sk %p, parent %p", sk, parent);
2281
2282 l2cap_pi(sk)->conf_state = 0;
2283 l2cap_sock_clear_timer(sk);
2284
2285 if (!parent) {
2286 /* Outgoing channel.
2287 * Wake up socket sleeping on connect.
2288 */
2289 sk->sk_state = BT_CONNECTED;
2290 sk->sk_state_change(sk);
2291 } else {
2292 /* Incoming channel.
2293 * Wake up socket sleeping on accept.
2294 */
2295 parent->sk_data_ready(parent, 0);
2296 }
2297}
2298
2299/* Copy frame to all raw sockets on that connection */
2300static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2301{
2302 struct l2cap_chan_list *l = &conn->chan_list;
2303 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002304 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002305
2306 BT_DBG("conn %p", conn);
2307
2308 read_lock(&l->lock);
2309 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2310 if (sk->sk_type != SOCK_RAW)
2311 continue;
2312
2313 /* Don't send frame to the socket it came from */
2314 if (skb->sk == sk)
2315 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002316 nskb = skb_clone(skb, GFP_ATOMIC);
2317 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002318 continue;
2319
2320 if (sock_queue_rcv_skb(sk, nskb))
2321 kfree_skb(nskb);
2322 }
2323 read_unlock(&l->lock);
2324}
2325
2326/* ---- L2CAP signalling commands ---- */
2327static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2328 u8 code, u8 ident, u16 dlen, void *data)
2329{
2330 struct sk_buff *skb, **frag;
2331 struct l2cap_cmd_hdr *cmd;
2332 struct l2cap_hdr *lh;
2333 int len, count;
2334
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002335 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2336 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002337
2338 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2339 count = min_t(unsigned int, conn->mtu, len);
2340
2341 skb = bt_skb_alloc(count, GFP_ATOMIC);
2342 if (!skb)
2343 return NULL;
2344
2345 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002346 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002347 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002348
2349 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2350 cmd->code = code;
2351 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002352 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002353
2354 if (dlen) {
2355 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2356 memcpy(skb_put(skb, count), data, count);
2357 data += count;
2358 }
2359
2360 len -= skb->len;
2361
2362 /* Continuation fragments (no L2CAP header) */
2363 frag = &skb_shinfo(skb)->frag_list;
2364 while (len) {
2365 count = min_t(unsigned int, conn->mtu, len);
2366
2367 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2368 if (!*frag)
2369 goto fail;
2370
2371 memcpy(skb_put(*frag, count), data, count);
2372
2373 len -= count;
2374 data += count;
2375
2376 frag = &(*frag)->next;
2377 }
2378
2379 return skb;
2380
2381fail:
2382 kfree_skb(skb);
2383 return NULL;
2384}
2385
2386static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2387{
2388 struct l2cap_conf_opt *opt = *ptr;
2389 int len;
2390
2391 len = L2CAP_CONF_OPT_SIZE + opt->len;
2392 *ptr += len;
2393
2394 *type = opt->type;
2395 *olen = opt->len;
2396
2397 switch (opt->len) {
2398 case 1:
2399 *val = *((u8 *) opt->val);
2400 break;
2401
2402 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002403 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002404 break;
2405
2406 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002407 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002408 break;
2409
2410 default:
2411 *val = (unsigned long) opt->val;
2412 break;
2413 }
2414
2415 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2416 return len;
2417}
2418
Linus Torvalds1da177e2005-04-16 15:20:36 -07002419static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2420{
2421 struct l2cap_conf_opt *opt = *ptr;
2422
2423 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2424
2425 opt->type = type;
2426 opt->len = len;
2427
2428 switch (len) {
2429 case 1:
2430 *((u8 *) opt->val) = val;
2431 break;
2432
2433 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002434 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002435 break;
2436
2437 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002438 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002439 break;
2440
2441 default:
2442 memcpy(opt->val, (void *) val, len);
2443 break;
2444 }
2445
2446 *ptr += L2CAP_CONF_OPT_SIZE + len;
2447}
2448
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002449static void l2cap_ack_timeout(unsigned long arg)
2450{
2451 struct sock *sk = (void *) arg;
2452
2453 bh_lock_sock(sk);
2454 l2cap_send_ack(l2cap_pi(sk));
2455 bh_unlock_sock(sk);
2456}
2457
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002458static inline void l2cap_ertm_init(struct sock *sk)
2459{
2460 l2cap_pi(sk)->expected_ack_seq = 0;
2461 l2cap_pi(sk)->unacked_frames = 0;
2462 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002463 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002464 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002465
2466 setup_timer(&l2cap_pi(sk)->retrans_timer,
2467 l2cap_retrans_timeout, (unsigned long) sk);
2468 setup_timer(&l2cap_pi(sk)->monitor_timer,
2469 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002470 setup_timer(&l2cap_pi(sk)->ack_timer,
2471 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002472
2473 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002474 __skb_queue_head_init(BUSY_QUEUE(sk));
2475
2476 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03002477
2478 sk->sk_backlog_rcv = l2cap_ertm_data_rcv;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002479}
2480
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002481static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2482{
2483 switch (mode) {
2484 case L2CAP_MODE_STREAMING:
2485 case L2CAP_MODE_ERTM:
2486 if (l2cap_mode_supported(mode, remote_feat_mask))
2487 return mode;
2488 /* fall through */
2489 default:
2490 return L2CAP_MODE_BASIC;
2491 }
2492}
2493
Linus Torvalds1da177e2005-04-16 15:20:36 -07002494static int l2cap_build_conf_req(struct sock *sk, void *data)
2495{
2496 struct l2cap_pinfo *pi = l2cap_pi(sk);
2497 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002498 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499 void *ptr = req->data;
2500
2501 BT_DBG("sk %p", sk);
2502
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002503 if (pi->num_conf_req || pi->num_conf_rsp)
2504 goto done;
2505
2506 switch (pi->mode) {
2507 case L2CAP_MODE_STREAMING:
2508 case L2CAP_MODE_ERTM:
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002509 if (pi->conf_state & L2CAP_CONF_STATE2_DEVICE)
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002510 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002511
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002512 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002513 default:
2514 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2515 break;
2516 }
2517
2518done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002519 switch (pi->mode) {
2520 case L2CAP_MODE_BASIC:
2521 if (pi->imtu != L2CAP_DEFAULT_MTU)
2522 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002523
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002524 if (!(pi->conn->feat_mask & L2CAP_FEAT_ERTM) &&
2525 !(pi->conn->feat_mask & L2CAP_FEAT_STREAMING))
2526 break;
2527
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002528 rfc.mode = L2CAP_MODE_BASIC;
2529 rfc.txwin_size = 0;
2530 rfc.max_transmit = 0;
2531 rfc.retrans_timeout = 0;
2532 rfc.monitor_timeout = 0;
2533 rfc.max_pdu_size = 0;
2534
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002535 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2536 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002537 break;
2538
2539 case L2CAP_MODE_ERTM:
2540 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002541 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002542 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002543 rfc.retrans_timeout = 0;
2544 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002545 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002546 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002547 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002548
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002549 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2550 (unsigned long) &rfc);
2551
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002552 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2553 break;
2554
2555 if (pi->fcs == L2CAP_FCS_NONE ||
2556 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2557 pi->fcs = L2CAP_FCS_NONE;
2558 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2559 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002560 break;
2561
2562 case L2CAP_MODE_STREAMING:
2563 rfc.mode = L2CAP_MODE_STREAMING;
2564 rfc.txwin_size = 0;
2565 rfc.max_transmit = 0;
2566 rfc.retrans_timeout = 0;
2567 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002568 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002569 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002570 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002571
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002572 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2573 (unsigned long) &rfc);
2574
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002575 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2576 break;
2577
2578 if (pi->fcs == L2CAP_FCS_NONE ||
2579 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2580 pi->fcs = L2CAP_FCS_NONE;
2581 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2582 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002583 break;
2584 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002585
2586 /* FIXME: Need actual value of the flush timeout */
2587 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2588 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2589
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002590 req->dcid = cpu_to_le16(pi->dcid);
2591 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002592
2593 return ptr - data;
2594}
2595
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002596static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002597{
2598 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002599 struct l2cap_conf_rsp *rsp = data;
2600 void *ptr = rsp->data;
2601 void *req = pi->conf_req;
2602 int len = pi->conf_len;
2603 int type, hint, olen;
2604 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002605 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002606 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002607 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002608
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002609 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002610
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002611 while (len >= L2CAP_CONF_OPT_SIZE) {
2612 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002613
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002614 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002615 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002616
2617 switch (type) {
2618 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002619 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002620 break;
2621
2622 case L2CAP_CONF_FLUSH_TO:
2623 pi->flush_to = val;
2624 break;
2625
2626 case L2CAP_CONF_QOS:
2627 break;
2628
Marcel Holtmann6464f352007-10-20 13:39:51 +02002629 case L2CAP_CONF_RFC:
2630 if (olen == sizeof(rfc))
2631 memcpy(&rfc, (void *) val, olen);
2632 break;
2633
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002634 case L2CAP_CONF_FCS:
2635 if (val == L2CAP_FCS_NONE)
2636 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2637
2638 break;
2639
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002640 default:
2641 if (hint)
2642 break;
2643
2644 result = L2CAP_CONF_UNKNOWN;
2645 *((u8 *) ptr++) = type;
2646 break;
2647 }
2648 }
2649
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002650 if (pi->num_conf_rsp || pi->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002651 goto done;
2652
2653 switch (pi->mode) {
2654 case L2CAP_MODE_STREAMING:
2655 case L2CAP_MODE_ERTM:
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002656 if (!(pi->conf_state & L2CAP_CONF_STATE2_DEVICE)) {
2657 pi->mode = l2cap_select_mode(rfc.mode,
2658 pi->conn->feat_mask);
2659 break;
2660 }
2661
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03002662 if (pi->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002663 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03002664
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002665 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002666 }
2667
2668done:
2669 if (pi->mode != rfc.mode) {
2670 result = L2CAP_CONF_UNACCEPT;
2671 rfc.mode = pi->mode;
2672
2673 if (pi->num_conf_rsp == 1)
2674 return -ECONNREFUSED;
2675
2676 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2677 sizeof(rfc), (unsigned long) &rfc);
2678 }
2679
2680
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002681 if (result == L2CAP_CONF_SUCCESS) {
2682 /* Configure output options and let the other side know
2683 * which ones we don't like. */
2684
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002685 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2686 result = L2CAP_CONF_UNACCEPT;
2687 else {
2688 pi->omtu = mtu;
2689 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2690 }
2691 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002692
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002693 switch (rfc.mode) {
2694 case L2CAP_MODE_BASIC:
2695 pi->fcs = L2CAP_FCS_NONE;
2696 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2697 break;
2698
2699 case L2CAP_MODE_ERTM:
2700 pi->remote_tx_win = rfc.txwin_size;
2701 pi->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07002702
2703 if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
2704 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002705
2706 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002707
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002708 rfc.retrans_timeout =
2709 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2710 rfc.monitor_timeout =
2711 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002712
2713 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002714
2715 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2716 sizeof(rfc), (unsigned long) &rfc);
2717
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002718 break;
2719
2720 case L2CAP_MODE_STREAMING:
Mat Martineau86b1b262010-08-05 15:54:22 -07002721 if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
2722 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002723
2724 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002725
2726 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002727
2728 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2729 sizeof(rfc), (unsigned long) &rfc);
2730
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002731 break;
2732
2733 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002734 result = L2CAP_CONF_UNACCEPT;
2735
2736 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002737 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002738 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002739
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002740 if (result == L2CAP_CONF_SUCCESS)
2741 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2742 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002743 rsp->scid = cpu_to_le16(pi->dcid);
2744 rsp->result = cpu_to_le16(result);
2745 rsp->flags = cpu_to_le16(0x0000);
2746
2747 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002748}
2749
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002750static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2751{
2752 struct l2cap_pinfo *pi = l2cap_pi(sk);
2753 struct l2cap_conf_req *req = data;
2754 void *ptr = req->data;
2755 int type, olen;
2756 unsigned long val;
2757 struct l2cap_conf_rfc rfc;
2758
2759 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2760
2761 while (len >= L2CAP_CONF_OPT_SIZE) {
2762 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2763
2764 switch (type) {
2765 case L2CAP_CONF_MTU:
2766 if (val < L2CAP_DEFAULT_MIN_MTU) {
2767 *result = L2CAP_CONF_UNACCEPT;
Andrei Emeltchenko8183b772010-09-01 15:17:25 +03002768 pi->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002769 } else
Andrei Emeltchenko8183b772010-09-01 15:17:25 +03002770 pi->imtu = val;
2771 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002772 break;
2773
2774 case L2CAP_CONF_FLUSH_TO:
2775 pi->flush_to = val;
2776 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2777 2, pi->flush_to);
2778 break;
2779
2780 case L2CAP_CONF_RFC:
2781 if (olen == sizeof(rfc))
2782 memcpy(&rfc, (void *)val, olen);
2783
2784 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2785 rfc.mode != pi->mode)
2786 return -ECONNREFUSED;
2787
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002788 pi->fcs = 0;
2789
2790 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2791 sizeof(rfc), (unsigned long) &rfc);
2792 break;
2793 }
2794 }
2795
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03002796 if (pi->mode == L2CAP_MODE_BASIC && pi->mode != rfc.mode)
2797 return -ECONNREFUSED;
2798
2799 pi->mode = rfc.mode;
2800
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002801 if (*result == L2CAP_CONF_SUCCESS) {
2802 switch (rfc.mode) {
2803 case L2CAP_MODE_ERTM:
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002804 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2805 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002806 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002807 break;
2808 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002809 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002810 }
2811 }
2812
2813 req->dcid = cpu_to_le16(pi->dcid);
2814 req->flags = cpu_to_le16(0x0000);
2815
2816 return ptr - data;
2817}
2818
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002819static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002820{
2821 struct l2cap_conf_rsp *rsp = data;
2822 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002823
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002824 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002825
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002826 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002827 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002828 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002829
2830 return ptr - data;
2831}
2832
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002833static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2834{
2835 struct l2cap_pinfo *pi = l2cap_pi(sk);
2836 int type, olen;
2837 unsigned long val;
2838 struct l2cap_conf_rfc rfc;
2839
2840 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2841
2842 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2843 return;
2844
2845 while (len >= L2CAP_CONF_OPT_SIZE) {
2846 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2847
2848 switch (type) {
2849 case L2CAP_CONF_RFC:
2850 if (olen == sizeof(rfc))
2851 memcpy(&rfc, (void *)val, olen);
2852 goto done;
2853 }
2854 }
2855
2856done:
2857 switch (rfc.mode) {
2858 case L2CAP_MODE_ERTM:
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002859 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2860 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002861 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2862 break;
2863 case L2CAP_MODE_STREAMING:
2864 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2865 }
2866}
2867
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002868static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2869{
2870 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2871
2872 if (rej->reason != 0x0000)
2873 return 0;
2874
2875 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2876 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002877 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002878
2879 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002880 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002881
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002882 l2cap_conn_start(conn);
2883 }
2884
2885 return 0;
2886}
2887
Linus Torvalds1da177e2005-04-16 15:20:36 -07002888static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2889{
2890 struct l2cap_chan_list *list = &conn->chan_list;
2891 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2892 struct l2cap_conn_rsp rsp;
Nathan Holsteind793fe82010-10-15 11:54:02 -04002893 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002894 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002895
2896 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002897 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002898
2899 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2900
2901 /* Check if we have socket listening on psm */
2902 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2903 if (!parent) {
2904 result = L2CAP_CR_BAD_PSM;
2905 goto sendresp;
2906 }
2907
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00002908 bh_lock_sock(parent);
2909
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002910 /* Check if the ACL is secure enough (if not SDP) */
2911 if (psm != cpu_to_le16(0x0001) &&
2912 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002913 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002914 result = L2CAP_CR_SEC_BLOCK;
2915 goto response;
2916 }
2917
Linus Torvalds1da177e2005-04-16 15:20:36 -07002918 result = L2CAP_CR_NO_MEM;
2919
2920 /* Check for backlog size */
2921 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002922 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002923 goto response;
2924 }
2925
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002926 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927 if (!sk)
2928 goto response;
2929
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002930 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002931
2932 /* Check if we already have channel with that dcid */
2933 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002934 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002935 sock_set_flag(sk, SOCK_ZAPPED);
2936 l2cap_sock_kill(sk);
2937 goto response;
2938 }
2939
2940 hci_conn_hold(conn->hcon);
2941
2942 l2cap_sock_init(sk, parent);
2943 bacpy(&bt_sk(sk)->src, conn->src);
2944 bacpy(&bt_sk(sk)->dst, conn->dst);
2945 l2cap_pi(sk)->psm = psm;
2946 l2cap_pi(sk)->dcid = scid;
2947
2948 __l2cap_chan_add(conn, sk, parent);
2949 dcid = l2cap_pi(sk)->scid;
2950
2951 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2952
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953 l2cap_pi(sk)->ident = cmd->ident;
2954
Marcel Holtmann984947d2009-02-06 23:35:19 +01002955 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002956 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002957 if (bt_sk(sk)->defer_setup) {
2958 sk->sk_state = BT_CONNECT2;
2959 result = L2CAP_CR_PEND;
2960 status = L2CAP_CS_AUTHOR_PEND;
2961 parent->sk_data_ready(parent, 0);
2962 } else {
2963 sk->sk_state = BT_CONFIG;
2964 result = L2CAP_CR_SUCCESS;
2965 status = L2CAP_CS_NO_INFO;
2966 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002967 } else {
2968 sk->sk_state = BT_CONNECT2;
2969 result = L2CAP_CR_PEND;
2970 status = L2CAP_CS_AUTHEN_PEND;
2971 }
2972 } else {
2973 sk->sk_state = BT_CONNECT2;
2974 result = L2CAP_CR_PEND;
2975 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002976 }
2977
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002978 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979
2980response:
2981 bh_unlock_sock(parent);
2982
2983sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002984 rsp.scid = cpu_to_le16(scid);
2985 rsp.dcid = cpu_to_le16(dcid);
2986 rsp.result = cpu_to_le16(result);
2987 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002988 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002989
2990 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2991 struct l2cap_info_req info;
2992 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2993
2994 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2995 conn->info_ident = l2cap_get_ident(conn);
2996
2997 mod_timer(&conn->info_timer, jiffies +
2998 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2999
3000 l2cap_send_cmd(conn, conn->info_ident,
3001 L2CAP_INFO_REQ, sizeof(info), &info);
3002 }
3003
Nathan Holsteind793fe82010-10-15 11:54:02 -04003004 if (sk && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) &&
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003005 result == L2CAP_CR_SUCCESS) {
3006 u8 buf[128];
3007 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
3008 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3009 l2cap_build_conf_req(sk, buf), buf);
3010 l2cap_pi(sk)->num_conf_req++;
3011 }
3012
Linus Torvalds1da177e2005-04-16 15:20:36 -07003013 return 0;
3014}
3015
3016static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3017{
3018 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3019 u16 scid, dcid, result, status;
3020 struct sock *sk;
3021 u8 req[128];
3022
3023 scid = __le16_to_cpu(rsp->scid);
3024 dcid = __le16_to_cpu(rsp->dcid);
3025 result = __le16_to_cpu(rsp->result);
3026 status = __le16_to_cpu(rsp->status);
3027
3028 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
3029
3030 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003031 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3032 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03003033 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003034 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003035 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
3036 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03003037 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003038 }
3039
3040 switch (result) {
3041 case L2CAP_CR_SUCCESS:
3042 sk->sk_state = BT_CONFIG;
3043 l2cap_pi(sk)->ident = 0;
3044 l2cap_pi(sk)->dcid = dcid;
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003045 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
3046
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003047 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)
3048 break;
3049
3050 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
3051
Linus Torvalds1da177e2005-04-16 15:20:36 -07003052 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3053 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003054 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003055 break;
3056
3057 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003058 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003059 break;
3060
3061 default:
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02003062 /* don't delete l2cap channel if sk is owned by user */
3063 if (sock_owned_by_user(sk)) {
3064 sk->sk_state = BT_DISCONN;
3065 l2cap_sock_clear_timer(sk);
3066 l2cap_sock_set_timer(sk, HZ / 5);
3067 break;
3068 }
3069
Linus Torvalds1da177e2005-04-16 15:20:36 -07003070 l2cap_chan_del(sk, ECONNREFUSED);
3071 break;
3072 }
3073
3074 bh_unlock_sock(sk);
3075 return 0;
3076}
3077
Mat Martineau8c462b62010-08-24 15:35:42 -07003078static inline void set_default_fcs(struct l2cap_pinfo *pi)
3079{
3080 /* FCS is enabled only in ERTM or streaming mode, if one or both
3081 * sides request it.
3082 */
3083 if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING)
3084 pi->fcs = L2CAP_FCS_NONE;
3085 else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV))
3086 pi->fcs = L2CAP_FCS_CRC16;
3087}
3088
Al Viro88219a02007-07-29 00:17:25 -07003089static 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 -07003090{
3091 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3092 u16 dcid, flags;
3093 u8 rsp[64];
3094 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003095 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003096
3097 dcid = __le16_to_cpu(req->dcid);
3098 flags = __le16_to_cpu(req->flags);
3099
3100 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3101
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003102 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3103 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003104 return -ENOENT;
3105
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003106 if (sk->sk_state != BT_CONFIG) {
3107 struct l2cap_cmd_rej rej;
3108
3109 rej.reason = cpu_to_le16(0x0002);
3110 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
3111 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003112 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003113 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003114
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003115 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003116 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003117 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
3118 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
3119 l2cap_build_conf_rsp(sk, rsp,
3120 L2CAP_CONF_REJECT, flags), rsp);
3121 goto unlock;
3122 }
3123
3124 /* Store config. */
3125 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
3126 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003127
3128 if (flags & 0x0001) {
3129 /* Incomplete config. Send empty response. */
3130 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003131 l2cap_build_conf_rsp(sk, rsp,
3132 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003133 goto unlock;
3134 }
3135
3136 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003137 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003138 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003139 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003140 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003141 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003142
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003143 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003144 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003145
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003146 /* Reset config buffer. */
3147 l2cap_pi(sk)->conf_len = 0;
3148
Marcel Holtmann876d9482007-10-20 13:35:42 +02003149 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
3150 goto unlock;
3151
Linus Torvalds1da177e2005-04-16 15:20:36 -07003152 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Mat Martineau8c462b62010-08-24 15:35:42 -07003153 set_default_fcs(l2cap_pi(sk));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003154
Linus Torvalds1da177e2005-04-16 15:20:36 -07003155 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003156
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003157 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003158 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003159 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003160 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3161 l2cap_ertm_init(sk);
3162
Linus Torvalds1da177e2005-04-16 15:20:36 -07003163 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02003164 goto unlock;
3165 }
3166
3167 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003168 u8 buf[64];
Haijun Liuab3e5712010-09-30 16:52:40 +08003169 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003170 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003171 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003172 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003173 }
3174
3175unlock:
3176 bh_unlock_sock(sk);
3177 return 0;
3178}
3179
3180static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3181{
3182 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3183 u16 scid, flags, result;
3184 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003185 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003186
3187 scid = __le16_to_cpu(rsp->scid);
3188 flags = __le16_to_cpu(rsp->flags);
3189 result = __le16_to_cpu(rsp->result);
3190
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003191 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
3192 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003193
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003194 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3195 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003196 return 0;
3197
3198 switch (result) {
3199 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003200 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003201 break;
3202
3203 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003204 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003205 char req[64];
3206
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003207 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003208 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003209 goto done;
3210 }
3211
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003212 /* throw out any old stored conf requests */
3213 result = L2CAP_CONF_SUCCESS;
3214 len = l2cap_parse_conf_rsp(sk, rsp->data,
3215 len, req, &result);
3216 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003217 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003218 goto done;
3219 }
3220
3221 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3222 L2CAP_CONF_REQ, len, req);
3223 l2cap_pi(sk)->num_conf_req++;
3224 if (result != L2CAP_CONF_SUCCESS)
3225 goto done;
3226 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003227 }
3228
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003229 default:
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003230 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003231 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003232 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003233 goto done;
3234 }
3235
3236 if (flags & 0x01)
3237 goto done;
3238
Linus Torvalds1da177e2005-04-16 15:20:36 -07003239 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3240
3241 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Mat Martineau8c462b62010-08-24 15:35:42 -07003242 set_default_fcs(l2cap_pi(sk));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003243
Linus Torvalds1da177e2005-04-16 15:20:36 -07003244 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003245 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003246 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003247 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003248 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3249 l2cap_ertm_init(sk);
3250
Linus Torvalds1da177e2005-04-16 15:20:36 -07003251 l2cap_chan_ready(sk);
3252 }
3253
3254done:
3255 bh_unlock_sock(sk);
3256 return 0;
3257}
3258
3259static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3260{
3261 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3262 struct l2cap_disconn_rsp rsp;
3263 u16 dcid, scid;
3264 struct sock *sk;
3265
3266 scid = __le16_to_cpu(req->scid);
3267 dcid = __le16_to_cpu(req->dcid);
3268
3269 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3270
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003271 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3272 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003273 return 0;
3274
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003275 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3276 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003277 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3278
3279 sk->sk_shutdown = SHUTDOWN_MASK;
3280
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02003281 /* don't delete l2cap channel if sk is owned by user */
3282 if (sock_owned_by_user(sk)) {
3283 sk->sk_state = BT_DISCONN;
3284 l2cap_sock_clear_timer(sk);
3285 l2cap_sock_set_timer(sk, HZ / 5);
3286 bh_unlock_sock(sk);
3287 return 0;
3288 }
3289
Linus Torvalds1da177e2005-04-16 15:20:36 -07003290 l2cap_chan_del(sk, ECONNRESET);
3291 bh_unlock_sock(sk);
3292
3293 l2cap_sock_kill(sk);
3294 return 0;
3295}
3296
3297static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3298{
3299 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3300 u16 dcid, scid;
3301 struct sock *sk;
3302
3303 scid = __le16_to_cpu(rsp->scid);
3304 dcid = __le16_to_cpu(rsp->dcid);
3305
3306 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3307
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003308 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3309 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003310 return 0;
3311
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02003312 /* don't delete l2cap channel if sk is owned by user */
3313 if (sock_owned_by_user(sk)) {
3314 sk->sk_state = BT_DISCONN;
3315 l2cap_sock_clear_timer(sk);
3316 l2cap_sock_set_timer(sk, HZ / 5);
3317 bh_unlock_sock(sk);
3318 return 0;
3319 }
3320
Linus Torvalds1da177e2005-04-16 15:20:36 -07003321 l2cap_chan_del(sk, 0);
3322 bh_unlock_sock(sk);
3323
3324 l2cap_sock_kill(sk);
3325 return 0;
3326}
3327
3328static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3329{
3330 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003331 u16 type;
3332
3333 type = __le16_to_cpu(req->type);
3334
3335 BT_DBG("type 0x%4.4x", type);
3336
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003337 if (type == L2CAP_IT_FEAT_MASK) {
3338 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003339 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003340 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3341 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3342 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03003343 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003344 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3345 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003346 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003347 l2cap_send_cmd(conn, cmd->ident,
3348 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003349 } else if (type == L2CAP_IT_FIXED_CHAN) {
3350 u8 buf[12];
3351 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3352 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3353 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3354 memcpy(buf + 4, l2cap_fixed_chan, 8);
3355 l2cap_send_cmd(conn, cmd->ident,
3356 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003357 } else {
3358 struct l2cap_info_rsp rsp;
3359 rsp.type = cpu_to_le16(type);
3360 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3361 l2cap_send_cmd(conn, cmd->ident,
3362 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3363 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003364
3365 return 0;
3366}
3367
3368static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3369{
3370 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3371 u16 type, result;
3372
3373 type = __le16_to_cpu(rsp->type);
3374 result = __le16_to_cpu(rsp->result);
3375
3376 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3377
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003378 del_timer(&conn->info_timer);
3379
Ville Tervoadb08ed2010-08-04 09:43:33 +03003380 if (result != L2CAP_IR_SUCCESS) {
3381 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3382 conn->info_ident = 0;
3383
3384 l2cap_conn_start(conn);
3385
3386 return 0;
3387 }
3388
Marcel Holtmann984947d2009-02-06 23:35:19 +01003389 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003390 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003391
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003392 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003393 struct l2cap_info_req req;
3394 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3395
3396 conn->info_ident = l2cap_get_ident(conn);
3397
3398 l2cap_send_cmd(conn, conn->info_ident,
3399 L2CAP_INFO_REQ, sizeof(req), &req);
3400 } else {
3401 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3402 conn->info_ident = 0;
3403
3404 l2cap_conn_start(conn);
3405 }
3406 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003407 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003408 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003409
3410 l2cap_conn_start(conn);
3411 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003412
Linus Torvalds1da177e2005-04-16 15:20:36 -07003413 return 0;
3414}
3415
3416static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3417{
3418 u8 *data = skb->data;
3419 int len = skb->len;
3420 struct l2cap_cmd_hdr cmd;
3421 int err = 0;
3422
3423 l2cap_raw_recv(conn, skb);
3424
3425 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003426 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003427 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3428 data += L2CAP_CMD_HDR_SIZE;
3429 len -= L2CAP_CMD_HDR_SIZE;
3430
Al Viro88219a02007-07-29 00:17:25 -07003431 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003432
Al Viro88219a02007-07-29 00:17:25 -07003433 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 -07003434
Al Viro88219a02007-07-29 00:17:25 -07003435 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003436 BT_DBG("corrupted command");
3437 break;
3438 }
3439
3440 switch (cmd.code) {
3441 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003442 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003443 break;
3444
3445 case L2CAP_CONN_REQ:
3446 err = l2cap_connect_req(conn, &cmd, data);
3447 break;
3448
3449 case L2CAP_CONN_RSP:
3450 err = l2cap_connect_rsp(conn, &cmd, data);
3451 break;
3452
3453 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003454 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003455 break;
3456
3457 case L2CAP_CONF_RSP:
3458 err = l2cap_config_rsp(conn, &cmd, data);
3459 break;
3460
3461 case L2CAP_DISCONN_REQ:
3462 err = l2cap_disconnect_req(conn, &cmd, data);
3463 break;
3464
3465 case L2CAP_DISCONN_RSP:
3466 err = l2cap_disconnect_rsp(conn, &cmd, data);
3467 break;
3468
3469 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003470 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003471 break;
3472
3473 case L2CAP_ECHO_RSP:
3474 break;
3475
3476 case L2CAP_INFO_REQ:
3477 err = l2cap_information_req(conn, &cmd, data);
3478 break;
3479
3480 case L2CAP_INFO_RSP:
3481 err = l2cap_information_rsp(conn, &cmd, data);
3482 break;
3483
3484 default:
3485 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3486 err = -EINVAL;
3487 break;
3488 }
3489
3490 if (err) {
3491 struct l2cap_cmd_rej rej;
3492 BT_DBG("error %d", err);
3493
3494 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003495 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003496 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3497 }
3498
Al Viro88219a02007-07-29 00:17:25 -07003499 data += cmd_len;
3500 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003501 }
3502
3503 kfree_skb(skb);
3504}
3505
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003506static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3507{
3508 u16 our_fcs, rcv_fcs;
3509 int hdr_size = L2CAP_HDR_SIZE + 2;
3510
3511 if (pi->fcs == L2CAP_FCS_CRC16) {
3512 skb_trim(skb, skb->len - 2);
3513 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3514 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3515
3516 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03003517 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003518 }
3519 return 0;
3520}
3521
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003522static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3523{
3524 struct l2cap_pinfo *pi = l2cap_pi(sk);
3525 u16 control = 0;
3526
3527 pi->frames_sent = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003528
3529 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3530
3531 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan64988862010-05-10 14:54:14 -03003532 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003533 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003534 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003535 }
3536
Gustavo F. Padovan4ea727e2010-06-03 16:34:20 -03003537 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY)
3538 l2cap_retransmit_frames(sk);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003539
3540 l2cap_ertm_send(sk);
3541
3542 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3543 pi->frames_sent == 0) {
3544 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003545 l2cap_send_sframe(pi, control);
3546 }
3547}
3548
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003549static 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 -03003550{
3551 struct sk_buff *next_skb;
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003552 struct l2cap_pinfo *pi = l2cap_pi(sk);
3553 int tx_seq_offset, next_tx_seq_offset;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003554
3555 bt_cb(skb)->tx_seq = tx_seq;
3556 bt_cb(skb)->sar = sar;
3557
3558 next_skb = skb_peek(SREJ_QUEUE(sk));
3559 if (!next_skb) {
3560 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003561 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003562 }
3563
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003564 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3565 if (tx_seq_offset < 0)
3566 tx_seq_offset += 64;
3567
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003568 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003569 if (bt_cb(next_skb)->tx_seq == tx_seq)
3570 return -EINVAL;
3571
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003572 next_tx_seq_offset = (bt_cb(next_skb)->tx_seq -
3573 pi->buffer_seq) % 64;
3574 if (next_tx_seq_offset < 0)
3575 next_tx_seq_offset += 64;
3576
3577 if (next_tx_seq_offset > tx_seq_offset) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003578 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003579 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003580 }
3581
3582 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3583 break;
3584
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003585 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003586
3587 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003588
3589 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003590}
3591
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003592static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3593{
3594 struct l2cap_pinfo *pi = l2cap_pi(sk);
3595 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003596 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003597
3598 switch (control & L2CAP_CTRL_SAR) {
3599 case L2CAP_SDU_UNSEGMENTED:
3600 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3601 goto drop;
3602
3603 err = sock_queue_rcv_skb(sk, skb);
3604 if (!err)
3605 return err;
3606
3607 break;
3608
3609 case L2CAP_SDU_START:
3610 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3611 goto drop;
3612
3613 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003614
3615 if (pi->sdu_len > pi->imtu)
3616 goto disconnect;
3617
3618 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003619 if (!pi->sdu)
3620 return -ENOMEM;
3621
3622 /* pull sdu_len bytes only after alloc, because of Local Busy
3623 * condition we have to be sure that this will be executed
3624 * only once, i.e., when alloc does not fail */
3625 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003626
3627 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3628
3629 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3630 pi->partial_sdu_len = skb->len;
3631 break;
3632
3633 case L2CAP_SDU_CONTINUE:
3634 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3635 goto disconnect;
3636
3637 if (!pi->sdu)
3638 goto disconnect;
3639
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003640 pi->partial_sdu_len += skb->len;
3641 if (pi->partial_sdu_len > pi->sdu_len)
3642 goto drop;
3643
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003644 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3645
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003646 break;
3647
3648 case L2CAP_SDU_END:
3649 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3650 goto disconnect;
3651
3652 if (!pi->sdu)
3653 goto disconnect;
3654
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003655 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003656 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003657
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003658 if (pi->partial_sdu_len > pi->imtu)
3659 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003660
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003661 if (pi->partial_sdu_len != pi->sdu_len)
3662 goto drop;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003663
3664 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003665 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003666
3667 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003668 if (!_skb) {
3669 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3670 return -ENOMEM;
3671 }
3672
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003673 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003674 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003675 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003676 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3677 return err;
3678 }
3679
3680 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
3681 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003682
3683 kfree_skb(pi->sdu);
3684 break;
3685 }
3686
3687 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003688 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003689
3690drop:
3691 kfree_skb(pi->sdu);
3692 pi->sdu = NULL;
3693
3694disconnect:
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003695 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003696 kfree_skb(skb);
3697 return 0;
3698}
3699
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003700static int l2cap_try_push_rx_skb(struct sock *sk)
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003701{
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003702 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003703 struct sk_buff *skb;
3704 u16 control;
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003705 int err;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003706
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003707 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
3708 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3709 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3710 if (err < 0) {
3711 skb_queue_head(BUSY_QUEUE(sk), skb);
3712 return -EBUSY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003713 }
3714
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003715 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003716 }
3717
3718 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
3719 goto done;
3720
3721 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3722 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
3723 l2cap_send_sframe(pi, control);
3724 l2cap_pi(sk)->retry_count = 1;
3725
3726 del_timer(&pi->retrans_timer);
3727 __mod_monitor_timer();
3728
3729 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
3730
3731done:
3732 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
3733 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
3734
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003735 BT_DBG("sk %p, Exit local busy", sk);
3736
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003737 return 0;
3738}
3739
3740static void l2cap_busy_work(struct work_struct *work)
3741{
3742 DECLARE_WAITQUEUE(wait, current);
3743 struct l2cap_pinfo *pi =
3744 container_of(work, struct l2cap_pinfo, busy_work);
3745 struct sock *sk = (struct sock *)pi;
3746 int n_tries = 0, timeo = HZ/5, err;
3747 struct sk_buff *skb;
3748
3749 lock_sock(sk);
3750
3751 add_wait_queue(sk_sleep(sk), &wait);
3752 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
3753 set_current_state(TASK_INTERRUPTIBLE);
3754
3755 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
3756 err = -EBUSY;
3757 l2cap_send_disconn_req(pi->conn, sk, EBUSY);
3758 break;
3759 }
3760
3761 if (!timeo)
3762 timeo = HZ/5;
3763
3764 if (signal_pending(current)) {
3765 err = sock_intr_errno(timeo);
3766 break;
3767 }
3768
3769 release_sock(sk);
3770 timeo = schedule_timeout(timeo);
3771 lock_sock(sk);
3772
3773 err = sock_error(sk);
3774 if (err)
3775 break;
3776
3777 if (l2cap_try_push_rx_skb(sk) == 0)
3778 break;
3779 }
3780
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003781 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003782 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003783
3784 release_sock(sk);
3785}
3786
3787static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
3788{
3789 struct l2cap_pinfo *pi = l2cap_pi(sk);
3790 int sctrl, err;
3791
3792 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3793 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3794 __skb_queue_tail(BUSY_QUEUE(sk), skb);
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003795 return l2cap_try_push_rx_skb(sk);
3796
3797
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003798 }
3799
3800 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3801 if (err >= 0) {
3802 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3803 return err;
3804 }
3805
3806 /* Busy Condition */
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003807 BT_DBG("sk %p, Enter local busy", sk);
3808
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003809 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
3810 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3811 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3812
3813 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3814 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
3815 l2cap_send_sframe(pi, sctrl);
3816
3817 pi->conn_state |= L2CAP_CONN_RNR_SENT;
3818
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03003819 del_timer(&pi->ack_timer);
3820
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003821 queue_work(_busy_wq, &pi->busy_work);
3822
3823 return err;
3824}
3825
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003826static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003827{
3828 struct l2cap_pinfo *pi = l2cap_pi(sk);
3829 struct sk_buff *_skb;
3830 int err = -EINVAL;
3831
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003832 /*
3833 * TODO: We have to notify the userland if some data is lost with the
3834 * Streaming Mode.
3835 */
3836
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003837 switch (control & L2CAP_CTRL_SAR) {
3838 case L2CAP_SDU_UNSEGMENTED:
3839 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3840 kfree_skb(pi->sdu);
3841 break;
3842 }
3843
3844 err = sock_queue_rcv_skb(sk, skb);
3845 if (!err)
3846 return 0;
3847
3848 break;
3849
3850 case L2CAP_SDU_START:
3851 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3852 kfree_skb(pi->sdu);
3853 break;
3854 }
3855
3856 pi->sdu_len = get_unaligned_le16(skb->data);
3857 skb_pull(skb, 2);
3858
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003859 if (pi->sdu_len > pi->imtu) {
3860 err = -EMSGSIZE;
3861 break;
3862 }
3863
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003864 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3865 if (!pi->sdu) {
3866 err = -ENOMEM;
3867 break;
3868 }
3869
3870 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3871
3872 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3873 pi->partial_sdu_len = skb->len;
3874 err = 0;
3875 break;
3876
3877 case L2CAP_SDU_CONTINUE:
3878 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3879 break;
3880
3881 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3882
3883 pi->partial_sdu_len += skb->len;
3884 if (pi->partial_sdu_len > pi->sdu_len)
3885 kfree_skb(pi->sdu);
3886 else
3887 err = 0;
3888
3889 break;
3890
3891 case L2CAP_SDU_END:
3892 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3893 break;
3894
3895 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3896
3897 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3898 pi->partial_sdu_len += skb->len;
3899
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003900 if (pi->partial_sdu_len > pi->imtu)
3901 goto drop;
3902
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003903 if (pi->partial_sdu_len == pi->sdu_len) {
3904 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3905 err = sock_queue_rcv_skb(sk, _skb);
3906 if (err < 0)
3907 kfree_skb(_skb);
3908 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003909 err = 0;
3910
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003911drop:
3912 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003913 break;
3914 }
3915
3916 kfree_skb(skb);
3917 return err;
3918}
3919
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003920static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3921{
3922 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003923 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003924
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003925 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003926 if (bt_cb(skb)->tx_seq != tx_seq)
3927 break;
3928
3929 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003930 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003931 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003932 l2cap_pi(sk)->buffer_seq_srej =
3933 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003934 tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003935 }
3936}
3937
3938static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3939{
3940 struct l2cap_pinfo *pi = l2cap_pi(sk);
3941 struct srej_list *l, *tmp;
3942 u16 control;
3943
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003944 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003945 if (l->tx_seq == tx_seq) {
3946 list_del(&l->list);
3947 kfree(l);
3948 return;
3949 }
3950 control = L2CAP_SUPER_SELECT_REJECT;
3951 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3952 l2cap_send_sframe(pi, control);
3953 list_del(&l->list);
3954 list_add_tail(&l->list, SREJ_LIST(sk));
3955 }
3956}
3957
3958static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3959{
3960 struct l2cap_pinfo *pi = l2cap_pi(sk);
3961 struct srej_list *new;
3962 u16 control;
3963
3964 while (tx_seq != pi->expected_tx_seq) {
3965 control = L2CAP_SUPER_SELECT_REJECT;
3966 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3967 l2cap_send_sframe(pi, control);
3968
3969 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003970 new->tx_seq = pi->expected_tx_seq;
3971 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003972 list_add_tail(&new->list, SREJ_LIST(sk));
3973 }
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003974 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003975}
3976
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003977static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3978{
3979 struct l2cap_pinfo *pi = l2cap_pi(sk);
3980 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003981 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003982 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03003983 int tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003984 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003985 int err = 0;
3986
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003987 BT_DBG("sk %p len %d tx_seq %d rx_control 0x%4.4x", sk, skb->len, tx_seq,
3988 rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003989
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003990 if (L2CAP_CTRL_FINAL & rx_control &&
3991 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003992 del_timer(&pi->monitor_timer);
3993 if (pi->unacked_frames > 0)
3994 __mod_retrans_timer();
3995 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3996 }
3997
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003998 pi->expected_ack_seq = req_seq;
3999 l2cap_drop_acked_frames(sk);
4000
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004001 if (tx_seq == pi->expected_tx_seq)
4002 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004003
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03004004 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
4005 if (tx_seq_offset < 0)
4006 tx_seq_offset += 64;
4007
4008 /* invalid tx_seq */
4009 if (tx_seq_offset >= pi->tx_win) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03004010 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03004011 goto drop;
4012 }
4013
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004014 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
4015 goto drop;
4016
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004017 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
4018 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004019
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004020 first = list_first_entry(SREJ_LIST(sk),
4021 struct srej_list, list);
4022 if (tx_seq == first->tx_seq) {
4023 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
4024 l2cap_check_srej_gap(sk, tx_seq);
4025
4026 list_del(&first->list);
4027 kfree(first);
4028
4029 if (list_empty(SREJ_LIST(sk))) {
4030 pi->buffer_seq = pi->buffer_seq_srej;
4031 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666cc2010-05-01 16:15:40 -03004032 l2cap_send_ack(pi);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004033 BT_DBG("sk %p, Exit SREJ_SENT", sk);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004034 }
4035 } else {
4036 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03004037
4038 /* duplicated tx_seq */
4039 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
4040 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004041
4042 list_for_each_entry(l, SREJ_LIST(sk), list) {
4043 if (l->tx_seq == tx_seq) {
4044 l2cap_resend_srejframe(sk, tx_seq);
4045 return 0;
4046 }
4047 }
4048 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004049 }
4050 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03004051 expected_tx_seq_offset =
4052 (pi->expected_tx_seq - pi->buffer_seq) % 64;
4053 if (expected_tx_seq_offset < 0)
4054 expected_tx_seq_offset += 64;
4055
4056 /* duplicated tx_seq */
4057 if (tx_seq_offset < expected_tx_seq_offset)
4058 goto drop;
4059
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004060 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004061
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004062 BT_DBG("sk %p, Enter SREJ", sk);
4063
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004064 INIT_LIST_HEAD(SREJ_LIST(sk));
4065 pi->buffer_seq_srej = pi->buffer_seq;
4066
4067 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004068 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004069 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
4070
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03004071 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
4072
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004073 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03004074
4075 del_timer(&pi->ack_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004076 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004077 return 0;
4078
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004079expected:
4080 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4081
4082 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03004083 bt_cb(skb)->tx_seq = tx_seq;
4084 bt_cb(skb)->sar = sar;
4085 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004086 return 0;
4087 }
4088
Gustavo F. Padovan2ece3682010-06-16 17:21:44 -03004089 err = l2cap_push_rx_skb(sk, skb, rx_control);
4090 if (err < 0)
4091 return 0;
4092
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03004093 if (rx_control & L2CAP_CTRL_FINAL) {
4094 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4095 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004096 else
4097 l2cap_retransmit_frames(sk);
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03004098 }
4099
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03004100 __mod_ack_timer();
4101
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03004102 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
4103 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03004104 l2cap_send_ack(pi);
4105
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004106 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03004107
4108drop:
4109 kfree_skb(skb);
4110 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004111}
4112
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004113static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004114{
4115 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03004116
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004117 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control),
4118 rx_control);
4119
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03004120 pi->expected_ack_seq = __get_reqseq(rx_control);
4121 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004122
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004123 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004124 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03004125 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
4126 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
4127 (pi->unacked_frames > 0))
4128 __mod_retrans_timer();
4129
4130 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4131 l2cap_send_srejtail(sk);
4132 } else {
4133 l2cap_send_i_or_rr_or_rnr(sk);
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03004134 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004135
4136 } else if (rx_control & L2CAP_CTRL_FINAL) {
4137 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004138
4139 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4140 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004141 else
4142 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004143
4144 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004145 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
4146 (pi->unacked_frames > 0))
4147 __mod_retrans_timer();
4148
4149 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Andrei Emeltchenko894718a2010-12-01 16:58:24 +02004150 if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004151 l2cap_send_ack(pi);
Andrei Emeltchenko894718a2010-12-01 16:58:24 +02004152 else
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004153 l2cap_ertm_send(sk);
4154 }
4155}
4156
4157static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
4158{
4159 struct l2cap_pinfo *pi = l2cap_pi(sk);
4160 u8 tx_seq = __get_reqseq(rx_control);
4161
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004162 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4163
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004164 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4165
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03004166 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004167 l2cap_drop_acked_frames(sk);
4168
4169 if (rx_control & L2CAP_CTRL_FINAL) {
4170 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4171 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004172 else
4173 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004174 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004175 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004176
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03004177 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004178 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004179 }
4180}
4181static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
4182{
4183 struct l2cap_pinfo *pi = l2cap_pi(sk);
4184 u8 tx_seq = __get_reqseq(rx_control);
4185
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004186 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4187
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004188 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4189
4190 if (rx_control & L2CAP_CTRL_POLL) {
4191 pi->expected_ack_seq = tx_seq;
4192 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004193
4194 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004195 l2cap_retransmit_one_frame(sk, tx_seq);
4196
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004197 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004198
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004199 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4200 pi->srej_save_reqseq = tx_seq;
4201 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4202 }
4203 } else if (rx_control & L2CAP_CTRL_FINAL) {
4204 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
4205 pi->srej_save_reqseq == tx_seq)
4206 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
4207 else
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004208 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004209 } 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 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4212 pi->srej_save_reqseq = tx_seq;
4213 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4214 }
4215 }
4216}
4217
4218static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
4219{
4220 struct l2cap_pinfo *pi = l2cap_pi(sk);
4221 u8 tx_seq = __get_reqseq(rx_control);
4222
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004223 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4224
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004225 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
4226 pi->expected_ack_seq = tx_seq;
4227 l2cap_drop_acked_frames(sk);
4228
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004229 if (rx_control & L2CAP_CTRL_POLL)
4230 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
4231
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004232 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
4233 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03004234 if (rx_control & L2CAP_CTRL_POLL)
4235 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004236 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004237 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004238
4239 if (rx_control & L2CAP_CTRL_POLL)
4240 l2cap_send_srejtail(sk);
4241 else
4242 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004243}
4244
4245static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
4246{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004247 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
4248
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03004249 if (L2CAP_CTRL_FINAL & rx_control &&
4250 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004251 del_timer(&l2cap_pi(sk)->monitor_timer);
4252 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004253 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004254 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004255 }
4256
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004257 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
4258 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004259 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004260 break;
4261
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004262 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004263 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004264 break;
4265
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004266 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004267 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004268 break;
4269
4270 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004271 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004272 break;
4273 }
4274
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03004275 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004276 return 0;
4277}
4278
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004279static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
4280{
4281 struct l2cap_pinfo *pi = l2cap_pi(sk);
4282 u16 control;
4283 u8 req_seq;
4284 int len, next_tx_seq_offset, req_seq_offset;
4285
4286 control = get_unaligned_le16(skb->data);
4287 skb_pull(skb, 2);
4288 len = skb->len;
4289
4290 /*
4291 * We can just drop the corrupted I-frame here.
4292 * Receiver will miss it and start proper recovery
4293 * procedures and ask retransmission.
4294 */
4295 if (l2cap_check_fcs(pi, skb))
4296 goto drop;
4297
4298 if (__is_sar_start(control) && __is_iframe(control))
4299 len -= 2;
4300
4301 if (pi->fcs == L2CAP_FCS_CRC16)
4302 len -= 2;
4303
4304 if (len > pi->mps) {
4305 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4306 goto drop;
4307 }
4308
4309 req_seq = __get_reqseq(control);
4310 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
4311 if (req_seq_offset < 0)
4312 req_seq_offset += 64;
4313
4314 next_tx_seq_offset =
4315 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
4316 if (next_tx_seq_offset < 0)
4317 next_tx_seq_offset += 64;
4318
4319 /* check for invalid req-seq */
4320 if (req_seq_offset > next_tx_seq_offset) {
4321 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4322 goto drop;
4323 }
4324
4325 if (__is_iframe(control)) {
4326 if (len < 0) {
4327 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4328 goto drop;
4329 }
4330
4331 l2cap_data_channel_iframe(sk, control, skb);
4332 } else {
4333 if (len != 0) {
4334 BT_ERR("%d", len);
4335 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4336 goto drop;
4337 }
4338
4339 l2cap_data_channel_sframe(sk, control, skb);
4340 }
4341
4342 return 0;
4343
4344drop:
4345 kfree_skb(skb);
4346 return 0;
4347}
4348
Linus Torvalds1da177e2005-04-16 15:20:36 -07004349static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
4350{
4351 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004352 struct l2cap_pinfo *pi;
Nathan Holstein51893f82010-06-09 15:46:25 -04004353 u16 control;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004354 u8 tx_seq;
4355 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004356
4357 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
4358 if (!sk) {
4359 BT_DBG("unknown cid 0x%4.4x", cid);
4360 goto drop;
4361 }
4362
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004363 pi = l2cap_pi(sk);
4364
Linus Torvalds1da177e2005-04-16 15:20:36 -07004365 BT_DBG("sk %p, len %d", sk, skb->len);
4366
4367 if (sk->sk_state != BT_CONNECTED)
4368 goto drop;
4369
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004370 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004371 case L2CAP_MODE_BASIC:
4372 /* If socket recv buffers overflows we drop data here
4373 * which is *bad* because L2CAP has to be reliable.
4374 * But we don't have any other choice. L2CAP doesn't
4375 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004376
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004377 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004378 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004379
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004380 if (!sock_queue_rcv_skb(sk, skb))
4381 goto done;
4382 break;
4383
4384 case L2CAP_MODE_ERTM:
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004385 if (!sock_owned_by_user(sk)) {
4386 l2cap_ertm_data_rcv(sk, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004387 } else {
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004388 if (sk_add_backlog(sk, skb))
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004389 goto drop;
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004390 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004391
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004392 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004393
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004394 case L2CAP_MODE_STREAMING:
4395 control = get_unaligned_le16(skb->data);
4396 skb_pull(skb, 2);
4397 len = skb->len;
4398
Gustavo F. Padovan26000082010-05-11 22:02:00 -03004399 if (l2cap_check_fcs(pi, skb))
4400 goto drop;
4401
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004402 if (__is_sar_start(control))
4403 len -= 2;
4404
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004405 if (pi->fcs == L2CAP_FCS_CRC16)
4406 len -= 2;
4407
Nathan Holstein51893f82010-06-09 15:46:25 -04004408 if (len > pi->mps || len < 0 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004409 goto drop;
4410
4411 tx_seq = __get_txseq(control);
4412
4413 if (pi->expected_tx_seq == tx_seq)
4414 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4415 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03004416 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004417
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004418 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004419
4420 goto done;
4421
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004422 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03004423 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004424 break;
4425 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004426
4427drop:
4428 kfree_skb(skb);
4429
4430done:
Marcel Holtmann01394182006-07-03 10:02:46 +02004431 if (sk)
4432 bh_unlock_sock(sk);
4433
Linus Torvalds1da177e2005-04-16 15:20:36 -07004434 return 0;
4435}
4436
Al Viro8e036fc2007-07-29 00:16:36 -07004437static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004438{
4439 struct sock *sk;
4440
4441 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
4442 if (!sk)
4443 goto drop;
4444
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00004445 bh_lock_sock(sk);
4446
Linus Torvalds1da177e2005-04-16 15:20:36 -07004447 BT_DBG("sk %p, len %d", sk, skb->len);
4448
4449 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
4450 goto drop;
4451
4452 if (l2cap_pi(sk)->imtu < skb->len)
4453 goto drop;
4454
4455 if (!sock_queue_rcv_skb(sk, skb))
4456 goto done;
4457
4458drop:
4459 kfree_skb(skb);
4460
4461done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004462 if (sk)
4463 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004464 return 0;
4465}
4466
4467static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
4468{
4469 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07004470 u16 cid, len;
4471 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004472
4473 skb_pull(skb, L2CAP_HDR_SIZE);
4474 cid = __le16_to_cpu(lh->cid);
4475 len = __le16_to_cpu(lh->len);
4476
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004477 if (len != skb->len) {
4478 kfree_skb(skb);
4479 return;
4480 }
4481
Linus Torvalds1da177e2005-04-16 15:20:36 -07004482 BT_DBG("len %d, cid 0x%4.4x", len, cid);
4483
4484 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004485 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004486 l2cap_sig_channel(conn, skb);
4487 break;
4488
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004489 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004490 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004491 skb_pull(skb, 2);
4492 l2cap_conless_channel(conn, psm, skb);
4493 break;
4494
4495 default:
4496 l2cap_data_channel(conn, cid, skb);
4497 break;
4498 }
4499}
4500
4501/* ---- L2CAP interface with lower layer (HCI) ---- */
4502
4503static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
4504{
4505 int exact = 0, lm1 = 0, lm2 = 0;
4506 register struct sock *sk;
4507 struct hlist_node *node;
4508
4509 if (type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03004510 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004511
4512 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
4513
4514 /* Find listening sockets and check their link_mode */
4515 read_lock(&l2cap_sk_list.lock);
4516 sk_for_each(sk, node, &l2cap_sk_list.head) {
4517 if (sk->sk_state != BT_LISTEN)
4518 continue;
4519
4520 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004521 lm1 |= HCI_LM_ACCEPT;
4522 if (l2cap_pi(sk)->role_switch)
4523 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004524 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004525 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
4526 lm2 |= HCI_LM_ACCEPT;
4527 if (l2cap_pi(sk)->role_switch)
4528 lm2 |= HCI_LM_MASTER;
4529 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004530 }
4531 read_unlock(&l2cap_sk_list.lock);
4532
4533 return exact ? lm1 : lm2;
4534}
4535
4536static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
4537{
Marcel Holtmann01394182006-07-03 10:02:46 +02004538 struct l2cap_conn *conn;
4539
Linus Torvalds1da177e2005-04-16 15:20:36 -07004540 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
4541
4542 if (hcon->type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03004543 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004544
4545 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004546 conn = l2cap_conn_add(hcon, status);
4547 if (conn)
4548 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02004549 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004550 l2cap_conn_del(hcon, bt_err(status));
4551
4552 return 0;
4553}
4554
Marcel Holtmann2950f212009-02-12 14:02:50 +01004555static int l2cap_disconn_ind(struct hci_conn *hcon)
4556{
4557 struct l2cap_conn *conn = hcon->l2cap_data;
4558
4559 BT_DBG("hcon %p", hcon);
4560
4561 if (hcon->type != ACL_LINK || !conn)
4562 return 0x13;
4563
4564 return conn->disc_reason;
4565}
4566
4567static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004568{
4569 BT_DBG("hcon %p reason %d", hcon, reason);
4570
4571 if (hcon->type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03004572 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004573
4574 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004575
Linus Torvalds1da177e2005-04-16 15:20:36 -07004576 return 0;
4577}
4578
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004579static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4580{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004581 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004582 return;
4583
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004584 if (encrypt == 0x00) {
4585 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4586 l2cap_sock_clear_timer(sk);
4587 l2cap_sock_set_timer(sk, HZ * 5);
4588 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4589 __l2cap_sock_close(sk, ECONNREFUSED);
4590 } else {
4591 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4592 l2cap_sock_clear_timer(sk);
4593 }
4594}
4595
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004596static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004597{
4598 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004599 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004600 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004601
Marcel Holtmann01394182006-07-03 10:02:46 +02004602 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004603 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004604
Linus Torvalds1da177e2005-04-16 15:20:36 -07004605 l = &conn->chan_list;
4606
4607 BT_DBG("conn %p", conn);
4608
4609 read_lock(&l->lock);
4610
4611 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4612 bh_lock_sock(sk);
4613
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004614 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4615 bh_unlock_sock(sk);
4616 continue;
4617 }
4618
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004619 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004620 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004621 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004622 bh_unlock_sock(sk);
4623 continue;
4624 }
4625
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004626 if (sk->sk_state == BT_CONNECT) {
4627 if (!status) {
4628 struct l2cap_conn_req req;
4629 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4630 req.psm = l2cap_pi(sk)->psm;
4631
4632 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03004633 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004634
4635 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4636 L2CAP_CONN_REQ, sizeof(req), &req);
4637 } else {
4638 l2cap_sock_clear_timer(sk);
4639 l2cap_sock_set_timer(sk, HZ / 10);
4640 }
4641 } else if (sk->sk_state == BT_CONNECT2) {
4642 struct l2cap_conn_rsp rsp;
4643 __u16 result;
4644
4645 if (!status) {
4646 sk->sk_state = BT_CONFIG;
4647 result = L2CAP_CR_SUCCESS;
4648 } else {
4649 sk->sk_state = BT_DISCONN;
4650 l2cap_sock_set_timer(sk, HZ / 10);
4651 result = L2CAP_CR_SEC_BLOCK;
4652 }
4653
4654 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4655 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4656 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004657 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004658 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4659 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004660 }
4661
Linus Torvalds1da177e2005-04-16 15:20:36 -07004662 bh_unlock_sock(sk);
4663 }
4664
4665 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004666
Linus Torvalds1da177e2005-04-16 15:20:36 -07004667 return 0;
4668}
4669
4670static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4671{
4672 struct l2cap_conn *conn = hcon->l2cap_data;
4673
4674 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4675 goto drop;
4676
4677 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4678
4679 if (flags & ACL_START) {
4680 struct l2cap_hdr *hdr;
Andrei Emeltchenko89794812010-09-15 14:28:44 +03004681 struct sock *sk;
4682 u16 cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004683 int len;
4684
4685 if (conn->rx_len) {
4686 BT_ERR("Unexpected start frame (len %d)", skb->len);
4687 kfree_skb(conn->rx_skb);
4688 conn->rx_skb = NULL;
4689 conn->rx_len = 0;
4690 l2cap_conn_unreliable(conn, ECOMM);
4691 }
4692
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03004693 /* Start fragment always begin with Basic L2CAP header */
4694 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004695 BT_ERR("Frame is too short (len %d)", skb->len);
4696 l2cap_conn_unreliable(conn, ECOMM);
4697 goto drop;
4698 }
4699
4700 hdr = (struct l2cap_hdr *) skb->data;
4701 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
Andrei Emeltchenko89794812010-09-15 14:28:44 +03004702 cid = __le16_to_cpu(hdr->cid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004703
4704 if (len == skb->len) {
4705 /* Complete frame received */
4706 l2cap_recv_frame(conn, skb);
4707 return 0;
4708 }
4709
4710 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4711
4712 if (skb->len > len) {
4713 BT_ERR("Frame is too long (len %d, expected len %d)",
4714 skb->len, len);
4715 l2cap_conn_unreliable(conn, ECOMM);
4716 goto drop;
4717 }
4718
Andrei Emeltchenko89794812010-09-15 14:28:44 +03004719 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
4720
4721 if (sk && l2cap_pi(sk)->imtu < len - L2CAP_HDR_SIZE) {
4722 BT_ERR("Frame exceeding recv MTU (len %d, MTU %d)",
4723 len, l2cap_pi(sk)->imtu);
4724 bh_unlock_sock(sk);
4725 l2cap_conn_unreliable(conn, ECOMM);
4726 goto drop;
4727 }
4728
4729 if (sk)
4730 bh_unlock_sock(sk);
4731
Linus Torvalds1da177e2005-04-16 15:20:36 -07004732 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004733 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4734 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004735 goto drop;
4736
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004737 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004738 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004739 conn->rx_len = len - skb->len;
4740 } else {
4741 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4742
4743 if (!conn->rx_len) {
4744 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4745 l2cap_conn_unreliable(conn, ECOMM);
4746 goto drop;
4747 }
4748
4749 if (skb->len > conn->rx_len) {
4750 BT_ERR("Fragment is too long (len %d, expected %d)",
4751 skb->len, conn->rx_len);
4752 kfree_skb(conn->rx_skb);
4753 conn->rx_skb = NULL;
4754 conn->rx_len = 0;
4755 l2cap_conn_unreliable(conn, ECOMM);
4756 goto drop;
4757 }
4758
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004759 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004760 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004761 conn->rx_len -= skb->len;
4762
4763 if (!conn->rx_len) {
4764 /* Complete frame received */
4765 l2cap_recv_frame(conn, conn->rx_skb);
4766 conn->rx_skb = NULL;
4767 }
4768 }
4769
4770drop:
4771 kfree_skb(skb);
4772 return 0;
4773}
4774
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004775static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004776{
4777 struct sock *sk;
4778 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004779
4780 read_lock_bh(&l2cap_sk_list.lock);
4781
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004782 sk_for_each(sk, node, &l2cap_sk_list.head) {
4783 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004784
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004785 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4786 batostr(&bt_sk(sk)->src),
4787 batostr(&bt_sk(sk)->dst),
4788 sk->sk_state, __le16_to_cpu(pi->psm),
4789 pi->scid, pi->dcid,
4790 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004791 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004792
Linus Torvalds1da177e2005-04-16 15:20:36 -07004793 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004794
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004795 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004796}
4797
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004798static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4799{
4800 return single_open(file, l2cap_debugfs_show, inode->i_private);
4801}
4802
4803static const struct file_operations l2cap_debugfs_fops = {
4804 .open = l2cap_debugfs_open,
4805 .read = seq_read,
4806 .llseek = seq_lseek,
4807 .release = single_release,
4808};
4809
4810static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004811
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004812static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004813 .family = PF_BLUETOOTH,
4814 .owner = THIS_MODULE,
4815 .release = l2cap_sock_release,
4816 .bind = l2cap_sock_bind,
4817 .connect = l2cap_sock_connect,
4818 .listen = l2cap_sock_listen,
4819 .accept = l2cap_sock_accept,
4820 .getname = l2cap_sock_getname,
4821 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004822 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004823 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004824 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004825 .mmap = sock_no_mmap,
4826 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004827 .shutdown = l2cap_sock_shutdown,
4828 .setsockopt = l2cap_sock_setsockopt,
4829 .getsockopt = l2cap_sock_getsockopt
4830};
4831
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004832static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004833 .family = PF_BLUETOOTH,
4834 .owner = THIS_MODULE,
4835 .create = l2cap_sock_create,
4836};
4837
4838static struct hci_proto l2cap_hci_proto = {
4839 .name = "L2CAP",
4840 .id = HCI_PROTO_L2CAP,
4841 .connect_ind = l2cap_connect_ind,
4842 .connect_cfm = l2cap_connect_cfm,
4843 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004844 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004845 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004846 .recv_acldata = l2cap_recv_acldata
4847};
4848
4849static int __init l2cap_init(void)
4850{
4851 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004852
Linus Torvalds1da177e2005-04-16 15:20:36 -07004853 err = proto_register(&l2cap_proto, 0);
4854 if (err < 0)
4855 return err;
4856
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004857 _busy_wq = create_singlethread_workqueue("l2cap");
Anderson Lizardob78d7b4f2010-11-29 12:15:50 -04004858 if (!_busy_wq) {
4859 proto_unregister(&l2cap_proto);
4860 return -ENOMEM;
4861 }
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004862
Linus Torvalds1da177e2005-04-16 15:20:36 -07004863 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4864 if (err < 0) {
4865 BT_ERR("L2CAP socket registration failed");
4866 goto error;
4867 }
4868
4869 err = hci_register_proto(&l2cap_hci_proto);
4870 if (err < 0) {
4871 BT_ERR("L2CAP protocol registration failed");
4872 bt_sock_unregister(BTPROTO_L2CAP);
4873 goto error;
4874 }
4875
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004876 if (bt_debugfs) {
4877 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4878 bt_debugfs, NULL, &l2cap_debugfs_fops);
4879 if (!l2cap_debugfs)
4880 BT_ERR("Failed to create L2CAP debug file");
4881 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004882
4883 BT_INFO("L2CAP ver %s", VERSION);
4884 BT_INFO("L2CAP socket layer initialized");
4885
4886 return 0;
4887
4888error:
Anderson Lizardob78d7b4f2010-11-29 12:15:50 -04004889 destroy_workqueue(_busy_wq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004890 proto_unregister(&l2cap_proto);
4891 return err;
4892}
4893
4894static void __exit l2cap_exit(void)
4895{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004896 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004897
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004898 flush_workqueue(_busy_wq);
4899 destroy_workqueue(_busy_wq);
4900
Linus Torvalds1da177e2005-04-16 15:20:36 -07004901 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4902 BT_ERR("L2CAP socket unregistration failed");
4903
4904 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4905 BT_ERR("L2CAP protocol unregistration failed");
4906
4907 proto_unregister(&l2cap_proto);
4908}
4909
4910void l2cap_load(void)
4911{
4912 /* Dummy function to trigger automatic L2CAP module loading by
4913 * other modules that use L2CAP sockets but don't use any other
4914 * symbols from it. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004915}
4916EXPORT_SYMBOL(l2cap_load);
4917
4918module_init(l2cap_init);
4919module_exit(l2cap_exit);
4920
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004921module_param(disable_ertm, bool, 0644);
4922MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004923
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004924MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004925MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4926MODULE_VERSION(VERSION);
4927MODULE_LICENSE("GPL");
4928MODULE_ALIAS("bt-proto-0");