blob: a1c7ae88dd1ff98b4d453a6ef40a1d12cbdc1155 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
Gustavo F. Padovance5706b2010-07-13 11:57:11 -03004 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
Gustavo F. Padovan5d8868f2010-07-16 16:18:39 -03005 Copyright (C) 2010 Google Inc.
Linus Torvalds1da177e2005-04-16 15:20:36 -07006
7 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License version 2 as
11 published by the Free Software Foundation;
12
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
16 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090017 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
18 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070020 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090022 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
23 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070024 SOFTWARE IS DISCLAIMED.
25*/
26
27/* Bluetooth L2CAP core and sockets. */
28
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#include <linux/module.h>
30
31#include <linux/types.h>
Randy Dunlap4fc268d2006-01-11 12:17:47 -080032#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/errno.h>
34#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035#include <linux/sched.h>
36#include <linux/slab.h>
37#include <linux/poll.h>
38#include <linux/fcntl.h>
39#include <linux/init.h>
40#include <linux/interrupt.h>
41#include <linux/socket.h>
42#include <linux/skbuff.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#include <linux/list.h>
Marcel Holtmannbe9d1222005-11-08 09:57:38 -080044#include <linux/device.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010045#include <linux/debugfs.h>
46#include <linux/seq_file.h>
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -030047#include <linux/uaccess.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030048#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070049#include <net/sock.h>
50
51#include <asm/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070052#include <asm/unaligned.h>
53
54#include <net/bluetooth/bluetooth.h>
55#include <net/bluetooth/hci_core.h>
56#include <net/bluetooth/l2cap.h>
57
Gustavo F. Padovandd135242010-07-13 11:57:12 -030058#define VERSION "2.15"
Marcel Holtmann44dd46d2009-05-02 19:09:01 -070059
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -030060static int disable_ertm = 0;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020061
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070062static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Marcel Holtmanne1027a72009-02-09 09:18:02 +010063static u8 l2cap_fixed_chan[8] = { 0x02, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070064
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080065static const struct proto_ops l2cap_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070066
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030067static struct workqueue_struct *_busy_wq;
68
Linus Torvalds1da177e2005-04-16 15:20:36 -070069static struct bt_sock_list l2cap_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070070 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070071};
72
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030073static void l2cap_busy_work(struct work_struct *work);
74
Linus Torvalds1da177e2005-04-16 15:20:36 -070075static void __l2cap_sock_close(struct sock *sk, int reason);
76static void l2cap_sock_close(struct sock *sk);
77static void l2cap_sock_kill(struct sock *sk);
78
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -030079static int l2cap_build_conf_req(struct sock *sk, void *data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070080static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
81 u8 code, u8 ident, u16 dlen, void *data);
82
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -030083static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
84
Linus Torvalds1da177e2005-04-16 15:20:36 -070085/* ---- L2CAP timers ---- */
Andrei Emeltchenko940a9ee2010-11-03 12:32:45 +020086static void l2cap_sock_set_timer(struct sock *sk, long timeout)
87{
88 BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
89 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
90}
91
92static void l2cap_sock_clear_timer(struct sock *sk)
93{
94 BT_DBG("sock %p state %d", sk, sk->sk_state);
95 sk_stop_timer(sk, &sk->sk_timer);
96}
97
Linus Torvalds1da177e2005-04-16 15:20:36 -070098static void l2cap_sock_timeout(unsigned long arg)
99{
100 struct sock *sk = (struct sock *) arg;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200101 int reason;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
103 BT_DBG("sock %p state %d", sk, sk->sk_state);
104
105 bh_lock_sock(sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200106
Andrei Emeltchenko940a9ee2010-11-03 12:32:45 +0200107 if (sock_owned_by_user(sk)) {
108 /* sk is owned by user. Try again later */
109 l2cap_sock_set_timer(sk, HZ / 5);
110 bh_unlock_sock(sk);
111 sock_put(sk);
112 return;
113 }
114
Marcel Holtmannf62e4322009-01-15 21:58:44 +0100115 if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
116 reason = ECONNREFUSED;
117 else if (sk->sk_state == BT_CONNECT &&
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100118 l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200119 reason = ECONNREFUSED;
120 else
121 reason = ETIMEDOUT;
122
123 __l2cap_sock_close(sk, reason);
124
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125 bh_unlock_sock(sk);
126
127 l2cap_sock_kill(sk);
128 sock_put(sk);
129}
130
Marcel Holtmann01394182006-07-03 10:02:46 +0200131/* ---- L2CAP channels ---- */
132static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
133{
134 struct sock *s;
135 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
136 if (l2cap_pi(s)->dcid == cid)
137 break;
138 }
139 return s;
140}
141
142static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
143{
144 struct sock *s;
145 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
146 if (l2cap_pi(s)->scid == cid)
147 break;
148 }
149 return s;
150}
151
152/* Find channel with given SCID.
153 * Returns locked socket */
154static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
155{
156 struct sock *s;
157 read_lock(&l->lock);
158 s = __l2cap_get_chan_by_scid(l, cid);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300159 if (s)
160 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200161 read_unlock(&l->lock);
162 return s;
163}
164
165static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
166{
167 struct sock *s;
168 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
169 if (l2cap_pi(s)->ident == ident)
170 break;
171 }
172 return s;
173}
174
175static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
176{
177 struct sock *s;
178 read_lock(&l->lock);
179 s = __l2cap_get_chan_by_ident(l, ident);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300180 if (s)
181 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200182 read_unlock(&l->lock);
183 return s;
184}
185
186static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
187{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300188 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200189
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300190 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300191 if (!__l2cap_get_chan_by_scid(l, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200192 return cid;
193 }
194
195 return 0;
196}
197
198static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
199{
200 sock_hold(sk);
201
202 if (l->head)
203 l2cap_pi(l->head)->prev_c = sk;
204
205 l2cap_pi(sk)->next_c = l->head;
206 l2cap_pi(sk)->prev_c = NULL;
207 l->head = sk;
208}
209
210static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
211{
212 struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
213
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200214 write_lock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200215 if (sk == l->head)
216 l->head = next;
217
218 if (next)
219 l2cap_pi(next)->prev_c = prev;
220 if (prev)
221 l2cap_pi(prev)->next_c = next;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200222 write_unlock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200223
224 __sock_put(sk);
225}
226
227static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
228{
229 struct l2cap_chan_list *l = &conn->chan_list;
230
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300231 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
232 l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200233
Marcel Holtmann2950f212009-02-12 14:02:50 +0100234 conn->disc_reason = 0x13;
235
Marcel Holtmann01394182006-07-03 10:02:46 +0200236 l2cap_pi(sk)->conn = conn;
237
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300238 if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200239 /* Alloc CID for connection-oriented socket */
240 l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
241 } else if (sk->sk_type == SOCK_DGRAM) {
242 /* Connectionless socket */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300243 l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
244 l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
Marcel Holtmann01394182006-07-03 10:02:46 +0200245 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
246 } else {
247 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300248 l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
249 l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
Marcel Holtmann01394182006-07-03 10:02:46 +0200250 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
251 }
252
253 __l2cap_chan_link(l, sk);
254
255 if (parent)
256 bt_accept_enqueue(parent, sk);
257}
258
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900259/* Delete channel.
Marcel Holtmann01394182006-07-03 10:02:46 +0200260 * Must be called on the locked socket. */
261static void l2cap_chan_del(struct sock *sk, int err)
262{
263 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
264 struct sock *parent = bt_sk(sk)->parent;
265
266 l2cap_sock_clear_timer(sk);
267
268 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
269
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900270 if (conn) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200271 /* Unlink from channel list */
272 l2cap_chan_unlink(&conn->chan_list, sk);
273 l2cap_pi(sk)->conn = NULL;
274 hci_conn_put(conn->hcon);
275 }
276
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200277 sk->sk_state = BT_CLOSED;
Marcel Holtmann01394182006-07-03 10:02:46 +0200278 sock_set_flag(sk, SOCK_ZAPPED);
279
280 if (err)
281 sk->sk_err = err;
282
283 if (parent) {
284 bt_accept_unlink(sk);
285 parent->sk_data_ready(parent, 0);
286 } else
287 sk->sk_state_change(sk);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300288
289 skb_queue_purge(TX_QUEUE(sk));
290
291 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
292 struct srej_list *l, *tmp;
293
294 del_timer(&l2cap_pi(sk)->retrans_timer);
295 del_timer(&l2cap_pi(sk)->monitor_timer);
296 del_timer(&l2cap_pi(sk)->ack_timer);
297
298 skb_queue_purge(SREJ_QUEUE(sk));
299 skb_queue_purge(BUSY_QUEUE(sk));
300
301 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
302 list_del(&l->list);
303 kfree(l);
304 }
305 }
Marcel Holtmann01394182006-07-03 10:02:46 +0200306}
307
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200308/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100309static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200310{
311 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100312 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200313
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100314 if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
315 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
316 auth_type = HCI_AT_NO_BONDING_MITM;
317 else
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300318 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100319
320 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
321 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
322 } else {
323 switch (l2cap_pi(sk)->sec_level) {
324 case BT_SECURITY_HIGH:
325 auth_type = HCI_AT_GENERAL_BONDING_MITM;
326 break;
327 case BT_SECURITY_MEDIUM:
328 auth_type = HCI_AT_GENERAL_BONDING;
329 break;
330 default:
331 auth_type = HCI_AT_NO_BONDING;
332 break;
333 }
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100334 }
335
336 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
337 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200338}
339
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200340static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
341{
342 u8 id;
343
344 /* Get next available identificator.
345 * 1 - 128 are used by kernel.
346 * 129 - 199 are reserved.
347 * 200 - 254 are used by utilities like l2ping, etc.
348 */
349
350 spin_lock_bh(&conn->lock);
351
352 if (++conn->tx_ident > 128)
353 conn->tx_ident = 1;
354
355 id = conn->tx_ident;
356
357 spin_unlock_bh(&conn->lock);
358
359 return id;
360}
361
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300362static inline void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200363{
364 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
365
366 BT_DBG("code 0x%2.2x", code);
367
368 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300369 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200370
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300371 hci_send_acl(conn->hcon, skb, 0);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200372}
373
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300374static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300375{
376 struct sk_buff *skb;
377 struct l2cap_hdr *lh;
378 struct l2cap_conn *conn = pi->conn;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300379 struct sock *sk = (struct sock *)pi;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300380 int count, hlen = L2CAP_HDR_SIZE + 2;
381
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300382 if (sk->sk_state != BT_CONNECTED)
383 return;
384
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300385 if (pi->fcs == L2CAP_FCS_CRC16)
386 hlen += 2;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300387
388 BT_DBG("pi %p, control 0x%2.2x", pi, control);
389
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300390 count = min_t(unsigned int, conn->mtu, hlen);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300391 control |= L2CAP_CTRL_FRAME_TYPE;
392
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -0300393 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
394 control |= L2CAP_CTRL_FINAL;
395 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
396 }
397
Gustavo F. Padovanf0946cc2010-05-01 16:15:37 -0300398 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
399 control |= L2CAP_CTRL_POLL;
400 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
401 }
402
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300403 skb = bt_skb_alloc(count, GFP_ATOMIC);
404 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300405 return;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300406
407 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300408 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300409 lh->cid = cpu_to_le16(pi->dcid);
410 put_unaligned_le16(control, skb_put(skb, 2));
411
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300412 if (pi->fcs == L2CAP_FCS_CRC16) {
413 u16 fcs = crc16(0, (u8 *)lh, count - 2);
414 put_unaligned_le16(fcs, skb_put(skb, 2));
415 }
416
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300417 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300418}
419
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300420static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300421{
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300422 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300423 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300424 pi->conn_state |= L2CAP_CONN_RNR_SENT;
425 } else
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300426 control |= L2CAP_SUPER_RCV_READY;
427
Gustavo F. Padovan2ab25cd2009-10-03 02:34:40 -0300428 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
429
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300430 l2cap_send_sframe(pi, control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300431}
432
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300433static inline int __l2cap_no_conn_pending(struct sock *sk)
434{
435 return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND);
436}
437
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200438static void l2cap_do_start(struct sock *sk)
439{
440 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
441
442 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100443 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
444 return;
445
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300446 if (l2cap_check_security(sk) && __l2cap_no_conn_pending(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200447 struct l2cap_conn_req req;
448 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
449 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200450
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200451 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300452 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200453
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200454 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200455 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200456 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200457 } else {
458 struct l2cap_info_req req;
459 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
460
461 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
462 conn->info_ident = l2cap_get_ident(conn);
463
464 mod_timer(&conn->info_timer, jiffies +
465 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
466
467 l2cap_send_cmd(conn, conn->info_ident,
468 L2CAP_INFO_REQ, sizeof(req), &req);
469 }
470}
471
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300472static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
473{
474 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -0300475 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300476 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
477
478 switch (mode) {
479 case L2CAP_MODE_ERTM:
480 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
481 case L2CAP_MODE_STREAMING:
482 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
483 default:
484 return 0x00;
485 }
486}
487
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300488static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300489{
490 struct l2cap_disconn_req req;
491
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300492 if (!conn)
493 return;
494
495 skb_queue_purge(TX_QUEUE(sk));
496
497 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
498 del_timer(&l2cap_pi(sk)->retrans_timer);
499 del_timer(&l2cap_pi(sk)->monitor_timer);
500 del_timer(&l2cap_pi(sk)->ack_timer);
501 }
502
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300503 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
504 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
505 l2cap_send_cmd(conn, l2cap_get_ident(conn),
506 L2CAP_DISCONN_REQ, sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300507
508 sk->sk_state = BT_DISCONN;
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300509 sk->sk_err = err;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300510}
511
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200513static void l2cap_conn_start(struct l2cap_conn *conn)
514{
515 struct l2cap_chan_list *l = &conn->chan_list;
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300516 struct sock_del_list del, *tmp1, *tmp2;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200517 struct sock *sk;
518
519 BT_DBG("conn %p", conn);
520
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300521 INIT_LIST_HEAD(&del.list);
522
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200523 read_lock(&l->lock);
524
525 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
526 bh_lock_sock(sk);
527
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300528 if (sk->sk_type != SOCK_SEQPACKET &&
529 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200530 bh_unlock_sock(sk);
531 continue;
532 }
533
534 if (sk->sk_state == BT_CONNECT) {
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300535 struct l2cap_conn_req req;
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300536
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300537 if (!l2cap_check_security(sk) ||
538 !__l2cap_no_conn_pending(sk)) {
539 bh_unlock_sock(sk);
540 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200541 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300542
543 if (!l2cap_mode_supported(l2cap_pi(sk)->mode,
544 conn->feat_mask)
545 && l2cap_pi(sk)->conf_state &
546 L2CAP_CONF_STATE2_DEVICE) {
547 tmp1 = kzalloc(sizeof(struct sock_del_list),
548 GFP_ATOMIC);
549 tmp1->sk = sk;
550 list_add_tail(&tmp1->list, &del.list);
551 bh_unlock_sock(sk);
552 continue;
553 }
554
555 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
556 req.psm = l2cap_pi(sk)->psm;
557
558 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
559 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
560
561 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
562 L2CAP_CONN_REQ, sizeof(req), &req);
563
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200564 } else if (sk->sk_state == BT_CONNECT2) {
565 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -0300566 char buf[128];
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200567 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
568 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
569
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100570 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100571 if (bt_sk(sk)->defer_setup) {
572 struct sock *parent = bt_sk(sk)->parent;
573 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
574 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
575 parent->sk_data_ready(parent, 0);
576
577 } else {
578 sk->sk_state = BT_CONFIG;
579 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
580 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
581 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200582 } else {
583 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
584 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
585 }
586
587 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
588 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -0300589
590 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT ||
591 rsp.result != L2CAP_CR_SUCCESS) {
592 bh_unlock_sock(sk);
593 continue;
594 }
595
596 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
597 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
598 l2cap_build_conf_req(sk, buf), buf);
599 l2cap_pi(sk)->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200600 }
601
602 bh_unlock_sock(sk);
603 }
604
605 read_unlock(&l->lock);
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300606
607 list_for_each_entry_safe(tmp1, tmp2, &del.list, list) {
608 bh_lock_sock(tmp1->sk);
609 __l2cap_sock_close(tmp1->sk, ECONNRESET);
610 bh_unlock_sock(tmp1->sk);
611 list_del(&tmp1->list);
612 kfree(tmp1);
613 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200614}
615
616static void l2cap_conn_ready(struct l2cap_conn *conn)
617{
618 struct l2cap_chan_list *l = &conn->chan_list;
619 struct sock *sk;
620
621 BT_DBG("conn %p", conn);
622
623 read_lock(&l->lock);
624
625 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
626 bh_lock_sock(sk);
627
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300628 if (sk->sk_type != SOCK_SEQPACKET &&
629 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200630 l2cap_sock_clear_timer(sk);
631 sk->sk_state = BT_CONNECTED;
632 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200633 } else if (sk->sk_state == BT_CONNECT)
634 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200635
636 bh_unlock_sock(sk);
637 }
638
639 read_unlock(&l->lock);
640}
641
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200642/* Notify sockets that we cannot guaranty reliability anymore */
643static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
644{
645 struct l2cap_chan_list *l = &conn->chan_list;
646 struct sock *sk;
647
648 BT_DBG("conn %p", conn);
649
650 read_lock(&l->lock);
651
652 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100653 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200654 sk->sk_err = err;
655 }
656
657 read_unlock(&l->lock);
658}
659
660static void l2cap_info_timeout(unsigned long arg)
661{
662 struct l2cap_conn *conn = (void *) arg;
663
Marcel Holtmann984947d2009-02-06 23:35:19 +0100664 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100665 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100666
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200667 l2cap_conn_start(conn);
668}
669
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
671{
Marcel Holtmann01394182006-07-03 10:02:46 +0200672 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673
Marcel Holtmann01394182006-07-03 10:02:46 +0200674 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675 return conn;
676
Marcel Holtmann01394182006-07-03 10:02:46 +0200677 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
678 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680
681 hcon->l2cap_data = conn;
682 conn->hcon = hcon;
683
Marcel Holtmann01394182006-07-03 10:02:46 +0200684 BT_DBG("hcon %p conn %p", hcon, conn);
685
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 conn->mtu = hcon->hdev->acl_mtu;
687 conn->src = &hcon->hdev->bdaddr;
688 conn->dst = &hcon->dst;
689
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200690 conn->feat_mask = 0;
691
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692 spin_lock_init(&conn->lock);
693 rwlock_init(&conn->chan_list.lock);
694
Dave Young45054dc2009-10-18 20:28:30 +0000695 setup_timer(&conn->info_timer, l2cap_info_timeout,
696 (unsigned long) conn);
697
Marcel Holtmann2950f212009-02-12 14:02:50 +0100698 conn->disc_reason = 0x13;
699
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700 return conn;
701}
702
Marcel Holtmann01394182006-07-03 10:02:46 +0200703static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704{
Marcel Holtmann01394182006-07-03 10:02:46 +0200705 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706 struct sock *sk;
707
Marcel Holtmann01394182006-07-03 10:02:46 +0200708 if (!conn)
709 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710
711 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
712
Wei Yongjun7585b972009-02-25 18:29:52 +0800713 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714
715 /* Kill channels */
716 while ((sk = conn->chan_list.head)) {
717 bh_lock_sock(sk);
718 l2cap_chan_del(sk, err);
719 bh_unlock_sock(sk);
720 l2cap_sock_kill(sk);
721 }
722
Dave Young8e8440f2008-03-03 12:18:55 -0800723 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
724 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800725
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726 hcon->l2cap_data = NULL;
727 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728}
729
730static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
731{
732 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200733 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200735 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736}
737
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700739static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740{
741 struct sock *sk;
742 struct hlist_node *node;
743 sk_for_each(sk, node, &l2cap_sk_list.head)
744 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
745 goto found;
746 sk = NULL;
747found:
748 return sk;
749}
750
751/* Find socket with psm and source bdaddr.
752 * Returns closest match.
753 */
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +0000754static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755{
756 struct sock *sk = NULL, *sk1 = NULL;
757 struct hlist_node *node;
758
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +0000759 read_lock(&l2cap_sk_list.lock);
760
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761 sk_for_each(sk, node, &l2cap_sk_list.head) {
762 if (state && sk->sk_state != state)
763 continue;
764
765 if (l2cap_pi(sk)->psm == psm) {
766 /* Exact match. */
767 if (!bacmp(&bt_sk(sk)->src, src))
768 break;
769
770 /* Closest match */
771 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
772 sk1 = sk;
773 }
774 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776 read_unlock(&l2cap_sk_list.lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +0000777
778 return node ? sk : sk1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779}
780
781static void l2cap_sock_destruct(struct sock *sk)
782{
783 BT_DBG("sk %p", sk);
784
785 skb_queue_purge(&sk->sk_receive_queue);
786 skb_queue_purge(&sk->sk_write_queue);
787}
788
789static void l2cap_sock_cleanup_listen(struct sock *parent)
790{
791 struct sock *sk;
792
793 BT_DBG("parent %p", parent);
794
795 /* Close not yet accepted channels */
796 while ((sk = bt_accept_dequeue(parent, NULL)))
797 l2cap_sock_close(sk);
798
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200799 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800 sock_set_flag(parent, SOCK_ZAPPED);
801}
802
803/* Kill socket (only if zapped and orphan)
804 * Must be called on unlocked socket.
805 */
806static void l2cap_sock_kill(struct sock *sk)
807{
808 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
809 return;
810
811 BT_DBG("sk %p state %d", sk, sk->sk_state);
812
813 /* Kill poor orphan */
814 bt_sock_unlink(&l2cap_sk_list, sk);
815 sock_set_flag(sk, SOCK_DEAD);
816 sock_put(sk);
817}
818
819static void __l2cap_sock_close(struct sock *sk, int reason)
820{
821 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
822
823 switch (sk->sk_state) {
824 case BT_LISTEN:
825 l2cap_sock_cleanup_listen(sk);
826 break;
827
828 case BT_CONNECTED:
829 case BT_CONFIG:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300830 if (sk->sk_type == SOCK_SEQPACKET ||
831 sk->sk_type == SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300835 l2cap_send_disconn_req(conn, sk, reason);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200836 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838 break;
839
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100840 case BT_CONNECT2:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300841 if (sk->sk_type == SOCK_SEQPACKET ||
842 sk->sk_type == SOCK_STREAM) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100843 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
844 struct l2cap_conn_rsp rsp;
845 __u16 result;
846
847 if (bt_sk(sk)->defer_setup)
848 result = L2CAP_CR_SEC_BLOCK;
849 else
850 result = L2CAP_CR_BAD_PSM;
851
852 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
853 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
854 rsp.result = cpu_to_le16(result);
855 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
856 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
857 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
858 } else
859 l2cap_chan_del(sk, reason);
860 break;
861
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862 case BT_CONNECT:
863 case BT_DISCONN:
864 l2cap_chan_del(sk, reason);
865 break;
866
867 default:
868 sock_set_flag(sk, SOCK_ZAPPED);
869 break;
870 }
871}
872
873/* Must be called on unlocked socket. */
874static void l2cap_sock_close(struct sock *sk)
875{
876 l2cap_sock_clear_timer(sk);
877 lock_sock(sk);
878 __l2cap_sock_close(sk, ECONNRESET);
879 release_sock(sk);
880 l2cap_sock_kill(sk);
881}
882
883static void l2cap_sock_init(struct sock *sk, struct sock *parent)
884{
885 struct l2cap_pinfo *pi = l2cap_pi(sk);
886
887 BT_DBG("sk %p", sk);
888
889 if (parent) {
890 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100891 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
892
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 pi->imtu = l2cap_pi(parent)->imtu;
894 pi->omtu = l2cap_pi(parent)->omtu;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300895 pi->conf_state = l2cap_pi(parent)->conf_state;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700896 pi->mode = l2cap_pi(parent)->mode;
897 pi->fcs = l2cap_pi(parent)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -0300898 pi->max_tx = l2cap_pi(parent)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -0300899 pi->tx_win = l2cap_pi(parent)->tx_win;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100900 pi->sec_level = l2cap_pi(parent)->sec_level;
901 pi->role_switch = l2cap_pi(parent)->role_switch;
902 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 } else {
904 pi->imtu = L2CAP_DEFAULT_MTU;
905 pi->omtu = 0;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -0300906 if (!disable_ertm && sk->sk_type == SOCK_STREAM) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300907 pi->mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300908 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
909 } else {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300910 pi->mode = L2CAP_MODE_BASIC;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300911 }
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300912 pi->max_tx = L2CAP_DEFAULT_MAX_TX;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700913 pi->fcs = L2CAP_FCS_CRC16;
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300914 pi->tx_win = L2CAP_DEFAULT_TX_WINDOW;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100915 pi->sec_level = BT_SECURITY_LOW;
916 pi->role_switch = 0;
917 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 }
919
920 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200921 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Dave Young45054dc2009-10-18 20:28:30 +0000923 skb_queue_head_init(TX_QUEUE(sk));
924 skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300925 skb_queue_head_init(BUSY_QUEUE(sk));
Dave Young45054dc2009-10-18 20:28:30 +0000926 INIT_LIST_HEAD(SREJ_LIST(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927}
928
929static struct proto l2cap_proto = {
930 .name = "L2CAP",
931 .owner = THIS_MODULE,
932 .obj_size = sizeof(struct l2cap_pinfo)
933};
934
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700935static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936{
937 struct sock *sk;
938
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700939 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940 if (!sk)
941 return NULL;
942
943 sock_init_data(sock, sk);
944 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
945
946 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200947 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948
949 sock_reset_flag(sk, SOCK_ZAPPED);
950
951 sk->sk_protocol = proto;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200952 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200954 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955
956 bt_sock_link(&l2cap_sk_list, sk);
957 return sk;
958}
959
Eric Paris3f378b62009-11-05 22:18:14 -0800960static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
961 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962{
963 struct sock *sk;
964
965 BT_DBG("sock %p", sock);
966
967 sock->state = SS_UNCONNECTED;
968
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300969 if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
971 return -ESOCKTNOSUPPORT;
972
Eric Parisc84b3262009-11-05 20:45:52 -0800973 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974 return -EPERM;
975
976 sock->ops = &l2cap_sock_ops;
977
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700978 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700979 if (!sk)
980 return -ENOMEM;
981
982 l2cap_sock_init(sk, NULL);
983 return 0;
984}
985
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100986static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100989 struct sockaddr_l2 la;
990 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100992 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993
994 if (!addr || addr->sa_family != AF_BLUETOOTH)
995 return -EINVAL;
996
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100997 memset(&la, 0, sizeof(la));
998 len = min_t(unsigned int, sizeof(la), alen);
999 memcpy(&la, addr, len);
1000
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001001 if (la.l2_cid)
1002 return -EINVAL;
1003
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004 lock_sock(sk);
1005
1006 if (sk->sk_state != BT_OPEN) {
1007 err = -EBADFD;
1008 goto done;
1009 }
1010
Mat Martineau0fba2552010-09-08 10:05:26 -07001011 if (la.l2_psm) {
1012 __u16 psm = __le16_to_cpu(la.l2_psm);
1013
1014 /* PSM must be odd and lsb of upper byte must be 0 */
1015 if ((psm & 0x0101) != 0x0001) {
1016 err = -EINVAL;
1017 goto done;
1018 }
1019
1020 /* Restrict usage of well-known PSMs */
1021 if (psm < 0x1001 && !capable(CAP_NET_BIND_SERVICE)) {
1022 err = -EACCES;
1023 goto done;
1024 }
Marcel Holtmann847641d2007-01-22 22:00:45 +01001025 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001026
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027 write_lock_bh(&l2cap_sk_list.lock);
1028
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001029 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030 err = -EADDRINUSE;
1031 } else {
1032 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001033 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
1034 l2cap_pi(sk)->psm = la.l2_psm;
1035 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001037
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001038 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
1039 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001040 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 }
1042
1043 write_unlock_bh(&l2cap_sk_list.lock);
1044
1045done:
1046 release_sock(sk);
1047 return err;
1048}
1049
1050static int l2cap_do_connect(struct sock *sk)
1051{
1052 bdaddr_t *src = &bt_sk(sk)->src;
1053 bdaddr_t *dst = &bt_sk(sk)->dst;
1054 struct l2cap_conn *conn;
1055 struct hci_conn *hcon;
1056 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001057 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001058 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001060 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
1061 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001063 hdev = hci_get_route(dst, src);
1064 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065 return -EHOSTUNREACH;
1066
1067 hci_dev_lock_bh(hdev);
1068
1069 err = -ENOMEM;
1070
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001071 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001072 switch (l2cap_pi(sk)->sec_level) {
1073 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001074 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001075 break;
1076 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001077 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001078 break;
1079 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001080 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001081 break;
1082 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001083 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001084 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001085 auth_type = HCI_AT_NO_BONDING_MITM;
1086 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001087 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +01001088
1089 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
1090 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001091 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001092 switch (l2cap_pi(sk)->sec_level) {
1093 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001094 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001095 break;
1096 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001097 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001098 break;
1099 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001100 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001101 break;
1102 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001103 }
1104
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001105 hcon = hci_connect(hdev, ACL_LINK, dst,
1106 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107 if (!hcon)
1108 goto done;
1109
1110 conn = l2cap_conn_add(hcon, 0);
1111 if (!conn) {
1112 hci_conn_put(hcon);
1113 goto done;
1114 }
1115
1116 err = 0;
1117
1118 /* Update source addr of the socket */
1119 bacpy(src, conn->src);
1120
1121 l2cap_chan_add(conn, sk, NULL);
1122
1123 sk->sk_state = BT_CONNECT;
1124 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
1125
1126 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001127 if (sk->sk_type != SOCK_SEQPACKET &&
1128 sk->sk_type != SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129 l2cap_sock_clear_timer(sk);
1130 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001131 } else
1132 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133 }
1134
1135done:
1136 hci_dev_unlock_bh(hdev);
1137 hci_dev_put(hdev);
1138 return err;
1139}
1140
1141static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
1142{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001143 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001144 struct sockaddr_l2 la;
1145 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146
Linus Torvalds1da177e2005-04-16 15:20:36 -07001147 BT_DBG("sk %p", sk);
1148
Changli Gao6503d962010-03-31 22:58:26 +00001149 if (!addr || alen < sizeof(addr->sa_family) ||
1150 addr->sa_family != AF_BLUETOOTH)
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001151 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001153 memset(&la, 0, sizeof(la));
1154 len = min_t(unsigned int, sizeof(la), alen);
1155 memcpy(&la, addr, len);
1156
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001157 if (la.l2_cid)
1158 return -EINVAL;
1159
1160 lock_sock(sk);
1161
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001162 if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
1163 && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 err = -EINVAL;
1165 goto done;
1166 }
1167
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001168 switch (l2cap_pi(sk)->mode) {
1169 case L2CAP_MODE_BASIC:
1170 break;
1171 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001172 case L2CAP_MODE_STREAMING:
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001173 if (!disable_ertm)
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001174 break;
1175 /* fall through */
1176 default:
1177 err = -ENOTSUPP;
1178 goto done;
1179 }
1180
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001181 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182 case BT_CONNECT:
1183 case BT_CONNECT2:
1184 case BT_CONFIG:
1185 /* Already connecting */
1186 goto wait;
1187
1188 case BT_CONNECTED:
1189 /* Already connected */
João Paulo Rechi Vita8b0dc6d2010-06-22 13:56:22 -03001190 err = -EISCONN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191 goto done;
1192
1193 case BT_OPEN:
1194 case BT_BOUND:
1195 /* Can connect */
1196 break;
1197
1198 default:
1199 err = -EBADFD;
1200 goto done;
1201 }
1202
Mat Martineau0fba2552010-09-08 10:05:26 -07001203 /* PSM must be odd and lsb of upper byte must be 0 */
1204 if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 &&
1205 sk->sk_type != SOCK_RAW) {
1206 err = -EINVAL;
1207 goto done;
1208 }
1209
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001211 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1212 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001214 err = l2cap_do_connect(sk);
1215 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216 goto done;
1217
1218wait:
1219 err = bt_sock_wait_state(sk, BT_CONNECTED,
1220 sock_sndtimeo(sk, flags & O_NONBLOCK));
1221done:
1222 release_sock(sk);
1223 return err;
1224}
1225
1226static int l2cap_sock_listen(struct socket *sock, int backlog)
1227{
1228 struct sock *sk = sock->sk;
1229 int err = 0;
1230
1231 BT_DBG("sk %p backlog %d", sk, backlog);
1232
1233 lock_sock(sk);
1234
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001235 if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
1236 || sk->sk_state != BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237 err = -EBADFD;
1238 goto done;
1239 }
1240
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001241 switch (l2cap_pi(sk)->mode) {
1242 case L2CAP_MODE_BASIC:
1243 break;
1244 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001245 case L2CAP_MODE_STREAMING:
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001246 if (!disable_ertm)
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001247 break;
1248 /* fall through */
1249 default:
1250 err = -ENOTSUPP;
1251 goto done;
1252 }
1253
Linus Torvalds1da177e2005-04-16 15:20:36 -07001254 if (!l2cap_pi(sk)->psm) {
1255 bdaddr_t *src = &bt_sk(sk)->src;
1256 u16 psm;
1257
1258 err = -EINVAL;
1259
1260 write_lock_bh(&l2cap_sk_list.lock);
1261
1262 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001263 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1264 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1265 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001266 err = 0;
1267 break;
1268 }
1269
1270 write_unlock_bh(&l2cap_sk_list.lock);
1271
1272 if (err < 0)
1273 goto done;
1274 }
1275
1276 sk->sk_max_ack_backlog = backlog;
1277 sk->sk_ack_backlog = 0;
1278 sk->sk_state = BT_LISTEN;
1279
1280done:
1281 release_sock(sk);
1282 return err;
1283}
1284
1285static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1286{
1287 DECLARE_WAITQUEUE(wait, current);
1288 struct sock *sk = sock->sk, *nsk;
1289 long timeo;
1290 int err = 0;
1291
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001292 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001293
1294 if (sk->sk_state != BT_LISTEN) {
1295 err = -EBADFD;
1296 goto done;
1297 }
1298
1299 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1300
1301 BT_DBG("sk %p timeo %ld", sk, timeo);
1302
1303 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +00001304 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001305 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1306 set_current_state(TASK_INTERRUPTIBLE);
1307 if (!timeo) {
1308 err = -EAGAIN;
1309 break;
1310 }
1311
1312 release_sock(sk);
1313 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001314 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315
1316 if (sk->sk_state != BT_LISTEN) {
1317 err = -EBADFD;
1318 break;
1319 }
1320
1321 if (signal_pending(current)) {
1322 err = sock_intr_errno(timeo);
1323 break;
1324 }
1325 }
1326 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +00001327 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328
1329 if (err)
1330 goto done;
1331
1332 newsock->state = SS_CONNECTED;
1333
1334 BT_DBG("new socket %p", nsk);
1335
1336done:
1337 release_sock(sk);
1338 return err;
1339}
1340
1341static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1342{
1343 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1344 struct sock *sk = sock->sk;
1345
1346 BT_DBG("sock %p, sk %p", sock, sk);
1347
1348 addr->sa_family = AF_BLUETOOTH;
1349 *len = sizeof(struct sockaddr_l2);
1350
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001351 if (peer) {
1352 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001353 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001354 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001355 } else {
1356 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001358 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001359 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001360
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361 return 0;
1362}
1363
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001364static int __l2cap_wait_ack(struct sock *sk)
1365{
1366 DECLARE_WAITQUEUE(wait, current);
1367 int err = 0;
1368 int timeo = HZ/5;
1369
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001370 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001371 while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
1372 set_current_state(TASK_INTERRUPTIBLE);
1373
1374 if (!timeo)
1375 timeo = HZ/5;
1376
1377 if (signal_pending(current)) {
1378 err = sock_intr_errno(timeo);
1379 break;
1380 }
1381
1382 release_sock(sk);
1383 timeo = schedule_timeout(timeo);
1384 lock_sock(sk);
1385
1386 err = sock_error(sk);
1387 if (err)
1388 break;
1389 }
1390 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001391 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001392 return err;
1393}
1394
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001395static void l2cap_monitor_timeout(unsigned long arg)
1396{
1397 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001398
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001399 BT_DBG("sk %p", sk);
1400
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001401 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001402 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001403 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001404 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001405 return;
1406 }
1407
1408 l2cap_pi(sk)->retry_count++;
1409 __mod_monitor_timer();
1410
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001411 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001412 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001413}
1414
1415static void l2cap_retrans_timeout(unsigned long arg)
1416{
1417 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001418
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001419 BT_DBG("sk %p", sk);
1420
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001421 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001422 l2cap_pi(sk)->retry_count = 1;
1423 __mod_monitor_timer();
1424
1425 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1426
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001427 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001428 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001429}
1430
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001431static void l2cap_drop_acked_frames(struct sock *sk)
1432{
1433 struct sk_buff *skb;
1434
Gustavo F. Padovan812e7372010-05-01 16:15:42 -03001435 while ((skb = skb_peek(TX_QUEUE(sk))) &&
1436 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001437 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1438 break;
1439
1440 skb = skb_dequeue(TX_QUEUE(sk));
1441 kfree_skb(skb);
1442
1443 l2cap_pi(sk)->unacked_frames--;
1444 }
1445
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001446 if (!l2cap_pi(sk)->unacked_frames)
1447 del_timer(&l2cap_pi(sk)->retrans_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001448}
1449
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001450static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001451{
1452 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001453
1454 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1455
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001456 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001457}
1458
João Paulo Rechi Vita305682e2010-06-22 13:56:23 -03001459static void l2cap_streaming_send(struct sock *sk)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001460{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001461 struct sk_buff *skb;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001462 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001463 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001464
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001465 while ((skb = skb_dequeue(TX_QUEUE(sk)))) {
1466 control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001467 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001468 put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001469
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001470 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001471 fcs = crc16(0, (u8 *)skb->data, skb->len - 2);
1472 put_unaligned_le16(fcs, skb->data + skb->len - 2);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001473 }
1474
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001475 l2cap_do_send(sk, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001476
1477 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001478 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001479}
1480
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001481static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001482{
1483 struct l2cap_pinfo *pi = l2cap_pi(sk);
1484 struct sk_buff *skb, *tx_skb;
1485 u16 control, fcs;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001486
1487 skb = skb_peek(TX_QUEUE(sk));
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001488 if (!skb)
1489 return;
1490
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001491 do {
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001492 if (bt_cb(skb)->tx_seq == tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001493 break;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001494
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001495 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1496 return;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001497
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001498 } while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001499
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001500 if (pi->remote_max_tx &&
1501 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001502 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001503 return;
1504 }
1505
1506 tx_skb = skb_clone(skb, GFP_ATOMIC);
1507 bt_cb(skb)->retries++;
1508 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001509
1510 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1511 control |= L2CAP_CTRL_FINAL;
1512 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1513 }
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001514
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001515 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1516 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001517
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001518 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1519
1520 if (pi->fcs == L2CAP_FCS_CRC16) {
1521 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1522 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1523 }
1524
1525 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001526}
1527
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001528static int l2cap_ertm_send(struct sock *sk)
1529{
1530 struct sk_buff *skb, *tx_skb;
1531 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001532 u16 control, fcs;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001533 int nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001534
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001535 if (sk->sk_state != BT_CONNECTED)
1536 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001537
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001538 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001539
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001540 if (pi->remote_max_tx &&
1541 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001542 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001543 break;
1544 }
1545
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001546 tx_skb = skb_clone(skb, GFP_ATOMIC);
1547
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001548 bt_cb(skb)->retries++;
1549
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001550 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001551 control &= L2CAP_CTRL_SAR;
1552
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001553 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1554 control |= L2CAP_CTRL_FINAL;
1555 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1556 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001557 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001558 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1559 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1560
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001561
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001562 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001563 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1564 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1565 }
1566
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001567 l2cap_do_send(sk, tx_skb);
1568
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001569 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001570
1571 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1572 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1573
1574 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001575 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001576
1577 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1578 sk->sk_send_head = NULL;
1579 else
1580 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001581
1582 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001583 }
1584
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001585 return nsent;
1586}
1587
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001588static int l2cap_retransmit_frames(struct sock *sk)
1589{
1590 struct l2cap_pinfo *pi = l2cap_pi(sk);
1591 int ret;
1592
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001593 if (!skb_queue_empty(TX_QUEUE(sk)))
1594 sk->sk_send_head = TX_QUEUE(sk)->next;
1595
1596 pi->next_tx_seq = pi->expected_ack_seq;
1597 ret = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001598 return ret;
1599}
1600
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001601static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001602{
1603 struct sock *sk = (struct sock *)pi;
1604 u16 control = 0;
1605
1606 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1607
1608 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1609 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001610 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001611 l2cap_send_sframe(pi, control);
1612 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001613 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001614
Gustavo F. Padovane0f66212010-06-21 18:50:49 -03001615 if (l2cap_ertm_send(sk) > 0)
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001616 return;
1617
1618 control |= L2CAP_SUPER_RCV_READY;
1619 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001620}
1621
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001622static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001623{
1624 struct srej_list *tail;
1625 u16 control;
1626
1627 control = L2CAP_SUPER_SELECT_REJECT;
1628 control |= L2CAP_CTRL_FINAL;
1629
1630 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1631 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1632
1633 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001634}
1635
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001636static 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 -07001637{
1638 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001639 struct sk_buff **frag;
1640 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001642 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001643 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644
1645 sent += count;
1646 len -= count;
1647
1648 /* Continuation fragments (no L2CAP header) */
1649 frag = &skb_shinfo(skb)->frag_list;
1650 while (len) {
1651 count = min_t(unsigned int, conn->mtu, len);
1652
1653 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1654 if (!*frag)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001655 return err;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001656 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1657 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658
1659 sent += count;
1660 len -= count;
1661
1662 frag = &(*frag)->next;
1663 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664
1665 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001666}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001668static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1669{
1670 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1671 struct sk_buff *skb;
1672 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1673 struct l2cap_hdr *lh;
1674
1675 BT_DBG("sk %p len %d", sk, (int)len);
1676
1677 count = min_t(unsigned int, (conn->mtu - hlen), len);
1678 skb = bt_skb_send_alloc(sk, count + hlen,
1679 msg->msg_flags & MSG_DONTWAIT, &err);
1680 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001681 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001682
1683 /* Create L2CAP header */
1684 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1685 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1686 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1687 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1688
1689 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1690 if (unlikely(err < 0)) {
1691 kfree_skb(skb);
1692 return ERR_PTR(err);
1693 }
1694 return skb;
1695}
1696
1697static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1698{
1699 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1700 struct sk_buff *skb;
1701 int err, count, hlen = L2CAP_HDR_SIZE;
1702 struct l2cap_hdr *lh;
1703
1704 BT_DBG("sk %p len %d", sk, (int)len);
1705
1706 count = min_t(unsigned int, (conn->mtu - hlen), len);
1707 skb = bt_skb_send_alloc(sk, count + hlen,
1708 msg->msg_flags & MSG_DONTWAIT, &err);
1709 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001710 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001711
1712 /* Create L2CAP header */
1713 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1714 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1715 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1716
1717 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1718 if (unlikely(err < 0)) {
1719 kfree_skb(skb);
1720 return ERR_PTR(err);
1721 }
1722 return skb;
1723}
1724
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001725static struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001726{
1727 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1728 struct sk_buff *skb;
1729 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1730 struct l2cap_hdr *lh;
1731
1732 BT_DBG("sk %p len %d", sk, (int)len);
1733
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001734 if (!conn)
1735 return ERR_PTR(-ENOTCONN);
1736
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001737 if (sdulen)
1738 hlen += 2;
1739
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001740 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1741 hlen += 2;
1742
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001743 count = min_t(unsigned int, (conn->mtu - hlen), len);
1744 skb = bt_skb_send_alloc(sk, count + hlen,
1745 msg->msg_flags & MSG_DONTWAIT, &err);
1746 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001747 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001748
1749 /* Create L2CAP header */
1750 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1751 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1752 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1753 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001754 if (sdulen)
1755 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001756
1757 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1758 if (unlikely(err < 0)) {
1759 kfree_skb(skb);
1760 return ERR_PTR(err);
1761 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001762
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001763 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1764 put_unaligned_le16(0, skb_put(skb, 2));
1765
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001766 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001767 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768}
1769
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001770static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1771{
1772 struct l2cap_pinfo *pi = l2cap_pi(sk);
1773 struct sk_buff *skb;
1774 struct sk_buff_head sar_queue;
1775 u16 control;
1776 size_t size = 0;
1777
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001778 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001779 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001780 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001781 if (IS_ERR(skb))
1782 return PTR_ERR(skb);
1783
1784 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001785 len -= pi->remote_mps;
1786 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001787
1788 while (len > 0) {
1789 size_t buflen;
1790
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001791 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001792 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001793 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001794 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001795 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001796 buflen = len;
1797 }
1798
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001799 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001800 if (IS_ERR(skb)) {
1801 skb_queue_purge(&sar_queue);
1802 return PTR_ERR(skb);
1803 }
1804
1805 __skb_queue_tail(&sar_queue, skb);
1806 len -= buflen;
1807 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001808 }
1809 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1810 if (sk->sk_send_head == NULL)
1811 sk->sk_send_head = sar_queue.next;
1812
1813 return size;
1814}
1815
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1817{
1818 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001819 struct l2cap_pinfo *pi = l2cap_pi(sk);
1820 struct sk_buff *skb;
1821 u16 control;
1822 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823
1824 BT_DBG("sock %p, sk %p", sock, sk);
1825
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001826 err = sock_error(sk);
1827 if (err)
1828 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829
1830 if (msg->msg_flags & MSG_OOB)
1831 return -EOPNOTSUPP;
1832
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833 lock_sock(sk);
1834
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001835 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001837 goto done;
1838 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001840 /* Connectionless channel */
1841 if (sk->sk_type == SOCK_DGRAM) {
1842 skb = l2cap_create_connless_pdu(sk, msg, len);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001843 if (IS_ERR(skb)) {
Dan Carpenter477fffb2010-04-21 23:52:01 +00001844 err = PTR_ERR(skb);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001845 } else {
1846 l2cap_do_send(sk, skb);
1847 err = len;
1848 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001849 goto done;
1850 }
1851
1852 switch (pi->mode) {
1853 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001854 /* Check outgoing MTU */
1855 if (len > pi->omtu) {
João Paulo Rechi Vitaf9dd11b2010-06-22 13:56:24 -03001856 err = -EMSGSIZE;
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001857 goto done;
1858 }
1859
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001860 /* Create a basic PDU */
1861 skb = l2cap_create_basic_pdu(sk, msg, len);
1862 if (IS_ERR(skb)) {
1863 err = PTR_ERR(skb);
1864 goto done;
1865 }
1866
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001867 l2cap_do_send(sk, skb);
1868 err = len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001869 break;
1870
1871 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001872 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001873 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001874 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001875 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001876 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001877 if (IS_ERR(skb)) {
1878 err = PTR_ERR(skb);
1879 goto done;
1880 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001881 __skb_queue_tail(TX_QUEUE(sk), skb);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001882
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001883 if (sk->sk_send_head == NULL)
1884 sk->sk_send_head = skb;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001885
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001886 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001887 /* Segment SDU into multiples PDUs */
1888 err = l2cap_sar_segment_sdu(sk, msg, len);
1889 if (err < 0)
1890 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001891 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001892
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001893 if (pi->mode == L2CAP_MODE_STREAMING) {
João Paulo Rechi Vita305682e2010-06-22 13:56:23 -03001894 l2cap_streaming_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001895 } else {
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001896 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY &&
1897 pi->conn_state && L2CAP_CONN_WAIT_F) {
1898 err = len;
1899 break;
1900 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001901 err = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001902 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001903
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001904 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001905 err = len;
1906 break;
1907
1908 default:
1909 BT_DBG("bad state %1.1x", pi->mode);
João Paulo Rechi Vitabc766db22010-06-22 13:56:25 -03001910 err = -EBADFD;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001911 }
1912
1913done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914 release_sock(sk);
1915 return err;
1916}
1917
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001918static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1919{
1920 struct sock *sk = sock->sk;
1921
1922 lock_sock(sk);
1923
1924 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1925 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001926 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1927 u8 buf[128];
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001928
1929 sk->sk_state = BT_CONFIG;
1930
1931 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1932 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1933 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1934 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1935 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1936 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1937
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001938 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) {
1939 release_sock(sk);
1940 return 0;
1941 }
1942
1943 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
1944 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
1945 l2cap_build_conf_req(sk, buf), buf);
1946 l2cap_pi(sk)->num_conf_req++;
1947
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001948 release_sock(sk);
1949 return 0;
1950 }
1951
1952 release_sock(sk);
1953
Mat Martineau6fdf4822010-09-08 10:05:29 -07001954 if (sock->type == SOCK_STREAM)
1955 return bt_sock_stream_recvmsg(iocb, sock, msg, len, flags);
1956
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001957 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1958}
1959
David S. Millerb7058842009-09-30 16:12:20 -07001960static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961{
1962 struct sock *sk = sock->sk;
1963 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001964 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965 u32 opt;
1966
1967 BT_DBG("sk %p", sk);
1968
1969 lock_sock(sk);
1970
1971 switch (optname) {
1972 case L2CAP_OPTIONS:
Gustavo F. Padovaneaa71b32010-10-04 19:28:52 -03001973 if (sk->sk_state == BT_CONNECTED) {
1974 err = -EINVAL;
1975 break;
1976 }
1977
Marcel Holtmann0878b662007-05-05 00:35:59 +02001978 opts.imtu = l2cap_pi(sk)->imtu;
1979 opts.omtu = l2cap_pi(sk)->omtu;
1980 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001981 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001982 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001983 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001984 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001985
Linus Torvalds1da177e2005-04-16 15:20:36 -07001986 len = min_t(unsigned int, sizeof(opts), optlen);
1987 if (copy_from_user((char *) &opts, optval, len)) {
1988 err = -EFAULT;
1989 break;
1990 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001991
Gustavo F. Padovan45d65c42010-06-07 19:21:30 -03001992 if (opts.txwin_size > L2CAP_DEFAULT_TX_WINDOW) {
1993 err = -EINVAL;
1994 break;
1995 }
1996
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001997 l2cap_pi(sk)->mode = opts.mode;
1998 switch (l2cap_pi(sk)->mode) {
1999 case L2CAP_MODE_BASIC:
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002000 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_STATE2_DEVICE;
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03002001 break;
2002 case L2CAP_MODE_ERTM:
2003 case L2CAP_MODE_STREAMING:
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03002004 if (!disable_ertm)
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03002005 break;
2006 /* fall through */
2007 default:
2008 err = -EINVAL;
2009 break;
2010 }
2011
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07002012 l2cap_pi(sk)->imtu = opts.imtu;
2013 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002014 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002015 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002016 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002017 break;
2018
2019 case L2CAP_LM:
2020 if (get_user(opt, (u32 __user *) optval)) {
2021 err = -EFAULT;
2022 break;
2023 }
2024
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002025 if (opt & L2CAP_LM_AUTH)
2026 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
2027 if (opt & L2CAP_LM_ENCRYPT)
2028 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
2029 if (opt & L2CAP_LM_SECURE)
2030 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
2031
2032 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
2033 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002034 break;
2035
2036 default:
2037 err = -ENOPROTOOPT;
2038 break;
2039 }
2040
2041 release_sock(sk);
2042 return err;
2043}
2044
David S. Millerb7058842009-09-30 16:12:20 -07002045static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002046{
2047 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002048 struct bt_security sec;
2049 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002050 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002051
2052 BT_DBG("sk %p", sk);
2053
2054 if (level == SOL_L2CAP)
2055 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
2056
Marcel Holtmann0588d942009-01-16 10:06:13 +01002057 if (level != SOL_BLUETOOTH)
2058 return -ENOPROTOOPT;
2059
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002060 lock_sock(sk);
2061
2062 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002063 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002064 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2065 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002066 err = -EINVAL;
2067 break;
2068 }
2069
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002070 sec.level = BT_SECURITY_LOW;
2071
2072 len = min_t(unsigned int, sizeof(sec), optlen);
2073 if (copy_from_user((char *) &sec, optval, len)) {
2074 err = -EFAULT;
2075 break;
2076 }
2077
2078 if (sec.level < BT_SECURITY_LOW ||
2079 sec.level > BT_SECURITY_HIGH) {
2080 err = -EINVAL;
2081 break;
2082 }
2083
2084 l2cap_pi(sk)->sec_level = sec.level;
2085 break;
2086
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002087 case BT_DEFER_SETUP:
2088 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2089 err = -EINVAL;
2090 break;
2091 }
2092
2093 if (get_user(opt, (u32 __user *) optval)) {
2094 err = -EFAULT;
2095 break;
2096 }
2097
2098 bt_sk(sk)->defer_setup = opt;
2099 break;
2100
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002101 default:
2102 err = -ENOPROTOOPT;
2103 break;
2104 }
2105
2106 release_sock(sk);
2107 return err;
2108}
2109
2110static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002111{
2112 struct sock *sk = sock->sk;
2113 struct l2cap_options opts;
2114 struct l2cap_conninfo cinfo;
2115 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002116 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002117
2118 BT_DBG("sk %p", sk);
2119
2120 if (get_user(len, optlen))
2121 return -EFAULT;
2122
2123 lock_sock(sk);
2124
2125 switch (optname) {
2126 case L2CAP_OPTIONS:
2127 opts.imtu = l2cap_pi(sk)->imtu;
2128 opts.omtu = l2cap_pi(sk)->omtu;
2129 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07002130 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002131 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002132 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002133 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002134
2135 len = min_t(unsigned int, len, sizeof(opts));
2136 if (copy_to_user(optval, (char *) &opts, len))
2137 err = -EFAULT;
2138
2139 break;
2140
2141 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002142 switch (l2cap_pi(sk)->sec_level) {
2143 case BT_SECURITY_LOW:
2144 opt = L2CAP_LM_AUTH;
2145 break;
2146 case BT_SECURITY_MEDIUM:
2147 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
2148 break;
2149 case BT_SECURITY_HIGH:
2150 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
2151 L2CAP_LM_SECURE;
2152 break;
2153 default:
2154 opt = 0;
2155 break;
2156 }
2157
2158 if (l2cap_pi(sk)->role_switch)
2159 opt |= L2CAP_LM_MASTER;
2160
2161 if (l2cap_pi(sk)->force_reliable)
2162 opt |= L2CAP_LM_RELIABLE;
2163
2164 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002165 err = -EFAULT;
2166 break;
2167
2168 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002169 if (sk->sk_state != BT_CONNECTED &&
2170 !(sk->sk_state == BT_CONNECT2 &&
2171 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002172 err = -ENOTCONN;
2173 break;
2174 }
2175
2176 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
2177 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
2178
2179 len = min_t(unsigned int, len, sizeof(cinfo));
2180 if (copy_to_user(optval, (char *) &cinfo, len))
2181 err = -EFAULT;
2182
2183 break;
2184
2185 default:
2186 err = -ENOPROTOOPT;
2187 break;
2188 }
2189
2190 release_sock(sk);
2191 return err;
2192}
2193
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002194static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
2195{
2196 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002197 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002198 int len, err = 0;
2199
2200 BT_DBG("sk %p", sk);
2201
2202 if (level == SOL_L2CAP)
2203 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
2204
Marcel Holtmann0588d942009-01-16 10:06:13 +01002205 if (level != SOL_BLUETOOTH)
2206 return -ENOPROTOOPT;
2207
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002208 if (get_user(len, optlen))
2209 return -EFAULT;
2210
2211 lock_sock(sk);
2212
2213 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002214 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002215 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2216 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002217 err = -EINVAL;
2218 break;
2219 }
2220
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002221 sec.level = l2cap_pi(sk)->sec_level;
2222
2223 len = min_t(unsigned int, len, sizeof(sec));
2224 if (copy_to_user(optval, (char *) &sec, len))
2225 err = -EFAULT;
2226
2227 break;
2228
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002229 case BT_DEFER_SETUP:
2230 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2231 err = -EINVAL;
2232 break;
2233 }
2234
2235 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2236 err = -EFAULT;
2237
2238 break;
2239
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002240 default:
2241 err = -ENOPROTOOPT;
2242 break;
2243 }
2244
2245 release_sock(sk);
2246 return err;
2247}
2248
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249static int l2cap_sock_shutdown(struct socket *sock, int how)
2250{
2251 struct sock *sk = sock->sk;
2252 int err = 0;
2253
2254 BT_DBG("sock %p, sk %p", sock, sk);
2255
2256 if (!sk)
2257 return 0;
2258
2259 lock_sock(sk);
2260 if (!sk->sk_shutdown) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03002261 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2262 err = __l2cap_wait_ack(sk);
2263
Linus Torvalds1da177e2005-04-16 15:20:36 -07002264 sk->sk_shutdown = SHUTDOWN_MASK;
2265 l2cap_sock_clear_timer(sk);
2266 __l2cap_sock_close(sk, 0);
2267
2268 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002269 err = bt_sock_wait_state(sk, BT_CLOSED,
2270 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002271 }
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002272
2273 if (!err && sk->sk_err)
2274 err = -sk->sk_err;
2275
Linus Torvalds1da177e2005-04-16 15:20:36 -07002276 release_sock(sk);
2277 return err;
2278}
2279
2280static int l2cap_sock_release(struct socket *sock)
2281{
2282 struct sock *sk = sock->sk;
2283 int err;
2284
2285 BT_DBG("sock %p, sk %p", sock, sk);
2286
2287 if (!sk)
2288 return 0;
2289
2290 err = l2cap_sock_shutdown(sock, 2);
2291
2292 sock_orphan(sk);
2293 l2cap_sock_kill(sk);
2294 return err;
2295}
2296
Linus Torvalds1da177e2005-04-16 15:20:36 -07002297static void l2cap_chan_ready(struct sock *sk)
2298{
2299 struct sock *parent = bt_sk(sk)->parent;
2300
2301 BT_DBG("sk %p, parent %p", sk, parent);
2302
2303 l2cap_pi(sk)->conf_state = 0;
2304 l2cap_sock_clear_timer(sk);
2305
2306 if (!parent) {
2307 /* Outgoing channel.
2308 * Wake up socket sleeping on connect.
2309 */
2310 sk->sk_state = BT_CONNECTED;
2311 sk->sk_state_change(sk);
2312 } else {
2313 /* Incoming channel.
2314 * Wake up socket sleeping on accept.
2315 */
2316 parent->sk_data_ready(parent, 0);
2317 }
2318}
2319
2320/* Copy frame to all raw sockets on that connection */
2321static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2322{
2323 struct l2cap_chan_list *l = &conn->chan_list;
2324 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002325 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002326
2327 BT_DBG("conn %p", conn);
2328
2329 read_lock(&l->lock);
2330 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2331 if (sk->sk_type != SOCK_RAW)
2332 continue;
2333
2334 /* Don't send frame to the socket it came from */
2335 if (skb->sk == sk)
2336 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002337 nskb = skb_clone(skb, GFP_ATOMIC);
2338 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002339 continue;
2340
2341 if (sock_queue_rcv_skb(sk, nskb))
2342 kfree_skb(nskb);
2343 }
2344 read_unlock(&l->lock);
2345}
2346
2347/* ---- L2CAP signalling commands ---- */
2348static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2349 u8 code, u8 ident, u16 dlen, void *data)
2350{
2351 struct sk_buff *skb, **frag;
2352 struct l2cap_cmd_hdr *cmd;
2353 struct l2cap_hdr *lh;
2354 int len, count;
2355
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002356 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2357 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002358
2359 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2360 count = min_t(unsigned int, conn->mtu, len);
2361
2362 skb = bt_skb_alloc(count, GFP_ATOMIC);
2363 if (!skb)
2364 return NULL;
2365
2366 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002367 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002368 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002369
2370 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2371 cmd->code = code;
2372 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002373 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002374
2375 if (dlen) {
2376 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2377 memcpy(skb_put(skb, count), data, count);
2378 data += count;
2379 }
2380
2381 len -= skb->len;
2382
2383 /* Continuation fragments (no L2CAP header) */
2384 frag = &skb_shinfo(skb)->frag_list;
2385 while (len) {
2386 count = min_t(unsigned int, conn->mtu, len);
2387
2388 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2389 if (!*frag)
2390 goto fail;
2391
2392 memcpy(skb_put(*frag, count), data, count);
2393
2394 len -= count;
2395 data += count;
2396
2397 frag = &(*frag)->next;
2398 }
2399
2400 return skb;
2401
2402fail:
2403 kfree_skb(skb);
2404 return NULL;
2405}
2406
2407static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2408{
2409 struct l2cap_conf_opt *opt = *ptr;
2410 int len;
2411
2412 len = L2CAP_CONF_OPT_SIZE + opt->len;
2413 *ptr += len;
2414
2415 *type = opt->type;
2416 *olen = opt->len;
2417
2418 switch (opt->len) {
2419 case 1:
2420 *val = *((u8 *) opt->val);
2421 break;
2422
2423 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002424 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002425 break;
2426
2427 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002428 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002429 break;
2430
2431 default:
2432 *val = (unsigned long) opt->val;
2433 break;
2434 }
2435
2436 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2437 return len;
2438}
2439
Linus Torvalds1da177e2005-04-16 15:20:36 -07002440static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2441{
2442 struct l2cap_conf_opt *opt = *ptr;
2443
2444 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2445
2446 opt->type = type;
2447 opt->len = len;
2448
2449 switch (len) {
2450 case 1:
2451 *((u8 *) opt->val) = val;
2452 break;
2453
2454 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002455 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002456 break;
2457
2458 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002459 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002460 break;
2461
2462 default:
2463 memcpy(opt->val, (void *) val, len);
2464 break;
2465 }
2466
2467 *ptr += L2CAP_CONF_OPT_SIZE + len;
2468}
2469
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002470static void l2cap_ack_timeout(unsigned long arg)
2471{
2472 struct sock *sk = (void *) arg;
2473
2474 bh_lock_sock(sk);
2475 l2cap_send_ack(l2cap_pi(sk));
2476 bh_unlock_sock(sk);
2477}
2478
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002479static inline void l2cap_ertm_init(struct sock *sk)
2480{
2481 l2cap_pi(sk)->expected_ack_seq = 0;
2482 l2cap_pi(sk)->unacked_frames = 0;
2483 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002484 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002485 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002486
2487 setup_timer(&l2cap_pi(sk)->retrans_timer,
2488 l2cap_retrans_timeout, (unsigned long) sk);
2489 setup_timer(&l2cap_pi(sk)->monitor_timer,
2490 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002491 setup_timer(&l2cap_pi(sk)->ack_timer,
2492 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002493
2494 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002495 __skb_queue_head_init(BUSY_QUEUE(sk));
2496
2497 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03002498
2499 sk->sk_backlog_rcv = l2cap_ertm_data_rcv;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002500}
2501
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002502static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2503{
2504 switch (mode) {
2505 case L2CAP_MODE_STREAMING:
2506 case L2CAP_MODE_ERTM:
2507 if (l2cap_mode_supported(mode, remote_feat_mask))
2508 return mode;
2509 /* fall through */
2510 default:
2511 return L2CAP_MODE_BASIC;
2512 }
2513}
2514
Linus Torvalds1da177e2005-04-16 15:20:36 -07002515static int l2cap_build_conf_req(struct sock *sk, void *data)
2516{
2517 struct l2cap_pinfo *pi = l2cap_pi(sk);
2518 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002519 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002520 void *ptr = req->data;
2521
2522 BT_DBG("sk %p", sk);
2523
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002524 if (pi->num_conf_req || pi->num_conf_rsp)
2525 goto done;
2526
2527 switch (pi->mode) {
2528 case L2CAP_MODE_STREAMING:
2529 case L2CAP_MODE_ERTM:
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002530 if (pi->conf_state & L2CAP_CONF_STATE2_DEVICE)
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002531 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002532
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002533 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002534 default:
2535 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2536 break;
2537 }
2538
2539done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002540 switch (pi->mode) {
2541 case L2CAP_MODE_BASIC:
2542 if (pi->imtu != L2CAP_DEFAULT_MTU)
2543 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002544
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002545 if (!(pi->conn->feat_mask & L2CAP_FEAT_ERTM) &&
2546 !(pi->conn->feat_mask & L2CAP_FEAT_STREAMING))
2547 break;
2548
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002549 rfc.mode = L2CAP_MODE_BASIC;
2550 rfc.txwin_size = 0;
2551 rfc.max_transmit = 0;
2552 rfc.retrans_timeout = 0;
2553 rfc.monitor_timeout = 0;
2554 rfc.max_pdu_size = 0;
2555
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002556 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2557 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002558 break;
2559
2560 case L2CAP_MODE_ERTM:
2561 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002562 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002563 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002564 rfc.retrans_timeout = 0;
2565 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002566 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002567 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002568 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002569
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002570 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2571 (unsigned long) &rfc);
2572
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002573 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2574 break;
2575
2576 if (pi->fcs == L2CAP_FCS_NONE ||
2577 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2578 pi->fcs = L2CAP_FCS_NONE;
2579 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2580 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002581 break;
2582
2583 case L2CAP_MODE_STREAMING:
2584 rfc.mode = L2CAP_MODE_STREAMING;
2585 rfc.txwin_size = 0;
2586 rfc.max_transmit = 0;
2587 rfc.retrans_timeout = 0;
2588 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002589 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002590 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002591 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002592
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002593 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2594 (unsigned long) &rfc);
2595
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002596 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2597 break;
2598
2599 if (pi->fcs == L2CAP_FCS_NONE ||
2600 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2601 pi->fcs = L2CAP_FCS_NONE;
2602 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2603 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002604 break;
2605 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002606
2607 /* FIXME: Need actual value of the flush timeout */
2608 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2609 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2610
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002611 req->dcid = cpu_to_le16(pi->dcid);
2612 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002613
2614 return ptr - data;
2615}
2616
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002617static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002618{
2619 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002620 struct l2cap_conf_rsp *rsp = data;
2621 void *ptr = rsp->data;
2622 void *req = pi->conf_req;
2623 int len = pi->conf_len;
2624 int type, hint, olen;
2625 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002626 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002627 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002628 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002629
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002630 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002631
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002632 while (len >= L2CAP_CONF_OPT_SIZE) {
2633 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002634
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002635 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002636 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002637
2638 switch (type) {
2639 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002640 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002641 break;
2642
2643 case L2CAP_CONF_FLUSH_TO:
2644 pi->flush_to = val;
2645 break;
2646
2647 case L2CAP_CONF_QOS:
2648 break;
2649
Marcel Holtmann6464f352007-10-20 13:39:51 +02002650 case L2CAP_CONF_RFC:
2651 if (olen == sizeof(rfc))
2652 memcpy(&rfc, (void *) val, olen);
2653 break;
2654
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002655 case L2CAP_CONF_FCS:
2656 if (val == L2CAP_FCS_NONE)
2657 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2658
2659 break;
2660
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002661 default:
2662 if (hint)
2663 break;
2664
2665 result = L2CAP_CONF_UNKNOWN;
2666 *((u8 *) ptr++) = type;
2667 break;
2668 }
2669 }
2670
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002671 if (pi->num_conf_rsp || pi->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002672 goto done;
2673
2674 switch (pi->mode) {
2675 case L2CAP_MODE_STREAMING:
2676 case L2CAP_MODE_ERTM:
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002677 if (!(pi->conf_state & L2CAP_CONF_STATE2_DEVICE)) {
2678 pi->mode = l2cap_select_mode(rfc.mode,
2679 pi->conn->feat_mask);
2680 break;
2681 }
2682
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03002683 if (pi->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002684 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03002685
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002686 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002687 }
2688
2689done:
2690 if (pi->mode != rfc.mode) {
2691 result = L2CAP_CONF_UNACCEPT;
2692 rfc.mode = pi->mode;
2693
2694 if (pi->num_conf_rsp == 1)
2695 return -ECONNREFUSED;
2696
2697 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2698 sizeof(rfc), (unsigned long) &rfc);
2699 }
2700
2701
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002702 if (result == L2CAP_CONF_SUCCESS) {
2703 /* Configure output options and let the other side know
2704 * which ones we don't like. */
2705
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002706 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2707 result = L2CAP_CONF_UNACCEPT;
2708 else {
2709 pi->omtu = mtu;
2710 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2711 }
2712 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002713
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002714 switch (rfc.mode) {
2715 case L2CAP_MODE_BASIC:
2716 pi->fcs = L2CAP_FCS_NONE;
2717 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2718 break;
2719
2720 case L2CAP_MODE_ERTM:
2721 pi->remote_tx_win = rfc.txwin_size;
2722 pi->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07002723
2724 if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
2725 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002726
2727 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002728
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002729 rfc.retrans_timeout =
2730 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2731 rfc.monitor_timeout =
2732 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002733
2734 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002735
2736 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2737 sizeof(rfc), (unsigned long) &rfc);
2738
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002739 break;
2740
2741 case L2CAP_MODE_STREAMING:
Mat Martineau86b1b262010-08-05 15:54:22 -07002742 if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
2743 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002744
2745 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002746
2747 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002748
2749 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2750 sizeof(rfc), (unsigned long) &rfc);
2751
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002752 break;
2753
2754 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002755 result = L2CAP_CONF_UNACCEPT;
2756
2757 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002758 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002759 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002760
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002761 if (result == L2CAP_CONF_SUCCESS)
2762 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2763 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002764 rsp->scid = cpu_to_le16(pi->dcid);
2765 rsp->result = cpu_to_le16(result);
2766 rsp->flags = cpu_to_le16(0x0000);
2767
2768 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002769}
2770
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002771static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2772{
2773 struct l2cap_pinfo *pi = l2cap_pi(sk);
2774 struct l2cap_conf_req *req = data;
2775 void *ptr = req->data;
2776 int type, olen;
2777 unsigned long val;
2778 struct l2cap_conf_rfc rfc;
2779
2780 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2781
2782 while (len >= L2CAP_CONF_OPT_SIZE) {
2783 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2784
2785 switch (type) {
2786 case L2CAP_CONF_MTU:
2787 if (val < L2CAP_DEFAULT_MIN_MTU) {
2788 *result = L2CAP_CONF_UNACCEPT;
Andrei Emeltchenko8183b772010-09-01 15:17:25 +03002789 pi->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002790 } else
Andrei Emeltchenko8183b772010-09-01 15:17:25 +03002791 pi->imtu = val;
2792 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002793 break;
2794
2795 case L2CAP_CONF_FLUSH_TO:
2796 pi->flush_to = val;
2797 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2798 2, pi->flush_to);
2799 break;
2800
2801 case L2CAP_CONF_RFC:
2802 if (olen == sizeof(rfc))
2803 memcpy(&rfc, (void *)val, olen);
2804
2805 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2806 rfc.mode != pi->mode)
2807 return -ECONNREFUSED;
2808
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002809 pi->fcs = 0;
2810
2811 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2812 sizeof(rfc), (unsigned long) &rfc);
2813 break;
2814 }
2815 }
2816
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03002817 if (pi->mode == L2CAP_MODE_BASIC && pi->mode != rfc.mode)
2818 return -ECONNREFUSED;
2819
2820 pi->mode = rfc.mode;
2821
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002822 if (*result == L2CAP_CONF_SUCCESS) {
2823 switch (rfc.mode) {
2824 case L2CAP_MODE_ERTM:
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002825 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2826 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002827 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002828 break;
2829 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002830 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002831 }
2832 }
2833
2834 req->dcid = cpu_to_le16(pi->dcid);
2835 req->flags = cpu_to_le16(0x0000);
2836
2837 return ptr - data;
2838}
2839
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002840static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002841{
2842 struct l2cap_conf_rsp *rsp = data;
2843 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002844
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002845 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002846
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002847 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002848 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002849 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002850
2851 return ptr - data;
2852}
2853
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002854static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2855{
2856 struct l2cap_pinfo *pi = l2cap_pi(sk);
2857 int type, olen;
2858 unsigned long val;
2859 struct l2cap_conf_rfc rfc;
2860
2861 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2862
2863 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2864 return;
2865
2866 while (len >= L2CAP_CONF_OPT_SIZE) {
2867 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2868
2869 switch (type) {
2870 case L2CAP_CONF_RFC:
2871 if (olen == sizeof(rfc))
2872 memcpy(&rfc, (void *)val, olen);
2873 goto done;
2874 }
2875 }
2876
2877done:
2878 switch (rfc.mode) {
2879 case L2CAP_MODE_ERTM:
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002880 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2881 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002882 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2883 break;
2884 case L2CAP_MODE_STREAMING:
2885 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2886 }
2887}
2888
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002889static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2890{
2891 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2892
2893 if (rej->reason != 0x0000)
2894 return 0;
2895
2896 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2897 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002898 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002899
2900 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002901 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002902
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002903 l2cap_conn_start(conn);
2904 }
2905
2906 return 0;
2907}
2908
Linus Torvalds1da177e2005-04-16 15:20:36 -07002909static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2910{
2911 struct l2cap_chan_list *list = &conn->chan_list;
2912 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2913 struct l2cap_conn_rsp rsp;
Nathan Holsteind793fe82010-10-15 11:54:02 -04002914 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002915 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002916
2917 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002918 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002919
2920 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2921
2922 /* Check if we have socket listening on psm */
2923 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2924 if (!parent) {
2925 result = L2CAP_CR_BAD_PSM;
2926 goto sendresp;
2927 }
2928
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00002929 bh_lock_sock(parent);
2930
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002931 /* Check if the ACL is secure enough (if not SDP) */
2932 if (psm != cpu_to_le16(0x0001) &&
2933 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002934 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002935 result = L2CAP_CR_SEC_BLOCK;
2936 goto response;
2937 }
2938
Linus Torvalds1da177e2005-04-16 15:20:36 -07002939 result = L2CAP_CR_NO_MEM;
2940
2941 /* Check for backlog size */
2942 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002943 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002944 goto response;
2945 }
2946
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002947 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002948 if (!sk)
2949 goto response;
2950
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002951 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002952
2953 /* Check if we already have channel with that dcid */
2954 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002955 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002956 sock_set_flag(sk, SOCK_ZAPPED);
2957 l2cap_sock_kill(sk);
2958 goto response;
2959 }
2960
2961 hci_conn_hold(conn->hcon);
2962
2963 l2cap_sock_init(sk, parent);
2964 bacpy(&bt_sk(sk)->src, conn->src);
2965 bacpy(&bt_sk(sk)->dst, conn->dst);
2966 l2cap_pi(sk)->psm = psm;
2967 l2cap_pi(sk)->dcid = scid;
2968
2969 __l2cap_chan_add(conn, sk, parent);
2970 dcid = l2cap_pi(sk)->scid;
2971
2972 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2973
Linus Torvalds1da177e2005-04-16 15:20:36 -07002974 l2cap_pi(sk)->ident = cmd->ident;
2975
Marcel Holtmann984947d2009-02-06 23:35:19 +01002976 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002977 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002978 if (bt_sk(sk)->defer_setup) {
2979 sk->sk_state = BT_CONNECT2;
2980 result = L2CAP_CR_PEND;
2981 status = L2CAP_CS_AUTHOR_PEND;
2982 parent->sk_data_ready(parent, 0);
2983 } else {
2984 sk->sk_state = BT_CONFIG;
2985 result = L2CAP_CR_SUCCESS;
2986 status = L2CAP_CS_NO_INFO;
2987 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002988 } else {
2989 sk->sk_state = BT_CONNECT2;
2990 result = L2CAP_CR_PEND;
2991 status = L2CAP_CS_AUTHEN_PEND;
2992 }
2993 } else {
2994 sk->sk_state = BT_CONNECT2;
2995 result = L2CAP_CR_PEND;
2996 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002997 }
2998
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002999 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003000
3001response:
3002 bh_unlock_sock(parent);
3003
3004sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003005 rsp.scid = cpu_to_le16(scid);
3006 rsp.dcid = cpu_to_le16(dcid);
3007 rsp.result = cpu_to_le16(result);
3008 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003009 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003010
3011 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3012 struct l2cap_info_req info;
3013 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3014
3015 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3016 conn->info_ident = l2cap_get_ident(conn);
3017
3018 mod_timer(&conn->info_timer, jiffies +
3019 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
3020
3021 l2cap_send_cmd(conn, conn->info_ident,
3022 L2CAP_INFO_REQ, sizeof(info), &info);
3023 }
3024
Nathan Holsteind793fe82010-10-15 11:54:02 -04003025 if (sk && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) &&
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003026 result == L2CAP_CR_SUCCESS) {
3027 u8 buf[128];
3028 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
3029 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3030 l2cap_build_conf_req(sk, buf), buf);
3031 l2cap_pi(sk)->num_conf_req++;
3032 }
3033
Linus Torvalds1da177e2005-04-16 15:20:36 -07003034 return 0;
3035}
3036
3037static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3038{
3039 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3040 u16 scid, dcid, result, status;
3041 struct sock *sk;
3042 u8 req[128];
3043
3044 scid = __le16_to_cpu(rsp->scid);
3045 dcid = __le16_to_cpu(rsp->dcid);
3046 result = __le16_to_cpu(rsp->result);
3047 status = __le16_to_cpu(rsp->status);
3048
3049 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
3050
3051 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003052 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3053 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03003054 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003055 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003056 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
3057 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03003058 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003059 }
3060
3061 switch (result) {
3062 case L2CAP_CR_SUCCESS:
3063 sk->sk_state = BT_CONFIG;
3064 l2cap_pi(sk)->ident = 0;
3065 l2cap_pi(sk)->dcid = dcid;
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003066 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
3067
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003068 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)
3069 break;
3070
3071 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
3072
Linus Torvalds1da177e2005-04-16 15:20:36 -07003073 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3074 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003075 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003076 break;
3077
3078 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003079 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003080 break;
3081
3082 default:
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02003083 /* don't delete l2cap channel if sk is owned by user */
3084 if (sock_owned_by_user(sk)) {
3085 sk->sk_state = BT_DISCONN;
3086 l2cap_sock_clear_timer(sk);
3087 l2cap_sock_set_timer(sk, HZ / 5);
3088 break;
3089 }
3090
Linus Torvalds1da177e2005-04-16 15:20:36 -07003091 l2cap_chan_del(sk, ECONNREFUSED);
3092 break;
3093 }
3094
3095 bh_unlock_sock(sk);
3096 return 0;
3097}
3098
Mat Martineau8c462b62010-08-24 15:35:42 -07003099static inline void set_default_fcs(struct l2cap_pinfo *pi)
3100{
3101 /* FCS is enabled only in ERTM or streaming mode, if one or both
3102 * sides request it.
3103 */
3104 if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING)
3105 pi->fcs = L2CAP_FCS_NONE;
3106 else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV))
3107 pi->fcs = L2CAP_FCS_CRC16;
3108}
3109
Al Viro88219a02007-07-29 00:17:25 -07003110static 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 -07003111{
3112 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3113 u16 dcid, flags;
3114 u8 rsp[64];
3115 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003116 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003117
3118 dcid = __le16_to_cpu(req->dcid);
3119 flags = __le16_to_cpu(req->flags);
3120
3121 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3122
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003123 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3124 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003125 return -ENOENT;
3126
Gustavo F. Padovanb0239c82010-09-08 14:59:44 -03003127 if (sk->sk_state == BT_DISCONN)
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003128 goto unlock;
3129
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003130 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003131 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003132 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
3133 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
3134 l2cap_build_conf_rsp(sk, rsp,
3135 L2CAP_CONF_REJECT, flags), rsp);
3136 goto unlock;
3137 }
3138
3139 /* Store config. */
3140 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
3141 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003142
3143 if (flags & 0x0001) {
3144 /* Incomplete config. Send empty response. */
3145 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003146 l2cap_build_conf_rsp(sk, rsp,
3147 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003148 goto unlock;
3149 }
3150
3151 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003152 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003153 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003154 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003155 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003156 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003157
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003158 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003159 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003160
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003161 /* Reset config buffer. */
3162 l2cap_pi(sk)->conf_len = 0;
3163
Marcel Holtmann876d9482007-10-20 13:35:42 +02003164 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
3165 goto unlock;
3166
Linus Torvalds1da177e2005-04-16 15:20:36 -07003167 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Mat Martineau8c462b62010-08-24 15:35:42 -07003168 set_default_fcs(l2cap_pi(sk));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003169
Linus Torvalds1da177e2005-04-16 15:20:36 -07003170 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003171
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003172 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003173 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003174 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003175 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3176 l2cap_ertm_init(sk);
3177
Linus Torvalds1da177e2005-04-16 15:20:36 -07003178 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02003179 goto unlock;
3180 }
3181
3182 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003183 u8 buf[64];
Haijun Liuab3e5712010-09-30 16:52:40 +08003184 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003185 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003186 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003187 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003188 }
3189
3190unlock:
3191 bh_unlock_sock(sk);
3192 return 0;
3193}
3194
3195static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3196{
3197 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3198 u16 scid, flags, result;
3199 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003200 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003201
3202 scid = __le16_to_cpu(rsp->scid);
3203 flags = __le16_to_cpu(rsp->flags);
3204 result = __le16_to_cpu(rsp->result);
3205
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003206 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
3207 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003208
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003209 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3210 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003211 return 0;
3212
3213 switch (result) {
3214 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003215 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003216 break;
3217
3218 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003219 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003220 char req[64];
3221
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003222 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003223 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003224 goto done;
3225 }
3226
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003227 /* throw out any old stored conf requests */
3228 result = L2CAP_CONF_SUCCESS;
3229 len = l2cap_parse_conf_rsp(sk, rsp->data,
3230 len, req, &result);
3231 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003232 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003233 goto done;
3234 }
3235
3236 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3237 L2CAP_CONF_REQ, len, req);
3238 l2cap_pi(sk)->num_conf_req++;
3239 if (result != L2CAP_CONF_SUCCESS)
3240 goto done;
3241 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003242 }
3243
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003244 default:
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003245 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003246 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003247 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003248 goto done;
3249 }
3250
3251 if (flags & 0x01)
3252 goto done;
3253
Linus Torvalds1da177e2005-04-16 15:20:36 -07003254 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3255
3256 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Mat Martineau8c462b62010-08-24 15:35:42 -07003257 set_default_fcs(l2cap_pi(sk));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003258
Linus Torvalds1da177e2005-04-16 15:20:36 -07003259 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003260 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003261 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003262 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003263 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3264 l2cap_ertm_init(sk);
3265
Linus Torvalds1da177e2005-04-16 15:20:36 -07003266 l2cap_chan_ready(sk);
3267 }
3268
3269done:
3270 bh_unlock_sock(sk);
3271 return 0;
3272}
3273
3274static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3275{
3276 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3277 struct l2cap_disconn_rsp rsp;
3278 u16 dcid, scid;
3279 struct sock *sk;
3280
3281 scid = __le16_to_cpu(req->scid);
3282 dcid = __le16_to_cpu(req->dcid);
3283
3284 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3285
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003286 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3287 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003288 return 0;
3289
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003290 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3291 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003292 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3293
3294 sk->sk_shutdown = SHUTDOWN_MASK;
3295
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02003296 /* don't delete l2cap channel if sk is owned by user */
3297 if (sock_owned_by_user(sk)) {
3298 sk->sk_state = BT_DISCONN;
3299 l2cap_sock_clear_timer(sk);
3300 l2cap_sock_set_timer(sk, HZ / 5);
3301 bh_unlock_sock(sk);
3302 return 0;
3303 }
3304
Linus Torvalds1da177e2005-04-16 15:20:36 -07003305 l2cap_chan_del(sk, ECONNRESET);
3306 bh_unlock_sock(sk);
3307
3308 l2cap_sock_kill(sk);
3309 return 0;
3310}
3311
3312static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3313{
3314 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3315 u16 dcid, scid;
3316 struct sock *sk;
3317
3318 scid = __le16_to_cpu(rsp->scid);
3319 dcid = __le16_to_cpu(rsp->dcid);
3320
3321 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3322
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003323 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3324 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003325 return 0;
3326
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02003327 /* don't delete l2cap channel if sk is owned by user */
3328 if (sock_owned_by_user(sk)) {
3329 sk->sk_state = BT_DISCONN;
3330 l2cap_sock_clear_timer(sk);
3331 l2cap_sock_set_timer(sk, HZ / 5);
3332 bh_unlock_sock(sk);
3333 return 0;
3334 }
3335
Linus Torvalds1da177e2005-04-16 15:20:36 -07003336 l2cap_chan_del(sk, 0);
3337 bh_unlock_sock(sk);
3338
3339 l2cap_sock_kill(sk);
3340 return 0;
3341}
3342
3343static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3344{
3345 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003346 u16 type;
3347
3348 type = __le16_to_cpu(req->type);
3349
3350 BT_DBG("type 0x%4.4x", type);
3351
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003352 if (type == L2CAP_IT_FEAT_MASK) {
3353 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003354 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003355 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3356 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3357 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03003358 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003359 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3360 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003361 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003362 l2cap_send_cmd(conn, cmd->ident,
3363 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003364 } else if (type == L2CAP_IT_FIXED_CHAN) {
3365 u8 buf[12];
3366 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3367 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3368 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3369 memcpy(buf + 4, l2cap_fixed_chan, 8);
3370 l2cap_send_cmd(conn, cmd->ident,
3371 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003372 } else {
3373 struct l2cap_info_rsp rsp;
3374 rsp.type = cpu_to_le16(type);
3375 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3376 l2cap_send_cmd(conn, cmd->ident,
3377 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3378 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003379
3380 return 0;
3381}
3382
3383static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3384{
3385 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3386 u16 type, result;
3387
3388 type = __le16_to_cpu(rsp->type);
3389 result = __le16_to_cpu(rsp->result);
3390
3391 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3392
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003393 del_timer(&conn->info_timer);
3394
Ville Tervoadb08ed2010-08-04 09:43:33 +03003395 if (result != L2CAP_IR_SUCCESS) {
3396 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3397 conn->info_ident = 0;
3398
3399 l2cap_conn_start(conn);
3400
3401 return 0;
3402 }
3403
Marcel Holtmann984947d2009-02-06 23:35:19 +01003404 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003405 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003406
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003407 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003408 struct l2cap_info_req req;
3409 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3410
3411 conn->info_ident = l2cap_get_ident(conn);
3412
3413 l2cap_send_cmd(conn, conn->info_ident,
3414 L2CAP_INFO_REQ, sizeof(req), &req);
3415 } else {
3416 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3417 conn->info_ident = 0;
3418
3419 l2cap_conn_start(conn);
3420 }
3421 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003422 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003423 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003424
3425 l2cap_conn_start(conn);
3426 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003427
Linus Torvalds1da177e2005-04-16 15:20:36 -07003428 return 0;
3429}
3430
3431static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3432{
3433 u8 *data = skb->data;
3434 int len = skb->len;
3435 struct l2cap_cmd_hdr cmd;
3436 int err = 0;
3437
3438 l2cap_raw_recv(conn, skb);
3439
3440 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003441 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003442 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3443 data += L2CAP_CMD_HDR_SIZE;
3444 len -= L2CAP_CMD_HDR_SIZE;
3445
Al Viro88219a02007-07-29 00:17:25 -07003446 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003447
Al Viro88219a02007-07-29 00:17:25 -07003448 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 -07003449
Al Viro88219a02007-07-29 00:17:25 -07003450 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003451 BT_DBG("corrupted command");
3452 break;
3453 }
3454
3455 switch (cmd.code) {
3456 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003457 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003458 break;
3459
3460 case L2CAP_CONN_REQ:
3461 err = l2cap_connect_req(conn, &cmd, data);
3462 break;
3463
3464 case L2CAP_CONN_RSP:
3465 err = l2cap_connect_rsp(conn, &cmd, data);
3466 break;
3467
3468 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003469 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003470 break;
3471
3472 case L2CAP_CONF_RSP:
3473 err = l2cap_config_rsp(conn, &cmd, data);
3474 break;
3475
3476 case L2CAP_DISCONN_REQ:
3477 err = l2cap_disconnect_req(conn, &cmd, data);
3478 break;
3479
3480 case L2CAP_DISCONN_RSP:
3481 err = l2cap_disconnect_rsp(conn, &cmd, data);
3482 break;
3483
3484 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003485 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003486 break;
3487
3488 case L2CAP_ECHO_RSP:
3489 break;
3490
3491 case L2CAP_INFO_REQ:
3492 err = l2cap_information_req(conn, &cmd, data);
3493 break;
3494
3495 case L2CAP_INFO_RSP:
3496 err = l2cap_information_rsp(conn, &cmd, data);
3497 break;
3498
3499 default:
3500 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3501 err = -EINVAL;
3502 break;
3503 }
3504
3505 if (err) {
3506 struct l2cap_cmd_rej rej;
3507 BT_DBG("error %d", err);
3508
3509 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003510 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003511 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3512 }
3513
Al Viro88219a02007-07-29 00:17:25 -07003514 data += cmd_len;
3515 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003516 }
3517
3518 kfree_skb(skb);
3519}
3520
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003521static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3522{
3523 u16 our_fcs, rcv_fcs;
3524 int hdr_size = L2CAP_HDR_SIZE + 2;
3525
3526 if (pi->fcs == L2CAP_FCS_CRC16) {
3527 skb_trim(skb, skb->len - 2);
3528 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3529 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3530
3531 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03003532 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003533 }
3534 return 0;
3535}
3536
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003537static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3538{
3539 struct l2cap_pinfo *pi = l2cap_pi(sk);
3540 u16 control = 0;
3541
3542 pi->frames_sent = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003543
3544 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3545
3546 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan64988862010-05-10 14:54:14 -03003547 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003548 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003549 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003550 }
3551
Gustavo F. Padovan4ea727e2010-06-03 16:34:20 -03003552 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY)
3553 l2cap_retransmit_frames(sk);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003554
3555 l2cap_ertm_send(sk);
3556
3557 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3558 pi->frames_sent == 0) {
3559 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003560 l2cap_send_sframe(pi, control);
3561 }
3562}
3563
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003564static 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 -03003565{
3566 struct sk_buff *next_skb;
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003567 struct l2cap_pinfo *pi = l2cap_pi(sk);
3568 int tx_seq_offset, next_tx_seq_offset;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003569
3570 bt_cb(skb)->tx_seq = tx_seq;
3571 bt_cb(skb)->sar = sar;
3572
3573 next_skb = skb_peek(SREJ_QUEUE(sk));
3574 if (!next_skb) {
3575 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003576 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003577 }
3578
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003579 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3580 if (tx_seq_offset < 0)
3581 tx_seq_offset += 64;
3582
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003583 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003584 if (bt_cb(next_skb)->tx_seq == tx_seq)
3585 return -EINVAL;
3586
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003587 next_tx_seq_offset = (bt_cb(next_skb)->tx_seq -
3588 pi->buffer_seq) % 64;
3589 if (next_tx_seq_offset < 0)
3590 next_tx_seq_offset += 64;
3591
3592 if (next_tx_seq_offset > tx_seq_offset) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003593 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003594 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003595 }
3596
3597 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3598 break;
3599
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003600 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003601
3602 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003603
3604 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003605}
3606
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003607static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3608{
3609 struct l2cap_pinfo *pi = l2cap_pi(sk);
3610 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003611 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003612
3613 switch (control & L2CAP_CTRL_SAR) {
3614 case L2CAP_SDU_UNSEGMENTED:
3615 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3616 goto drop;
3617
3618 err = sock_queue_rcv_skb(sk, skb);
3619 if (!err)
3620 return err;
3621
3622 break;
3623
3624 case L2CAP_SDU_START:
3625 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3626 goto drop;
3627
3628 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003629
3630 if (pi->sdu_len > pi->imtu)
3631 goto disconnect;
3632
3633 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003634 if (!pi->sdu)
3635 return -ENOMEM;
3636
3637 /* pull sdu_len bytes only after alloc, because of Local Busy
3638 * condition we have to be sure that this will be executed
3639 * only once, i.e., when alloc does not fail */
3640 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003641
3642 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3643
3644 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3645 pi->partial_sdu_len = skb->len;
3646 break;
3647
3648 case L2CAP_SDU_CONTINUE:
3649 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3650 goto disconnect;
3651
3652 if (!pi->sdu)
3653 goto disconnect;
3654
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003655 pi->partial_sdu_len += skb->len;
3656 if (pi->partial_sdu_len > pi->sdu_len)
3657 goto drop;
3658
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003659 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3660
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003661 break;
3662
3663 case L2CAP_SDU_END:
3664 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3665 goto disconnect;
3666
3667 if (!pi->sdu)
3668 goto disconnect;
3669
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003670 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003671 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003672
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003673 if (pi->partial_sdu_len > pi->imtu)
3674 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003675
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003676 if (pi->partial_sdu_len != pi->sdu_len)
3677 goto drop;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003678
3679 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003680 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003681
3682 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003683 if (!_skb) {
3684 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3685 return -ENOMEM;
3686 }
3687
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003688 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003689 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003690 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003691 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3692 return err;
3693 }
3694
3695 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
3696 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003697
3698 kfree_skb(pi->sdu);
3699 break;
3700 }
3701
3702 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003703 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003704
3705drop:
3706 kfree_skb(pi->sdu);
3707 pi->sdu = NULL;
3708
3709disconnect:
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003710 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003711 kfree_skb(skb);
3712 return 0;
3713}
3714
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003715static int l2cap_try_push_rx_skb(struct sock *sk)
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003716{
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003717 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003718 struct sk_buff *skb;
3719 u16 control;
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003720 int err;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003721
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003722 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
3723 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3724 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3725 if (err < 0) {
3726 skb_queue_head(BUSY_QUEUE(sk), skb);
3727 return -EBUSY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003728 }
3729
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003730 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003731 }
3732
3733 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
3734 goto done;
3735
3736 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3737 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
3738 l2cap_send_sframe(pi, control);
3739 l2cap_pi(sk)->retry_count = 1;
3740
3741 del_timer(&pi->retrans_timer);
3742 __mod_monitor_timer();
3743
3744 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
3745
3746done:
3747 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
3748 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
3749
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003750 BT_DBG("sk %p, Exit local busy", sk);
3751
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003752 return 0;
3753}
3754
3755static void l2cap_busy_work(struct work_struct *work)
3756{
3757 DECLARE_WAITQUEUE(wait, current);
3758 struct l2cap_pinfo *pi =
3759 container_of(work, struct l2cap_pinfo, busy_work);
3760 struct sock *sk = (struct sock *)pi;
3761 int n_tries = 0, timeo = HZ/5, err;
3762 struct sk_buff *skb;
3763
3764 lock_sock(sk);
3765
3766 add_wait_queue(sk_sleep(sk), &wait);
3767 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
3768 set_current_state(TASK_INTERRUPTIBLE);
3769
3770 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
3771 err = -EBUSY;
3772 l2cap_send_disconn_req(pi->conn, sk, EBUSY);
3773 break;
3774 }
3775
3776 if (!timeo)
3777 timeo = HZ/5;
3778
3779 if (signal_pending(current)) {
3780 err = sock_intr_errno(timeo);
3781 break;
3782 }
3783
3784 release_sock(sk);
3785 timeo = schedule_timeout(timeo);
3786 lock_sock(sk);
3787
3788 err = sock_error(sk);
3789 if (err)
3790 break;
3791
3792 if (l2cap_try_push_rx_skb(sk) == 0)
3793 break;
3794 }
3795
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003796 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003797 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003798
3799 release_sock(sk);
3800}
3801
3802static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
3803{
3804 struct l2cap_pinfo *pi = l2cap_pi(sk);
3805 int sctrl, err;
3806
3807 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3808 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3809 __skb_queue_tail(BUSY_QUEUE(sk), skb);
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003810 return l2cap_try_push_rx_skb(sk);
3811
3812
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003813 }
3814
3815 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3816 if (err >= 0) {
3817 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3818 return err;
3819 }
3820
3821 /* Busy Condition */
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003822 BT_DBG("sk %p, Enter local busy", sk);
3823
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003824 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
3825 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3826 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3827
3828 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3829 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
3830 l2cap_send_sframe(pi, sctrl);
3831
3832 pi->conn_state |= L2CAP_CONN_RNR_SENT;
3833
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03003834 del_timer(&pi->ack_timer);
3835
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003836 queue_work(_busy_wq, &pi->busy_work);
3837
3838 return err;
3839}
3840
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003841static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003842{
3843 struct l2cap_pinfo *pi = l2cap_pi(sk);
3844 struct sk_buff *_skb;
3845 int err = -EINVAL;
3846
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003847 /*
3848 * TODO: We have to notify the userland if some data is lost with the
3849 * Streaming Mode.
3850 */
3851
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003852 switch (control & L2CAP_CTRL_SAR) {
3853 case L2CAP_SDU_UNSEGMENTED:
3854 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3855 kfree_skb(pi->sdu);
3856 break;
3857 }
3858
3859 err = sock_queue_rcv_skb(sk, skb);
3860 if (!err)
3861 return 0;
3862
3863 break;
3864
3865 case L2CAP_SDU_START:
3866 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3867 kfree_skb(pi->sdu);
3868 break;
3869 }
3870
3871 pi->sdu_len = get_unaligned_le16(skb->data);
3872 skb_pull(skb, 2);
3873
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003874 if (pi->sdu_len > pi->imtu) {
3875 err = -EMSGSIZE;
3876 break;
3877 }
3878
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003879 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3880 if (!pi->sdu) {
3881 err = -ENOMEM;
3882 break;
3883 }
3884
3885 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3886
3887 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3888 pi->partial_sdu_len = skb->len;
3889 err = 0;
3890 break;
3891
3892 case L2CAP_SDU_CONTINUE:
3893 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3894 break;
3895
3896 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3897
3898 pi->partial_sdu_len += skb->len;
3899 if (pi->partial_sdu_len > pi->sdu_len)
3900 kfree_skb(pi->sdu);
3901 else
3902 err = 0;
3903
3904 break;
3905
3906 case L2CAP_SDU_END:
3907 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3908 break;
3909
3910 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3911
3912 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3913 pi->partial_sdu_len += skb->len;
3914
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003915 if (pi->partial_sdu_len > pi->imtu)
3916 goto drop;
3917
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003918 if (pi->partial_sdu_len == pi->sdu_len) {
3919 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3920 err = sock_queue_rcv_skb(sk, _skb);
3921 if (err < 0)
3922 kfree_skb(_skb);
3923 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003924 err = 0;
3925
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003926drop:
3927 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003928 break;
3929 }
3930
3931 kfree_skb(skb);
3932 return err;
3933}
3934
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003935static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3936{
3937 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003938 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003939
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003940 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003941 if (bt_cb(skb)->tx_seq != tx_seq)
3942 break;
3943
3944 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003945 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003946 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003947 l2cap_pi(sk)->buffer_seq_srej =
3948 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003949 tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003950 }
3951}
3952
3953static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3954{
3955 struct l2cap_pinfo *pi = l2cap_pi(sk);
3956 struct srej_list *l, *tmp;
3957 u16 control;
3958
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003959 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003960 if (l->tx_seq == tx_seq) {
3961 list_del(&l->list);
3962 kfree(l);
3963 return;
3964 }
3965 control = L2CAP_SUPER_SELECT_REJECT;
3966 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3967 l2cap_send_sframe(pi, control);
3968 list_del(&l->list);
3969 list_add_tail(&l->list, SREJ_LIST(sk));
3970 }
3971}
3972
3973static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3974{
3975 struct l2cap_pinfo *pi = l2cap_pi(sk);
3976 struct srej_list *new;
3977 u16 control;
3978
3979 while (tx_seq != pi->expected_tx_seq) {
3980 control = L2CAP_SUPER_SELECT_REJECT;
3981 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3982 l2cap_send_sframe(pi, control);
3983
3984 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003985 new->tx_seq = pi->expected_tx_seq;
3986 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003987 list_add_tail(&new->list, SREJ_LIST(sk));
3988 }
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003989 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003990}
3991
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003992static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3993{
3994 struct l2cap_pinfo *pi = l2cap_pi(sk);
3995 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003996 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003997 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03003998 int tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003999 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004000 int err = 0;
4001
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004002 BT_DBG("sk %p len %d tx_seq %d rx_control 0x%4.4x", sk, skb->len, tx_seq,
4003 rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004004
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03004005 if (L2CAP_CTRL_FINAL & rx_control &&
4006 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004007 del_timer(&pi->monitor_timer);
4008 if (pi->unacked_frames > 0)
4009 __mod_retrans_timer();
4010 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
4011 }
4012
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03004013 pi->expected_ack_seq = req_seq;
4014 l2cap_drop_acked_frames(sk);
4015
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004016 if (tx_seq == pi->expected_tx_seq)
4017 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004018
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03004019 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
4020 if (tx_seq_offset < 0)
4021 tx_seq_offset += 64;
4022
4023 /* invalid tx_seq */
4024 if (tx_seq_offset >= pi->tx_win) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03004025 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03004026 goto drop;
4027 }
4028
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004029 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
4030 goto drop;
4031
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004032 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
4033 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004034
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004035 first = list_first_entry(SREJ_LIST(sk),
4036 struct srej_list, list);
4037 if (tx_seq == first->tx_seq) {
4038 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
4039 l2cap_check_srej_gap(sk, tx_seq);
4040
4041 list_del(&first->list);
4042 kfree(first);
4043
4044 if (list_empty(SREJ_LIST(sk))) {
4045 pi->buffer_seq = pi->buffer_seq_srej;
4046 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666cc2010-05-01 16:15:40 -03004047 l2cap_send_ack(pi);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004048 BT_DBG("sk %p, Exit SREJ_SENT", sk);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004049 }
4050 } else {
4051 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03004052
4053 /* duplicated tx_seq */
4054 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
4055 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004056
4057 list_for_each_entry(l, SREJ_LIST(sk), list) {
4058 if (l->tx_seq == tx_seq) {
4059 l2cap_resend_srejframe(sk, tx_seq);
4060 return 0;
4061 }
4062 }
4063 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004064 }
4065 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03004066 expected_tx_seq_offset =
4067 (pi->expected_tx_seq - pi->buffer_seq) % 64;
4068 if (expected_tx_seq_offset < 0)
4069 expected_tx_seq_offset += 64;
4070
4071 /* duplicated tx_seq */
4072 if (tx_seq_offset < expected_tx_seq_offset)
4073 goto drop;
4074
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004075 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004076
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004077 BT_DBG("sk %p, Enter SREJ", sk);
4078
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004079 INIT_LIST_HEAD(SREJ_LIST(sk));
4080 pi->buffer_seq_srej = pi->buffer_seq;
4081
4082 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004083 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004084 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
4085
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03004086 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
4087
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004088 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03004089
4090 del_timer(&pi->ack_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004091 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004092 return 0;
4093
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004094expected:
4095 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4096
4097 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03004098 bt_cb(skb)->tx_seq = tx_seq;
4099 bt_cb(skb)->sar = sar;
4100 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004101 return 0;
4102 }
4103
Gustavo F. Padovan2ece3682010-06-16 17:21:44 -03004104 err = l2cap_push_rx_skb(sk, skb, rx_control);
4105 if (err < 0)
4106 return 0;
4107
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03004108 if (rx_control & L2CAP_CTRL_FINAL) {
4109 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4110 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004111 else
4112 l2cap_retransmit_frames(sk);
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03004113 }
4114
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03004115 __mod_ack_timer();
4116
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03004117 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
4118 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03004119 l2cap_send_ack(pi);
4120
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004121 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03004122
4123drop:
4124 kfree_skb(skb);
4125 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004126}
4127
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004128static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004129{
4130 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03004131
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004132 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control),
4133 rx_control);
4134
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03004135 pi->expected_ack_seq = __get_reqseq(rx_control);
4136 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004137
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004138 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004139 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03004140 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
4141 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
4142 (pi->unacked_frames > 0))
4143 __mod_retrans_timer();
4144
4145 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4146 l2cap_send_srejtail(sk);
4147 } else {
4148 l2cap_send_i_or_rr_or_rnr(sk);
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03004149 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004150
4151 } else if (rx_control & L2CAP_CTRL_FINAL) {
4152 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004153
4154 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4155 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004156 else
4157 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004158
4159 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004160 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
4161 (pi->unacked_frames > 0))
4162 __mod_retrans_timer();
4163
4164 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004165 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004166 l2cap_send_ack(pi);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004167 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004168 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004169 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004170 }
4171}
4172
4173static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
4174{
4175 struct l2cap_pinfo *pi = l2cap_pi(sk);
4176 u8 tx_seq = __get_reqseq(rx_control);
4177
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004178 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4179
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004180 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4181
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03004182 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004183 l2cap_drop_acked_frames(sk);
4184
4185 if (rx_control & L2CAP_CTRL_FINAL) {
4186 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4187 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004188 else
4189 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004190 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004191 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004192
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03004193 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004194 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004195 }
4196}
4197static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
4198{
4199 struct l2cap_pinfo *pi = l2cap_pi(sk);
4200 u8 tx_seq = __get_reqseq(rx_control);
4201
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004202 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4203
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004204 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4205
4206 if (rx_control & L2CAP_CTRL_POLL) {
4207 pi->expected_ack_seq = tx_seq;
4208 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004209
4210 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004211 l2cap_retransmit_one_frame(sk, tx_seq);
4212
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004213 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004214
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004215 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4216 pi->srej_save_reqseq = tx_seq;
4217 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4218 }
4219 } else if (rx_control & L2CAP_CTRL_FINAL) {
4220 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
4221 pi->srej_save_reqseq == tx_seq)
4222 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
4223 else
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004224 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004225 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004226 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004227 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4228 pi->srej_save_reqseq = tx_seq;
4229 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4230 }
4231 }
4232}
4233
4234static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
4235{
4236 struct l2cap_pinfo *pi = l2cap_pi(sk);
4237 u8 tx_seq = __get_reqseq(rx_control);
4238
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004239 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4240
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004241 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
4242 pi->expected_ack_seq = tx_seq;
4243 l2cap_drop_acked_frames(sk);
4244
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004245 if (rx_control & L2CAP_CTRL_POLL)
4246 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
4247
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004248 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
4249 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03004250 if (rx_control & L2CAP_CTRL_POLL)
4251 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004252 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004253 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004254
4255 if (rx_control & L2CAP_CTRL_POLL)
4256 l2cap_send_srejtail(sk);
4257 else
4258 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004259}
4260
4261static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
4262{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004263 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
4264
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03004265 if (L2CAP_CTRL_FINAL & rx_control &&
4266 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004267 del_timer(&l2cap_pi(sk)->monitor_timer);
4268 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004269 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004270 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004271 }
4272
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004273 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
4274 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004275 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004276 break;
4277
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004278 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004279 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004280 break;
4281
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004282 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004283 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004284 break;
4285
4286 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004287 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004288 break;
4289 }
4290
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03004291 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004292 return 0;
4293}
4294
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004295static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
4296{
4297 struct l2cap_pinfo *pi = l2cap_pi(sk);
4298 u16 control;
4299 u8 req_seq;
4300 int len, next_tx_seq_offset, req_seq_offset;
4301
4302 control = get_unaligned_le16(skb->data);
4303 skb_pull(skb, 2);
4304 len = skb->len;
4305
4306 /*
4307 * We can just drop the corrupted I-frame here.
4308 * Receiver will miss it and start proper recovery
4309 * procedures and ask retransmission.
4310 */
4311 if (l2cap_check_fcs(pi, skb))
4312 goto drop;
4313
4314 if (__is_sar_start(control) && __is_iframe(control))
4315 len -= 2;
4316
4317 if (pi->fcs == L2CAP_FCS_CRC16)
4318 len -= 2;
4319
4320 if (len > pi->mps) {
4321 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4322 goto drop;
4323 }
4324
4325 req_seq = __get_reqseq(control);
4326 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
4327 if (req_seq_offset < 0)
4328 req_seq_offset += 64;
4329
4330 next_tx_seq_offset =
4331 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
4332 if (next_tx_seq_offset < 0)
4333 next_tx_seq_offset += 64;
4334
4335 /* check for invalid req-seq */
4336 if (req_seq_offset > next_tx_seq_offset) {
4337 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4338 goto drop;
4339 }
4340
4341 if (__is_iframe(control)) {
4342 if (len < 0) {
4343 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4344 goto drop;
4345 }
4346
4347 l2cap_data_channel_iframe(sk, control, skb);
4348 } else {
4349 if (len != 0) {
4350 BT_ERR("%d", len);
4351 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4352 goto drop;
4353 }
4354
4355 l2cap_data_channel_sframe(sk, control, skb);
4356 }
4357
4358 return 0;
4359
4360drop:
4361 kfree_skb(skb);
4362 return 0;
4363}
4364
Linus Torvalds1da177e2005-04-16 15:20:36 -07004365static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
4366{
4367 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004368 struct l2cap_pinfo *pi;
Nathan Holstein51893f82010-06-09 15:46:25 -04004369 u16 control;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004370 u8 tx_seq;
4371 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004372
4373 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
4374 if (!sk) {
4375 BT_DBG("unknown cid 0x%4.4x", cid);
4376 goto drop;
4377 }
4378
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004379 pi = l2cap_pi(sk);
4380
Linus Torvalds1da177e2005-04-16 15:20:36 -07004381 BT_DBG("sk %p, len %d", sk, skb->len);
4382
4383 if (sk->sk_state != BT_CONNECTED)
4384 goto drop;
4385
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004386 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004387 case L2CAP_MODE_BASIC:
4388 /* If socket recv buffers overflows we drop data here
4389 * which is *bad* because L2CAP has to be reliable.
4390 * But we don't have any other choice. L2CAP doesn't
4391 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004392
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004393 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004394 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004395
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004396 if (!sock_queue_rcv_skb(sk, skb))
4397 goto done;
4398 break;
4399
4400 case L2CAP_MODE_ERTM:
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004401 if (!sock_owned_by_user(sk)) {
4402 l2cap_ertm_data_rcv(sk, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004403 } else {
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004404 if (sk_add_backlog(sk, skb))
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004405 goto drop;
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004406 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004407
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004408 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004409
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004410 case L2CAP_MODE_STREAMING:
4411 control = get_unaligned_le16(skb->data);
4412 skb_pull(skb, 2);
4413 len = skb->len;
4414
Gustavo F. Padovan26000082010-05-11 22:02:00 -03004415 if (l2cap_check_fcs(pi, skb))
4416 goto drop;
4417
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004418 if (__is_sar_start(control))
4419 len -= 2;
4420
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004421 if (pi->fcs == L2CAP_FCS_CRC16)
4422 len -= 2;
4423
Nathan Holstein51893f82010-06-09 15:46:25 -04004424 if (len > pi->mps || len < 0 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004425 goto drop;
4426
4427 tx_seq = __get_txseq(control);
4428
4429 if (pi->expected_tx_seq == tx_seq)
4430 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4431 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03004432 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004433
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004434 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004435
4436 goto done;
4437
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004438 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03004439 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004440 break;
4441 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004442
4443drop:
4444 kfree_skb(skb);
4445
4446done:
Marcel Holtmann01394182006-07-03 10:02:46 +02004447 if (sk)
4448 bh_unlock_sock(sk);
4449
Linus Torvalds1da177e2005-04-16 15:20:36 -07004450 return 0;
4451}
4452
Al Viro8e036fc2007-07-29 00:16:36 -07004453static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004454{
4455 struct sock *sk;
4456
4457 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
4458 if (!sk)
4459 goto drop;
4460
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00004461 bh_lock_sock(sk);
4462
Linus Torvalds1da177e2005-04-16 15:20:36 -07004463 BT_DBG("sk %p, len %d", sk, skb->len);
4464
4465 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
4466 goto drop;
4467
4468 if (l2cap_pi(sk)->imtu < skb->len)
4469 goto drop;
4470
4471 if (!sock_queue_rcv_skb(sk, skb))
4472 goto done;
4473
4474drop:
4475 kfree_skb(skb);
4476
4477done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004478 if (sk)
4479 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004480 return 0;
4481}
4482
4483static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
4484{
4485 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07004486 u16 cid, len;
4487 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004488
4489 skb_pull(skb, L2CAP_HDR_SIZE);
4490 cid = __le16_to_cpu(lh->cid);
4491 len = __le16_to_cpu(lh->len);
4492
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004493 if (len != skb->len) {
4494 kfree_skb(skb);
4495 return;
4496 }
4497
Linus Torvalds1da177e2005-04-16 15:20:36 -07004498 BT_DBG("len %d, cid 0x%4.4x", len, cid);
4499
4500 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004501 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004502 l2cap_sig_channel(conn, skb);
4503 break;
4504
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004505 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004506 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004507 skb_pull(skb, 2);
4508 l2cap_conless_channel(conn, psm, skb);
4509 break;
4510
4511 default:
4512 l2cap_data_channel(conn, cid, skb);
4513 break;
4514 }
4515}
4516
4517/* ---- L2CAP interface with lower layer (HCI) ---- */
4518
4519static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
4520{
4521 int exact = 0, lm1 = 0, lm2 = 0;
4522 register struct sock *sk;
4523 struct hlist_node *node;
4524
4525 if (type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03004526 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004527
4528 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
4529
4530 /* Find listening sockets and check their link_mode */
4531 read_lock(&l2cap_sk_list.lock);
4532 sk_for_each(sk, node, &l2cap_sk_list.head) {
4533 if (sk->sk_state != BT_LISTEN)
4534 continue;
4535
4536 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004537 lm1 |= HCI_LM_ACCEPT;
4538 if (l2cap_pi(sk)->role_switch)
4539 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004540 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004541 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
4542 lm2 |= HCI_LM_ACCEPT;
4543 if (l2cap_pi(sk)->role_switch)
4544 lm2 |= HCI_LM_MASTER;
4545 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004546 }
4547 read_unlock(&l2cap_sk_list.lock);
4548
4549 return exact ? lm1 : lm2;
4550}
4551
4552static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
4553{
Marcel Holtmann01394182006-07-03 10:02:46 +02004554 struct l2cap_conn *conn;
4555
Linus Torvalds1da177e2005-04-16 15:20:36 -07004556 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
4557
4558 if (hcon->type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03004559 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004560
4561 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004562 conn = l2cap_conn_add(hcon, status);
4563 if (conn)
4564 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02004565 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004566 l2cap_conn_del(hcon, bt_err(status));
4567
4568 return 0;
4569}
4570
Marcel Holtmann2950f212009-02-12 14:02:50 +01004571static int l2cap_disconn_ind(struct hci_conn *hcon)
4572{
4573 struct l2cap_conn *conn = hcon->l2cap_data;
4574
4575 BT_DBG("hcon %p", hcon);
4576
4577 if (hcon->type != ACL_LINK || !conn)
4578 return 0x13;
4579
4580 return conn->disc_reason;
4581}
4582
4583static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004584{
4585 BT_DBG("hcon %p reason %d", hcon, reason);
4586
4587 if (hcon->type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03004588 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004589
4590 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004591
Linus Torvalds1da177e2005-04-16 15:20:36 -07004592 return 0;
4593}
4594
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004595static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4596{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004597 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004598 return;
4599
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004600 if (encrypt == 0x00) {
4601 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4602 l2cap_sock_clear_timer(sk);
4603 l2cap_sock_set_timer(sk, HZ * 5);
4604 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4605 __l2cap_sock_close(sk, ECONNREFUSED);
4606 } else {
4607 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4608 l2cap_sock_clear_timer(sk);
4609 }
4610}
4611
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004612static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004613{
4614 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004615 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004616 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004617
Marcel Holtmann01394182006-07-03 10:02:46 +02004618 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004619 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004620
Linus Torvalds1da177e2005-04-16 15:20:36 -07004621 l = &conn->chan_list;
4622
4623 BT_DBG("conn %p", conn);
4624
4625 read_lock(&l->lock);
4626
4627 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4628 bh_lock_sock(sk);
4629
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004630 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4631 bh_unlock_sock(sk);
4632 continue;
4633 }
4634
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004635 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004636 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004637 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004638 bh_unlock_sock(sk);
4639 continue;
4640 }
4641
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004642 if (sk->sk_state == BT_CONNECT) {
4643 if (!status) {
4644 struct l2cap_conn_req req;
4645 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4646 req.psm = l2cap_pi(sk)->psm;
4647
4648 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03004649 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004650
4651 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4652 L2CAP_CONN_REQ, sizeof(req), &req);
4653 } else {
4654 l2cap_sock_clear_timer(sk);
4655 l2cap_sock_set_timer(sk, HZ / 10);
4656 }
4657 } else if (sk->sk_state == BT_CONNECT2) {
4658 struct l2cap_conn_rsp rsp;
4659 __u16 result;
4660
4661 if (!status) {
4662 sk->sk_state = BT_CONFIG;
4663 result = L2CAP_CR_SUCCESS;
4664 } else {
4665 sk->sk_state = BT_DISCONN;
4666 l2cap_sock_set_timer(sk, HZ / 10);
4667 result = L2CAP_CR_SEC_BLOCK;
4668 }
4669
4670 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4671 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4672 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004673 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004674 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4675 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004676 }
4677
Linus Torvalds1da177e2005-04-16 15:20:36 -07004678 bh_unlock_sock(sk);
4679 }
4680
4681 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004682
Linus Torvalds1da177e2005-04-16 15:20:36 -07004683 return 0;
4684}
4685
4686static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4687{
4688 struct l2cap_conn *conn = hcon->l2cap_data;
4689
4690 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4691 goto drop;
4692
4693 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4694
4695 if (flags & ACL_START) {
4696 struct l2cap_hdr *hdr;
Andrei Emeltchenko89794812010-09-15 14:28:44 +03004697 struct sock *sk;
4698 u16 cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004699 int len;
4700
4701 if (conn->rx_len) {
4702 BT_ERR("Unexpected start frame (len %d)", skb->len);
4703 kfree_skb(conn->rx_skb);
4704 conn->rx_skb = NULL;
4705 conn->rx_len = 0;
4706 l2cap_conn_unreliable(conn, ECOMM);
4707 }
4708
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03004709 /* Start fragment always begin with Basic L2CAP header */
4710 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004711 BT_ERR("Frame is too short (len %d)", skb->len);
4712 l2cap_conn_unreliable(conn, ECOMM);
4713 goto drop;
4714 }
4715
4716 hdr = (struct l2cap_hdr *) skb->data;
4717 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
Andrei Emeltchenko89794812010-09-15 14:28:44 +03004718 cid = __le16_to_cpu(hdr->cid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004719
4720 if (len == skb->len) {
4721 /* Complete frame received */
4722 l2cap_recv_frame(conn, skb);
4723 return 0;
4724 }
4725
4726 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4727
4728 if (skb->len > len) {
4729 BT_ERR("Frame is too long (len %d, expected len %d)",
4730 skb->len, len);
4731 l2cap_conn_unreliable(conn, ECOMM);
4732 goto drop;
4733 }
4734
Andrei Emeltchenko89794812010-09-15 14:28:44 +03004735 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
4736
4737 if (sk && l2cap_pi(sk)->imtu < len - L2CAP_HDR_SIZE) {
4738 BT_ERR("Frame exceeding recv MTU (len %d, MTU %d)",
4739 len, l2cap_pi(sk)->imtu);
4740 bh_unlock_sock(sk);
4741 l2cap_conn_unreliable(conn, ECOMM);
4742 goto drop;
4743 }
4744
4745 if (sk)
4746 bh_unlock_sock(sk);
4747
Linus Torvalds1da177e2005-04-16 15:20:36 -07004748 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004749 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4750 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004751 goto drop;
4752
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004753 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004754 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004755 conn->rx_len = len - skb->len;
4756 } else {
4757 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4758
4759 if (!conn->rx_len) {
4760 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4761 l2cap_conn_unreliable(conn, ECOMM);
4762 goto drop;
4763 }
4764
4765 if (skb->len > conn->rx_len) {
4766 BT_ERR("Fragment is too long (len %d, expected %d)",
4767 skb->len, conn->rx_len);
4768 kfree_skb(conn->rx_skb);
4769 conn->rx_skb = NULL;
4770 conn->rx_len = 0;
4771 l2cap_conn_unreliable(conn, ECOMM);
4772 goto drop;
4773 }
4774
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004775 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004776 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004777 conn->rx_len -= skb->len;
4778
4779 if (!conn->rx_len) {
4780 /* Complete frame received */
4781 l2cap_recv_frame(conn, conn->rx_skb);
4782 conn->rx_skb = NULL;
4783 }
4784 }
4785
4786drop:
4787 kfree_skb(skb);
4788 return 0;
4789}
4790
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004791static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004792{
4793 struct sock *sk;
4794 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004795
4796 read_lock_bh(&l2cap_sk_list.lock);
4797
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004798 sk_for_each(sk, node, &l2cap_sk_list.head) {
4799 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004800
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004801 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4802 batostr(&bt_sk(sk)->src),
4803 batostr(&bt_sk(sk)->dst),
4804 sk->sk_state, __le16_to_cpu(pi->psm),
4805 pi->scid, pi->dcid,
4806 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004807 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004808
Linus Torvalds1da177e2005-04-16 15:20:36 -07004809 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004810
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004811 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004812}
4813
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004814static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4815{
4816 return single_open(file, l2cap_debugfs_show, inode->i_private);
4817}
4818
4819static const struct file_operations l2cap_debugfs_fops = {
4820 .open = l2cap_debugfs_open,
4821 .read = seq_read,
4822 .llseek = seq_lseek,
4823 .release = single_release,
4824};
4825
4826static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004827
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004828static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004829 .family = PF_BLUETOOTH,
4830 .owner = THIS_MODULE,
4831 .release = l2cap_sock_release,
4832 .bind = l2cap_sock_bind,
4833 .connect = l2cap_sock_connect,
4834 .listen = l2cap_sock_listen,
4835 .accept = l2cap_sock_accept,
4836 .getname = l2cap_sock_getname,
4837 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004838 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004839 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004840 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004841 .mmap = sock_no_mmap,
4842 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004843 .shutdown = l2cap_sock_shutdown,
4844 .setsockopt = l2cap_sock_setsockopt,
4845 .getsockopt = l2cap_sock_getsockopt
4846};
4847
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004848static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004849 .family = PF_BLUETOOTH,
4850 .owner = THIS_MODULE,
4851 .create = l2cap_sock_create,
4852};
4853
4854static struct hci_proto l2cap_hci_proto = {
4855 .name = "L2CAP",
4856 .id = HCI_PROTO_L2CAP,
4857 .connect_ind = l2cap_connect_ind,
4858 .connect_cfm = l2cap_connect_cfm,
4859 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004860 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004861 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004862 .recv_acldata = l2cap_recv_acldata
4863};
4864
4865static int __init l2cap_init(void)
4866{
4867 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004868
Linus Torvalds1da177e2005-04-16 15:20:36 -07004869 err = proto_register(&l2cap_proto, 0);
4870 if (err < 0)
4871 return err;
4872
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004873 _busy_wq = create_singlethread_workqueue("l2cap");
Anderson Lizardob78d7b4f2010-11-29 12:15:50 -04004874 if (!_busy_wq) {
4875 proto_unregister(&l2cap_proto);
4876 return -ENOMEM;
4877 }
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004878
Linus Torvalds1da177e2005-04-16 15:20:36 -07004879 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4880 if (err < 0) {
4881 BT_ERR("L2CAP socket registration failed");
4882 goto error;
4883 }
4884
4885 err = hci_register_proto(&l2cap_hci_proto);
4886 if (err < 0) {
4887 BT_ERR("L2CAP protocol registration failed");
4888 bt_sock_unregister(BTPROTO_L2CAP);
4889 goto error;
4890 }
4891
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004892 if (bt_debugfs) {
4893 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4894 bt_debugfs, NULL, &l2cap_debugfs_fops);
4895 if (!l2cap_debugfs)
4896 BT_ERR("Failed to create L2CAP debug file");
4897 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004898
4899 BT_INFO("L2CAP ver %s", VERSION);
4900 BT_INFO("L2CAP socket layer initialized");
4901
4902 return 0;
4903
4904error:
Anderson Lizardob78d7b4f2010-11-29 12:15:50 -04004905 destroy_workqueue(_busy_wq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004906 proto_unregister(&l2cap_proto);
4907 return err;
4908}
4909
4910static void __exit l2cap_exit(void)
4911{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004912 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004913
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004914 flush_workqueue(_busy_wq);
4915 destroy_workqueue(_busy_wq);
4916
Linus Torvalds1da177e2005-04-16 15:20:36 -07004917 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4918 BT_ERR("L2CAP socket unregistration failed");
4919
4920 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4921 BT_ERR("L2CAP protocol unregistration failed");
4922
4923 proto_unregister(&l2cap_proto);
4924}
4925
4926void l2cap_load(void)
4927{
4928 /* Dummy function to trigger automatic L2CAP module loading by
4929 * other modules that use L2CAP sockets but don't use any other
4930 * symbols from it. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004931}
4932EXPORT_SYMBOL(l2cap_load);
4933
4934module_init(l2cap_init);
4935module_exit(l2cap_exit);
4936
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004937module_param(disable_ertm, bool, 0644);
4938MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004939
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004940MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004941MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4942MODULE_VERSION(VERSION);
4943MODULE_LICENSE("GPL");
4944MODULE_ALIAS("bt-proto-0");