blob: bf09f6027bd2f6c6342b7bb0b045dbe3a2aa053e [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
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020027/* Bluetooth L2CAP core. */
Linus Torvalds1da177e2005-04-16 15:20:36 -070028
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. Padovanbb58f742011-02-03 20:50:35 -020058int disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020059
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070060static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Marcel Holtmanne1027a72009-02-09 09:18:02 +010061static u8 l2cap_fixed_chan[8] = { 0x02, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070062
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030063static struct workqueue_struct *_busy_wq;
64
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020065struct bt_sock_list l2cap_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070066 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070067};
68
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030069static void l2cap_busy_work(struct work_struct *work);
70
Linus Torvalds1da177e2005-04-16 15:20:36 -070071static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
72 u8 code, u8 ident, u16 dlen, void *data);
73
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -030074static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
75
Marcel Holtmann01394182006-07-03 10:02:46 +020076/* ---- L2CAP channels ---- */
77static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
78{
79 struct sock *s;
80 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
81 if (l2cap_pi(s)->dcid == cid)
82 break;
83 }
84 return s;
85}
86
87static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
88{
89 struct sock *s;
90 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
91 if (l2cap_pi(s)->scid == cid)
92 break;
93 }
94 return s;
95}
96
97/* Find channel with given SCID.
98 * Returns locked socket */
99static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
100{
101 struct sock *s;
102 read_lock(&l->lock);
103 s = __l2cap_get_chan_by_scid(l, cid);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300104 if (s)
105 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200106 read_unlock(&l->lock);
107 return s;
108}
109
110static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
111{
112 struct sock *s;
113 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
114 if (l2cap_pi(s)->ident == ident)
115 break;
116 }
117 return s;
118}
119
120static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
121{
122 struct sock *s;
123 read_lock(&l->lock);
124 s = __l2cap_get_chan_by_ident(l, ident);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300125 if (s)
126 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200127 read_unlock(&l->lock);
128 return s;
129}
130
131static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
132{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300133 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200134
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300135 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300136 if (!__l2cap_get_chan_by_scid(l, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200137 return cid;
138 }
139
140 return 0;
141}
142
143static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
144{
145 sock_hold(sk);
146
147 if (l->head)
148 l2cap_pi(l->head)->prev_c = sk;
149
150 l2cap_pi(sk)->next_c = l->head;
151 l2cap_pi(sk)->prev_c = NULL;
152 l->head = sk;
153}
154
155static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
156{
157 struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
158
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200159 write_lock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200160 if (sk == l->head)
161 l->head = next;
162
163 if (next)
164 l2cap_pi(next)->prev_c = prev;
165 if (prev)
166 l2cap_pi(prev)->next_c = next;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200167 write_unlock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200168
169 __sock_put(sk);
170}
171
Gustavo F. Padovand1010242011-03-25 00:39:48 -0300172static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk)
Marcel Holtmann01394182006-07-03 10:02:46 +0200173{
174 struct l2cap_chan_list *l = &conn->chan_list;
175
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300176 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
177 l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200178
Marcel Holtmann2950f212009-02-12 14:02:50 +0100179 conn->disc_reason = 0x13;
180
Marcel Holtmann01394182006-07-03 10:02:46 +0200181 l2cap_pi(sk)->conn = conn;
182
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300183 if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
Ville Tervob62f3282011-02-10 22:38:50 -0300184 if (conn->hcon->type == LE_LINK) {
185 /* LE connection */
186 l2cap_pi(sk)->omtu = L2CAP_LE_DEFAULT_MTU;
187 l2cap_pi(sk)->scid = L2CAP_CID_LE_DATA;
188 l2cap_pi(sk)->dcid = L2CAP_CID_LE_DATA;
189 } else {
190 /* Alloc CID for connection-oriented socket */
191 l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
192 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
193 }
Marcel Holtmann01394182006-07-03 10:02:46 +0200194 } else if (sk->sk_type == SOCK_DGRAM) {
195 /* Connectionless socket */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300196 l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
197 l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
Marcel Holtmann01394182006-07-03 10:02:46 +0200198 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
199 } else {
200 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300201 l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
202 l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
Marcel Holtmann01394182006-07-03 10:02:46 +0200203 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
204 }
205
206 __l2cap_chan_link(l, sk);
Marcel Holtmann01394182006-07-03 10:02:46 +0200207}
208
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900209/* Delete channel.
Marcel Holtmann01394182006-07-03 10:02:46 +0200210 * Must be called on the locked socket. */
Gustavo F. Padovan6de07022011-02-04 03:35:20 -0200211void l2cap_chan_del(struct sock *sk, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200212{
213 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
214 struct sock *parent = bt_sk(sk)->parent;
215
216 l2cap_sock_clear_timer(sk);
217
218 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
219
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900220 if (conn) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200221 /* Unlink from channel list */
222 l2cap_chan_unlink(&conn->chan_list, sk);
223 l2cap_pi(sk)->conn = NULL;
224 hci_conn_put(conn->hcon);
225 }
226
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200227 sk->sk_state = BT_CLOSED;
Marcel Holtmann01394182006-07-03 10:02:46 +0200228 sock_set_flag(sk, SOCK_ZAPPED);
229
230 if (err)
231 sk->sk_err = err;
232
233 if (parent) {
234 bt_accept_unlink(sk);
235 parent->sk_data_ready(parent, 0);
236 } else
237 sk->sk_state_change(sk);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300238
239 skb_queue_purge(TX_QUEUE(sk));
240
241 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
242 struct srej_list *l, *tmp;
243
244 del_timer(&l2cap_pi(sk)->retrans_timer);
245 del_timer(&l2cap_pi(sk)->monitor_timer);
246 del_timer(&l2cap_pi(sk)->ack_timer);
247
248 skb_queue_purge(SREJ_QUEUE(sk));
249 skb_queue_purge(BUSY_QUEUE(sk));
250
251 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
252 list_del(&l->list);
253 kfree(l);
254 }
255 }
Marcel Holtmann01394182006-07-03 10:02:46 +0200256}
257
Johan Hedberg8556edd32011-01-19 12:06:50 +0530258static inline u8 l2cap_get_auth_type(struct sock *sk)
259{
260 if (sk->sk_type == SOCK_RAW) {
261 switch (l2cap_pi(sk)->sec_level) {
262 case BT_SECURITY_HIGH:
263 return HCI_AT_DEDICATED_BONDING_MITM;
264 case BT_SECURITY_MEDIUM:
265 return HCI_AT_DEDICATED_BONDING;
266 default:
267 return HCI_AT_NO_BONDING;
268 }
269 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
270 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
271 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
272
273 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
274 return HCI_AT_NO_BONDING_MITM;
275 else
276 return HCI_AT_NO_BONDING;
277 } else {
278 switch (l2cap_pi(sk)->sec_level) {
279 case BT_SECURITY_HIGH:
280 return HCI_AT_GENERAL_BONDING_MITM;
281 case BT_SECURITY_MEDIUM:
282 return HCI_AT_GENERAL_BONDING;
283 default:
284 return HCI_AT_NO_BONDING;
285 }
286 }
287}
288
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200289/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100290static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200291{
292 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100293 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200294
Johan Hedberg8556edd32011-01-19 12:06:50 +0530295 auth_type = l2cap_get_auth_type(sk);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100296
297 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
298 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200299}
300
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200301u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200302{
303 u8 id;
304
305 /* Get next available identificator.
306 * 1 - 128 are used by kernel.
307 * 129 - 199 are reserved.
308 * 200 - 254 are used by utilities like l2ping, etc.
309 */
310
311 spin_lock_bh(&conn->lock);
312
313 if (++conn->tx_ident > 128)
314 conn->tx_ident = 1;
315
316 id = conn->tx_ident;
317
318 spin_unlock_bh(&conn->lock);
319
320 return id;
321}
322
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200323void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200324{
325 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200326 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200327
328 BT_DBG("code 0x%2.2x", code);
329
330 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300331 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200332
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200333 if (lmp_no_flush_capable(conn->hcon->hdev))
334 flags = ACL_START_NO_FLUSH;
335 else
336 flags = ACL_START;
337
338 hci_send_acl(conn->hcon, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200339}
340
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300341static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300342{
343 struct sk_buff *skb;
344 struct l2cap_hdr *lh;
345 struct l2cap_conn *conn = pi->conn;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300346 struct sock *sk = (struct sock *)pi;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300347 int count, hlen = L2CAP_HDR_SIZE + 2;
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200348 u8 flags;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300349
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300350 if (sk->sk_state != BT_CONNECTED)
351 return;
352
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300353 if (pi->fcs == L2CAP_FCS_CRC16)
354 hlen += 2;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300355
356 BT_DBG("pi %p, control 0x%2.2x", pi, control);
357
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300358 count = min_t(unsigned int, conn->mtu, hlen);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300359 control |= L2CAP_CTRL_FRAME_TYPE;
360
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -0300361 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
362 control |= L2CAP_CTRL_FINAL;
363 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
364 }
365
Gustavo F. Padovanf0946cc2010-05-01 16:15:37 -0300366 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
367 control |= L2CAP_CTRL_POLL;
368 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
369 }
370
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300371 skb = bt_skb_alloc(count, GFP_ATOMIC);
372 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300373 return;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300374
375 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300376 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300377 lh->cid = cpu_to_le16(pi->dcid);
378 put_unaligned_le16(control, skb_put(skb, 2));
379
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300380 if (pi->fcs == L2CAP_FCS_CRC16) {
381 u16 fcs = crc16(0, (u8 *)lh, count - 2);
382 put_unaligned_le16(fcs, skb_put(skb, 2));
383 }
384
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200385 if (lmp_no_flush_capable(conn->hcon->hdev))
386 flags = ACL_START_NO_FLUSH;
387 else
388 flags = ACL_START;
389
390 hci_send_acl(pi->conn->hcon, skb, flags);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300391}
392
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300393static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300394{
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300395 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300396 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300397 pi->conn_state |= L2CAP_CONN_RNR_SENT;
398 } else
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300399 control |= L2CAP_SUPER_RCV_READY;
400
Gustavo F. Padovan2ab25cd2009-10-03 02:34:40 -0300401 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
402
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300403 l2cap_send_sframe(pi, control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300404}
405
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300406static inline int __l2cap_no_conn_pending(struct sock *sk)
407{
408 return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND);
409}
410
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200411static void l2cap_do_start(struct sock *sk)
412{
413 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
414
415 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100416 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
417 return;
418
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300419 if (l2cap_check_security(sk) && __l2cap_no_conn_pending(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200420 struct l2cap_conn_req req;
421 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
422 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200423
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200424 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300425 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200426
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200427 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200428 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200429 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200430 } else {
431 struct l2cap_info_req req;
432 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
433
434 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
435 conn->info_ident = l2cap_get_ident(conn);
436
437 mod_timer(&conn->info_timer, jiffies +
438 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
439
440 l2cap_send_cmd(conn, conn->info_ident,
441 L2CAP_INFO_REQ, sizeof(req), &req);
442 }
443}
444
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300445static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
446{
447 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -0300448 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300449 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
450
451 switch (mode) {
452 case L2CAP_MODE_ERTM:
453 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
454 case L2CAP_MODE_STREAMING:
455 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
456 default:
457 return 0x00;
458 }
459}
460
Gustavo F. Padovan6de07022011-02-04 03:35:20 -0200461void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300462{
463 struct l2cap_disconn_req req;
464
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300465 if (!conn)
466 return;
467
468 skb_queue_purge(TX_QUEUE(sk));
469
470 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
471 del_timer(&l2cap_pi(sk)->retrans_timer);
472 del_timer(&l2cap_pi(sk)->monitor_timer);
473 del_timer(&l2cap_pi(sk)->ack_timer);
474 }
475
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300476 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
477 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
478 l2cap_send_cmd(conn, l2cap_get_ident(conn),
479 L2CAP_DISCONN_REQ, sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300480
481 sk->sk_state = BT_DISCONN;
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300482 sk->sk_err = err;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300483}
484
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200486static void l2cap_conn_start(struct l2cap_conn *conn)
487{
488 struct l2cap_chan_list *l = &conn->chan_list;
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300489 struct sock_del_list del, *tmp1, *tmp2;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200490 struct sock *sk;
491
492 BT_DBG("conn %p", conn);
493
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300494 INIT_LIST_HEAD(&del.list);
495
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200496 read_lock(&l->lock);
497
498 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
499 bh_lock_sock(sk);
500
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300501 if (sk->sk_type != SOCK_SEQPACKET &&
502 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200503 bh_unlock_sock(sk);
504 continue;
505 }
506
507 if (sk->sk_state == BT_CONNECT) {
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300508 struct l2cap_conn_req req;
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300509
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300510 if (!l2cap_check_security(sk) ||
511 !__l2cap_no_conn_pending(sk)) {
512 bh_unlock_sock(sk);
513 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200514 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300515
516 if (!l2cap_mode_supported(l2cap_pi(sk)->mode,
517 conn->feat_mask)
518 && l2cap_pi(sk)->conf_state &
519 L2CAP_CONF_STATE2_DEVICE) {
520 tmp1 = kzalloc(sizeof(struct sock_del_list),
521 GFP_ATOMIC);
522 tmp1->sk = sk;
523 list_add_tail(&tmp1->list, &del.list);
524 bh_unlock_sock(sk);
525 continue;
526 }
527
528 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
529 req.psm = l2cap_pi(sk)->psm;
530
531 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
532 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
533
534 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
535 L2CAP_CONN_REQ, sizeof(req), &req);
536
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200537 } else if (sk->sk_state == BT_CONNECT2) {
538 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -0300539 char buf[128];
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200540 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
541 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
542
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100543 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100544 if (bt_sk(sk)->defer_setup) {
545 struct sock *parent = bt_sk(sk)->parent;
546 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
547 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
548 parent->sk_data_ready(parent, 0);
549
550 } else {
551 sk->sk_state = BT_CONFIG;
552 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
553 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
554 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200555 } else {
556 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
557 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
558 }
559
560 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
561 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -0300562
563 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT ||
564 rsp.result != L2CAP_CR_SUCCESS) {
565 bh_unlock_sock(sk);
566 continue;
567 }
568
569 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
570 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
571 l2cap_build_conf_req(sk, buf), buf);
572 l2cap_pi(sk)->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200573 }
574
575 bh_unlock_sock(sk);
576 }
577
578 read_unlock(&l->lock);
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300579
580 list_for_each_entry_safe(tmp1, tmp2, &del.list, list) {
581 bh_lock_sock(tmp1->sk);
582 __l2cap_sock_close(tmp1->sk, ECONNRESET);
583 bh_unlock_sock(tmp1->sk);
584 list_del(&tmp1->list);
585 kfree(tmp1);
586 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200587}
588
Ville Tervob62f3282011-02-10 22:38:50 -0300589/* Find socket with cid and source bdaddr.
590 * Returns closest match, locked.
591 */
592static struct sock *l2cap_get_sock_by_scid(int state, __le16 cid, bdaddr_t *src)
593{
594 struct sock *s, *sk = NULL, *sk1 = NULL;
595 struct hlist_node *node;
596
597 read_lock(&l2cap_sk_list.lock);
598
599 sk_for_each(sk, node, &l2cap_sk_list.head) {
600 if (state && sk->sk_state != state)
601 continue;
602
603 if (l2cap_pi(sk)->scid == cid) {
604 /* Exact match. */
605 if (!bacmp(&bt_sk(sk)->src, src))
606 break;
607
608 /* Closest match */
609 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
610 sk1 = sk;
611 }
612 }
613 s = node ? sk : sk1;
614 if (s)
615 bh_lock_sock(s);
616 read_unlock(&l2cap_sk_list.lock);
617
618 return s;
619}
620
621static void l2cap_le_conn_ready(struct l2cap_conn *conn)
622{
623 struct l2cap_chan_list *list = &conn->chan_list;
624 struct sock *parent, *uninitialized_var(sk);
625
626 BT_DBG("");
627
628 /* Check if we have socket listening on cid */
629 parent = l2cap_get_sock_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
630 conn->src);
631 if (!parent)
632 return;
633
634 /* Check for backlog size */
635 if (sk_acceptq_is_full(parent)) {
636 BT_DBG("backlog full %d", parent->sk_ack_backlog);
637 goto clean;
638 }
639
640 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
641 if (!sk)
642 goto clean;
643
644 write_lock_bh(&list->lock);
645
646 hci_conn_hold(conn->hcon);
647
648 l2cap_sock_init(sk, parent);
649 bacpy(&bt_sk(sk)->src, conn->src);
650 bacpy(&bt_sk(sk)->dst, conn->dst);
651
Gustavo F. Padovand1010242011-03-25 00:39:48 -0300652 bt_accept_enqueue(parent, sk);
653
654 __l2cap_chan_add(conn, sk);
Ville Tervob62f3282011-02-10 22:38:50 -0300655
656 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
657
658 sk->sk_state = BT_CONNECTED;
659 parent->sk_data_ready(parent, 0);
660
661 write_unlock_bh(&list->lock);
662
663clean:
664 bh_unlock_sock(parent);
665}
666
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200667static void l2cap_conn_ready(struct l2cap_conn *conn)
668{
669 struct l2cap_chan_list *l = &conn->chan_list;
670 struct sock *sk;
671
672 BT_DBG("conn %p", conn);
673
Ville Tervob62f3282011-02-10 22:38:50 -0300674 if (!conn->hcon->out && conn->hcon->type == LE_LINK)
675 l2cap_le_conn_ready(conn);
676
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200677 read_lock(&l->lock);
678
679 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
680 bh_lock_sock(sk);
681
Ville Tervoacd7d372011-02-10 22:38:49 -0300682 if (conn->hcon->type == LE_LINK) {
683 l2cap_sock_clear_timer(sk);
684 sk->sk_state = BT_CONNECTED;
685 sk->sk_state_change(sk);
686 }
687
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300688 if (sk->sk_type != SOCK_SEQPACKET &&
689 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200690 l2cap_sock_clear_timer(sk);
691 sk->sk_state = BT_CONNECTED;
692 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200693 } else if (sk->sk_state == BT_CONNECT)
694 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200695
696 bh_unlock_sock(sk);
697 }
698
699 read_unlock(&l->lock);
700}
701
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200702/* Notify sockets that we cannot guaranty reliability anymore */
703static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
704{
705 struct l2cap_chan_list *l = &conn->chan_list;
706 struct sock *sk;
707
708 BT_DBG("conn %p", conn);
709
710 read_lock(&l->lock);
711
712 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100713 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200714 sk->sk_err = err;
715 }
716
717 read_unlock(&l->lock);
718}
719
720static void l2cap_info_timeout(unsigned long arg)
721{
722 struct l2cap_conn *conn = (void *) arg;
723
Marcel Holtmann984947d2009-02-06 23:35:19 +0100724 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100725 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100726
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200727 l2cap_conn_start(conn);
728}
729
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
731{
Marcel Holtmann01394182006-07-03 10:02:46 +0200732 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733
Marcel Holtmann01394182006-07-03 10:02:46 +0200734 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735 return conn;
736
Marcel Holtmann01394182006-07-03 10:02:46 +0200737 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
738 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740
741 hcon->l2cap_data = conn;
742 conn->hcon = hcon;
743
Marcel Holtmann01394182006-07-03 10:02:46 +0200744 BT_DBG("hcon %p conn %p", hcon, conn);
745
Ville Tervoacd7d372011-02-10 22:38:49 -0300746 if (hcon->hdev->le_mtu && hcon->type == LE_LINK)
747 conn->mtu = hcon->hdev->le_mtu;
748 else
749 conn->mtu = hcon->hdev->acl_mtu;
750
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751 conn->src = &hcon->hdev->bdaddr;
752 conn->dst = &hcon->dst;
753
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200754 conn->feat_mask = 0;
755
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756 spin_lock_init(&conn->lock);
757 rwlock_init(&conn->chan_list.lock);
758
Ville Tervob62f3282011-02-10 22:38:50 -0300759 if (hcon->type != LE_LINK)
760 setup_timer(&conn->info_timer, l2cap_info_timeout,
Dave Young45054dc2009-10-18 20:28:30 +0000761 (unsigned long) conn);
762
Marcel Holtmann2950f212009-02-12 14:02:50 +0100763 conn->disc_reason = 0x13;
764
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 return conn;
766}
767
Marcel Holtmann01394182006-07-03 10:02:46 +0200768static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769{
Marcel Holtmann01394182006-07-03 10:02:46 +0200770 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 struct sock *sk;
772
Marcel Holtmann01394182006-07-03 10:02:46 +0200773 if (!conn)
774 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775
776 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
777
Wei Yongjun7585b972009-02-25 18:29:52 +0800778 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779
780 /* Kill channels */
781 while ((sk = conn->chan_list.head)) {
782 bh_lock_sock(sk);
783 l2cap_chan_del(sk, err);
784 bh_unlock_sock(sk);
785 l2cap_sock_kill(sk);
786 }
787
Dave Young8e8440f2008-03-03 12:18:55 -0800788 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
789 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800790
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791 hcon->l2cap_data = NULL;
792 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793}
794
Gustavo F. Padovand1010242011-03-25 00:39:48 -0300795static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796{
797 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200798 write_lock_bh(&l->lock);
Gustavo F. Padovand1010242011-03-25 00:39:48 -0300799 __l2cap_chan_add(conn, sk);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200800 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801}
802
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804
805/* Find socket with psm and source bdaddr.
806 * Returns closest match.
807 */
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +0000808static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809{
810 struct sock *sk = NULL, *sk1 = NULL;
811 struct hlist_node *node;
812
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +0000813 read_lock(&l2cap_sk_list.lock);
814
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815 sk_for_each(sk, node, &l2cap_sk_list.head) {
816 if (state && sk->sk_state != state)
817 continue;
818
819 if (l2cap_pi(sk)->psm == psm) {
820 /* Exact match. */
821 if (!bacmp(&bt_sk(sk)->src, src))
822 break;
823
824 /* Closest match */
825 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
826 sk1 = sk;
827 }
828 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830 read_unlock(&l2cap_sk_list.lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +0000831
832 return node ? sk : sk1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833}
834
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200835int l2cap_do_connect(struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836{
837 bdaddr_t *src = &bt_sk(sk)->src;
838 bdaddr_t *dst = &bt_sk(sk)->dst;
839 struct l2cap_conn *conn;
840 struct hci_conn *hcon;
841 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200842 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +0200843 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700844
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100845 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
846 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300848 hdev = hci_get_route(dst, src);
849 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850 return -EHOSTUNREACH;
851
852 hci_dev_lock_bh(hdev);
853
Johan Hedberg8556edd32011-01-19 12:06:50 +0530854 auth_type = l2cap_get_auth_type(sk);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200855
Ville Tervoacd7d372011-02-10 22:38:49 -0300856 if (l2cap_pi(sk)->dcid == L2CAP_CID_LE_DATA)
857 hcon = hci_connect(hdev, LE_LINK, dst,
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100858 l2cap_pi(sk)->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -0300859 else
860 hcon = hci_connect(hdev, ACL_LINK, dst,
861 l2cap_pi(sk)->sec_level, auth_type);
862
Ville Tervo30e76272011-02-22 16:10:53 -0300863 if (IS_ERR(hcon)) {
864 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -0300866 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867
868 conn = l2cap_conn_add(hcon, 0);
869 if (!conn) {
870 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -0300871 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872 goto done;
873 }
874
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 /* Update source addr of the socket */
876 bacpy(src, conn->src);
877
Gustavo F. Padovand1010242011-03-25 00:39:48 -0300878 l2cap_chan_add(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879
880 sk->sk_state = BT_CONNECT;
881 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
882
883 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300884 if (sk->sk_type != SOCK_SEQPACKET &&
885 sk->sk_type != SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886 l2cap_sock_clear_timer(sk);
Johan Hedbergd00ef242011-01-19 12:06:51 +0530887 if (l2cap_check_security(sk))
888 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200889 } else
890 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891 }
892
Ville Tervo30e76272011-02-22 16:10:53 -0300893 err = 0;
894
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895done:
896 hci_dev_unlock_bh(hdev);
897 hci_dev_put(hdev);
898 return err;
899}
900
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -0200901int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -0300902{
903 DECLARE_WAITQUEUE(wait, current);
904 int err = 0;
905 int timeo = HZ/5;
906
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +0200907 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -0300908 while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
909 set_current_state(TASK_INTERRUPTIBLE);
910
911 if (!timeo)
912 timeo = HZ/5;
913
914 if (signal_pending(current)) {
915 err = sock_intr_errno(timeo);
916 break;
917 }
918
919 release_sock(sk);
920 timeo = schedule_timeout(timeo);
921 lock_sock(sk);
922
923 err = sock_error(sk);
924 if (err)
925 break;
926 }
927 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +0200928 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -0300929 return err;
930}
931
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300932static void l2cap_monitor_timeout(unsigned long arg)
933{
934 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300935
Gustavo F. Padovan0e989582010-04-19 14:45:38 -0300936 BT_DBG("sk %p", sk);
937
Gustavo F. Padovane6862192009-08-24 00:45:19 -0300938 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300939 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300940 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +0200941 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300942 return;
943 }
944
945 l2cap_pi(sk)->retry_count++;
946 __mod_monitor_timer();
947
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -0300948 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -0300949 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300950}
951
952static void l2cap_retrans_timeout(unsigned long arg)
953{
954 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300955
Gustavo F. Padovan0e989582010-04-19 14:45:38 -0300956 BT_DBG("sk %p", sk);
957
Gustavo F. Padovane6862192009-08-24 00:45:19 -0300958 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300959 l2cap_pi(sk)->retry_count = 1;
960 __mod_monitor_timer();
961
962 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
963
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -0300964 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -0300965 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300966}
967
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300968static void l2cap_drop_acked_frames(struct sock *sk)
969{
970 struct sk_buff *skb;
971
Gustavo F. Padovan812e7372010-05-01 16:15:42 -0300972 while ((skb = skb_peek(TX_QUEUE(sk))) &&
973 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300974 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
975 break;
976
977 skb = skb_dequeue(TX_QUEUE(sk));
978 kfree_skb(skb);
979
980 l2cap_pi(sk)->unacked_frames--;
981 }
982
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300983 if (!l2cap_pi(sk)->unacked_frames)
984 del_timer(&l2cap_pi(sk)->retrans_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300985}
986
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -0200987void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300988{
989 struct l2cap_pinfo *pi = l2cap_pi(sk);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200990 struct hci_conn *hcon = pi->conn->hcon;
991 u16 flags;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300992
993 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
994
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200995 if (!pi->flushable && lmp_no_flush_capable(hcon->hdev))
996 flags = ACL_START_NO_FLUSH;
997 else
998 flags = ACL_START;
999
1000 hci_send_acl(hcon, skb, flags);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001001}
1002
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001003void l2cap_streaming_send(struct sock *sk)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001004{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001005 struct sk_buff *skb;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001006 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001007 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001008
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001009 while ((skb = skb_dequeue(TX_QUEUE(sk)))) {
1010 control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001011 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001012 put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001013
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001014 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001015 fcs = crc16(0, (u8 *)skb->data, skb->len - 2);
1016 put_unaligned_le16(fcs, skb->data + skb->len - 2);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001017 }
1018
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001019 l2cap_do_send(sk, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001020
1021 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001022 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001023}
1024
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001025static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001026{
1027 struct l2cap_pinfo *pi = l2cap_pi(sk);
1028 struct sk_buff *skb, *tx_skb;
1029 u16 control, fcs;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001030
1031 skb = skb_peek(TX_QUEUE(sk));
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001032 if (!skb)
1033 return;
1034
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001035 do {
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001036 if (bt_cb(skb)->tx_seq == tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001037 break;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001038
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001039 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1040 return;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001041
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001042 } while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001043
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001044 if (pi->remote_max_tx &&
1045 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001046 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001047 return;
1048 }
1049
1050 tx_skb = skb_clone(skb, GFP_ATOMIC);
1051 bt_cb(skb)->retries++;
1052 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001053
1054 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1055 control |= L2CAP_CTRL_FINAL;
1056 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1057 }
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001058
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001059 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1060 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001061
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001062 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1063
1064 if (pi->fcs == L2CAP_FCS_CRC16) {
1065 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1066 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1067 }
1068
1069 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001070}
1071
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001072int l2cap_ertm_send(struct sock *sk)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001073{
1074 struct sk_buff *skb, *tx_skb;
1075 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001076 u16 control, fcs;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001077 int nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001078
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001079 if (sk->sk_state != BT_CONNECTED)
1080 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001081
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001082 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001083
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001084 if (pi->remote_max_tx &&
1085 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001086 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001087 break;
1088 }
1089
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001090 tx_skb = skb_clone(skb, GFP_ATOMIC);
1091
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001092 bt_cb(skb)->retries++;
1093
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001094 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001095 control &= L2CAP_CTRL_SAR;
1096
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001097 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1098 control |= L2CAP_CTRL_FINAL;
1099 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1100 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001101 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001102 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1103 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1104
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001105
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001106 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001107 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1108 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1109 }
1110
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001111 l2cap_do_send(sk, tx_skb);
1112
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001113 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001114
1115 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1116 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1117
1118 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001119 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001120
1121 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1122 sk->sk_send_head = NULL;
1123 else
1124 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001125
1126 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001127 }
1128
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001129 return nsent;
1130}
1131
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001132static int l2cap_retransmit_frames(struct sock *sk)
1133{
1134 struct l2cap_pinfo *pi = l2cap_pi(sk);
1135 int ret;
1136
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001137 if (!skb_queue_empty(TX_QUEUE(sk)))
1138 sk->sk_send_head = TX_QUEUE(sk)->next;
1139
1140 pi->next_tx_seq = pi->expected_ack_seq;
1141 ret = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001142 return ret;
1143}
1144
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001145static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001146{
1147 struct sock *sk = (struct sock *)pi;
1148 u16 control = 0;
1149
1150 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1151
1152 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1153 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001154 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001155 l2cap_send_sframe(pi, control);
1156 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001157 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001158
Gustavo F. Padovane0f66212010-06-21 18:50:49 -03001159 if (l2cap_ertm_send(sk) > 0)
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001160 return;
1161
1162 control |= L2CAP_SUPER_RCV_READY;
1163 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001164}
1165
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001166static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001167{
1168 struct srej_list *tail;
1169 u16 control;
1170
1171 control = L2CAP_SUPER_SELECT_REJECT;
1172 control |= L2CAP_CTRL_FINAL;
1173
1174 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1175 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1176
1177 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001178}
1179
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001180static 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 -07001181{
1182 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001183 struct sk_buff **frag;
1184 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001186 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001187 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001188
1189 sent += count;
1190 len -= count;
1191
1192 /* Continuation fragments (no L2CAP header) */
1193 frag = &skb_shinfo(skb)->frag_list;
1194 while (len) {
1195 count = min_t(unsigned int, conn->mtu, len);
1196
1197 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1198 if (!*frag)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001199 return err;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001200 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1201 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202
1203 sent += count;
1204 len -= count;
1205
1206 frag = &(*frag)->next;
1207 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208
1209 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001210}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001212struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001213{
1214 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1215 struct sk_buff *skb;
1216 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1217 struct l2cap_hdr *lh;
1218
1219 BT_DBG("sk %p len %d", sk, (int)len);
1220
1221 count = min_t(unsigned int, (conn->mtu - hlen), len);
1222 skb = bt_skb_send_alloc(sk, count + hlen,
1223 msg->msg_flags & MSG_DONTWAIT, &err);
1224 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001225 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001226
1227 /* Create L2CAP header */
1228 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1229 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1230 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1231 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1232
1233 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1234 if (unlikely(err < 0)) {
1235 kfree_skb(skb);
1236 return ERR_PTR(err);
1237 }
1238 return skb;
1239}
1240
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001241struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001242{
1243 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1244 struct sk_buff *skb;
1245 int err, count, hlen = L2CAP_HDR_SIZE;
1246 struct l2cap_hdr *lh;
1247
1248 BT_DBG("sk %p len %d", sk, (int)len);
1249
1250 count = min_t(unsigned int, (conn->mtu - hlen), len);
1251 skb = bt_skb_send_alloc(sk, count + hlen,
1252 msg->msg_flags & MSG_DONTWAIT, &err);
1253 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001254 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001255
1256 /* Create L2CAP header */
1257 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1258 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1259 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1260
1261 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1262 if (unlikely(err < 0)) {
1263 kfree_skb(skb);
1264 return ERR_PTR(err);
1265 }
1266 return skb;
1267}
1268
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001269struct 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 -03001270{
1271 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1272 struct sk_buff *skb;
1273 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1274 struct l2cap_hdr *lh;
1275
1276 BT_DBG("sk %p len %d", sk, (int)len);
1277
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001278 if (!conn)
1279 return ERR_PTR(-ENOTCONN);
1280
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001281 if (sdulen)
1282 hlen += 2;
1283
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001284 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1285 hlen += 2;
1286
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001287 count = min_t(unsigned int, (conn->mtu - hlen), len);
1288 skb = bt_skb_send_alloc(sk, count + hlen,
1289 msg->msg_flags & MSG_DONTWAIT, &err);
1290 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001291 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001292
1293 /* Create L2CAP header */
1294 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1295 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1296 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1297 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001298 if (sdulen)
1299 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001300
1301 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1302 if (unlikely(err < 0)) {
1303 kfree_skb(skb);
1304 return ERR_PTR(err);
1305 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001306
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001307 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1308 put_unaligned_le16(0, skb_put(skb, 2));
1309
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001310 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001311 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312}
1313
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001314int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001315{
1316 struct l2cap_pinfo *pi = l2cap_pi(sk);
1317 struct sk_buff *skb;
1318 struct sk_buff_head sar_queue;
1319 u16 control;
1320 size_t size = 0;
1321
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001322 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001323 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001324 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001325 if (IS_ERR(skb))
1326 return PTR_ERR(skb);
1327
1328 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001329 len -= pi->remote_mps;
1330 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001331
1332 while (len > 0) {
1333 size_t buflen;
1334
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001335 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001336 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001337 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001338 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001339 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001340 buflen = len;
1341 }
1342
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001343 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001344 if (IS_ERR(skb)) {
1345 skb_queue_purge(&sar_queue);
1346 return PTR_ERR(skb);
1347 }
1348
1349 __skb_queue_tail(&sar_queue, skb);
1350 len -= buflen;
1351 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001352 }
1353 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1354 if (sk->sk_send_head == NULL)
1355 sk->sk_send_head = sar_queue.next;
1356
1357 return size;
1358}
1359
Linus Torvalds1da177e2005-04-16 15:20:36 -07001360static void l2cap_chan_ready(struct sock *sk)
1361{
1362 struct sock *parent = bt_sk(sk)->parent;
1363
1364 BT_DBG("sk %p, parent %p", sk, parent);
1365
1366 l2cap_pi(sk)->conf_state = 0;
1367 l2cap_sock_clear_timer(sk);
1368
1369 if (!parent) {
1370 /* Outgoing channel.
1371 * Wake up socket sleeping on connect.
1372 */
1373 sk->sk_state = BT_CONNECTED;
1374 sk->sk_state_change(sk);
1375 } else {
1376 /* Incoming channel.
1377 * Wake up socket sleeping on accept.
1378 */
1379 parent->sk_data_ready(parent, 0);
1380 }
1381}
1382
1383/* Copy frame to all raw sockets on that connection */
1384static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
1385{
1386 struct l2cap_chan_list *l = &conn->chan_list;
1387 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001388 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389
1390 BT_DBG("conn %p", conn);
1391
1392 read_lock(&l->lock);
1393 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
1394 if (sk->sk_type != SOCK_RAW)
1395 continue;
1396
1397 /* Don't send frame to the socket it came from */
1398 if (skb->sk == sk)
1399 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001400 nskb = skb_clone(skb, GFP_ATOMIC);
1401 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402 continue;
1403
1404 if (sock_queue_rcv_skb(sk, nskb))
1405 kfree_skb(nskb);
1406 }
1407 read_unlock(&l->lock);
1408}
1409
1410/* ---- L2CAP signalling commands ---- */
1411static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
1412 u8 code, u8 ident, u16 dlen, void *data)
1413{
1414 struct sk_buff *skb, **frag;
1415 struct l2cap_cmd_hdr *cmd;
1416 struct l2cap_hdr *lh;
1417 int len, count;
1418
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001419 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
1420 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421
1422 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
1423 count = min_t(unsigned int, conn->mtu, len);
1424
1425 skb = bt_skb_alloc(count, GFP_ATOMIC);
1426 if (!skb)
1427 return NULL;
1428
1429 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001430 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02001431
1432 if (conn->hcon->type == LE_LINK)
1433 lh->cid = cpu_to_le16(L2CAP_CID_LE_SIGNALING);
1434 else
1435 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436
1437 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
1438 cmd->code = code;
1439 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001440 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441
1442 if (dlen) {
1443 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
1444 memcpy(skb_put(skb, count), data, count);
1445 data += count;
1446 }
1447
1448 len -= skb->len;
1449
1450 /* Continuation fragments (no L2CAP header) */
1451 frag = &skb_shinfo(skb)->frag_list;
1452 while (len) {
1453 count = min_t(unsigned int, conn->mtu, len);
1454
1455 *frag = bt_skb_alloc(count, GFP_ATOMIC);
1456 if (!*frag)
1457 goto fail;
1458
1459 memcpy(skb_put(*frag, count), data, count);
1460
1461 len -= count;
1462 data += count;
1463
1464 frag = &(*frag)->next;
1465 }
1466
1467 return skb;
1468
1469fail:
1470 kfree_skb(skb);
1471 return NULL;
1472}
1473
1474static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
1475{
1476 struct l2cap_conf_opt *opt = *ptr;
1477 int len;
1478
1479 len = L2CAP_CONF_OPT_SIZE + opt->len;
1480 *ptr += len;
1481
1482 *type = opt->type;
1483 *olen = opt->len;
1484
1485 switch (opt->len) {
1486 case 1:
1487 *val = *((u8 *) opt->val);
1488 break;
1489
1490 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04001491 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492 break;
1493
1494 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04001495 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496 break;
1497
1498 default:
1499 *val = (unsigned long) opt->val;
1500 break;
1501 }
1502
1503 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
1504 return len;
1505}
1506
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
1508{
1509 struct l2cap_conf_opt *opt = *ptr;
1510
1511 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
1512
1513 opt->type = type;
1514 opt->len = len;
1515
1516 switch (len) {
1517 case 1:
1518 *((u8 *) opt->val) = val;
1519 break;
1520
1521 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02001522 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 break;
1524
1525 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02001526 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527 break;
1528
1529 default:
1530 memcpy(opt->val, (void *) val, len);
1531 break;
1532 }
1533
1534 *ptr += L2CAP_CONF_OPT_SIZE + len;
1535}
1536
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03001537static void l2cap_ack_timeout(unsigned long arg)
1538{
1539 struct sock *sk = (void *) arg;
1540
1541 bh_lock_sock(sk);
1542 l2cap_send_ack(l2cap_pi(sk));
1543 bh_unlock_sock(sk);
1544}
1545
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03001546static inline void l2cap_ertm_init(struct sock *sk)
1547{
1548 l2cap_pi(sk)->expected_ack_seq = 0;
1549 l2cap_pi(sk)->unacked_frames = 0;
1550 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03001551 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001552 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03001553
1554 setup_timer(&l2cap_pi(sk)->retrans_timer,
1555 l2cap_retrans_timeout, (unsigned long) sk);
1556 setup_timer(&l2cap_pi(sk)->monitor_timer,
1557 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03001558 setup_timer(&l2cap_pi(sk)->ack_timer,
1559 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03001560
1561 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001562 __skb_queue_head_init(BUSY_QUEUE(sk));
1563
1564 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03001565
1566 sk->sk_backlog_rcv = l2cap_ertm_data_rcv;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03001567}
1568
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001569static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
1570{
1571 switch (mode) {
1572 case L2CAP_MODE_STREAMING:
1573 case L2CAP_MODE_ERTM:
1574 if (l2cap_mode_supported(mode, remote_feat_mask))
1575 return mode;
1576 /* fall through */
1577 default:
1578 return L2CAP_MODE_BASIC;
1579 }
1580}
1581
Gustavo F. Padovan68983252011-02-04 03:02:31 -02001582int l2cap_build_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583{
1584 struct l2cap_pinfo *pi = l2cap_pi(sk);
1585 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001586 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587 void *ptr = req->data;
1588
1589 BT_DBG("sk %p", sk);
1590
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001591 if (pi->num_conf_req || pi->num_conf_rsp)
1592 goto done;
1593
1594 switch (pi->mode) {
1595 case L2CAP_MODE_STREAMING:
1596 case L2CAP_MODE_ERTM:
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03001597 if (pi->conf_state & L2CAP_CONF_STATE2_DEVICE)
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03001598 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03001599
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03001600 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001601 default:
1602 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
1603 break;
1604 }
1605
1606done:
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02001607 if (pi->imtu != L2CAP_DEFAULT_MTU)
1608 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
1609
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001610 switch (pi->mode) {
1611 case L2CAP_MODE_BASIC:
Gustavo F. Padovan63406502010-08-03 23:49:29 -03001612 if (!(pi->conn->feat_mask & L2CAP_FEAT_ERTM) &&
1613 !(pi->conn->feat_mask & L2CAP_FEAT_STREAMING))
1614 break;
1615
Gustavo F. Padovan62547752010-06-08 20:05:31 -03001616 rfc.mode = L2CAP_MODE_BASIC;
1617 rfc.txwin_size = 0;
1618 rfc.max_transmit = 0;
1619 rfc.retrans_timeout = 0;
1620 rfc.monitor_timeout = 0;
1621 rfc.max_pdu_size = 0;
1622
Gustavo F. Padovan63406502010-08-03 23:49:29 -03001623 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
1624 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001625 break;
1626
1627 case L2CAP_MODE_ERTM:
1628 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001629 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001630 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001631 rfc.retrans_timeout = 0;
1632 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001633 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03001634 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001635 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001636
Gustavo F. Padovan63406502010-08-03 23:49:29 -03001637 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
1638 (unsigned long) &rfc);
1639
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001640 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
1641 break;
1642
1643 if (pi->fcs == L2CAP_FCS_NONE ||
1644 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
1645 pi->fcs = L2CAP_FCS_NONE;
1646 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
1647 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001648 break;
1649
1650 case L2CAP_MODE_STREAMING:
1651 rfc.mode = L2CAP_MODE_STREAMING;
1652 rfc.txwin_size = 0;
1653 rfc.max_transmit = 0;
1654 rfc.retrans_timeout = 0;
1655 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001656 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03001657 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001658 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001659
Gustavo F. Padovan63406502010-08-03 23:49:29 -03001660 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
1661 (unsigned long) &rfc);
1662
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001663 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
1664 break;
1665
1666 if (pi->fcs == L2CAP_FCS_NONE ||
1667 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
1668 pi->fcs = L2CAP_FCS_NONE;
1669 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
1670 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001671 break;
1672 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001674 req->dcid = cpu_to_le16(pi->dcid);
1675 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676
1677 return ptr - data;
1678}
1679
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001680static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681{
1682 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001683 struct l2cap_conf_rsp *rsp = data;
1684 void *ptr = rsp->data;
1685 void *req = pi->conf_req;
1686 int len = pi->conf_len;
1687 int type, hint, olen;
1688 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02001689 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02001690 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001691 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001693 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01001694
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001695 while (len >= L2CAP_CONF_OPT_SIZE) {
1696 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03001698 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07001699 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001700
1701 switch (type) {
1702 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02001703 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001704 break;
1705
1706 case L2CAP_CONF_FLUSH_TO:
1707 pi->flush_to = val;
1708 break;
1709
1710 case L2CAP_CONF_QOS:
1711 break;
1712
Marcel Holtmann6464f352007-10-20 13:39:51 +02001713 case L2CAP_CONF_RFC:
1714 if (olen == sizeof(rfc))
1715 memcpy(&rfc, (void *) val, olen);
1716 break;
1717
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001718 case L2CAP_CONF_FCS:
1719 if (val == L2CAP_FCS_NONE)
1720 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
1721
1722 break;
1723
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001724 default:
1725 if (hint)
1726 break;
1727
1728 result = L2CAP_CONF_UNKNOWN;
1729 *((u8 *) ptr++) = type;
1730 break;
1731 }
1732 }
1733
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001734 if (pi->num_conf_rsp || pi->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001735 goto done;
1736
1737 switch (pi->mode) {
1738 case L2CAP_MODE_STREAMING:
1739 case L2CAP_MODE_ERTM:
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03001740 if (!(pi->conf_state & L2CAP_CONF_STATE2_DEVICE)) {
1741 pi->mode = l2cap_select_mode(rfc.mode,
1742 pi->conn->feat_mask);
1743 break;
1744 }
1745
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03001746 if (pi->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001747 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03001748
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001749 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001750 }
1751
1752done:
1753 if (pi->mode != rfc.mode) {
1754 result = L2CAP_CONF_UNACCEPT;
1755 rfc.mode = pi->mode;
1756
1757 if (pi->num_conf_rsp == 1)
1758 return -ECONNREFUSED;
1759
1760 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1761 sizeof(rfc), (unsigned long) &rfc);
1762 }
1763
1764
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001765 if (result == L2CAP_CONF_SUCCESS) {
1766 /* Configure output options and let the other side know
1767 * which ones we don't like. */
1768
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001769 if (mtu < L2CAP_DEFAULT_MIN_MTU)
1770 result = L2CAP_CONF_UNACCEPT;
1771 else {
1772 pi->omtu = mtu;
1773 pi->conf_state |= L2CAP_CONF_MTU_DONE;
1774 }
1775 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001776
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001777 switch (rfc.mode) {
1778 case L2CAP_MODE_BASIC:
1779 pi->fcs = L2CAP_FCS_NONE;
1780 pi->conf_state |= L2CAP_CONF_MODE_DONE;
1781 break;
1782
1783 case L2CAP_MODE_ERTM:
1784 pi->remote_tx_win = rfc.txwin_size;
1785 pi->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07001786
1787 if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
1788 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001789
1790 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001791
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03001792 rfc.retrans_timeout =
1793 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
1794 rfc.monitor_timeout =
1795 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001796
1797 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03001798
1799 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1800 sizeof(rfc), (unsigned long) &rfc);
1801
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001802 break;
1803
1804 case L2CAP_MODE_STREAMING:
Mat Martineau86b1b262010-08-05 15:54:22 -07001805 if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
1806 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001807
1808 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001809
1810 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03001811
1812 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1813 sizeof(rfc), (unsigned long) &rfc);
1814
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001815 break;
1816
1817 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02001818 result = L2CAP_CONF_UNACCEPT;
1819
1820 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001821 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02001822 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001823
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001824 if (result == L2CAP_CONF_SUCCESS)
1825 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
1826 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001827 rsp->scid = cpu_to_le16(pi->dcid);
1828 rsp->result = cpu_to_le16(result);
1829 rsp->flags = cpu_to_le16(0x0000);
1830
1831 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832}
1833
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001834static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
1835{
1836 struct l2cap_pinfo *pi = l2cap_pi(sk);
1837 struct l2cap_conf_req *req = data;
1838 void *ptr = req->data;
1839 int type, olen;
1840 unsigned long val;
1841 struct l2cap_conf_rfc rfc;
1842
1843 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
1844
1845 while (len >= L2CAP_CONF_OPT_SIZE) {
1846 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
1847
1848 switch (type) {
1849 case L2CAP_CONF_MTU:
1850 if (val < L2CAP_DEFAULT_MIN_MTU) {
1851 *result = L2CAP_CONF_UNACCEPT;
Andrei Emeltchenko8183b772010-09-01 15:17:25 +03001852 pi->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001853 } else
Andrei Emeltchenko8183b772010-09-01 15:17:25 +03001854 pi->imtu = val;
1855 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001856 break;
1857
1858 case L2CAP_CONF_FLUSH_TO:
1859 pi->flush_to = val;
1860 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
1861 2, pi->flush_to);
1862 break;
1863
1864 case L2CAP_CONF_RFC:
1865 if (olen == sizeof(rfc))
1866 memcpy(&rfc, (void *)val, olen);
1867
1868 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
1869 rfc.mode != pi->mode)
1870 return -ECONNREFUSED;
1871
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001872 pi->fcs = 0;
1873
1874 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1875 sizeof(rfc), (unsigned long) &rfc);
1876 break;
1877 }
1878 }
1879
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03001880 if (pi->mode == L2CAP_MODE_BASIC && pi->mode != rfc.mode)
1881 return -ECONNREFUSED;
1882
1883 pi->mode = rfc.mode;
1884
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001885 if (*result == L2CAP_CONF_SUCCESS) {
1886 switch (rfc.mode) {
1887 case L2CAP_MODE_ERTM:
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03001888 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
1889 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001890 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001891 break;
1892 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001893 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001894 }
1895 }
1896
1897 req->dcid = cpu_to_le16(pi->dcid);
1898 req->flags = cpu_to_le16(0x0000);
1899
1900 return ptr - data;
1901}
1902
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001903static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904{
1905 struct l2cap_conf_rsp *rsp = data;
1906 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001908 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001910 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001911 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001912 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913
1914 return ptr - data;
1915}
1916
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03001917static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
1918{
1919 struct l2cap_pinfo *pi = l2cap_pi(sk);
1920 int type, olen;
1921 unsigned long val;
1922 struct l2cap_conf_rfc rfc;
1923
1924 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
1925
1926 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
1927 return;
1928
1929 while (len >= L2CAP_CONF_OPT_SIZE) {
1930 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
1931
1932 switch (type) {
1933 case L2CAP_CONF_RFC:
1934 if (olen == sizeof(rfc))
1935 memcpy(&rfc, (void *)val, olen);
1936 goto done;
1937 }
1938 }
1939
1940done:
1941 switch (rfc.mode) {
1942 case L2CAP_MODE_ERTM:
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03001943 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
1944 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03001945 pi->mps = le16_to_cpu(rfc.max_pdu_size);
1946 break;
1947 case L2CAP_MODE_STREAMING:
1948 pi->mps = le16_to_cpu(rfc.max_pdu_size);
1949 }
1950}
1951
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001952static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
1953{
1954 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
1955
1956 if (rej->reason != 0x0000)
1957 return 0;
1958
1959 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
1960 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001961 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01001962
1963 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001964 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001965
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001966 l2cap_conn_start(conn);
1967 }
1968
1969 return 0;
1970}
1971
Linus Torvalds1da177e2005-04-16 15:20:36 -07001972static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
1973{
1974 struct l2cap_chan_list *list = &conn->chan_list;
1975 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
1976 struct l2cap_conn_rsp rsp;
Nathan Holsteind793fe82010-10-15 11:54:02 -04001977 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02001978 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001979
1980 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02001981 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001982
1983 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
1984
1985 /* Check if we have socket listening on psm */
1986 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
1987 if (!parent) {
1988 result = L2CAP_CR_BAD_PSM;
1989 goto sendresp;
1990 }
1991
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001992 bh_lock_sock(parent);
1993
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02001994 /* Check if the ACL is secure enough (if not SDP) */
1995 if (psm != cpu_to_le16(0x0001) &&
1996 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01001997 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02001998 result = L2CAP_CR_SEC_BLOCK;
1999 goto response;
2000 }
2001
Linus Torvalds1da177e2005-04-16 15:20:36 -07002002 result = L2CAP_CR_NO_MEM;
2003
2004 /* Check for backlog size */
2005 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002006 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002007 goto response;
2008 }
2009
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002010 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002011 if (!sk)
2012 goto response;
2013
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002014 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002015
2016 /* Check if we already have channel with that dcid */
2017 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002018 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002019 sock_set_flag(sk, SOCK_ZAPPED);
2020 l2cap_sock_kill(sk);
2021 goto response;
2022 }
2023
2024 hci_conn_hold(conn->hcon);
2025
2026 l2cap_sock_init(sk, parent);
2027 bacpy(&bt_sk(sk)->src, conn->src);
2028 bacpy(&bt_sk(sk)->dst, conn->dst);
2029 l2cap_pi(sk)->psm = psm;
2030 l2cap_pi(sk)->dcid = scid;
2031
Gustavo F. Padovand1010242011-03-25 00:39:48 -03002032 bt_accept_enqueue(parent, sk);
2033
2034 __l2cap_chan_add(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002035 dcid = l2cap_pi(sk)->scid;
2036
2037 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2038
Linus Torvalds1da177e2005-04-16 15:20:36 -07002039 l2cap_pi(sk)->ident = cmd->ident;
2040
Marcel Holtmann984947d2009-02-06 23:35:19 +01002041 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002042 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002043 if (bt_sk(sk)->defer_setup) {
2044 sk->sk_state = BT_CONNECT2;
2045 result = L2CAP_CR_PEND;
2046 status = L2CAP_CS_AUTHOR_PEND;
2047 parent->sk_data_ready(parent, 0);
2048 } else {
2049 sk->sk_state = BT_CONFIG;
2050 result = L2CAP_CR_SUCCESS;
2051 status = L2CAP_CS_NO_INFO;
2052 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002053 } else {
2054 sk->sk_state = BT_CONNECT2;
2055 result = L2CAP_CR_PEND;
2056 status = L2CAP_CS_AUTHEN_PEND;
2057 }
2058 } else {
2059 sk->sk_state = BT_CONNECT2;
2060 result = L2CAP_CR_PEND;
2061 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002062 }
2063
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002064 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002065
2066response:
2067 bh_unlock_sock(parent);
2068
2069sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002070 rsp.scid = cpu_to_le16(scid);
2071 rsp.dcid = cpu_to_le16(dcid);
2072 rsp.result = cpu_to_le16(result);
2073 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002074 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002075
2076 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2077 struct l2cap_info_req info;
2078 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2079
2080 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2081 conn->info_ident = l2cap_get_ident(conn);
2082
2083 mod_timer(&conn->info_timer, jiffies +
2084 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2085
2086 l2cap_send_cmd(conn, conn->info_ident,
2087 L2CAP_INFO_REQ, sizeof(info), &info);
2088 }
2089
Nathan Holsteind793fe82010-10-15 11:54:02 -04002090 if (sk && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) &&
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002091 result == L2CAP_CR_SUCCESS) {
2092 u8 buf[128];
2093 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2094 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2095 l2cap_build_conf_req(sk, buf), buf);
2096 l2cap_pi(sk)->num_conf_req++;
2097 }
2098
Linus Torvalds1da177e2005-04-16 15:20:36 -07002099 return 0;
2100}
2101
2102static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2103{
2104 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2105 u16 scid, dcid, result, status;
2106 struct sock *sk;
2107 u8 req[128];
2108
2109 scid = __le16_to_cpu(rsp->scid);
2110 dcid = __le16_to_cpu(rsp->dcid);
2111 result = __le16_to_cpu(rsp->result);
2112 status = __le16_to_cpu(rsp->status);
2113
2114 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2115
2116 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002117 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2118 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03002119 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002120 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002121 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2122 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03002123 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124 }
2125
2126 switch (result) {
2127 case L2CAP_CR_SUCCESS:
2128 sk->sk_state = BT_CONFIG;
2129 l2cap_pi(sk)->ident = 0;
2130 l2cap_pi(sk)->dcid = dcid;
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002131 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2132
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002133 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)
2134 break;
2135
2136 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2137
Linus Torvalds1da177e2005-04-16 15:20:36 -07002138 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2139 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002140 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002141 break;
2142
2143 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002144 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002145 break;
2146
2147 default:
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02002148 /* don't delete l2cap channel if sk is owned by user */
2149 if (sock_owned_by_user(sk)) {
2150 sk->sk_state = BT_DISCONN;
2151 l2cap_sock_clear_timer(sk);
2152 l2cap_sock_set_timer(sk, HZ / 5);
2153 break;
2154 }
2155
Linus Torvalds1da177e2005-04-16 15:20:36 -07002156 l2cap_chan_del(sk, ECONNREFUSED);
2157 break;
2158 }
2159
2160 bh_unlock_sock(sk);
2161 return 0;
2162}
2163
Mat Martineau8c462b62010-08-24 15:35:42 -07002164static inline void set_default_fcs(struct l2cap_pinfo *pi)
2165{
2166 /* FCS is enabled only in ERTM or streaming mode, if one or both
2167 * sides request it.
2168 */
2169 if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING)
2170 pi->fcs = L2CAP_FCS_NONE;
2171 else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV))
2172 pi->fcs = L2CAP_FCS_CRC16;
2173}
2174
Al Viro88219a02007-07-29 00:17:25 -07002175static 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 -07002176{
2177 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2178 u16 dcid, flags;
2179 u8 rsp[64];
2180 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002181 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002182
2183 dcid = __le16_to_cpu(req->dcid);
2184 flags = __le16_to_cpu(req->flags);
2185
2186 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2187
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002188 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2189 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002190 return -ENOENT;
2191
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03002192 if (sk->sk_state != BT_CONFIG) {
2193 struct l2cap_cmd_rej rej;
2194
2195 rej.reason = cpu_to_le16(0x0002);
2196 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
2197 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002198 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03002199 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002200
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002201 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002202 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002203 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2204 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2205 l2cap_build_conf_rsp(sk, rsp,
2206 L2CAP_CONF_REJECT, flags), rsp);
2207 goto unlock;
2208 }
2209
2210 /* Store config. */
2211 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2212 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002213
2214 if (flags & 0x0001) {
2215 /* Incomplete config. Send empty response. */
2216 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002217 l2cap_build_conf_rsp(sk, rsp,
2218 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002219 goto unlock;
2220 }
2221
2222 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002223 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002224 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002225 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002226 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002227 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002228
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002229 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002230 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002231
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002232 /* Reset config buffer. */
2233 l2cap_pi(sk)->conf_len = 0;
2234
Marcel Holtmann876d9482007-10-20 13:35:42 +02002235 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2236 goto unlock;
2237
Linus Torvalds1da177e2005-04-16 15:20:36 -07002238 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Mat Martineau8c462b62010-08-24 15:35:42 -07002239 set_default_fcs(l2cap_pi(sk));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002240
Linus Torvalds1da177e2005-04-16 15:20:36 -07002241 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002242
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002243 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002244 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002245 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002246 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2247 l2cap_ertm_init(sk);
2248
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002250 goto unlock;
2251 }
2252
2253 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002254 u8 buf[64];
Haijun Liuab3e5712010-09-30 16:52:40 +08002255 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002256 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002257 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002258 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002259 }
2260
2261unlock:
2262 bh_unlock_sock(sk);
2263 return 0;
2264}
2265
2266static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2267{
2268 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2269 u16 scid, flags, result;
2270 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002271 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002272
2273 scid = __le16_to_cpu(rsp->scid);
2274 flags = __le16_to_cpu(rsp->flags);
2275 result = __le16_to_cpu(rsp->result);
2276
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002277 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2278 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002279
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002280 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2281 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002282 return 0;
2283
2284 switch (result) {
2285 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002286 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002287 break;
2288
2289 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002290 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002291 char req[64];
2292
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02002293 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002294 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02002295 goto done;
2296 }
2297
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002298 /* throw out any old stored conf requests */
2299 result = L2CAP_CONF_SUCCESS;
2300 len = l2cap_parse_conf_rsp(sk, rsp->data,
2301 len, req, &result);
2302 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002303 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002304 goto done;
2305 }
2306
2307 l2cap_send_cmd(conn, l2cap_get_ident(conn),
2308 L2CAP_CONF_REQ, len, req);
2309 l2cap_pi(sk)->num_conf_req++;
2310 if (result != L2CAP_CONF_SUCCESS)
2311 goto done;
2312 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002313 }
2314
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002315 default:
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002316 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002317 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002318 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319 goto done;
2320 }
2321
2322 if (flags & 0x01)
2323 goto done;
2324
Linus Torvalds1da177e2005-04-16 15:20:36 -07002325 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
2326
2327 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Mat Martineau8c462b62010-08-24 15:35:42 -07002328 set_default_fcs(l2cap_pi(sk));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002329
Linus Torvalds1da177e2005-04-16 15:20:36 -07002330 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002331 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002332 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002333 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002334 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2335 l2cap_ertm_init(sk);
2336
Linus Torvalds1da177e2005-04-16 15:20:36 -07002337 l2cap_chan_ready(sk);
2338 }
2339
2340done:
2341 bh_unlock_sock(sk);
2342 return 0;
2343}
2344
2345static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2346{
2347 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
2348 struct l2cap_disconn_rsp rsp;
2349 u16 dcid, scid;
2350 struct sock *sk;
2351
2352 scid = __le16_to_cpu(req->scid);
2353 dcid = __le16_to_cpu(req->dcid);
2354
2355 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
2356
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002357 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2358 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002359 return 0;
2360
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002361 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
2362 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002363 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
2364
2365 sk->sk_shutdown = SHUTDOWN_MASK;
2366
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02002367 /* don't delete l2cap channel if sk is owned by user */
2368 if (sock_owned_by_user(sk)) {
2369 sk->sk_state = BT_DISCONN;
2370 l2cap_sock_clear_timer(sk);
2371 l2cap_sock_set_timer(sk, HZ / 5);
2372 bh_unlock_sock(sk);
2373 return 0;
2374 }
2375
Linus Torvalds1da177e2005-04-16 15:20:36 -07002376 l2cap_chan_del(sk, ECONNRESET);
2377 bh_unlock_sock(sk);
2378
2379 l2cap_sock_kill(sk);
2380 return 0;
2381}
2382
2383static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2384{
2385 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
2386 u16 dcid, scid;
2387 struct sock *sk;
2388
2389 scid = __le16_to_cpu(rsp->scid);
2390 dcid = __le16_to_cpu(rsp->dcid);
2391
2392 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
2393
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002394 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2395 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002396 return 0;
2397
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02002398 /* don't delete l2cap channel if sk is owned by user */
2399 if (sock_owned_by_user(sk)) {
2400 sk->sk_state = BT_DISCONN;
2401 l2cap_sock_clear_timer(sk);
2402 l2cap_sock_set_timer(sk, HZ / 5);
2403 bh_unlock_sock(sk);
2404 return 0;
2405 }
2406
Linus Torvalds1da177e2005-04-16 15:20:36 -07002407 l2cap_chan_del(sk, 0);
2408 bh_unlock_sock(sk);
2409
2410 l2cap_sock_kill(sk);
2411 return 0;
2412}
2413
2414static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2415{
2416 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002417 u16 type;
2418
2419 type = __le16_to_cpu(req->type);
2420
2421 BT_DBG("type 0x%4.4x", type);
2422
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002423 if (type == L2CAP_IT_FEAT_MASK) {
2424 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07002425 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002426 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2427 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2428 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03002429 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002430 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
2431 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03002432 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002433 l2cap_send_cmd(conn, cmd->ident,
2434 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002435 } else if (type == L2CAP_IT_FIXED_CHAN) {
2436 u8 buf[12];
2437 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2438 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
2439 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
2440 memcpy(buf + 4, l2cap_fixed_chan, 8);
2441 l2cap_send_cmd(conn, cmd->ident,
2442 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002443 } else {
2444 struct l2cap_info_rsp rsp;
2445 rsp.type = cpu_to_le16(type);
2446 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
2447 l2cap_send_cmd(conn, cmd->ident,
2448 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
2449 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002450
2451 return 0;
2452}
2453
2454static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2455{
2456 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
2457 u16 type, result;
2458
2459 type = __le16_to_cpu(rsp->type);
2460 result = __le16_to_cpu(rsp->result);
2461
2462 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
2463
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002464 del_timer(&conn->info_timer);
2465
Ville Tervoadb08ed2010-08-04 09:43:33 +03002466 if (result != L2CAP_IR_SUCCESS) {
2467 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
2468 conn->info_ident = 0;
2469
2470 l2cap_conn_start(conn);
2471
2472 return 0;
2473 }
2474
Marcel Holtmann984947d2009-02-06 23:35:19 +01002475 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07002476 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002477
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002478 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002479 struct l2cap_info_req req;
2480 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
2481
2482 conn->info_ident = l2cap_get_ident(conn);
2483
2484 l2cap_send_cmd(conn, conn->info_ident,
2485 L2CAP_INFO_REQ, sizeof(req), &req);
2486 } else {
2487 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
2488 conn->info_ident = 0;
2489
2490 l2cap_conn_start(conn);
2491 }
2492 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01002493 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002494 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002495
2496 l2cap_conn_start(conn);
2497 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002498
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499 return 0;
2500}
2501
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03002502static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Claudio Takahaside731152011-02-11 19:28:55 -02002503 u16 to_multiplier)
2504{
2505 u16 max_latency;
2506
2507 if (min > max || min < 6 || max > 3200)
2508 return -EINVAL;
2509
2510 if (to_multiplier < 10 || to_multiplier > 3200)
2511 return -EINVAL;
2512
2513 if (max >= to_multiplier * 8)
2514 return -EINVAL;
2515
2516 max_latency = (to_multiplier * 8 / max) - 1;
2517 if (latency > 499 || latency > max_latency)
2518 return -EINVAL;
2519
2520 return 0;
2521}
2522
2523static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
2524 struct l2cap_cmd_hdr *cmd, u8 *data)
2525{
2526 struct hci_conn *hcon = conn->hcon;
2527 struct l2cap_conn_param_update_req *req;
2528 struct l2cap_conn_param_update_rsp rsp;
2529 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02002530 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02002531
2532 if (!(hcon->link_mode & HCI_LM_MASTER))
2533 return -EINVAL;
2534
2535 cmd_len = __le16_to_cpu(cmd->len);
2536 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
2537 return -EPROTO;
2538
2539 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03002540 min = __le16_to_cpu(req->min);
2541 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02002542 latency = __le16_to_cpu(req->latency);
2543 to_multiplier = __le16_to_cpu(req->to_multiplier);
2544
2545 BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
2546 min, max, latency, to_multiplier);
2547
2548 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02002549
2550 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
2551 if (err)
Claudio Takahaside731152011-02-11 19:28:55 -02002552 rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
2553 else
2554 rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
2555
2556 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
2557 sizeof(rsp), &rsp);
2558
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02002559 if (!err)
2560 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
2561
Claudio Takahaside731152011-02-11 19:28:55 -02002562 return 0;
2563}
2564
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002565static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
2566 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
2567{
2568 int err = 0;
2569
2570 switch (cmd->code) {
2571 case L2CAP_COMMAND_REJ:
2572 l2cap_command_rej(conn, cmd, data);
2573 break;
2574
2575 case L2CAP_CONN_REQ:
2576 err = l2cap_connect_req(conn, cmd, data);
2577 break;
2578
2579 case L2CAP_CONN_RSP:
2580 err = l2cap_connect_rsp(conn, cmd, data);
2581 break;
2582
2583 case L2CAP_CONF_REQ:
2584 err = l2cap_config_req(conn, cmd, cmd_len, data);
2585 break;
2586
2587 case L2CAP_CONF_RSP:
2588 err = l2cap_config_rsp(conn, cmd, data);
2589 break;
2590
2591 case L2CAP_DISCONN_REQ:
2592 err = l2cap_disconnect_req(conn, cmd, data);
2593 break;
2594
2595 case L2CAP_DISCONN_RSP:
2596 err = l2cap_disconnect_rsp(conn, cmd, data);
2597 break;
2598
2599 case L2CAP_ECHO_REQ:
2600 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
2601 break;
2602
2603 case L2CAP_ECHO_RSP:
2604 break;
2605
2606 case L2CAP_INFO_REQ:
2607 err = l2cap_information_req(conn, cmd, data);
2608 break;
2609
2610 case L2CAP_INFO_RSP:
2611 err = l2cap_information_rsp(conn, cmd, data);
2612 break;
2613
2614 default:
2615 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
2616 err = -EINVAL;
2617 break;
2618 }
2619
2620 return err;
2621}
2622
2623static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
2624 struct l2cap_cmd_hdr *cmd, u8 *data)
2625{
2626 switch (cmd->code) {
2627 case L2CAP_COMMAND_REJ:
2628 return 0;
2629
2630 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02002631 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002632
2633 case L2CAP_CONN_PARAM_UPDATE_RSP:
2634 return 0;
2635
2636 default:
2637 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
2638 return -EINVAL;
2639 }
2640}
2641
2642static inline void l2cap_sig_channel(struct l2cap_conn *conn,
2643 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002644{
2645 u8 *data = skb->data;
2646 int len = skb->len;
2647 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002648 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002649
2650 l2cap_raw_recv(conn, skb);
2651
2652 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07002653 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002654 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
2655 data += L2CAP_CMD_HDR_SIZE;
2656 len -= L2CAP_CMD_HDR_SIZE;
2657
Al Viro88219a02007-07-29 00:17:25 -07002658 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002659
Al Viro88219a02007-07-29 00:17:25 -07002660 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 -07002661
Al Viro88219a02007-07-29 00:17:25 -07002662 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002663 BT_DBG("corrupted command");
2664 break;
2665 }
2666
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002667 if (conn->hcon->type == LE_LINK)
2668 err = l2cap_le_sig_cmd(conn, &cmd, data);
2669 else
2670 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002671
2672 if (err) {
2673 struct l2cap_cmd_rej rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03002674
2675 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002676
2677 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002678 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002679 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
2680 }
2681
Al Viro88219a02007-07-29 00:17:25 -07002682 data += cmd_len;
2683 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002684 }
2685
2686 kfree_skb(skb);
2687}
2688
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002689static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
2690{
2691 u16 our_fcs, rcv_fcs;
2692 int hdr_size = L2CAP_HDR_SIZE + 2;
2693
2694 if (pi->fcs == L2CAP_FCS_CRC16) {
2695 skb_trim(skb, skb->len - 2);
2696 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
2697 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
2698
2699 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03002700 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002701 }
2702 return 0;
2703}
2704
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002705static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
2706{
2707 struct l2cap_pinfo *pi = l2cap_pi(sk);
2708 u16 control = 0;
2709
2710 pi->frames_sent = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002711
2712 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
2713
2714 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan64988862010-05-10 14:54:14 -03002715 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002716 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002717 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002718 }
2719
Gustavo F. Padovan4ea727e2010-06-03 16:34:20 -03002720 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY)
2721 l2cap_retransmit_frames(sk);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002722
2723 l2cap_ertm_send(sk);
2724
2725 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
2726 pi->frames_sent == 0) {
2727 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002728 l2cap_send_sframe(pi, control);
2729 }
2730}
2731
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002732static 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 -03002733{
2734 struct sk_buff *next_skb;
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03002735 struct l2cap_pinfo *pi = l2cap_pi(sk);
2736 int tx_seq_offset, next_tx_seq_offset;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002737
2738 bt_cb(skb)->tx_seq = tx_seq;
2739 bt_cb(skb)->sar = sar;
2740
2741 next_skb = skb_peek(SREJ_QUEUE(sk));
2742 if (!next_skb) {
2743 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002744 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002745 }
2746
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03002747 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
2748 if (tx_seq_offset < 0)
2749 tx_seq_offset += 64;
2750
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002751 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002752 if (bt_cb(next_skb)->tx_seq == tx_seq)
2753 return -EINVAL;
2754
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03002755 next_tx_seq_offset = (bt_cb(next_skb)->tx_seq -
2756 pi->buffer_seq) % 64;
2757 if (next_tx_seq_offset < 0)
2758 next_tx_seq_offset += 64;
2759
2760 if (next_tx_seq_offset > tx_seq_offset) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002761 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002762 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002763 }
2764
2765 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
2766 break;
2767
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002768 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002769
2770 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002771
2772 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002773}
2774
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002775static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
2776{
2777 struct l2cap_pinfo *pi = l2cap_pi(sk);
2778 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002779 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002780
2781 switch (control & L2CAP_CTRL_SAR) {
2782 case L2CAP_SDU_UNSEGMENTED:
2783 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
2784 goto drop;
2785
2786 err = sock_queue_rcv_skb(sk, skb);
2787 if (!err)
2788 return err;
2789
2790 break;
2791
2792 case L2CAP_SDU_START:
2793 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
2794 goto drop;
2795
2796 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002797
2798 if (pi->sdu_len > pi->imtu)
2799 goto disconnect;
2800
2801 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002802 if (!pi->sdu)
2803 return -ENOMEM;
2804
2805 /* pull sdu_len bytes only after alloc, because of Local Busy
2806 * condition we have to be sure that this will be executed
2807 * only once, i.e., when alloc does not fail */
2808 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002809
2810 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
2811
2812 pi->conn_state |= L2CAP_CONN_SAR_SDU;
2813 pi->partial_sdu_len = skb->len;
2814 break;
2815
2816 case L2CAP_SDU_CONTINUE:
2817 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
2818 goto disconnect;
2819
2820 if (!pi->sdu)
2821 goto disconnect;
2822
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002823 pi->partial_sdu_len += skb->len;
2824 if (pi->partial_sdu_len > pi->sdu_len)
2825 goto drop;
2826
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03002827 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
2828
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002829 break;
2830
2831 case L2CAP_SDU_END:
2832 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
2833 goto disconnect;
2834
2835 if (!pi->sdu)
2836 goto disconnect;
2837
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002838 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002839 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002840
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002841 if (pi->partial_sdu_len > pi->imtu)
2842 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002843
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002844 if (pi->partial_sdu_len != pi->sdu_len)
2845 goto drop;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03002846
2847 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002848 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002849
2850 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002851 if (!_skb) {
2852 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
2853 return -ENOMEM;
2854 }
2855
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002856 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002857 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002858 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002859 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
2860 return err;
2861 }
2862
2863 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
2864 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002865
2866 kfree_skb(pi->sdu);
2867 break;
2868 }
2869
2870 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002871 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002872
2873drop:
2874 kfree_skb(pi->sdu);
2875 pi->sdu = NULL;
2876
2877disconnect:
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002878 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002879 kfree_skb(skb);
2880 return 0;
2881}
2882
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002883static int l2cap_try_push_rx_skb(struct sock *sk)
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002884{
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002885 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002886 struct sk_buff *skb;
2887 u16 control;
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002888 int err;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002889
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002890 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
2891 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
2892 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
2893 if (err < 0) {
2894 skb_queue_head(BUSY_QUEUE(sk), skb);
2895 return -EBUSY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002896 }
2897
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002898 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002899 }
2900
2901 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
2902 goto done;
2903
2904 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
2905 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
2906 l2cap_send_sframe(pi, control);
2907 l2cap_pi(sk)->retry_count = 1;
2908
2909 del_timer(&pi->retrans_timer);
2910 __mod_monitor_timer();
2911
2912 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
2913
2914done:
2915 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
2916 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
2917
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03002918 BT_DBG("sk %p, Exit local busy", sk);
2919
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002920 return 0;
2921}
2922
2923static void l2cap_busy_work(struct work_struct *work)
2924{
2925 DECLARE_WAITQUEUE(wait, current);
2926 struct l2cap_pinfo *pi =
2927 container_of(work, struct l2cap_pinfo, busy_work);
2928 struct sock *sk = (struct sock *)pi;
2929 int n_tries = 0, timeo = HZ/5, err;
2930 struct sk_buff *skb;
2931
2932 lock_sock(sk);
2933
2934 add_wait_queue(sk_sleep(sk), &wait);
2935 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
2936 set_current_state(TASK_INTERRUPTIBLE);
2937
2938 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
2939 err = -EBUSY;
2940 l2cap_send_disconn_req(pi->conn, sk, EBUSY);
2941 break;
2942 }
2943
2944 if (!timeo)
2945 timeo = HZ/5;
2946
2947 if (signal_pending(current)) {
2948 err = sock_intr_errno(timeo);
2949 break;
2950 }
2951
2952 release_sock(sk);
2953 timeo = schedule_timeout(timeo);
2954 lock_sock(sk);
2955
2956 err = sock_error(sk);
2957 if (err)
2958 break;
2959
2960 if (l2cap_try_push_rx_skb(sk) == 0)
2961 break;
2962 }
2963
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002964 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02002965 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002966
2967 release_sock(sk);
2968}
2969
2970static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
2971{
2972 struct l2cap_pinfo *pi = l2cap_pi(sk);
2973 int sctrl, err;
2974
2975 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
2976 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
2977 __skb_queue_tail(BUSY_QUEUE(sk), skb);
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002978 return l2cap_try_push_rx_skb(sk);
2979
2980
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002981 }
2982
2983 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
2984 if (err >= 0) {
2985 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
2986 return err;
2987 }
2988
2989 /* Busy Condition */
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03002990 BT_DBG("sk %p, Enter local busy", sk);
2991
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002992 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
2993 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
2994 __skb_queue_tail(BUSY_QUEUE(sk), skb);
2995
2996 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
2997 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
2998 l2cap_send_sframe(pi, sctrl);
2999
3000 pi->conn_state |= L2CAP_CONN_RNR_SENT;
3001
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03003002 del_timer(&pi->ack_timer);
3003
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003004 queue_work(_busy_wq, &pi->busy_work);
3005
3006 return err;
3007}
3008
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003009static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003010{
3011 struct l2cap_pinfo *pi = l2cap_pi(sk);
3012 struct sk_buff *_skb;
3013 int err = -EINVAL;
3014
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003015 /*
3016 * TODO: We have to notify the userland if some data is lost with the
3017 * Streaming Mode.
3018 */
3019
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003020 switch (control & L2CAP_CTRL_SAR) {
3021 case L2CAP_SDU_UNSEGMENTED:
3022 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3023 kfree_skb(pi->sdu);
3024 break;
3025 }
3026
3027 err = sock_queue_rcv_skb(sk, skb);
3028 if (!err)
3029 return 0;
3030
3031 break;
3032
3033 case L2CAP_SDU_START:
3034 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3035 kfree_skb(pi->sdu);
3036 break;
3037 }
3038
3039 pi->sdu_len = get_unaligned_le16(skb->data);
3040 skb_pull(skb, 2);
3041
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003042 if (pi->sdu_len > pi->imtu) {
3043 err = -EMSGSIZE;
3044 break;
3045 }
3046
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003047 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3048 if (!pi->sdu) {
3049 err = -ENOMEM;
3050 break;
3051 }
3052
3053 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3054
3055 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3056 pi->partial_sdu_len = skb->len;
3057 err = 0;
3058 break;
3059
3060 case L2CAP_SDU_CONTINUE:
3061 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3062 break;
3063
3064 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3065
3066 pi->partial_sdu_len += skb->len;
3067 if (pi->partial_sdu_len > pi->sdu_len)
3068 kfree_skb(pi->sdu);
3069 else
3070 err = 0;
3071
3072 break;
3073
3074 case L2CAP_SDU_END:
3075 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3076 break;
3077
3078 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3079
3080 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3081 pi->partial_sdu_len += skb->len;
3082
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003083 if (pi->partial_sdu_len > pi->imtu)
3084 goto drop;
3085
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003086 if (pi->partial_sdu_len == pi->sdu_len) {
3087 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3088 err = sock_queue_rcv_skb(sk, _skb);
3089 if (err < 0)
3090 kfree_skb(_skb);
3091 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003092 err = 0;
3093
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003094drop:
3095 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003096 break;
3097 }
3098
3099 kfree_skb(skb);
3100 return err;
3101}
3102
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003103static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3104{
3105 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003106 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003107
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003108 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003109 if (bt_cb(skb)->tx_seq != tx_seq)
3110 break;
3111
3112 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003113 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003114 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003115 l2cap_pi(sk)->buffer_seq_srej =
3116 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003117 tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003118 }
3119}
3120
3121static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3122{
3123 struct l2cap_pinfo *pi = l2cap_pi(sk);
3124 struct srej_list *l, *tmp;
3125 u16 control;
3126
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003127 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003128 if (l->tx_seq == tx_seq) {
3129 list_del(&l->list);
3130 kfree(l);
3131 return;
3132 }
3133 control = L2CAP_SUPER_SELECT_REJECT;
3134 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3135 l2cap_send_sframe(pi, control);
3136 list_del(&l->list);
3137 list_add_tail(&l->list, SREJ_LIST(sk));
3138 }
3139}
3140
3141static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3142{
3143 struct l2cap_pinfo *pi = l2cap_pi(sk);
3144 struct srej_list *new;
3145 u16 control;
3146
3147 while (tx_seq != pi->expected_tx_seq) {
3148 control = L2CAP_SUPER_SELECT_REJECT;
3149 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3150 l2cap_send_sframe(pi, control);
3151
3152 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003153 new->tx_seq = pi->expected_tx_seq;
3154 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003155 list_add_tail(&new->list, SREJ_LIST(sk));
3156 }
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003157 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003158}
3159
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003160static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3161{
3162 struct l2cap_pinfo *pi = l2cap_pi(sk);
3163 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003164 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003165 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03003166 int tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003167 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003168 int err = 0;
3169
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003170 BT_DBG("sk %p len %d tx_seq %d rx_control 0x%4.4x", sk, skb->len, tx_seq,
3171 rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003172
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003173 if (L2CAP_CTRL_FINAL & rx_control &&
3174 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003175 del_timer(&pi->monitor_timer);
3176 if (pi->unacked_frames > 0)
3177 __mod_retrans_timer();
3178 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3179 }
3180
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003181 pi->expected_ack_seq = req_seq;
3182 l2cap_drop_acked_frames(sk);
3183
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003184 if (tx_seq == pi->expected_tx_seq)
3185 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003186
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003187 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3188 if (tx_seq_offset < 0)
3189 tx_seq_offset += 64;
3190
3191 /* invalid tx_seq */
3192 if (tx_seq_offset >= pi->tx_win) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003193 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003194 goto drop;
3195 }
3196
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003197 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
3198 goto drop;
3199
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003200 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3201 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003202
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003203 first = list_first_entry(SREJ_LIST(sk),
3204 struct srej_list, list);
3205 if (tx_seq == first->tx_seq) {
3206 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3207 l2cap_check_srej_gap(sk, tx_seq);
3208
3209 list_del(&first->list);
3210 kfree(first);
3211
3212 if (list_empty(SREJ_LIST(sk))) {
3213 pi->buffer_seq = pi->buffer_seq_srej;
3214 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666cc2010-05-01 16:15:40 -03003215 l2cap_send_ack(pi);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003216 BT_DBG("sk %p, Exit SREJ_SENT", sk);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003217 }
3218 } else {
3219 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003220
3221 /* duplicated tx_seq */
3222 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
3223 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003224
3225 list_for_each_entry(l, SREJ_LIST(sk), list) {
3226 if (l->tx_seq == tx_seq) {
3227 l2cap_resend_srejframe(sk, tx_seq);
3228 return 0;
3229 }
3230 }
3231 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003232 }
3233 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003234 expected_tx_seq_offset =
3235 (pi->expected_tx_seq - pi->buffer_seq) % 64;
3236 if (expected_tx_seq_offset < 0)
3237 expected_tx_seq_offset += 64;
3238
3239 /* duplicated tx_seq */
3240 if (tx_seq_offset < expected_tx_seq_offset)
3241 goto drop;
3242
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003243 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003244
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003245 BT_DBG("sk %p, Enter SREJ", sk);
3246
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003247 INIT_LIST_HEAD(SREJ_LIST(sk));
3248 pi->buffer_seq_srej = pi->buffer_seq;
3249
3250 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003251 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003252 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3253
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003254 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3255
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003256 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03003257
3258 del_timer(&pi->ack_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003259 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003260 return 0;
3261
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003262expected:
3263 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3264
3265 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03003266 bt_cb(skb)->tx_seq = tx_seq;
3267 bt_cb(skb)->sar = sar;
3268 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003269 return 0;
3270 }
3271
Gustavo F. Padovan2ece3682010-06-16 17:21:44 -03003272 err = l2cap_push_rx_skb(sk, skb, rx_control);
3273 if (err < 0)
3274 return 0;
3275
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003276 if (rx_control & L2CAP_CTRL_FINAL) {
3277 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3278 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003279 else
3280 l2cap_retransmit_frames(sk);
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003281 }
3282
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003283 __mod_ack_timer();
3284
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003285 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
3286 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003287 l2cap_send_ack(pi);
3288
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003289 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003290
3291drop:
3292 kfree_skb(skb);
3293 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003294}
3295
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003296static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003297{
3298 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003299
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003300 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control),
3301 rx_control);
3302
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003303 pi->expected_ack_seq = __get_reqseq(rx_control);
3304 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003305
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003306 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03003307 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003308 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3309 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3310 (pi->unacked_frames > 0))
3311 __mod_retrans_timer();
3312
3313 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3314 l2cap_send_srejtail(sk);
3315 } else {
3316 l2cap_send_i_or_rr_or_rnr(sk);
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003317 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003318
3319 } else if (rx_control & L2CAP_CTRL_FINAL) {
3320 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003321
3322 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3323 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003324 else
3325 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003326
3327 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003328 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3329 (pi->unacked_frames > 0))
3330 __mod_retrans_timer();
3331
3332 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Andrei Emeltchenko894718a2010-12-01 16:58:24 +02003333 if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003334 l2cap_send_ack(pi);
Andrei Emeltchenko894718a2010-12-01 16:58:24 +02003335 else
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003336 l2cap_ertm_send(sk);
3337 }
3338}
3339
3340static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3341{
3342 struct l2cap_pinfo *pi = l2cap_pi(sk);
3343 u8 tx_seq = __get_reqseq(rx_control);
3344
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003345 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
3346
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003347 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3348
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03003349 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003350 l2cap_drop_acked_frames(sk);
3351
3352 if (rx_control & L2CAP_CTRL_FINAL) {
3353 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3354 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003355 else
3356 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003357 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003358 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003359
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03003360 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003361 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003362 }
3363}
3364static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
3365{
3366 struct l2cap_pinfo *pi = l2cap_pi(sk);
3367 u8 tx_seq = __get_reqseq(rx_control);
3368
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003369 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
3370
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003371 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3372
3373 if (rx_control & L2CAP_CTRL_POLL) {
3374 pi->expected_ack_seq = tx_seq;
3375 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03003376
3377 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003378 l2cap_retransmit_one_frame(sk, tx_seq);
3379
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003380 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003381
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003382 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3383 pi->srej_save_reqseq = tx_seq;
3384 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3385 }
3386 } else if (rx_control & L2CAP_CTRL_FINAL) {
3387 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3388 pi->srej_save_reqseq == tx_seq)
3389 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
3390 else
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003391 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003392 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003393 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003394 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3395 pi->srej_save_reqseq = tx_seq;
3396 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3397 }
3398 }
3399}
3400
3401static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
3402{
3403 struct l2cap_pinfo *pi = l2cap_pi(sk);
3404 u8 tx_seq = __get_reqseq(rx_control);
3405
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003406 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
3407
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003408 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
3409 pi->expected_ack_seq = tx_seq;
3410 l2cap_drop_acked_frames(sk);
3411
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03003412 if (rx_control & L2CAP_CTRL_POLL)
3413 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3414
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003415 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
3416 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03003417 if (rx_control & L2CAP_CTRL_POLL)
3418 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003419 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003420 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003421
3422 if (rx_control & L2CAP_CTRL_POLL)
3423 l2cap_send_srejtail(sk);
3424 else
3425 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003426}
3427
3428static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3429{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003430 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3431
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003432 if (L2CAP_CTRL_FINAL & rx_control &&
3433 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003434 del_timer(&l2cap_pi(sk)->monitor_timer);
3435 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003436 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003437 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003438 }
3439
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003440 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
3441 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003442 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003443 break;
3444
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003445 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003446 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003447 break;
3448
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003449 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003450 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003451 break;
3452
3453 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003454 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003455 break;
3456 }
3457
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03003458 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003459 return 0;
3460}
3461
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03003462static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
3463{
3464 struct l2cap_pinfo *pi = l2cap_pi(sk);
3465 u16 control;
3466 u8 req_seq;
3467 int len, next_tx_seq_offset, req_seq_offset;
3468
3469 control = get_unaligned_le16(skb->data);
3470 skb_pull(skb, 2);
3471 len = skb->len;
3472
3473 /*
3474 * We can just drop the corrupted I-frame here.
3475 * Receiver will miss it and start proper recovery
3476 * procedures and ask retransmission.
3477 */
3478 if (l2cap_check_fcs(pi, skb))
3479 goto drop;
3480
3481 if (__is_sar_start(control) && __is_iframe(control))
3482 len -= 2;
3483
3484 if (pi->fcs == L2CAP_FCS_CRC16)
3485 len -= 2;
3486
3487 if (len > pi->mps) {
3488 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
3489 goto drop;
3490 }
3491
3492 req_seq = __get_reqseq(control);
3493 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
3494 if (req_seq_offset < 0)
3495 req_seq_offset += 64;
3496
3497 next_tx_seq_offset =
3498 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
3499 if (next_tx_seq_offset < 0)
3500 next_tx_seq_offset += 64;
3501
3502 /* check for invalid req-seq */
3503 if (req_seq_offset > next_tx_seq_offset) {
3504 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
3505 goto drop;
3506 }
3507
3508 if (__is_iframe(control)) {
3509 if (len < 0) {
3510 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
3511 goto drop;
3512 }
3513
3514 l2cap_data_channel_iframe(sk, control, skb);
3515 } else {
3516 if (len != 0) {
3517 BT_ERR("%d", len);
3518 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
3519 goto drop;
3520 }
3521
3522 l2cap_data_channel_sframe(sk, control, skb);
3523 }
3524
3525 return 0;
3526
3527drop:
3528 kfree_skb(skb);
3529 return 0;
3530}
3531
Linus Torvalds1da177e2005-04-16 15:20:36 -07003532static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
3533{
3534 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003535 struct l2cap_pinfo *pi;
Nathan Holstein51893f82010-06-09 15:46:25 -04003536 u16 control;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03003537 u8 tx_seq;
3538 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003539
3540 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3541 if (!sk) {
3542 BT_DBG("unknown cid 0x%4.4x", cid);
3543 goto drop;
3544 }
3545
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003546 pi = l2cap_pi(sk);
3547
Linus Torvalds1da177e2005-04-16 15:20:36 -07003548 BT_DBG("sk %p, len %d", sk, skb->len);
3549
3550 if (sk->sk_state != BT_CONNECTED)
3551 goto drop;
3552
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003553 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003554 case L2CAP_MODE_BASIC:
3555 /* If socket recv buffers overflows we drop data here
3556 * which is *bad* because L2CAP has to be reliable.
3557 * But we don't have any other choice. L2CAP doesn't
3558 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003559
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003560 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003561 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003562
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003563 if (!sock_queue_rcv_skb(sk, skb))
3564 goto done;
3565 break;
3566
3567 case L2CAP_MODE_ERTM:
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03003568 if (!sock_owned_by_user(sk)) {
3569 l2cap_ertm_data_rcv(sk, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003570 } else {
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03003571 if (sk_add_backlog(sk, skb))
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003572 goto drop;
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003573 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003574
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003575 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003576
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003577 case L2CAP_MODE_STREAMING:
3578 control = get_unaligned_le16(skb->data);
3579 skb_pull(skb, 2);
3580 len = skb->len;
3581
Gustavo F. Padovan26000082010-05-11 22:02:00 -03003582 if (l2cap_check_fcs(pi, skb))
3583 goto drop;
3584
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003585 if (__is_sar_start(control))
3586 len -= 2;
3587
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003588 if (pi->fcs == L2CAP_FCS_CRC16)
3589 len -= 2;
3590
Nathan Holstein51893f82010-06-09 15:46:25 -04003591 if (len > pi->mps || len < 0 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003592 goto drop;
3593
3594 tx_seq = __get_txseq(control);
3595
3596 if (pi->expected_tx_seq == tx_seq)
3597 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3598 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03003599 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003600
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003601 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003602
3603 goto done;
3604
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003605 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03003606 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003607 break;
3608 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003609
3610drop:
3611 kfree_skb(skb);
3612
3613done:
Marcel Holtmann01394182006-07-03 10:02:46 +02003614 if (sk)
3615 bh_unlock_sock(sk);
3616
Linus Torvalds1da177e2005-04-16 15:20:36 -07003617 return 0;
3618}
3619
Al Viro8e036fc2007-07-29 00:16:36 -07003620static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003621{
3622 struct sock *sk;
3623
3624 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
3625 if (!sk)
3626 goto drop;
3627
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003628 bh_lock_sock(sk);
3629
Linus Torvalds1da177e2005-04-16 15:20:36 -07003630 BT_DBG("sk %p, len %d", sk, skb->len);
3631
3632 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
3633 goto drop;
3634
3635 if (l2cap_pi(sk)->imtu < skb->len)
3636 goto drop;
3637
3638 if (!sock_queue_rcv_skb(sk, skb))
3639 goto done;
3640
3641drop:
3642 kfree_skb(skb);
3643
3644done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003645 if (sk)
3646 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003647 return 0;
3648}
3649
3650static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
3651{
3652 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07003653 u16 cid, len;
3654 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003655
3656 skb_pull(skb, L2CAP_HDR_SIZE);
3657 cid = __le16_to_cpu(lh->cid);
3658 len = __le16_to_cpu(lh->len);
3659
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003660 if (len != skb->len) {
3661 kfree_skb(skb);
3662 return;
3663 }
3664
Linus Torvalds1da177e2005-04-16 15:20:36 -07003665 BT_DBG("len %d, cid 0x%4.4x", len, cid);
3666
3667 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02003668 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003669 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003670 l2cap_sig_channel(conn, skb);
3671 break;
3672
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003673 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003674 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003675 skb_pull(skb, 2);
3676 l2cap_conless_channel(conn, psm, skb);
3677 break;
3678
3679 default:
3680 l2cap_data_channel(conn, cid, skb);
3681 break;
3682 }
3683}
3684
3685/* ---- L2CAP interface with lower layer (HCI) ---- */
3686
3687static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3688{
3689 int exact = 0, lm1 = 0, lm2 = 0;
3690 register struct sock *sk;
3691 struct hlist_node *node;
3692
3693 if (type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03003694 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003695
3696 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
3697
3698 /* Find listening sockets and check their link_mode */
3699 read_lock(&l2cap_sk_list.lock);
3700 sk_for_each(sk, node, &l2cap_sk_list.head) {
3701 if (sk->sk_state != BT_LISTEN)
3702 continue;
3703
3704 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003705 lm1 |= HCI_LM_ACCEPT;
3706 if (l2cap_pi(sk)->role_switch)
3707 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003708 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003709 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
3710 lm2 |= HCI_LM_ACCEPT;
3711 if (l2cap_pi(sk)->role_switch)
3712 lm2 |= HCI_LM_MASTER;
3713 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003714 }
3715 read_unlock(&l2cap_sk_list.lock);
3716
3717 return exact ? lm1 : lm2;
3718}
3719
3720static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
3721{
Marcel Holtmann01394182006-07-03 10:02:46 +02003722 struct l2cap_conn *conn;
3723
Linus Torvalds1da177e2005-04-16 15:20:36 -07003724 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
3725
Ville Tervoacd7d372011-02-10 22:38:49 -03003726 if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK))
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03003727 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003728
3729 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003730 conn = l2cap_conn_add(hcon, status);
3731 if (conn)
3732 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02003733 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003734 l2cap_conn_del(hcon, bt_err(status));
3735
3736 return 0;
3737}
3738
Marcel Holtmann2950f212009-02-12 14:02:50 +01003739static int l2cap_disconn_ind(struct hci_conn *hcon)
3740{
3741 struct l2cap_conn *conn = hcon->l2cap_data;
3742
3743 BT_DBG("hcon %p", hcon);
3744
3745 if (hcon->type != ACL_LINK || !conn)
3746 return 0x13;
3747
3748 return conn->disc_reason;
3749}
3750
3751static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003752{
3753 BT_DBG("hcon %p reason %d", hcon, reason);
3754
Ville Tervoacd7d372011-02-10 22:38:49 -03003755 if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK))
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03003756 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003757
3758 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02003759
Linus Torvalds1da177e2005-04-16 15:20:36 -07003760 return 0;
3761}
3762
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003763static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
3764{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03003765 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01003766 return;
3767
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003768 if (encrypt == 0x00) {
3769 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
3770 l2cap_sock_clear_timer(sk);
3771 l2cap_sock_set_timer(sk, HZ * 5);
3772 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
3773 __l2cap_sock_close(sk, ECONNREFUSED);
3774 } else {
3775 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
3776 l2cap_sock_clear_timer(sk);
3777 }
3778}
3779
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003780static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003781{
3782 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02003783 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003784 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003785
Marcel Holtmann01394182006-07-03 10:02:46 +02003786 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003787 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02003788
Linus Torvalds1da177e2005-04-16 15:20:36 -07003789 l = &conn->chan_list;
3790
3791 BT_DBG("conn %p", conn);
3792
3793 read_lock(&l->lock);
3794
3795 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
3796 bh_lock_sock(sk);
3797
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003798 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
3799 bh_unlock_sock(sk);
3800 continue;
3801 }
3802
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003803 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003804 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003805 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02003806 bh_unlock_sock(sk);
3807 continue;
3808 }
3809
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003810 if (sk->sk_state == BT_CONNECT) {
3811 if (!status) {
3812 struct l2cap_conn_req req;
3813 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
3814 req.psm = l2cap_pi(sk)->psm;
3815
3816 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03003817 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003818
3819 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3820 L2CAP_CONN_REQ, sizeof(req), &req);
3821 } else {
3822 l2cap_sock_clear_timer(sk);
3823 l2cap_sock_set_timer(sk, HZ / 10);
3824 }
3825 } else if (sk->sk_state == BT_CONNECT2) {
3826 struct l2cap_conn_rsp rsp;
3827 __u16 result;
3828
3829 if (!status) {
3830 sk->sk_state = BT_CONFIG;
3831 result = L2CAP_CR_SUCCESS;
3832 } else {
3833 sk->sk_state = BT_DISCONN;
3834 l2cap_sock_set_timer(sk, HZ / 10);
3835 result = L2CAP_CR_SEC_BLOCK;
3836 }
3837
3838 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
3839 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3840 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003841 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003842 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3843 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003844 }
3845
Linus Torvalds1da177e2005-04-16 15:20:36 -07003846 bh_unlock_sock(sk);
3847 }
3848
3849 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003850
Linus Torvalds1da177e2005-04-16 15:20:36 -07003851 return 0;
3852}
3853
3854static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
3855{
3856 struct l2cap_conn *conn = hcon->l2cap_data;
3857
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02003858 if (!conn)
3859 conn = l2cap_conn_add(hcon, 0);
3860
3861 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003862 goto drop;
3863
3864 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
3865
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +02003866 if (!(flags & ACL_CONT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003867 struct l2cap_hdr *hdr;
Andrei Emeltchenko89794812010-09-15 14:28:44 +03003868 struct sock *sk;
3869 u16 cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003870 int len;
3871
3872 if (conn->rx_len) {
3873 BT_ERR("Unexpected start frame (len %d)", skb->len);
3874 kfree_skb(conn->rx_skb);
3875 conn->rx_skb = NULL;
3876 conn->rx_len = 0;
3877 l2cap_conn_unreliable(conn, ECOMM);
3878 }
3879
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03003880 /* Start fragment always begin with Basic L2CAP header */
3881 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003882 BT_ERR("Frame is too short (len %d)", skb->len);
3883 l2cap_conn_unreliable(conn, ECOMM);
3884 goto drop;
3885 }
3886
3887 hdr = (struct l2cap_hdr *) skb->data;
3888 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
Andrei Emeltchenko89794812010-09-15 14:28:44 +03003889 cid = __le16_to_cpu(hdr->cid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003890
3891 if (len == skb->len) {
3892 /* Complete frame received */
3893 l2cap_recv_frame(conn, skb);
3894 return 0;
3895 }
3896
3897 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
3898
3899 if (skb->len > len) {
3900 BT_ERR("Frame is too long (len %d, expected len %d)",
3901 skb->len, len);
3902 l2cap_conn_unreliable(conn, ECOMM);
3903 goto drop;
3904 }
3905
Andrei Emeltchenko89794812010-09-15 14:28:44 +03003906 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3907
3908 if (sk && l2cap_pi(sk)->imtu < len - L2CAP_HDR_SIZE) {
3909 BT_ERR("Frame exceeding recv MTU (len %d, MTU %d)",
3910 len, l2cap_pi(sk)->imtu);
3911 bh_unlock_sock(sk);
3912 l2cap_conn_unreliable(conn, ECOMM);
3913 goto drop;
3914 }
3915
3916 if (sk)
3917 bh_unlock_sock(sk);
3918
Linus Torvalds1da177e2005-04-16 15:20:36 -07003919 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003920 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
3921 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003922 goto drop;
3923
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03003924 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003925 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003926 conn->rx_len = len - skb->len;
3927 } else {
3928 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
3929
3930 if (!conn->rx_len) {
3931 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
3932 l2cap_conn_unreliable(conn, ECOMM);
3933 goto drop;
3934 }
3935
3936 if (skb->len > conn->rx_len) {
3937 BT_ERR("Fragment is too long (len %d, expected %d)",
3938 skb->len, conn->rx_len);
3939 kfree_skb(conn->rx_skb);
3940 conn->rx_skb = NULL;
3941 conn->rx_len = 0;
3942 l2cap_conn_unreliable(conn, ECOMM);
3943 goto drop;
3944 }
3945
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03003946 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003947 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003948 conn->rx_len -= skb->len;
3949
3950 if (!conn->rx_len) {
3951 /* Complete frame received */
3952 l2cap_recv_frame(conn, conn->rx_skb);
3953 conn->rx_skb = NULL;
3954 }
3955 }
3956
3957drop:
3958 kfree_skb(skb);
3959 return 0;
3960}
3961
Marcel Holtmannaef7d972010-03-21 05:27:45 +01003962static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003963{
3964 struct sock *sk;
3965 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003966
3967 read_lock_bh(&l2cap_sk_list.lock);
3968
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003969 sk_for_each(sk, node, &l2cap_sk_list.head) {
3970 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003971
Gustavo F. Padovan903d3432011-02-10 14:16:06 -02003972 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
Marcel Holtmannaef7d972010-03-21 05:27:45 +01003973 batostr(&bt_sk(sk)->src),
3974 batostr(&bt_sk(sk)->dst),
3975 sk->sk_state, __le16_to_cpu(pi->psm),
3976 pi->scid, pi->dcid,
Gustavo F. Padovan903d3432011-02-10 14:16:06 -02003977 pi->imtu, pi->omtu, pi->sec_level,
3978 pi->mode);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003979 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003980
Linus Torvalds1da177e2005-04-16 15:20:36 -07003981 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003982
Marcel Holtmannaef7d972010-03-21 05:27:45 +01003983 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003984}
3985
Marcel Holtmannaef7d972010-03-21 05:27:45 +01003986static int l2cap_debugfs_open(struct inode *inode, struct file *file)
3987{
3988 return single_open(file, l2cap_debugfs_show, inode->i_private);
3989}
3990
3991static const struct file_operations l2cap_debugfs_fops = {
3992 .open = l2cap_debugfs_open,
3993 .read = seq_read,
3994 .llseek = seq_lseek,
3995 .release = single_release,
3996};
3997
3998static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003999
Linus Torvalds1da177e2005-04-16 15:20:36 -07004000static struct hci_proto l2cap_hci_proto = {
4001 .name = "L2CAP",
4002 .id = HCI_PROTO_L2CAP,
4003 .connect_ind = l2cap_connect_ind,
4004 .connect_cfm = l2cap_connect_cfm,
4005 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004006 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004007 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004008 .recv_acldata = l2cap_recv_acldata
4009};
4010
Gustavo F. Padovan64274512011-02-07 20:08:52 -02004011int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004012{
4013 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004014
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02004015 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004016 if (err < 0)
4017 return err;
4018
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004019 _busy_wq = create_singlethread_workqueue("l2cap");
Anderson Lizardob78d7b4f2010-11-29 12:15:50 -04004020 if (!_busy_wq) {
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02004021 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004022 goto error;
4023 }
4024
4025 err = hci_register_proto(&l2cap_hci_proto);
4026 if (err < 0) {
4027 BT_ERR("L2CAP protocol registration failed");
4028 bt_sock_unregister(BTPROTO_L2CAP);
4029 goto error;
4030 }
4031
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004032 if (bt_debugfs) {
4033 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4034 bt_debugfs, NULL, &l2cap_debugfs_fops);
4035 if (!l2cap_debugfs)
4036 BT_ERR("Failed to create L2CAP debug file");
4037 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004038
Linus Torvalds1da177e2005-04-16 15:20:36 -07004039 return 0;
4040
4041error:
Anderson Lizardob78d7b4f2010-11-29 12:15:50 -04004042 destroy_workqueue(_busy_wq);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02004043 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004044 return err;
4045}
4046
Gustavo F. Padovan64274512011-02-07 20:08:52 -02004047void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004048{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004049 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004050
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004051 flush_workqueue(_busy_wq);
4052 destroy_workqueue(_busy_wq);
4053
Linus Torvalds1da177e2005-04-16 15:20:36 -07004054 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4055 BT_ERR("L2CAP protocol unregistration failed");
4056
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02004057 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004058}
4059
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004060module_param(disable_ertm, bool, 0644);
4061MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");