blob: f9e4da2677afdc6d99d6bfdb59989e70ba9596dc [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth L2CAP core and sockets. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
Randy Dunlap4fc268d2006-01-11 12:17:47 -080030#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/errno.h>
32#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/sched.h>
34#include <linux/slab.h>
35#include <linux/poll.h>
36#include <linux/fcntl.h>
37#include <linux/init.h>
38#include <linux/interrupt.h>
39#include <linux/socket.h>
40#include <linux/skbuff.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <linux/list.h>
Marcel Holtmannbe9d1222005-11-08 09:57:38 -080042#include <linux/device.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010043#include <linux/debugfs.h>
44#include <linux/seq_file.h>
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -030045#include <linux/uaccess.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030046#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070047#include <net/sock.h>
48
49#include <asm/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070050#include <asm/unaligned.h>
51
52#include <net/bluetooth/bluetooth.h>
53#include <net/bluetooth/hci_core.h>
54#include <net/bluetooth/l2cap.h>
55
Marcel Holtmann44dd46d2009-05-02 19:09:01 -070056#define VERSION "2.14"
57
58static int enable_ertm = 0;
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +020059static int max_transmit = L2CAP_DEFAULT_MAX_TX;
Gustavo F. Padovan369ba302010-05-01 16:15:41 -030060static int tx_window = L2CAP_DEFAULT_TX_WINDOW;
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
67static struct bt_sock_list l2cap_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070068 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070069};
70
Linus Torvalds1da177e2005-04-16 15:20:36 -070071static void __l2cap_sock_close(struct sock *sk, int reason);
72static void l2cap_sock_close(struct sock *sk);
73static void l2cap_sock_kill(struct sock *sk);
74
75static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
76 u8 code, u8 ident, u16 dlen, void *data);
77
78/* ---- L2CAP timers ---- */
79static void l2cap_sock_timeout(unsigned long arg)
80{
81 struct sock *sk = (struct sock *) arg;
Marcel Holtmannb1235d72008-07-14 20:13:54 +020082 int reason;
Linus Torvalds1da177e2005-04-16 15:20:36 -070083
84 BT_DBG("sock %p state %d", sk, sk->sk_state);
85
86 bh_lock_sock(sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +020087
Marcel Holtmannf62e4322009-01-15 21:58:44 +010088 if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
89 reason = ECONNREFUSED;
90 else if (sk->sk_state == BT_CONNECT &&
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +010091 l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
Marcel Holtmannb1235d72008-07-14 20:13:54 +020092 reason = ECONNREFUSED;
93 else
94 reason = ETIMEDOUT;
95
96 __l2cap_sock_close(sk, reason);
97
Linus Torvalds1da177e2005-04-16 15:20:36 -070098 bh_unlock_sock(sk);
99
100 l2cap_sock_kill(sk);
101 sock_put(sk);
102}
103
104static void l2cap_sock_set_timer(struct sock *sk, long timeout)
105{
106 BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
107 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
108}
109
110static void l2cap_sock_clear_timer(struct sock *sk)
111{
112 BT_DBG("sock %p state %d", sk, sk->sk_state);
113 sk_stop_timer(sk, &sk->sk_timer);
114}
115
Marcel Holtmann01394182006-07-03 10:02:46 +0200116/* ---- L2CAP channels ---- */
117static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
118{
119 struct sock *s;
120 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
121 if (l2cap_pi(s)->dcid == cid)
122 break;
123 }
124 return s;
125}
126
127static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
128{
129 struct sock *s;
130 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
131 if (l2cap_pi(s)->scid == cid)
132 break;
133 }
134 return s;
135}
136
137/* Find channel with given SCID.
138 * Returns locked socket */
139static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
140{
141 struct sock *s;
142 read_lock(&l->lock);
143 s = __l2cap_get_chan_by_scid(l, cid);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300144 if (s)
145 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200146 read_unlock(&l->lock);
147 return s;
148}
149
150static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
151{
152 struct sock *s;
153 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
154 if (l2cap_pi(s)->ident == ident)
155 break;
156 }
157 return s;
158}
159
160static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
161{
162 struct sock *s;
163 read_lock(&l->lock);
164 s = __l2cap_get_chan_by_ident(l, ident);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300165 if (s)
166 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200167 read_unlock(&l->lock);
168 return s;
169}
170
171static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
172{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300173 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200174
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300175 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300176 if (!__l2cap_get_chan_by_scid(l, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200177 return cid;
178 }
179
180 return 0;
181}
182
183static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
184{
185 sock_hold(sk);
186
187 if (l->head)
188 l2cap_pi(l->head)->prev_c = sk;
189
190 l2cap_pi(sk)->next_c = l->head;
191 l2cap_pi(sk)->prev_c = NULL;
192 l->head = sk;
193}
194
195static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
196{
197 struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
198
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200199 write_lock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200200 if (sk == l->head)
201 l->head = next;
202
203 if (next)
204 l2cap_pi(next)->prev_c = prev;
205 if (prev)
206 l2cap_pi(prev)->next_c = next;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200207 write_unlock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200208
209 __sock_put(sk);
210}
211
212static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
213{
214 struct l2cap_chan_list *l = &conn->chan_list;
215
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300216 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
217 l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200218
Marcel Holtmann2950f212009-02-12 14:02:50 +0100219 conn->disc_reason = 0x13;
220
Marcel Holtmann01394182006-07-03 10:02:46 +0200221 l2cap_pi(sk)->conn = conn;
222
223 if (sk->sk_type == SOCK_SEQPACKET) {
224 /* Alloc CID for connection-oriented socket */
225 l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
226 } else if (sk->sk_type == SOCK_DGRAM) {
227 /* Connectionless socket */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300228 l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
229 l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
Marcel Holtmann01394182006-07-03 10:02:46 +0200230 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
231 } else {
232 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300233 l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
234 l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
Marcel Holtmann01394182006-07-03 10:02:46 +0200235 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
236 }
237
238 __l2cap_chan_link(l, sk);
239
240 if (parent)
241 bt_accept_enqueue(parent, sk);
242}
243
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900244/* Delete channel.
Marcel Holtmann01394182006-07-03 10:02:46 +0200245 * Must be called on the locked socket. */
246static void l2cap_chan_del(struct sock *sk, int err)
247{
248 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
249 struct sock *parent = bt_sk(sk)->parent;
250
251 l2cap_sock_clear_timer(sk);
252
253 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
254
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900255 if (conn) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200256 /* Unlink from channel list */
257 l2cap_chan_unlink(&conn->chan_list, sk);
258 l2cap_pi(sk)->conn = NULL;
259 hci_conn_put(conn->hcon);
260 }
261
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200262 sk->sk_state = BT_CLOSED;
Marcel Holtmann01394182006-07-03 10:02:46 +0200263 sock_set_flag(sk, SOCK_ZAPPED);
264
265 if (err)
266 sk->sk_err = err;
267
268 if (parent) {
269 bt_accept_unlink(sk);
270 parent->sk_data_ready(parent, 0);
271 } else
272 sk->sk_state_change(sk);
273}
274
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200275/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100276static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200277{
278 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100279 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200280
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100281 if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
282 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
283 auth_type = HCI_AT_NO_BONDING_MITM;
284 else
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300285 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100286
287 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
288 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
289 } else {
290 switch (l2cap_pi(sk)->sec_level) {
291 case BT_SECURITY_HIGH:
292 auth_type = HCI_AT_GENERAL_BONDING_MITM;
293 break;
294 case BT_SECURITY_MEDIUM:
295 auth_type = HCI_AT_GENERAL_BONDING;
296 break;
297 default:
298 auth_type = HCI_AT_NO_BONDING;
299 break;
300 }
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100301 }
302
303 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
304 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200305}
306
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200307static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
308{
309 u8 id;
310
311 /* Get next available identificator.
312 * 1 - 128 are used by kernel.
313 * 129 - 199 are reserved.
314 * 200 - 254 are used by utilities like l2ping, etc.
315 */
316
317 spin_lock_bh(&conn->lock);
318
319 if (++conn->tx_ident > 128)
320 conn->tx_ident = 1;
321
322 id = conn->tx_ident;
323
324 spin_unlock_bh(&conn->lock);
325
326 return id;
327}
328
329static inline int l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
330{
331 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
332
333 BT_DBG("code 0x%2.2x", code);
334
335 if (!skb)
336 return -ENOMEM;
337
338 return hci_send_acl(conn->hcon, skb, 0);
339}
340
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300341static inline int l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
342{
343 struct sk_buff *skb;
344 struct l2cap_hdr *lh;
345 struct l2cap_conn *conn = pi->conn;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300346 int count, hlen = L2CAP_HDR_SIZE + 2;
347
348 if (pi->fcs == L2CAP_FCS_CRC16)
349 hlen += 2;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300350
351 BT_DBG("pi %p, control 0x%2.2x", pi, control);
352
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300353 count = min_t(unsigned int, conn->mtu, hlen);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300354 control |= L2CAP_CTRL_FRAME_TYPE;
355
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -0300356 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
357 control |= L2CAP_CTRL_FINAL;
358 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
359 }
360
Gustavo F. Padovanf0946cc2010-05-01 16:15:37 -0300361 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
362 control |= L2CAP_CTRL_POLL;
363 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
364 }
365
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300366 skb = bt_skb_alloc(count, GFP_ATOMIC);
367 if (!skb)
368 return -ENOMEM;
369
370 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300371 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300372 lh->cid = cpu_to_le16(pi->dcid);
373 put_unaligned_le16(control, skb_put(skb, 2));
374
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300375 if (pi->fcs == L2CAP_FCS_CRC16) {
376 u16 fcs = crc16(0, (u8 *)lh, count - 2);
377 put_unaligned_le16(fcs, skb_put(skb, 2));
378 }
379
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300380 return hci_send_acl(pi->conn->hcon, skb, 0);
381}
382
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300383static inline int l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
384{
385 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY)
386 control |= L2CAP_SUPER_RCV_NOT_READY;
387 else
388 control |= L2CAP_SUPER_RCV_READY;
389
Gustavo F. Padovan2ab25cd2009-10-03 02:34:40 -0300390 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
391
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300392 return l2cap_send_sframe(pi, control);
393}
394
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200395static void l2cap_do_start(struct sock *sk)
396{
397 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
398
399 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100400 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
401 return;
402
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100403 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200404 struct l2cap_conn_req req;
405 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
406 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200407
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200408 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200409
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200410 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200411 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200412 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200413 } else {
414 struct l2cap_info_req req;
415 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
416
417 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
418 conn->info_ident = l2cap_get_ident(conn);
419
420 mod_timer(&conn->info_timer, jiffies +
421 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
422
423 l2cap_send_cmd(conn, conn->info_ident,
424 L2CAP_INFO_REQ, sizeof(req), &req);
425 }
426}
427
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300428static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk)
429{
430 struct l2cap_disconn_req req;
431
432 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
433 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
434 l2cap_send_cmd(conn, l2cap_get_ident(conn),
435 L2CAP_DISCONN_REQ, sizeof(req), &req);
436}
437
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200439static void l2cap_conn_start(struct l2cap_conn *conn)
440{
441 struct l2cap_chan_list *l = &conn->chan_list;
442 struct sock *sk;
443
444 BT_DBG("conn %p", conn);
445
446 read_lock(&l->lock);
447
448 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
449 bh_lock_sock(sk);
450
451 if (sk->sk_type != SOCK_SEQPACKET) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200452 bh_unlock_sock(sk);
453 continue;
454 }
455
456 if (sk->sk_state == BT_CONNECT) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100457 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200458 struct l2cap_conn_req req;
459 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
460 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200461
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200462 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200463
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200464 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200465 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200466 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200467 } else if (sk->sk_state == BT_CONNECT2) {
468 struct l2cap_conn_rsp rsp;
469 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
470 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
471
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100472 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100473 if (bt_sk(sk)->defer_setup) {
474 struct sock *parent = bt_sk(sk)->parent;
475 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
476 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
477 parent->sk_data_ready(parent, 0);
478
479 } else {
480 sk->sk_state = BT_CONFIG;
481 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
482 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
483 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200484 } else {
485 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
486 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
487 }
488
489 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
490 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
491 }
492
493 bh_unlock_sock(sk);
494 }
495
496 read_unlock(&l->lock);
497}
498
499static void l2cap_conn_ready(struct l2cap_conn *conn)
500{
501 struct l2cap_chan_list *l = &conn->chan_list;
502 struct sock *sk;
503
504 BT_DBG("conn %p", conn);
505
506 read_lock(&l->lock);
507
508 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
509 bh_lock_sock(sk);
510
511 if (sk->sk_type != SOCK_SEQPACKET) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200512 l2cap_sock_clear_timer(sk);
513 sk->sk_state = BT_CONNECTED;
514 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200515 } else if (sk->sk_state == BT_CONNECT)
516 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200517
518 bh_unlock_sock(sk);
519 }
520
521 read_unlock(&l->lock);
522}
523
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200524/* Notify sockets that we cannot guaranty reliability anymore */
525static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
526{
527 struct l2cap_chan_list *l = &conn->chan_list;
528 struct sock *sk;
529
530 BT_DBG("conn %p", conn);
531
532 read_lock(&l->lock);
533
534 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100535 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200536 sk->sk_err = err;
537 }
538
539 read_unlock(&l->lock);
540}
541
542static void l2cap_info_timeout(unsigned long arg)
543{
544 struct l2cap_conn *conn = (void *) arg;
545
Marcel Holtmann984947d2009-02-06 23:35:19 +0100546 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100547 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100548
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200549 l2cap_conn_start(conn);
550}
551
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
553{
Marcel Holtmann01394182006-07-03 10:02:46 +0200554 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555
Marcel Holtmann01394182006-07-03 10:02:46 +0200556 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 return conn;
558
Marcel Holtmann01394182006-07-03 10:02:46 +0200559 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
560 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562
563 hcon->l2cap_data = conn;
564 conn->hcon = hcon;
565
Marcel Holtmann01394182006-07-03 10:02:46 +0200566 BT_DBG("hcon %p conn %p", hcon, conn);
567
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 conn->mtu = hcon->hdev->acl_mtu;
569 conn->src = &hcon->hdev->bdaddr;
570 conn->dst = &hcon->dst;
571
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200572 conn->feat_mask = 0;
573
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 spin_lock_init(&conn->lock);
575 rwlock_init(&conn->chan_list.lock);
576
Dave Young45054dc2009-10-18 20:28:30 +0000577 setup_timer(&conn->info_timer, l2cap_info_timeout,
578 (unsigned long) conn);
579
Marcel Holtmann2950f212009-02-12 14:02:50 +0100580 conn->disc_reason = 0x13;
581
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582 return conn;
583}
584
Marcel Holtmann01394182006-07-03 10:02:46 +0200585static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586{
Marcel Holtmann01394182006-07-03 10:02:46 +0200587 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 struct sock *sk;
589
Marcel Holtmann01394182006-07-03 10:02:46 +0200590 if (!conn)
591 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592
593 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
594
Wei Yongjun7585b972009-02-25 18:29:52 +0800595 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596
597 /* Kill channels */
598 while ((sk = conn->chan_list.head)) {
599 bh_lock_sock(sk);
600 l2cap_chan_del(sk, err);
601 bh_unlock_sock(sk);
602 l2cap_sock_kill(sk);
603 }
604
Dave Young8e8440f2008-03-03 12:18:55 -0800605 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
606 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800607
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 hcon->l2cap_data = NULL;
609 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610}
611
612static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
613{
614 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200615 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200617 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618}
619
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700621static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622{
623 struct sock *sk;
624 struct hlist_node *node;
625 sk_for_each(sk, node, &l2cap_sk_list.head)
626 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
627 goto found;
628 sk = NULL;
629found:
630 return sk;
631}
632
633/* Find socket with psm and source bdaddr.
634 * Returns closest match.
635 */
Al Viro8e036fc2007-07-29 00:16:36 -0700636static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637{
638 struct sock *sk = NULL, *sk1 = NULL;
639 struct hlist_node *node;
640
641 sk_for_each(sk, node, &l2cap_sk_list.head) {
642 if (state && sk->sk_state != state)
643 continue;
644
645 if (l2cap_pi(sk)->psm == psm) {
646 /* Exact match. */
647 if (!bacmp(&bt_sk(sk)->src, src))
648 break;
649
650 /* Closest match */
651 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
652 sk1 = sk;
653 }
654 }
655 return node ? sk : sk1;
656}
657
658/* Find socket with given address (psm, src).
659 * Returns locked socket */
Al Viro8e036fc2007-07-29 00:16:36 -0700660static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661{
662 struct sock *s;
663 read_lock(&l2cap_sk_list.lock);
664 s = __l2cap_get_sock_by_psm(state, psm, src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300665 if (s)
666 bh_lock_sock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667 read_unlock(&l2cap_sk_list.lock);
668 return s;
669}
670
671static void l2cap_sock_destruct(struct sock *sk)
672{
673 BT_DBG("sk %p", sk);
674
675 skb_queue_purge(&sk->sk_receive_queue);
676 skb_queue_purge(&sk->sk_write_queue);
677}
678
679static void l2cap_sock_cleanup_listen(struct sock *parent)
680{
681 struct sock *sk;
682
683 BT_DBG("parent %p", parent);
684
685 /* Close not yet accepted channels */
686 while ((sk = bt_accept_dequeue(parent, NULL)))
687 l2cap_sock_close(sk);
688
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200689 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690 sock_set_flag(parent, SOCK_ZAPPED);
691}
692
693/* Kill socket (only if zapped and orphan)
694 * Must be called on unlocked socket.
695 */
696static void l2cap_sock_kill(struct sock *sk)
697{
698 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
699 return;
700
701 BT_DBG("sk %p state %d", sk, sk->sk_state);
702
703 /* Kill poor orphan */
704 bt_sock_unlink(&l2cap_sk_list, sk);
705 sock_set_flag(sk, SOCK_DEAD);
706 sock_put(sk);
707}
708
709static void __l2cap_sock_close(struct sock *sk, int reason)
710{
711 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
712
713 switch (sk->sk_state) {
714 case BT_LISTEN:
715 l2cap_sock_cleanup_listen(sk);
716 break;
717
718 case BT_CONNECTED:
719 case BT_CONFIG:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720 if (sk->sk_type == SOCK_SEQPACKET) {
721 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722
723 sk->sk_state = BT_DISCONN;
724 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300725 l2cap_send_disconn_req(conn, sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200726 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728 break;
729
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100730 case BT_CONNECT2:
731 if (sk->sk_type == SOCK_SEQPACKET) {
732 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
733 struct l2cap_conn_rsp rsp;
734 __u16 result;
735
736 if (bt_sk(sk)->defer_setup)
737 result = L2CAP_CR_SEC_BLOCK;
738 else
739 result = L2CAP_CR_BAD_PSM;
740
741 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
742 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
743 rsp.result = cpu_to_le16(result);
744 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
745 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
746 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
747 } else
748 l2cap_chan_del(sk, reason);
749 break;
750
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751 case BT_CONNECT:
752 case BT_DISCONN:
753 l2cap_chan_del(sk, reason);
754 break;
755
756 default:
757 sock_set_flag(sk, SOCK_ZAPPED);
758 break;
759 }
760}
761
762/* Must be called on unlocked socket. */
763static void l2cap_sock_close(struct sock *sk)
764{
765 l2cap_sock_clear_timer(sk);
766 lock_sock(sk);
767 __l2cap_sock_close(sk, ECONNRESET);
768 release_sock(sk);
769 l2cap_sock_kill(sk);
770}
771
772static void l2cap_sock_init(struct sock *sk, struct sock *parent)
773{
774 struct l2cap_pinfo *pi = l2cap_pi(sk);
775
776 BT_DBG("sk %p", sk);
777
778 if (parent) {
779 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100780 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
781
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 pi->imtu = l2cap_pi(parent)->imtu;
783 pi->omtu = l2cap_pi(parent)->omtu;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700784 pi->mode = l2cap_pi(parent)->mode;
785 pi->fcs = l2cap_pi(parent)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -0300786 pi->max_tx = l2cap_pi(parent)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -0300787 pi->tx_win = l2cap_pi(parent)->tx_win;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100788 pi->sec_level = l2cap_pi(parent)->sec_level;
789 pi->role_switch = l2cap_pi(parent)->role_switch;
790 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791 } else {
792 pi->imtu = L2CAP_DEFAULT_MTU;
793 pi->omtu = 0;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700794 pi->mode = L2CAP_MODE_BASIC;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -0300795 pi->max_tx = max_transmit;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700796 pi->fcs = L2CAP_FCS_CRC16;
Gustavo F. Padovan369ba302010-05-01 16:15:41 -0300797 pi->tx_win = tx_window;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100798 pi->sec_level = BT_SECURITY_LOW;
799 pi->role_switch = 0;
800 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801 }
802
803 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200804 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Dave Young45054dc2009-10-18 20:28:30 +0000806 skb_queue_head_init(TX_QUEUE(sk));
807 skb_queue_head_init(SREJ_QUEUE(sk));
808 INIT_LIST_HEAD(SREJ_LIST(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809}
810
811static struct proto l2cap_proto = {
812 .name = "L2CAP",
813 .owner = THIS_MODULE,
814 .obj_size = sizeof(struct l2cap_pinfo)
815};
816
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700817static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818{
819 struct sock *sk;
820
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700821 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822 if (!sk)
823 return NULL;
824
825 sock_init_data(sock, sk);
826 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
827
828 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200829 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830
831 sock_reset_flag(sk, SOCK_ZAPPED);
832
833 sk->sk_protocol = proto;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200834 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200836 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837
838 bt_sock_link(&l2cap_sk_list, sk);
839 return sk;
840}
841
Eric Paris3f378b62009-11-05 22:18:14 -0800842static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
843 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700844{
845 struct sock *sk;
846
847 BT_DBG("sock %p", sock);
848
849 sock->state = SS_UNCONNECTED;
850
851 if (sock->type != SOCK_SEQPACKET &&
852 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
853 return -ESOCKTNOSUPPORT;
854
Eric Parisc84b3262009-11-05 20:45:52 -0800855 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 return -EPERM;
857
858 sock->ops = &l2cap_sock_ops;
859
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700860 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861 if (!sk)
862 return -ENOMEM;
863
864 l2cap_sock_init(sk, NULL);
865 return 0;
866}
867
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100868static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100871 struct sockaddr_l2 la;
872 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100874 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875
876 if (!addr || addr->sa_family != AF_BLUETOOTH)
877 return -EINVAL;
878
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100879 memset(&la, 0, sizeof(la));
880 len = min_t(unsigned int, sizeof(la), alen);
881 memcpy(&la, addr, len);
882
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100883 if (la.l2_cid)
884 return -EINVAL;
885
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886 lock_sock(sk);
887
888 if (sk->sk_state != BT_OPEN) {
889 err = -EBADFD;
890 goto done;
891 }
892
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200893 if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
Marcel Holtmann847641d2007-01-22 22:00:45 +0100894 !capable(CAP_NET_BIND_SERVICE)) {
895 err = -EACCES;
896 goto done;
897 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900898
Linus Torvalds1da177e2005-04-16 15:20:36 -0700899 write_lock_bh(&l2cap_sk_list.lock);
900
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100901 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902 err = -EADDRINUSE;
903 } else {
904 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100905 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
906 l2cap_pi(sk)->psm = la.l2_psm;
907 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100909
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200910 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
911 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100912 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913 }
914
915 write_unlock_bh(&l2cap_sk_list.lock);
916
917done:
918 release_sock(sk);
919 return err;
920}
921
922static int l2cap_do_connect(struct sock *sk)
923{
924 bdaddr_t *src = &bt_sk(sk)->src;
925 bdaddr_t *dst = &bt_sk(sk)->dst;
926 struct l2cap_conn *conn;
927 struct hci_conn *hcon;
928 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200929 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +0200930 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100932 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
933 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300935 hdev = hci_get_route(dst, src);
936 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937 return -EHOSTUNREACH;
938
939 hci_dev_lock_bh(hdev);
940
941 err = -ENOMEM;
942
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100943 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100944 switch (l2cap_pi(sk)->sec_level) {
945 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100946 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100947 break;
948 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100949 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100950 break;
951 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100952 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100953 break;
954 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100955 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100956 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200957 auth_type = HCI_AT_NO_BONDING_MITM;
958 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200959 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +0100960
961 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
962 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100963 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100964 switch (l2cap_pi(sk)->sec_level) {
965 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100966 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100967 break;
968 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200969 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100970 break;
971 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100972 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100973 break;
974 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200975 }
976
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100977 hcon = hci_connect(hdev, ACL_LINK, dst,
978 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700979 if (!hcon)
980 goto done;
981
982 conn = l2cap_conn_add(hcon, 0);
983 if (!conn) {
984 hci_conn_put(hcon);
985 goto done;
986 }
987
988 err = 0;
989
990 /* Update source addr of the socket */
991 bacpy(src, conn->src);
992
993 l2cap_chan_add(conn, sk, NULL);
994
995 sk->sk_state = BT_CONNECT;
996 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
997
998 if (hcon->state == BT_CONNECTED) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200999 if (sk->sk_type != SOCK_SEQPACKET) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 l2cap_sock_clear_timer(sk);
1001 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001002 } else
1003 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004 }
1005
1006done:
1007 hci_dev_unlock_bh(hdev);
1008 hci_dev_put(hdev);
1009 return err;
1010}
1011
1012static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
1013{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001014 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001015 struct sockaddr_l2 la;
1016 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018 BT_DBG("sk %p", sk);
1019
Changli Gao6503d962010-03-31 22:58:26 +00001020 if (!addr || alen < sizeof(addr->sa_family) ||
1021 addr->sa_family != AF_BLUETOOTH)
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001022 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001024 memset(&la, 0, sizeof(la));
1025 len = min_t(unsigned int, sizeof(la), alen);
1026 memcpy(&la, addr, len);
1027
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001028 if (la.l2_cid)
1029 return -EINVAL;
1030
1031 lock_sock(sk);
1032
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001033 if (sk->sk_type == SOCK_SEQPACKET && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034 err = -EINVAL;
1035 goto done;
1036 }
1037
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001038 switch (l2cap_pi(sk)->mode) {
1039 case L2CAP_MODE_BASIC:
1040 break;
1041 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001042 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001043 if (enable_ertm)
1044 break;
1045 /* fall through */
1046 default:
1047 err = -ENOTSUPP;
1048 goto done;
1049 }
1050
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001051 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052 case BT_CONNECT:
1053 case BT_CONNECT2:
1054 case BT_CONFIG:
1055 /* Already connecting */
1056 goto wait;
1057
1058 case BT_CONNECTED:
1059 /* Already connected */
1060 goto done;
1061
1062 case BT_OPEN:
1063 case BT_BOUND:
1064 /* Can connect */
1065 break;
1066
1067 default:
1068 err = -EBADFD;
1069 goto done;
1070 }
1071
1072 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001073 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1074 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001076 err = l2cap_do_connect(sk);
1077 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078 goto done;
1079
1080wait:
1081 err = bt_sock_wait_state(sk, BT_CONNECTED,
1082 sock_sndtimeo(sk, flags & O_NONBLOCK));
1083done:
1084 release_sock(sk);
1085 return err;
1086}
1087
1088static int l2cap_sock_listen(struct socket *sock, int backlog)
1089{
1090 struct sock *sk = sock->sk;
1091 int err = 0;
1092
1093 BT_DBG("sk %p backlog %d", sk, backlog);
1094
1095 lock_sock(sk);
1096
1097 if (sk->sk_state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
1098 err = -EBADFD;
1099 goto done;
1100 }
1101
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001102 switch (l2cap_pi(sk)->mode) {
1103 case L2CAP_MODE_BASIC:
1104 break;
1105 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001106 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001107 if (enable_ertm)
1108 break;
1109 /* fall through */
1110 default:
1111 err = -ENOTSUPP;
1112 goto done;
1113 }
1114
Linus Torvalds1da177e2005-04-16 15:20:36 -07001115 if (!l2cap_pi(sk)->psm) {
1116 bdaddr_t *src = &bt_sk(sk)->src;
1117 u16 psm;
1118
1119 err = -EINVAL;
1120
1121 write_lock_bh(&l2cap_sk_list.lock);
1122
1123 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001124 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1125 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1126 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127 err = 0;
1128 break;
1129 }
1130
1131 write_unlock_bh(&l2cap_sk_list.lock);
1132
1133 if (err < 0)
1134 goto done;
1135 }
1136
1137 sk->sk_max_ack_backlog = backlog;
1138 sk->sk_ack_backlog = 0;
1139 sk->sk_state = BT_LISTEN;
1140
1141done:
1142 release_sock(sk);
1143 return err;
1144}
1145
1146static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1147{
1148 DECLARE_WAITQUEUE(wait, current);
1149 struct sock *sk = sock->sk, *nsk;
1150 long timeo;
1151 int err = 0;
1152
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001153 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001154
1155 if (sk->sk_state != BT_LISTEN) {
1156 err = -EBADFD;
1157 goto done;
1158 }
1159
1160 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1161
1162 BT_DBG("sk %p timeo %ld", sk, timeo);
1163
1164 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +00001165 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1167 set_current_state(TASK_INTERRUPTIBLE);
1168 if (!timeo) {
1169 err = -EAGAIN;
1170 break;
1171 }
1172
1173 release_sock(sk);
1174 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001175 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176
1177 if (sk->sk_state != BT_LISTEN) {
1178 err = -EBADFD;
1179 break;
1180 }
1181
1182 if (signal_pending(current)) {
1183 err = sock_intr_errno(timeo);
1184 break;
1185 }
1186 }
1187 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +00001188 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189
1190 if (err)
1191 goto done;
1192
1193 newsock->state = SS_CONNECTED;
1194
1195 BT_DBG("new socket %p", nsk);
1196
1197done:
1198 release_sock(sk);
1199 return err;
1200}
1201
1202static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1203{
1204 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1205 struct sock *sk = sock->sk;
1206
1207 BT_DBG("sock %p, sk %p", sock, sk);
1208
1209 addr->sa_family = AF_BLUETOOTH;
1210 *len = sizeof(struct sockaddr_l2);
1211
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001212 if (peer) {
1213 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001215 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001216 } else {
1217 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001219 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001220 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 return 0;
1223}
1224
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001225static void l2cap_monitor_timeout(unsigned long arg)
1226{
1227 struct sock *sk = (void *) arg;
1228 u16 control;
1229
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001230 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001231 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
1232 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001233 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001234 return;
1235 }
1236
1237 l2cap_pi(sk)->retry_count++;
1238 __mod_monitor_timer();
1239
1240 control = L2CAP_CTRL_POLL;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001241 l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001242 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001243}
1244
1245static void l2cap_retrans_timeout(unsigned long arg)
1246{
1247 struct sock *sk = (void *) arg;
1248 u16 control;
1249
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001250 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001251 l2cap_pi(sk)->retry_count = 1;
1252 __mod_monitor_timer();
1253
1254 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1255
1256 control = L2CAP_CTRL_POLL;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001257 l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001258 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001259}
1260
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001261static void l2cap_drop_acked_frames(struct sock *sk)
1262{
1263 struct sk_buff *skb;
1264
1265 while ((skb = skb_peek(TX_QUEUE(sk)))) {
1266 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1267 break;
1268
1269 skb = skb_dequeue(TX_QUEUE(sk));
1270 kfree_skb(skb);
1271
1272 l2cap_pi(sk)->unacked_frames--;
1273 }
1274
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001275 if (!l2cap_pi(sk)->unacked_frames)
1276 del_timer(&l2cap_pi(sk)->retrans_timer);
1277
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001278 return;
1279}
1280
1281static inline int l2cap_do_send(struct sock *sk, struct sk_buff *skb)
1282{
1283 struct l2cap_pinfo *pi = l2cap_pi(sk);
1284 int err;
1285
1286 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1287
1288 err = hci_send_acl(pi->conn->hcon, skb, 0);
1289 if (err < 0)
1290 kfree_skb(skb);
1291
1292 return err;
1293}
1294
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001295static int l2cap_streaming_send(struct sock *sk)
1296{
1297 struct sk_buff *skb, *tx_skb;
1298 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001299 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001300 int err;
1301
1302 while ((skb = sk->sk_send_head)) {
1303 tx_skb = skb_clone(skb, GFP_ATOMIC);
1304
1305 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1306 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1307 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1308
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001309 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001310 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1311 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1312 }
1313
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001314 err = l2cap_do_send(sk, tx_skb);
1315 if (err < 0) {
1316 l2cap_send_disconn_req(pi->conn, sk);
1317 return err;
1318 }
1319
1320 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1321
1322 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1323 sk->sk_send_head = NULL;
1324 else
1325 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1326
1327 skb = skb_dequeue(TX_QUEUE(sk));
1328 kfree_skb(skb);
1329 }
1330 return 0;
1331}
1332
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001333static int l2cap_retransmit_frame(struct sock *sk, u8 tx_seq)
1334{
1335 struct l2cap_pinfo *pi = l2cap_pi(sk);
1336 struct sk_buff *skb, *tx_skb;
1337 u16 control, fcs;
1338 int err;
1339
1340 skb = skb_peek(TX_QUEUE(sk));
1341 do {
1342 if (bt_cb(skb)->tx_seq != tx_seq) {
1343 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1344 break;
1345 skb = skb_queue_next(TX_QUEUE(sk), skb);
1346 continue;
1347 }
1348
1349 if (pi->remote_max_tx &&
1350 bt_cb(skb)->retries == pi->remote_max_tx) {
1351 l2cap_send_disconn_req(pi->conn, sk);
1352 break;
1353 }
1354
1355 tx_skb = skb_clone(skb, GFP_ATOMIC);
1356 bt_cb(skb)->retries++;
1357 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001358 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001359 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1360 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1361
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001362 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001363 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1364 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1365 }
1366
1367 err = l2cap_do_send(sk, tx_skb);
1368 if (err < 0) {
1369 l2cap_send_disconn_req(pi->conn, sk);
1370 return err;
1371 }
1372 break;
1373 } while(1);
1374 return 0;
1375}
1376
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001377static int l2cap_ertm_send(struct sock *sk)
1378{
1379 struct sk_buff *skb, *tx_skb;
1380 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001381 u16 control, fcs;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001382 int err, nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001383
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001384 if (pi->conn_state & L2CAP_CONN_WAIT_F)
1385 return 0;
1386
Joe Perchesf64f9e72009-11-29 16:55:45 -08001387 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) &&
1388 !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001389
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001390 if (pi->remote_max_tx &&
1391 bt_cb(skb)->retries == pi->remote_max_tx) {
1392 l2cap_send_disconn_req(pi->conn, sk);
1393 break;
1394 }
1395
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001396 tx_skb = skb_clone(skb, GFP_ATOMIC);
1397
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001398 bt_cb(skb)->retries++;
1399
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001400 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001401 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1402 control |= L2CAP_CTRL_FINAL;
1403 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1404 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001405 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001406 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1407 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1408
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001409
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001410 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001411 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1412 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1413 }
1414
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001415 err = l2cap_do_send(sk, tx_skb);
1416 if (err < 0) {
1417 l2cap_send_disconn_req(pi->conn, sk);
1418 return err;
1419 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001420 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001421
1422 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1423 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1424
1425 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001426 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001427
1428 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1429 sk->sk_send_head = NULL;
1430 else
1431 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001432
1433 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001434 }
1435
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001436 return nsent;
1437}
1438
1439static int l2cap_send_ack(struct l2cap_pinfo *pi)
1440{
1441 struct sock *sk = (struct sock *)pi;
1442 u16 control = 0;
1443
1444 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1445
1446 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1447 control |= L2CAP_SUPER_RCV_NOT_READY;
1448 return l2cap_send_sframe(pi, control);
1449 } else if (l2cap_ertm_send(sk) == 0) {
1450 control |= L2CAP_SUPER_RCV_READY;
1451 return l2cap_send_sframe(pi, control);
1452 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001453 return 0;
1454}
1455
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001456static int l2cap_send_srejtail(struct sock *sk)
1457{
1458 struct srej_list *tail;
1459 u16 control;
1460
1461 control = L2CAP_SUPER_SELECT_REJECT;
1462 control |= L2CAP_CTRL_FINAL;
1463
1464 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1465 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1466
1467 l2cap_send_sframe(l2cap_pi(sk), control);
1468
1469 return 0;
1470}
1471
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001472static 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 -07001473{
1474 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001475 struct sk_buff **frag;
1476 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001477
1478 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001479 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480 }
1481
1482 sent += count;
1483 len -= count;
1484
1485 /* Continuation fragments (no L2CAP header) */
1486 frag = &skb_shinfo(skb)->frag_list;
1487 while (len) {
1488 count = min_t(unsigned int, conn->mtu, len);
1489
1490 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1491 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001492 return -EFAULT;
1493 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1494 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495
1496 sent += count;
1497 len -= count;
1498
1499 frag = &(*frag)->next;
1500 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001501
1502 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001503}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001505static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1506{
1507 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1508 struct sk_buff *skb;
1509 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1510 struct l2cap_hdr *lh;
1511
1512 BT_DBG("sk %p len %d", sk, (int)len);
1513
1514 count = min_t(unsigned int, (conn->mtu - hlen), len);
1515 skb = bt_skb_send_alloc(sk, count + hlen,
1516 msg->msg_flags & MSG_DONTWAIT, &err);
1517 if (!skb)
1518 return ERR_PTR(-ENOMEM);
1519
1520 /* Create L2CAP header */
1521 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1522 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1523 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1524 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1525
1526 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1527 if (unlikely(err < 0)) {
1528 kfree_skb(skb);
1529 return ERR_PTR(err);
1530 }
1531 return skb;
1532}
1533
1534static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1535{
1536 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1537 struct sk_buff *skb;
1538 int err, count, hlen = L2CAP_HDR_SIZE;
1539 struct l2cap_hdr *lh;
1540
1541 BT_DBG("sk %p len %d", sk, (int)len);
1542
1543 count = min_t(unsigned int, (conn->mtu - hlen), len);
1544 skb = bt_skb_send_alloc(sk, count + hlen,
1545 msg->msg_flags & MSG_DONTWAIT, &err);
1546 if (!skb)
1547 return ERR_PTR(-ENOMEM);
1548
1549 /* Create L2CAP header */
1550 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1551 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1552 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1553
1554 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1555 if (unlikely(err < 0)) {
1556 kfree_skb(skb);
1557 return ERR_PTR(err);
1558 }
1559 return skb;
1560}
1561
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001562static 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 -03001563{
1564 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1565 struct sk_buff *skb;
1566 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1567 struct l2cap_hdr *lh;
1568
1569 BT_DBG("sk %p len %d", sk, (int)len);
1570
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001571 if (sdulen)
1572 hlen += 2;
1573
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001574 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1575 hlen += 2;
1576
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001577 count = min_t(unsigned int, (conn->mtu - hlen), len);
1578 skb = bt_skb_send_alloc(sk, count + hlen,
1579 msg->msg_flags & MSG_DONTWAIT, &err);
1580 if (!skb)
1581 return ERR_PTR(-ENOMEM);
1582
1583 /* Create L2CAP header */
1584 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1585 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1586 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1587 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001588 if (sdulen)
1589 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001590
1591 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1592 if (unlikely(err < 0)) {
1593 kfree_skb(skb);
1594 return ERR_PTR(err);
1595 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001596
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001597 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1598 put_unaligned_le16(0, skb_put(skb, 2));
1599
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001600 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001601 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602}
1603
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001604static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1605{
1606 struct l2cap_pinfo *pi = l2cap_pi(sk);
1607 struct sk_buff *skb;
1608 struct sk_buff_head sar_queue;
1609 u16 control;
1610 size_t size = 0;
1611
1612 __skb_queue_head_init(&sar_queue);
1613 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001614 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001615 if (IS_ERR(skb))
1616 return PTR_ERR(skb);
1617
1618 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001619 len -= pi->remote_mps;
1620 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001621 control = 0;
1622
1623 while (len > 0) {
1624 size_t buflen;
1625
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001626 if (len > pi->remote_mps) {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001627 control |= L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001628 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001629 } else {
1630 control |= L2CAP_SDU_END;
1631 buflen = len;
1632 }
1633
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001634 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001635 if (IS_ERR(skb)) {
1636 skb_queue_purge(&sar_queue);
1637 return PTR_ERR(skb);
1638 }
1639
1640 __skb_queue_tail(&sar_queue, skb);
1641 len -= buflen;
1642 size += buflen;
1643 control = 0;
1644 }
1645 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1646 if (sk->sk_send_head == NULL)
1647 sk->sk_send_head = sar_queue.next;
1648
1649 return size;
1650}
1651
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1653{
1654 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001655 struct l2cap_pinfo *pi = l2cap_pi(sk);
1656 struct sk_buff *skb;
1657 u16 control;
1658 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659
1660 BT_DBG("sock %p, sk %p", sock, sk);
1661
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001662 err = sock_error(sk);
1663 if (err)
1664 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001665
1666 if (msg->msg_flags & MSG_OOB)
1667 return -EOPNOTSUPP;
1668
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669 lock_sock(sk);
1670
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001671 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001673 goto done;
1674 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001676 /* Connectionless channel */
1677 if (sk->sk_type == SOCK_DGRAM) {
1678 skb = l2cap_create_connless_pdu(sk, msg, len);
Dan Carpenter477fffb2010-04-21 23:52:01 +00001679 if (IS_ERR(skb))
1680 err = PTR_ERR(skb);
1681 else
1682 err = l2cap_do_send(sk, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001683 goto done;
1684 }
1685
1686 switch (pi->mode) {
1687 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001688 /* Check outgoing MTU */
1689 if (len > pi->omtu) {
1690 err = -EINVAL;
1691 goto done;
1692 }
1693
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001694 /* Create a basic PDU */
1695 skb = l2cap_create_basic_pdu(sk, msg, len);
1696 if (IS_ERR(skb)) {
1697 err = PTR_ERR(skb);
1698 goto done;
1699 }
1700
1701 err = l2cap_do_send(sk, skb);
1702 if (!err)
1703 err = len;
1704 break;
1705
1706 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001707 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001708 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001709 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001710 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001711 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001712 if (IS_ERR(skb)) {
1713 err = PTR_ERR(skb);
1714 goto done;
1715 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001716 __skb_queue_tail(TX_QUEUE(sk), skb);
1717 if (sk->sk_send_head == NULL)
1718 sk->sk_send_head = skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001719 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001720 /* Segment SDU into multiples PDUs */
1721 err = l2cap_sar_segment_sdu(sk, msg, len);
1722 if (err < 0)
1723 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001724 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001725
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001726 if (pi->mode == L2CAP_MODE_STREAMING)
1727 err = l2cap_streaming_send(sk);
1728 else
1729 err = l2cap_ertm_send(sk);
1730
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001731 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001732 err = len;
1733 break;
1734
1735 default:
1736 BT_DBG("bad state %1.1x", pi->mode);
1737 err = -EINVAL;
1738 }
1739
1740done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 release_sock(sk);
1742 return err;
1743}
1744
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001745static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1746{
1747 struct sock *sk = sock->sk;
1748
1749 lock_sock(sk);
1750
1751 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1752 struct l2cap_conn_rsp rsp;
1753
1754 sk->sk_state = BT_CONFIG;
1755
1756 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1757 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1758 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1759 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1760 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1761 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1762
1763 release_sock(sk);
1764 return 0;
1765 }
1766
1767 release_sock(sk);
1768
1769 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1770}
1771
David S. Millerb7058842009-09-30 16:12:20 -07001772static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773{
1774 struct sock *sk = sock->sk;
1775 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001776 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777 u32 opt;
1778
1779 BT_DBG("sk %p", sk);
1780
1781 lock_sock(sk);
1782
1783 switch (optname) {
1784 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001785 opts.imtu = l2cap_pi(sk)->imtu;
1786 opts.omtu = l2cap_pi(sk)->omtu;
1787 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001788 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001789 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001790 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001791 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001792
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793 len = min_t(unsigned int, sizeof(opts), optlen);
1794 if (copy_from_user((char *) &opts, optval, len)) {
1795 err = -EFAULT;
1796 break;
1797 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001798
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001799 l2cap_pi(sk)->imtu = opts.imtu;
1800 l2cap_pi(sk)->omtu = opts.omtu;
1801 l2cap_pi(sk)->mode = opts.mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001802 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001803 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001804 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 break;
1806
1807 case L2CAP_LM:
1808 if (get_user(opt, (u32 __user *) optval)) {
1809 err = -EFAULT;
1810 break;
1811 }
1812
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001813 if (opt & L2CAP_LM_AUTH)
1814 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1815 if (opt & L2CAP_LM_ENCRYPT)
1816 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1817 if (opt & L2CAP_LM_SECURE)
1818 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1819
1820 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1821 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822 break;
1823
1824 default:
1825 err = -ENOPROTOOPT;
1826 break;
1827 }
1828
1829 release_sock(sk);
1830 return err;
1831}
1832
David S. Millerb7058842009-09-30 16:12:20 -07001833static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001834{
1835 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001836 struct bt_security sec;
1837 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001838 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001839
1840 BT_DBG("sk %p", sk);
1841
1842 if (level == SOL_L2CAP)
1843 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1844
Marcel Holtmann0588d942009-01-16 10:06:13 +01001845 if (level != SOL_BLUETOOTH)
1846 return -ENOPROTOOPT;
1847
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001848 lock_sock(sk);
1849
1850 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001851 case BT_SECURITY:
Marcel Holtmann2526d3d2009-02-20 20:54:06 +01001852 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001853 err = -EINVAL;
1854 break;
1855 }
1856
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001857 sec.level = BT_SECURITY_LOW;
1858
1859 len = min_t(unsigned int, sizeof(sec), optlen);
1860 if (copy_from_user((char *) &sec, optval, len)) {
1861 err = -EFAULT;
1862 break;
1863 }
1864
1865 if (sec.level < BT_SECURITY_LOW ||
1866 sec.level > BT_SECURITY_HIGH) {
1867 err = -EINVAL;
1868 break;
1869 }
1870
1871 l2cap_pi(sk)->sec_level = sec.level;
1872 break;
1873
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001874 case BT_DEFER_SETUP:
1875 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1876 err = -EINVAL;
1877 break;
1878 }
1879
1880 if (get_user(opt, (u32 __user *) optval)) {
1881 err = -EFAULT;
1882 break;
1883 }
1884
1885 bt_sk(sk)->defer_setup = opt;
1886 break;
1887
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001888 default:
1889 err = -ENOPROTOOPT;
1890 break;
1891 }
1892
1893 release_sock(sk);
1894 return err;
1895}
1896
1897static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001898{
1899 struct sock *sk = sock->sk;
1900 struct l2cap_options opts;
1901 struct l2cap_conninfo cinfo;
1902 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001903 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904
1905 BT_DBG("sk %p", sk);
1906
1907 if (get_user(len, optlen))
1908 return -EFAULT;
1909
1910 lock_sock(sk);
1911
1912 switch (optname) {
1913 case L2CAP_OPTIONS:
1914 opts.imtu = l2cap_pi(sk)->imtu;
1915 opts.omtu = l2cap_pi(sk)->omtu;
1916 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001917 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001918 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001919 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001920 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921
1922 len = min_t(unsigned int, len, sizeof(opts));
1923 if (copy_to_user(optval, (char *) &opts, len))
1924 err = -EFAULT;
1925
1926 break;
1927
1928 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001929 switch (l2cap_pi(sk)->sec_level) {
1930 case BT_SECURITY_LOW:
1931 opt = L2CAP_LM_AUTH;
1932 break;
1933 case BT_SECURITY_MEDIUM:
1934 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
1935 break;
1936 case BT_SECURITY_HIGH:
1937 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
1938 L2CAP_LM_SECURE;
1939 break;
1940 default:
1941 opt = 0;
1942 break;
1943 }
1944
1945 if (l2cap_pi(sk)->role_switch)
1946 opt |= L2CAP_LM_MASTER;
1947
1948 if (l2cap_pi(sk)->force_reliable)
1949 opt |= L2CAP_LM_RELIABLE;
1950
1951 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001952 err = -EFAULT;
1953 break;
1954
1955 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001956 if (sk->sk_state != BT_CONNECTED &&
1957 !(sk->sk_state == BT_CONNECT2 &&
1958 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959 err = -ENOTCONN;
1960 break;
1961 }
1962
1963 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
1964 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
1965
1966 len = min_t(unsigned int, len, sizeof(cinfo));
1967 if (copy_to_user(optval, (char *) &cinfo, len))
1968 err = -EFAULT;
1969
1970 break;
1971
1972 default:
1973 err = -ENOPROTOOPT;
1974 break;
1975 }
1976
1977 release_sock(sk);
1978 return err;
1979}
1980
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001981static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
1982{
1983 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001984 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001985 int len, err = 0;
1986
1987 BT_DBG("sk %p", sk);
1988
1989 if (level == SOL_L2CAP)
1990 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
1991
Marcel Holtmann0588d942009-01-16 10:06:13 +01001992 if (level != SOL_BLUETOOTH)
1993 return -ENOPROTOOPT;
1994
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001995 if (get_user(len, optlen))
1996 return -EFAULT;
1997
1998 lock_sock(sk);
1999
2000 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002001 case BT_SECURITY:
Marcel Holtmann2526d3d2009-02-20 20:54:06 +01002002 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002003 err = -EINVAL;
2004 break;
2005 }
2006
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002007 sec.level = l2cap_pi(sk)->sec_level;
2008
2009 len = min_t(unsigned int, len, sizeof(sec));
2010 if (copy_to_user(optval, (char *) &sec, len))
2011 err = -EFAULT;
2012
2013 break;
2014
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002015 case BT_DEFER_SETUP:
2016 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2017 err = -EINVAL;
2018 break;
2019 }
2020
2021 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2022 err = -EFAULT;
2023
2024 break;
2025
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002026 default:
2027 err = -ENOPROTOOPT;
2028 break;
2029 }
2030
2031 release_sock(sk);
2032 return err;
2033}
2034
Linus Torvalds1da177e2005-04-16 15:20:36 -07002035static int l2cap_sock_shutdown(struct socket *sock, int how)
2036{
2037 struct sock *sk = sock->sk;
2038 int err = 0;
2039
2040 BT_DBG("sock %p, sk %p", sock, sk);
2041
2042 if (!sk)
2043 return 0;
2044
2045 lock_sock(sk);
2046 if (!sk->sk_shutdown) {
2047 sk->sk_shutdown = SHUTDOWN_MASK;
2048 l2cap_sock_clear_timer(sk);
2049 __l2cap_sock_close(sk, 0);
2050
2051 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002052 err = bt_sock_wait_state(sk, BT_CLOSED,
2053 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002054 }
2055 release_sock(sk);
2056 return err;
2057}
2058
2059static int l2cap_sock_release(struct socket *sock)
2060{
2061 struct sock *sk = sock->sk;
2062 int err;
2063
2064 BT_DBG("sock %p, sk %p", sock, sk);
2065
2066 if (!sk)
2067 return 0;
2068
2069 err = l2cap_sock_shutdown(sock, 2);
2070
2071 sock_orphan(sk);
2072 l2cap_sock_kill(sk);
2073 return err;
2074}
2075
Linus Torvalds1da177e2005-04-16 15:20:36 -07002076static void l2cap_chan_ready(struct sock *sk)
2077{
2078 struct sock *parent = bt_sk(sk)->parent;
2079
2080 BT_DBG("sk %p, parent %p", sk, parent);
2081
2082 l2cap_pi(sk)->conf_state = 0;
2083 l2cap_sock_clear_timer(sk);
2084
2085 if (!parent) {
2086 /* Outgoing channel.
2087 * Wake up socket sleeping on connect.
2088 */
2089 sk->sk_state = BT_CONNECTED;
2090 sk->sk_state_change(sk);
2091 } else {
2092 /* Incoming channel.
2093 * Wake up socket sleeping on accept.
2094 */
2095 parent->sk_data_ready(parent, 0);
2096 }
2097}
2098
2099/* Copy frame to all raw sockets on that connection */
2100static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2101{
2102 struct l2cap_chan_list *l = &conn->chan_list;
2103 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002104 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002105
2106 BT_DBG("conn %p", conn);
2107
2108 read_lock(&l->lock);
2109 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2110 if (sk->sk_type != SOCK_RAW)
2111 continue;
2112
2113 /* Don't send frame to the socket it came from */
2114 if (skb->sk == sk)
2115 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002116 nskb = skb_clone(skb, GFP_ATOMIC);
2117 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002118 continue;
2119
2120 if (sock_queue_rcv_skb(sk, nskb))
2121 kfree_skb(nskb);
2122 }
2123 read_unlock(&l->lock);
2124}
2125
2126/* ---- L2CAP signalling commands ---- */
2127static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2128 u8 code, u8 ident, u16 dlen, void *data)
2129{
2130 struct sk_buff *skb, **frag;
2131 struct l2cap_cmd_hdr *cmd;
2132 struct l2cap_hdr *lh;
2133 int len, count;
2134
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002135 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2136 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002137
2138 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2139 count = min_t(unsigned int, conn->mtu, len);
2140
2141 skb = bt_skb_alloc(count, GFP_ATOMIC);
2142 if (!skb)
2143 return NULL;
2144
2145 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002146 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002147 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002148
2149 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2150 cmd->code = code;
2151 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002152 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002153
2154 if (dlen) {
2155 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2156 memcpy(skb_put(skb, count), data, count);
2157 data += count;
2158 }
2159
2160 len -= skb->len;
2161
2162 /* Continuation fragments (no L2CAP header) */
2163 frag = &skb_shinfo(skb)->frag_list;
2164 while (len) {
2165 count = min_t(unsigned int, conn->mtu, len);
2166
2167 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2168 if (!*frag)
2169 goto fail;
2170
2171 memcpy(skb_put(*frag, count), data, count);
2172
2173 len -= count;
2174 data += count;
2175
2176 frag = &(*frag)->next;
2177 }
2178
2179 return skb;
2180
2181fail:
2182 kfree_skb(skb);
2183 return NULL;
2184}
2185
2186static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2187{
2188 struct l2cap_conf_opt *opt = *ptr;
2189 int len;
2190
2191 len = L2CAP_CONF_OPT_SIZE + opt->len;
2192 *ptr += len;
2193
2194 *type = opt->type;
2195 *olen = opt->len;
2196
2197 switch (opt->len) {
2198 case 1:
2199 *val = *((u8 *) opt->val);
2200 break;
2201
2202 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002203 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002204 break;
2205
2206 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002207 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002208 break;
2209
2210 default:
2211 *val = (unsigned long) opt->val;
2212 break;
2213 }
2214
2215 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2216 return len;
2217}
2218
Linus Torvalds1da177e2005-04-16 15:20:36 -07002219static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2220{
2221 struct l2cap_conf_opt *opt = *ptr;
2222
2223 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2224
2225 opt->type = type;
2226 opt->len = len;
2227
2228 switch (len) {
2229 case 1:
2230 *((u8 *) opt->val) = val;
2231 break;
2232
2233 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002234 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002235 break;
2236
2237 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002238 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002239 break;
2240
2241 default:
2242 memcpy(opt->val, (void *) val, len);
2243 break;
2244 }
2245
2246 *ptr += L2CAP_CONF_OPT_SIZE + len;
2247}
2248
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002249static void l2cap_ack_timeout(unsigned long arg)
2250{
2251 struct sock *sk = (void *) arg;
2252
2253 bh_lock_sock(sk);
2254 l2cap_send_ack(l2cap_pi(sk));
2255 bh_unlock_sock(sk);
2256}
2257
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002258static inline void l2cap_ertm_init(struct sock *sk)
2259{
2260 l2cap_pi(sk)->expected_ack_seq = 0;
2261 l2cap_pi(sk)->unacked_frames = 0;
2262 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002263 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002264 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002265
2266 setup_timer(&l2cap_pi(sk)->retrans_timer,
2267 l2cap_retrans_timeout, (unsigned long) sk);
2268 setup_timer(&l2cap_pi(sk)->monitor_timer,
2269 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002270 setup_timer(&l2cap_pi(sk)->ack_timer,
2271 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002272
2273 __skb_queue_head_init(SREJ_QUEUE(sk));
2274}
2275
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002276static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2277{
2278 u32 local_feat_mask = l2cap_feat_mask;
2279 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002280 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002281
2282 switch (mode) {
2283 case L2CAP_MODE_ERTM:
2284 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2285 case L2CAP_MODE_STREAMING:
2286 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2287 default:
2288 return 0x00;
2289 }
2290}
2291
2292static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2293{
2294 switch (mode) {
2295 case L2CAP_MODE_STREAMING:
2296 case L2CAP_MODE_ERTM:
2297 if (l2cap_mode_supported(mode, remote_feat_mask))
2298 return mode;
2299 /* fall through */
2300 default:
2301 return L2CAP_MODE_BASIC;
2302 }
2303}
2304
Linus Torvalds1da177e2005-04-16 15:20:36 -07002305static int l2cap_build_conf_req(struct sock *sk, void *data)
2306{
2307 struct l2cap_pinfo *pi = l2cap_pi(sk);
2308 struct l2cap_conf_req *req = data;
Gustavo F. Padovana0e55a32009-09-29 01:42:23 -03002309 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002310 void *ptr = req->data;
2311
2312 BT_DBG("sk %p", sk);
2313
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002314 if (pi->num_conf_req || pi->num_conf_rsp)
2315 goto done;
2316
2317 switch (pi->mode) {
2318 case L2CAP_MODE_STREAMING:
2319 case L2CAP_MODE_ERTM:
2320 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002321 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2322 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002323 break;
2324 default:
2325 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2326 break;
2327 }
2328
2329done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002330 switch (pi->mode) {
2331 case L2CAP_MODE_BASIC:
2332 if (pi->imtu != L2CAP_DEFAULT_MTU)
2333 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2334 break;
2335
2336 case L2CAP_MODE_ERTM:
2337 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002338 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002339 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002340 rfc.retrans_timeout = 0;
2341 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002342 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002343 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002344 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002345
2346 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2347 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002348
2349 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2350 break;
2351
2352 if (pi->fcs == L2CAP_FCS_NONE ||
2353 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2354 pi->fcs = L2CAP_FCS_NONE;
2355 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2356 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002357 break;
2358
2359 case L2CAP_MODE_STREAMING:
2360 rfc.mode = L2CAP_MODE_STREAMING;
2361 rfc.txwin_size = 0;
2362 rfc.max_transmit = 0;
2363 rfc.retrans_timeout = 0;
2364 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002365 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002366 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002367 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002368
2369 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2370 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002371
2372 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2373 break;
2374
2375 if (pi->fcs == L2CAP_FCS_NONE ||
2376 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2377 pi->fcs = L2CAP_FCS_NONE;
2378 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2379 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002380 break;
2381 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002382
2383 /* FIXME: Need actual value of the flush timeout */
2384 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2385 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2386
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002387 req->dcid = cpu_to_le16(pi->dcid);
2388 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002389
2390 return ptr - data;
2391}
2392
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002393static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002394{
2395 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002396 struct l2cap_conf_rsp *rsp = data;
2397 void *ptr = rsp->data;
2398 void *req = pi->conf_req;
2399 int len = pi->conf_len;
2400 int type, hint, olen;
2401 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002402 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002403 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002404 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002405
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002406 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002407
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002408 while (len >= L2CAP_CONF_OPT_SIZE) {
2409 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002410
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002411 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002412 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002413
2414 switch (type) {
2415 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002416 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002417 break;
2418
2419 case L2CAP_CONF_FLUSH_TO:
2420 pi->flush_to = val;
2421 break;
2422
2423 case L2CAP_CONF_QOS:
2424 break;
2425
Marcel Holtmann6464f352007-10-20 13:39:51 +02002426 case L2CAP_CONF_RFC:
2427 if (olen == sizeof(rfc))
2428 memcpy(&rfc, (void *) val, olen);
2429 break;
2430
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002431 case L2CAP_CONF_FCS:
2432 if (val == L2CAP_FCS_NONE)
2433 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2434
2435 break;
2436
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002437 default:
2438 if (hint)
2439 break;
2440
2441 result = L2CAP_CONF_UNKNOWN;
2442 *((u8 *) ptr++) = type;
2443 break;
2444 }
2445 }
2446
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002447 if (pi->num_conf_rsp || pi->num_conf_req)
2448 goto done;
2449
2450 switch (pi->mode) {
2451 case L2CAP_MODE_STREAMING:
2452 case L2CAP_MODE_ERTM:
2453 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2454 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2455 return -ECONNREFUSED;
2456 break;
2457 default:
2458 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2459 break;
2460 }
2461
2462done:
2463 if (pi->mode != rfc.mode) {
2464 result = L2CAP_CONF_UNACCEPT;
2465 rfc.mode = pi->mode;
2466
2467 if (pi->num_conf_rsp == 1)
2468 return -ECONNREFUSED;
2469
2470 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2471 sizeof(rfc), (unsigned long) &rfc);
2472 }
2473
2474
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002475 if (result == L2CAP_CONF_SUCCESS) {
2476 /* Configure output options and let the other side know
2477 * which ones we don't like. */
2478
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002479 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2480 result = L2CAP_CONF_UNACCEPT;
2481 else {
2482 pi->omtu = mtu;
2483 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2484 }
2485 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002486
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002487 switch (rfc.mode) {
2488 case L2CAP_MODE_BASIC:
2489 pi->fcs = L2CAP_FCS_NONE;
2490 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2491 break;
2492
2493 case L2CAP_MODE_ERTM:
2494 pi->remote_tx_win = rfc.txwin_size;
2495 pi->remote_max_tx = rfc.max_transmit;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002496 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2497 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2498
2499 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002500
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002501 rfc.retrans_timeout =
2502 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2503 rfc.monitor_timeout =
2504 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002505
2506 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002507
2508 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2509 sizeof(rfc), (unsigned long) &rfc);
2510
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002511 break;
2512
2513 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002514 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2515 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2516
2517 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002518
2519 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002520
2521 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2522 sizeof(rfc), (unsigned long) &rfc);
2523
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002524 break;
2525
2526 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002527 result = L2CAP_CONF_UNACCEPT;
2528
2529 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002530 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002531 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002532
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002533 if (result == L2CAP_CONF_SUCCESS)
2534 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2535 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002536 rsp->scid = cpu_to_le16(pi->dcid);
2537 rsp->result = cpu_to_le16(result);
2538 rsp->flags = cpu_to_le16(0x0000);
2539
2540 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002541}
2542
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002543static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2544{
2545 struct l2cap_pinfo *pi = l2cap_pi(sk);
2546 struct l2cap_conf_req *req = data;
2547 void *ptr = req->data;
2548 int type, olen;
2549 unsigned long val;
2550 struct l2cap_conf_rfc rfc;
2551
2552 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2553
2554 while (len >= L2CAP_CONF_OPT_SIZE) {
2555 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2556
2557 switch (type) {
2558 case L2CAP_CONF_MTU:
2559 if (val < L2CAP_DEFAULT_MIN_MTU) {
2560 *result = L2CAP_CONF_UNACCEPT;
2561 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2562 } else
2563 pi->omtu = val;
2564 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2565 break;
2566
2567 case L2CAP_CONF_FLUSH_TO:
2568 pi->flush_to = val;
2569 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2570 2, pi->flush_to);
2571 break;
2572
2573 case L2CAP_CONF_RFC:
2574 if (olen == sizeof(rfc))
2575 memcpy(&rfc, (void *)val, olen);
2576
2577 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2578 rfc.mode != pi->mode)
2579 return -ECONNREFUSED;
2580
2581 pi->mode = rfc.mode;
2582 pi->fcs = 0;
2583
2584 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2585 sizeof(rfc), (unsigned long) &rfc);
2586 break;
2587 }
2588 }
2589
2590 if (*result == L2CAP_CONF_SUCCESS) {
2591 switch (rfc.mode) {
2592 case L2CAP_MODE_ERTM:
2593 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002594 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2595 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002596 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002597 break;
2598 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002599 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002600 }
2601 }
2602
2603 req->dcid = cpu_to_le16(pi->dcid);
2604 req->flags = cpu_to_le16(0x0000);
2605
2606 return ptr - data;
2607}
2608
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002609static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002610{
2611 struct l2cap_conf_rsp *rsp = data;
2612 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002613
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002614 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002615
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002616 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002617 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002618 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002619
2620 return ptr - data;
2621}
2622
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002623static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2624{
2625 struct l2cap_pinfo *pi = l2cap_pi(sk);
2626 int type, olen;
2627 unsigned long val;
2628 struct l2cap_conf_rfc rfc;
2629
2630 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2631
2632 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2633 return;
2634
2635 while (len >= L2CAP_CONF_OPT_SIZE) {
2636 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2637
2638 switch (type) {
2639 case L2CAP_CONF_RFC:
2640 if (olen == sizeof(rfc))
2641 memcpy(&rfc, (void *)val, olen);
2642 goto done;
2643 }
2644 }
2645
2646done:
2647 switch (rfc.mode) {
2648 case L2CAP_MODE_ERTM:
2649 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002650 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2651 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002652 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2653 break;
2654 case L2CAP_MODE_STREAMING:
2655 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2656 }
2657}
2658
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002659static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2660{
2661 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2662
2663 if (rej->reason != 0x0000)
2664 return 0;
2665
2666 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2667 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002668 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002669
2670 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002671 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002672
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002673 l2cap_conn_start(conn);
2674 }
2675
2676 return 0;
2677}
2678
Linus Torvalds1da177e2005-04-16 15:20:36 -07002679static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2680{
2681 struct l2cap_chan_list *list = &conn->chan_list;
2682 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2683 struct l2cap_conn_rsp rsp;
2684 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002685 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002686
2687 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002688 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002689
2690 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2691
2692 /* Check if we have socket listening on psm */
2693 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2694 if (!parent) {
2695 result = L2CAP_CR_BAD_PSM;
2696 goto sendresp;
2697 }
2698
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002699 /* Check if the ACL is secure enough (if not SDP) */
2700 if (psm != cpu_to_le16(0x0001) &&
2701 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002702 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002703 result = L2CAP_CR_SEC_BLOCK;
2704 goto response;
2705 }
2706
Linus Torvalds1da177e2005-04-16 15:20:36 -07002707 result = L2CAP_CR_NO_MEM;
2708
2709 /* Check for backlog size */
2710 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002711 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002712 goto response;
2713 }
2714
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002715 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002716 if (!sk)
2717 goto response;
2718
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002719 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002720
2721 /* Check if we already have channel with that dcid */
2722 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002723 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002724 sock_set_flag(sk, SOCK_ZAPPED);
2725 l2cap_sock_kill(sk);
2726 goto response;
2727 }
2728
2729 hci_conn_hold(conn->hcon);
2730
2731 l2cap_sock_init(sk, parent);
2732 bacpy(&bt_sk(sk)->src, conn->src);
2733 bacpy(&bt_sk(sk)->dst, conn->dst);
2734 l2cap_pi(sk)->psm = psm;
2735 l2cap_pi(sk)->dcid = scid;
2736
2737 __l2cap_chan_add(conn, sk, parent);
2738 dcid = l2cap_pi(sk)->scid;
2739
2740 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2741
Linus Torvalds1da177e2005-04-16 15:20:36 -07002742 l2cap_pi(sk)->ident = cmd->ident;
2743
Marcel Holtmann984947d2009-02-06 23:35:19 +01002744 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002745 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002746 if (bt_sk(sk)->defer_setup) {
2747 sk->sk_state = BT_CONNECT2;
2748 result = L2CAP_CR_PEND;
2749 status = L2CAP_CS_AUTHOR_PEND;
2750 parent->sk_data_ready(parent, 0);
2751 } else {
2752 sk->sk_state = BT_CONFIG;
2753 result = L2CAP_CR_SUCCESS;
2754 status = L2CAP_CS_NO_INFO;
2755 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002756 } else {
2757 sk->sk_state = BT_CONNECT2;
2758 result = L2CAP_CR_PEND;
2759 status = L2CAP_CS_AUTHEN_PEND;
2760 }
2761 } else {
2762 sk->sk_state = BT_CONNECT2;
2763 result = L2CAP_CR_PEND;
2764 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002765 }
2766
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002767 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002768
2769response:
2770 bh_unlock_sock(parent);
2771
2772sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002773 rsp.scid = cpu_to_le16(scid);
2774 rsp.dcid = cpu_to_le16(dcid);
2775 rsp.result = cpu_to_le16(result);
2776 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002777 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002778
2779 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2780 struct l2cap_info_req info;
2781 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2782
2783 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2784 conn->info_ident = l2cap_get_ident(conn);
2785
2786 mod_timer(&conn->info_timer, jiffies +
2787 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2788
2789 l2cap_send_cmd(conn, conn->info_ident,
2790 L2CAP_INFO_REQ, sizeof(info), &info);
2791 }
2792
Linus Torvalds1da177e2005-04-16 15:20:36 -07002793 return 0;
2794}
2795
2796static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2797{
2798 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2799 u16 scid, dcid, result, status;
2800 struct sock *sk;
2801 u8 req[128];
2802
2803 scid = __le16_to_cpu(rsp->scid);
2804 dcid = __le16_to_cpu(rsp->dcid);
2805 result = __le16_to_cpu(rsp->result);
2806 status = __le16_to_cpu(rsp->status);
2807
2808 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2809
2810 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002811 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2812 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002813 return 0;
2814 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002815 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2816 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817 return 0;
2818 }
2819
2820 switch (result) {
2821 case L2CAP_CR_SUCCESS:
2822 sk->sk_state = BT_CONFIG;
2823 l2cap_pi(sk)->ident = 0;
2824 l2cap_pi(sk)->dcid = dcid;
2825 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2826
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002827 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2828
Linus Torvalds1da177e2005-04-16 15:20:36 -07002829 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2830 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002831 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002832 break;
2833
2834 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002835 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002836 break;
2837
2838 default:
2839 l2cap_chan_del(sk, ECONNREFUSED);
2840 break;
2841 }
2842
2843 bh_unlock_sock(sk);
2844 return 0;
2845}
2846
Al Viro88219a02007-07-29 00:17:25 -07002847static 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 -07002848{
2849 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2850 u16 dcid, flags;
2851 u8 rsp[64];
2852 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002853 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002854
2855 dcid = __le16_to_cpu(req->dcid);
2856 flags = __le16_to_cpu(req->flags);
2857
2858 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2859
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002860 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2861 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002862 return -ENOENT;
2863
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002864 if (sk->sk_state == BT_DISCONN)
2865 goto unlock;
2866
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002867 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002868 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002869 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2870 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2871 l2cap_build_conf_rsp(sk, rsp,
2872 L2CAP_CONF_REJECT, flags), rsp);
2873 goto unlock;
2874 }
2875
2876 /* Store config. */
2877 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2878 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002879
2880 if (flags & 0x0001) {
2881 /* Incomplete config. Send empty response. */
2882 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002883 l2cap_build_conf_rsp(sk, rsp,
2884 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002885 goto unlock;
2886 }
2887
2888 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002889 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002890 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002891 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002892 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002893 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002894
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002895 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002896 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002897
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002898 /* Reset config buffer. */
2899 l2cap_pi(sk)->conf_len = 0;
2900
Marcel Holtmann876d9482007-10-20 13:35:42 +02002901 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2902 goto unlock;
2903
Linus Torvalds1da177e2005-04-16 15:20:36 -07002904 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002905 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
2906 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002907 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2908
Linus Torvalds1da177e2005-04-16 15:20:36 -07002909 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002910
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002911 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002912 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002913 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002914 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2915 l2cap_ertm_init(sk);
2916
Linus Torvalds1da177e2005-04-16 15:20:36 -07002917 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002918 goto unlock;
2919 }
2920
2921 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002922 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002923 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002924 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002925 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002926 }
2927
2928unlock:
2929 bh_unlock_sock(sk);
2930 return 0;
2931}
2932
2933static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2934{
2935 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2936 u16 scid, flags, result;
2937 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002938 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002939
2940 scid = __le16_to_cpu(rsp->scid);
2941 flags = __le16_to_cpu(rsp->flags);
2942 result = __le16_to_cpu(rsp->result);
2943
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002944 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2945 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002946
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002947 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2948 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002949 return 0;
2950
2951 switch (result) {
2952 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002953 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002954 break;
2955
2956 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002957 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002958 char req[64];
2959
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02002960 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
2961 l2cap_send_disconn_req(conn, sk);
2962 goto done;
2963 }
2964
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002965 /* throw out any old stored conf requests */
2966 result = L2CAP_CONF_SUCCESS;
2967 len = l2cap_parse_conf_rsp(sk, rsp->data,
2968 len, req, &result);
2969 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002970 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002971 goto done;
2972 }
2973
2974 l2cap_send_cmd(conn, l2cap_get_ident(conn),
2975 L2CAP_CONF_REQ, len, req);
2976 l2cap_pi(sk)->num_conf_req++;
2977 if (result != L2CAP_CONF_SUCCESS)
2978 goto done;
2979 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002980 }
2981
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002982 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002983 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002984 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002985 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002986 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002987 goto done;
2988 }
2989
2990 if (flags & 0x01)
2991 goto done;
2992
Linus Torvalds1da177e2005-04-16 15:20:36 -07002993 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
2994
2995 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002996 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
2997 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002998 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2999
Linus Torvalds1da177e2005-04-16 15:20:36 -07003000 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003001 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003002 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003003 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003004 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3005 l2cap_ertm_init(sk);
3006
Linus Torvalds1da177e2005-04-16 15:20:36 -07003007 l2cap_chan_ready(sk);
3008 }
3009
3010done:
3011 bh_unlock_sock(sk);
3012 return 0;
3013}
3014
3015static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3016{
3017 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3018 struct l2cap_disconn_rsp rsp;
3019 u16 dcid, scid;
3020 struct sock *sk;
3021
3022 scid = __le16_to_cpu(req->scid);
3023 dcid = __le16_to_cpu(req->dcid);
3024
3025 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3026
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003027 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3028 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003029 return 0;
3030
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003031 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3032 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003033 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3034
3035 sk->sk_shutdown = SHUTDOWN_MASK;
3036
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003037 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003038
3039 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3040 skb_queue_purge(SREJ_QUEUE(sk));
3041 del_timer(&l2cap_pi(sk)->retrans_timer);
3042 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003043 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003044 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003045
Linus Torvalds1da177e2005-04-16 15:20:36 -07003046 l2cap_chan_del(sk, ECONNRESET);
3047 bh_unlock_sock(sk);
3048
3049 l2cap_sock_kill(sk);
3050 return 0;
3051}
3052
3053static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3054{
3055 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3056 u16 dcid, scid;
3057 struct sock *sk;
3058
3059 scid = __le16_to_cpu(rsp->scid);
3060 dcid = __le16_to_cpu(rsp->dcid);
3061
3062 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3063
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003064 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3065 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003066 return 0;
3067
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003068 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003069
3070 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3071 skb_queue_purge(SREJ_QUEUE(sk));
3072 del_timer(&l2cap_pi(sk)->retrans_timer);
3073 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003074 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003075 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003076
Linus Torvalds1da177e2005-04-16 15:20:36 -07003077 l2cap_chan_del(sk, 0);
3078 bh_unlock_sock(sk);
3079
3080 l2cap_sock_kill(sk);
3081 return 0;
3082}
3083
3084static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3085{
3086 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003087 u16 type;
3088
3089 type = __le16_to_cpu(req->type);
3090
3091 BT_DBG("type 0x%4.4x", type);
3092
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003093 if (type == L2CAP_IT_FEAT_MASK) {
3094 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003095 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003096 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3097 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3098 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003099 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003100 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3101 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003102 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003103 l2cap_send_cmd(conn, cmd->ident,
3104 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003105 } else if (type == L2CAP_IT_FIXED_CHAN) {
3106 u8 buf[12];
3107 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3108 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3109 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3110 memcpy(buf + 4, l2cap_fixed_chan, 8);
3111 l2cap_send_cmd(conn, cmd->ident,
3112 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003113 } else {
3114 struct l2cap_info_rsp rsp;
3115 rsp.type = cpu_to_le16(type);
3116 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3117 l2cap_send_cmd(conn, cmd->ident,
3118 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3119 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003120
3121 return 0;
3122}
3123
3124static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3125{
3126 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3127 u16 type, result;
3128
3129 type = __le16_to_cpu(rsp->type);
3130 result = __le16_to_cpu(rsp->result);
3131
3132 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3133
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003134 del_timer(&conn->info_timer);
3135
Marcel Holtmann984947d2009-02-06 23:35:19 +01003136 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003137 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003138
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003139 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003140 struct l2cap_info_req req;
3141 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3142
3143 conn->info_ident = l2cap_get_ident(conn);
3144
3145 l2cap_send_cmd(conn, conn->info_ident,
3146 L2CAP_INFO_REQ, sizeof(req), &req);
3147 } else {
3148 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3149 conn->info_ident = 0;
3150
3151 l2cap_conn_start(conn);
3152 }
3153 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003154 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003155 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003156
3157 l2cap_conn_start(conn);
3158 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003159
Linus Torvalds1da177e2005-04-16 15:20:36 -07003160 return 0;
3161}
3162
3163static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3164{
3165 u8 *data = skb->data;
3166 int len = skb->len;
3167 struct l2cap_cmd_hdr cmd;
3168 int err = 0;
3169
3170 l2cap_raw_recv(conn, skb);
3171
3172 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003173 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003174 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3175 data += L2CAP_CMD_HDR_SIZE;
3176 len -= L2CAP_CMD_HDR_SIZE;
3177
Al Viro88219a02007-07-29 00:17:25 -07003178 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003179
Al Viro88219a02007-07-29 00:17:25 -07003180 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 -07003181
Al Viro88219a02007-07-29 00:17:25 -07003182 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003183 BT_DBG("corrupted command");
3184 break;
3185 }
3186
3187 switch (cmd.code) {
3188 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003189 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003190 break;
3191
3192 case L2CAP_CONN_REQ:
3193 err = l2cap_connect_req(conn, &cmd, data);
3194 break;
3195
3196 case L2CAP_CONN_RSP:
3197 err = l2cap_connect_rsp(conn, &cmd, data);
3198 break;
3199
3200 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003201 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003202 break;
3203
3204 case L2CAP_CONF_RSP:
3205 err = l2cap_config_rsp(conn, &cmd, data);
3206 break;
3207
3208 case L2CAP_DISCONN_REQ:
3209 err = l2cap_disconnect_req(conn, &cmd, data);
3210 break;
3211
3212 case L2CAP_DISCONN_RSP:
3213 err = l2cap_disconnect_rsp(conn, &cmd, data);
3214 break;
3215
3216 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003217 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003218 break;
3219
3220 case L2CAP_ECHO_RSP:
3221 break;
3222
3223 case L2CAP_INFO_REQ:
3224 err = l2cap_information_req(conn, &cmd, data);
3225 break;
3226
3227 case L2CAP_INFO_RSP:
3228 err = l2cap_information_rsp(conn, &cmd, data);
3229 break;
3230
3231 default:
3232 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3233 err = -EINVAL;
3234 break;
3235 }
3236
3237 if (err) {
3238 struct l2cap_cmd_rej rej;
3239 BT_DBG("error %d", err);
3240
3241 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003242 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003243 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3244 }
3245
Al Viro88219a02007-07-29 00:17:25 -07003246 data += cmd_len;
3247 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003248 }
3249
3250 kfree_skb(skb);
3251}
3252
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003253static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3254{
3255 u16 our_fcs, rcv_fcs;
3256 int hdr_size = L2CAP_HDR_SIZE + 2;
3257
3258 if (pi->fcs == L2CAP_FCS_CRC16) {
3259 skb_trim(skb, skb->len - 2);
3260 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3261 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3262
3263 if (our_fcs != rcv_fcs)
3264 return -EINVAL;
3265 }
3266 return 0;
3267}
3268
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003269static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3270{
3271 struct l2cap_pinfo *pi = l2cap_pi(sk);
3272 u16 control = 0;
3273
3274 pi->frames_sent = 0;
3275 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3276
3277 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3278
3279 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3280 control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL;
3281 l2cap_send_sframe(pi, control);
3282 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
3283 }
3284
3285 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0)
3286 __mod_retrans_timer();
3287
3288 l2cap_ertm_send(sk);
3289
3290 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3291 pi->frames_sent == 0) {
3292 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003293 l2cap_send_sframe(pi, control);
3294 }
3295}
3296
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003297static void l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
3298{
3299 struct sk_buff *next_skb;
3300
3301 bt_cb(skb)->tx_seq = tx_seq;
3302 bt_cb(skb)->sar = sar;
3303
3304 next_skb = skb_peek(SREJ_QUEUE(sk));
3305 if (!next_skb) {
3306 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3307 return;
3308 }
3309
3310 do {
3311 if (bt_cb(next_skb)->tx_seq > tx_seq) {
3312 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
3313 return;
3314 }
3315
3316 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3317 break;
3318
3319 } while((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
3320
3321 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3322}
3323
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003324static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3325{
3326 struct l2cap_pinfo *pi = l2cap_pi(sk);
3327 struct sk_buff *_skb;
3328 int err = -EINVAL;
3329
3330 switch (control & L2CAP_CTRL_SAR) {
3331 case L2CAP_SDU_UNSEGMENTED:
3332 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3333 kfree_skb(pi->sdu);
3334 break;
3335 }
3336
3337 err = sock_queue_rcv_skb(sk, skb);
3338 if (!err)
3339 return 0;
3340
3341 break;
3342
3343 case L2CAP_SDU_START:
3344 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3345 kfree_skb(pi->sdu);
3346 break;
3347 }
3348
3349 pi->sdu_len = get_unaligned_le16(skb->data);
3350 skb_pull(skb, 2);
3351
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003352 if (pi->sdu_len > pi->imtu) {
3353 err = -EMSGSIZE;
3354 break;
3355 }
3356
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003357 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3358 if (!pi->sdu) {
3359 err = -ENOMEM;
3360 break;
3361 }
3362
3363 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3364
3365 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3366 pi->partial_sdu_len = skb->len;
3367 err = 0;
3368 break;
3369
3370 case L2CAP_SDU_CONTINUE:
3371 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3372 break;
3373
3374 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3375
3376 pi->partial_sdu_len += skb->len;
3377 if (pi->partial_sdu_len > pi->sdu_len)
3378 kfree_skb(pi->sdu);
3379 else
3380 err = 0;
3381
3382 break;
3383
3384 case L2CAP_SDU_END:
3385 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3386 break;
3387
3388 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3389
3390 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3391 pi->partial_sdu_len += skb->len;
3392
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003393 if (pi->partial_sdu_len > pi->imtu)
3394 goto drop;
3395
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003396 if (pi->partial_sdu_len == pi->sdu_len) {
3397 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3398 err = sock_queue_rcv_skb(sk, _skb);
3399 if (err < 0)
3400 kfree_skb(_skb);
3401 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003402 err = 0;
3403
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003404drop:
3405 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003406 break;
3407 }
3408
3409 kfree_skb(skb);
3410 return err;
3411}
3412
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003413static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3414{
3415 struct sk_buff *skb;
3416 u16 control = 0;
3417
3418 while((skb = skb_peek(SREJ_QUEUE(sk)))) {
3419 if (bt_cb(skb)->tx_seq != tx_seq)
3420 break;
3421
3422 skb = skb_dequeue(SREJ_QUEUE(sk));
3423 control |= bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3424 l2cap_sar_reassembly_sdu(sk, skb, control);
3425 l2cap_pi(sk)->buffer_seq_srej =
3426 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
3427 tx_seq++;
3428 }
3429}
3430
3431static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3432{
3433 struct l2cap_pinfo *pi = l2cap_pi(sk);
3434 struct srej_list *l, *tmp;
3435 u16 control;
3436
3437 list_for_each_entry_safe(l,tmp, SREJ_LIST(sk), list) {
3438 if (l->tx_seq == tx_seq) {
3439 list_del(&l->list);
3440 kfree(l);
3441 return;
3442 }
3443 control = L2CAP_SUPER_SELECT_REJECT;
3444 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3445 l2cap_send_sframe(pi, control);
3446 list_del(&l->list);
3447 list_add_tail(&l->list, SREJ_LIST(sk));
3448 }
3449}
3450
3451static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3452{
3453 struct l2cap_pinfo *pi = l2cap_pi(sk);
3454 struct srej_list *new;
3455 u16 control;
3456
3457 while (tx_seq != pi->expected_tx_seq) {
3458 control = L2CAP_SUPER_SELECT_REJECT;
3459 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3460 l2cap_send_sframe(pi, control);
3461
3462 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
3463 new->tx_seq = pi->expected_tx_seq++;
3464 list_add_tail(&new->list, SREJ_LIST(sk));
3465 }
3466 pi->expected_tx_seq++;
3467}
3468
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003469static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3470{
3471 struct l2cap_pinfo *pi = l2cap_pi(sk);
3472 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003473 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003474 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003475 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003476 int err = 0;
3477
3478 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3479
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003480 if (L2CAP_CTRL_FINAL & rx_control) {
3481 del_timer(&pi->monitor_timer);
3482 if (pi->unacked_frames > 0)
3483 __mod_retrans_timer();
3484 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3485 }
3486
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003487 pi->expected_ack_seq = req_seq;
3488 l2cap_drop_acked_frames(sk);
3489
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003490 if (tx_seq == pi->expected_tx_seq)
3491 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003492
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003493 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3494 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003495
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003496 first = list_first_entry(SREJ_LIST(sk),
3497 struct srej_list, list);
3498 if (tx_seq == first->tx_seq) {
3499 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3500 l2cap_check_srej_gap(sk, tx_seq);
3501
3502 list_del(&first->list);
3503 kfree(first);
3504
3505 if (list_empty(SREJ_LIST(sk))) {
3506 pi->buffer_seq = pi->buffer_seq_srej;
3507 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666cc2010-05-01 16:15:40 -03003508 l2cap_send_ack(pi);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003509 }
3510 } else {
3511 struct srej_list *l;
3512 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3513
3514 list_for_each_entry(l, SREJ_LIST(sk), list) {
3515 if (l->tx_seq == tx_seq) {
3516 l2cap_resend_srejframe(sk, tx_seq);
3517 return 0;
3518 }
3519 }
3520 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003521 }
3522 } else {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003523 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003524
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003525 INIT_LIST_HEAD(SREJ_LIST(sk));
3526 pi->buffer_seq_srej = pi->buffer_seq;
3527
3528 __skb_queue_head_init(SREJ_QUEUE(sk));
3529 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3530
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003531 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3532
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003533 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003534 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003535 return 0;
3536
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003537expected:
3538 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3539
3540 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3541 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3542 return 0;
3543 }
3544
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003545 if (rx_control & L2CAP_CTRL_FINAL) {
3546 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3547 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3548 else {
3549 sk->sk_send_head = TX_QUEUE(sk)->next;
3550 pi->next_tx_seq = pi->expected_ack_seq;
3551 l2cap_ertm_send(sk);
3552 }
3553 }
3554
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003555 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3556
3557 err = l2cap_sar_reassembly_sdu(sk, skb, rx_control);
3558 if (err < 0)
3559 return err;
3560
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003561 __mod_ack_timer();
3562
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003563 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
3564 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003565 l2cap_send_ack(pi);
3566
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003567 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003568}
3569
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003570static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003571{
3572 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003573
3574 pi->expected_ack_seq = __get_reqseq(rx_control);
3575 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003576
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003577 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003578 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3579 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3580 (pi->unacked_frames > 0))
3581 __mod_retrans_timer();
3582
3583 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3584 l2cap_send_srejtail(sk);
3585 } else {
3586 l2cap_send_i_or_rr_or_rnr(sk);
3587 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3588 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003589
3590 } else if (rx_control & L2CAP_CTRL_FINAL) {
3591 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003592
3593 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3594 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3595 else {
3596 sk->sk_send_head = TX_QUEUE(sk)->next;
3597 pi->next_tx_seq = pi->expected_ack_seq;
3598 l2cap_ertm_send(sk);
3599 }
3600
3601 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003602 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3603 (pi->unacked_frames > 0))
3604 __mod_retrans_timer();
3605
3606 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3607 if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
3608 l2cap_send_ack(pi);
3609 else
3610 l2cap_ertm_send(sk);
3611 }
3612}
3613
3614static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3615{
3616 struct l2cap_pinfo *pi = l2cap_pi(sk);
3617 u8 tx_seq = __get_reqseq(rx_control);
3618
3619 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3620
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03003621 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003622 l2cap_drop_acked_frames(sk);
3623
3624 if (rx_control & L2CAP_CTRL_FINAL) {
3625 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3626 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3627 else {
3628 sk->sk_send_head = TX_QUEUE(sk)->next;
3629 pi->next_tx_seq = pi->expected_ack_seq;
3630 l2cap_ertm_send(sk);
3631 }
3632 } else {
3633 sk->sk_send_head = TX_QUEUE(sk)->next;
3634 pi->next_tx_seq = pi->expected_ack_seq;
3635 l2cap_ertm_send(sk);
3636
3637 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3638 pi->srej_save_reqseq = tx_seq;
3639 pi->conn_state |= L2CAP_CONN_REJ_ACT;
3640 }
3641 }
3642}
3643static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
3644{
3645 struct l2cap_pinfo *pi = l2cap_pi(sk);
3646 u8 tx_seq = __get_reqseq(rx_control);
3647
3648 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3649
3650 if (rx_control & L2CAP_CTRL_POLL) {
3651 pi->expected_ack_seq = tx_seq;
3652 l2cap_drop_acked_frames(sk);
3653 l2cap_retransmit_frame(sk, tx_seq);
3654 l2cap_ertm_send(sk);
3655 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3656 pi->srej_save_reqseq = tx_seq;
3657 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3658 }
3659 } else if (rx_control & L2CAP_CTRL_FINAL) {
3660 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3661 pi->srej_save_reqseq == tx_seq)
3662 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
3663 else
3664 l2cap_retransmit_frame(sk, tx_seq);
3665 } else {
3666 l2cap_retransmit_frame(sk, tx_seq);
3667 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3668 pi->srej_save_reqseq = tx_seq;
3669 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3670 }
3671 }
3672}
3673
3674static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
3675{
3676 struct l2cap_pinfo *pi = l2cap_pi(sk);
3677 u8 tx_seq = __get_reqseq(rx_control);
3678
3679 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
3680 pi->expected_ack_seq = tx_seq;
3681 l2cap_drop_acked_frames(sk);
3682
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003683 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
3684 del_timer(&pi->retrans_timer);
3685 if (rx_control & L2CAP_CTRL_POLL) {
3686 u16 control = L2CAP_CTRL_FINAL;
3687 l2cap_send_rr_or_rnr(pi, control);
3688 }
3689 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003690 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003691
3692 if (rx_control & L2CAP_CTRL_POLL)
3693 l2cap_send_srejtail(sk);
3694 else
3695 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003696}
3697
3698static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3699{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003700 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3701
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003702 if (L2CAP_CTRL_FINAL & rx_control) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003703 del_timer(&l2cap_pi(sk)->monitor_timer);
3704 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003705 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003706 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003707 }
3708
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003709 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
3710 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003711 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003712 break;
3713
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003714 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003715 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003716 break;
3717
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003718 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003719 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003720 break;
3721
3722 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003723 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003724 break;
3725 }
3726
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03003727 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003728 return 0;
3729}
3730
Linus Torvalds1da177e2005-04-16 15:20:36 -07003731static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
3732{
3733 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003734 struct l2cap_pinfo *pi;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003735 u16 control, len;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003736 u8 tx_seq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003737
3738 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3739 if (!sk) {
3740 BT_DBG("unknown cid 0x%4.4x", cid);
3741 goto drop;
3742 }
3743
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003744 pi = l2cap_pi(sk);
3745
Linus Torvalds1da177e2005-04-16 15:20:36 -07003746 BT_DBG("sk %p, len %d", sk, skb->len);
3747
3748 if (sk->sk_state != BT_CONNECTED)
3749 goto drop;
3750
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003751 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003752 case L2CAP_MODE_BASIC:
3753 /* If socket recv buffers overflows we drop data here
3754 * which is *bad* because L2CAP has to be reliable.
3755 * But we don't have any other choice. L2CAP doesn't
3756 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003757
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003758 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003759 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003760
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003761 if (!sock_queue_rcv_skb(sk, skb))
3762 goto done;
3763 break;
3764
3765 case L2CAP_MODE_ERTM:
3766 control = get_unaligned_le16(skb->data);
3767 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003768 len = skb->len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003769
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003770 if (__is_sar_start(control))
3771 len -= 2;
3772
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003773 if (pi->fcs == L2CAP_FCS_CRC16)
3774 len -= 2;
3775
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003776 /*
3777 * We can just drop the corrupted I-frame here.
3778 * Receiver will miss it and start proper recovery
3779 * procedures and ask retransmission.
3780 */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03003781 if (len > pi->mps)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003782 goto drop;
3783
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003784 if (l2cap_check_fcs(pi, skb))
3785 goto drop;
3786
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003787 if (__is_iframe(control)) {
3788 if (len < 4)
3789 goto drop;
3790
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003791 l2cap_data_channel_iframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003792 } else {
3793 if (len != 0)
3794 goto drop;
3795
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003796 l2cap_data_channel_sframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003797 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003798
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003799 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003800
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003801 case L2CAP_MODE_STREAMING:
3802 control = get_unaligned_le16(skb->data);
3803 skb_pull(skb, 2);
3804 len = skb->len;
3805
3806 if (__is_sar_start(control))
3807 len -= 2;
3808
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003809 if (pi->fcs == L2CAP_FCS_CRC16)
3810 len -= 2;
3811
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03003812 if (len > pi->mps || len < 4 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003813 goto drop;
3814
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003815 if (l2cap_check_fcs(pi, skb))
3816 goto drop;
3817
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003818 tx_seq = __get_txseq(control);
3819
3820 if (pi->expected_tx_seq == tx_seq)
3821 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3822 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03003823 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003824
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003825 l2cap_sar_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003826
3827 goto done;
3828
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003829 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03003830 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003831 break;
3832 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003833
3834drop:
3835 kfree_skb(skb);
3836
3837done:
Marcel Holtmann01394182006-07-03 10:02:46 +02003838 if (sk)
3839 bh_unlock_sock(sk);
3840
Linus Torvalds1da177e2005-04-16 15:20:36 -07003841 return 0;
3842}
3843
Al Viro8e036fc2007-07-29 00:16:36 -07003844static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003845{
3846 struct sock *sk;
3847
3848 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
3849 if (!sk)
3850 goto drop;
3851
3852 BT_DBG("sk %p, len %d", sk, skb->len);
3853
3854 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
3855 goto drop;
3856
3857 if (l2cap_pi(sk)->imtu < skb->len)
3858 goto drop;
3859
3860 if (!sock_queue_rcv_skb(sk, skb))
3861 goto done;
3862
3863drop:
3864 kfree_skb(skb);
3865
3866done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003867 if (sk)
3868 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003869 return 0;
3870}
3871
3872static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
3873{
3874 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07003875 u16 cid, len;
3876 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003877
3878 skb_pull(skb, L2CAP_HDR_SIZE);
3879 cid = __le16_to_cpu(lh->cid);
3880 len = __le16_to_cpu(lh->len);
3881
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003882 if (len != skb->len) {
3883 kfree_skb(skb);
3884 return;
3885 }
3886
Linus Torvalds1da177e2005-04-16 15:20:36 -07003887 BT_DBG("len %d, cid 0x%4.4x", len, cid);
3888
3889 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003890 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003891 l2cap_sig_channel(conn, skb);
3892 break;
3893
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003894 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003895 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003896 skb_pull(skb, 2);
3897 l2cap_conless_channel(conn, psm, skb);
3898 break;
3899
3900 default:
3901 l2cap_data_channel(conn, cid, skb);
3902 break;
3903 }
3904}
3905
3906/* ---- L2CAP interface with lower layer (HCI) ---- */
3907
3908static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3909{
3910 int exact = 0, lm1 = 0, lm2 = 0;
3911 register struct sock *sk;
3912 struct hlist_node *node;
3913
3914 if (type != ACL_LINK)
3915 return 0;
3916
3917 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
3918
3919 /* Find listening sockets and check their link_mode */
3920 read_lock(&l2cap_sk_list.lock);
3921 sk_for_each(sk, node, &l2cap_sk_list.head) {
3922 if (sk->sk_state != BT_LISTEN)
3923 continue;
3924
3925 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003926 lm1 |= HCI_LM_ACCEPT;
3927 if (l2cap_pi(sk)->role_switch)
3928 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003929 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003930 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
3931 lm2 |= HCI_LM_ACCEPT;
3932 if (l2cap_pi(sk)->role_switch)
3933 lm2 |= HCI_LM_MASTER;
3934 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003935 }
3936 read_unlock(&l2cap_sk_list.lock);
3937
3938 return exact ? lm1 : lm2;
3939}
3940
3941static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
3942{
Marcel Holtmann01394182006-07-03 10:02:46 +02003943 struct l2cap_conn *conn;
3944
Linus Torvalds1da177e2005-04-16 15:20:36 -07003945 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
3946
3947 if (hcon->type != ACL_LINK)
3948 return 0;
3949
3950 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003951 conn = l2cap_conn_add(hcon, status);
3952 if (conn)
3953 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02003954 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003955 l2cap_conn_del(hcon, bt_err(status));
3956
3957 return 0;
3958}
3959
Marcel Holtmann2950f212009-02-12 14:02:50 +01003960static int l2cap_disconn_ind(struct hci_conn *hcon)
3961{
3962 struct l2cap_conn *conn = hcon->l2cap_data;
3963
3964 BT_DBG("hcon %p", hcon);
3965
3966 if (hcon->type != ACL_LINK || !conn)
3967 return 0x13;
3968
3969 return conn->disc_reason;
3970}
3971
3972static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003973{
3974 BT_DBG("hcon %p reason %d", hcon, reason);
3975
3976 if (hcon->type != ACL_LINK)
3977 return 0;
3978
3979 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02003980
Linus Torvalds1da177e2005-04-16 15:20:36 -07003981 return 0;
3982}
3983
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003984static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
3985{
Marcel Holtmann255c7602009-02-04 21:07:19 +01003986 if (sk->sk_type != SOCK_SEQPACKET)
3987 return;
3988
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003989 if (encrypt == 0x00) {
3990 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
3991 l2cap_sock_clear_timer(sk);
3992 l2cap_sock_set_timer(sk, HZ * 5);
3993 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
3994 __l2cap_sock_close(sk, ECONNREFUSED);
3995 } else {
3996 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
3997 l2cap_sock_clear_timer(sk);
3998 }
3999}
4000
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004001static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004002{
4003 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004004 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004005 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004006
Marcel Holtmann01394182006-07-03 10:02:46 +02004007 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004008 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004009
Linus Torvalds1da177e2005-04-16 15:20:36 -07004010 l = &conn->chan_list;
4011
4012 BT_DBG("conn %p", conn);
4013
4014 read_lock(&l->lock);
4015
4016 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4017 bh_lock_sock(sk);
4018
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004019 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4020 bh_unlock_sock(sk);
4021 continue;
4022 }
4023
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004024 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004025 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004026 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004027 bh_unlock_sock(sk);
4028 continue;
4029 }
4030
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004031 if (sk->sk_state == BT_CONNECT) {
4032 if (!status) {
4033 struct l2cap_conn_req req;
4034 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4035 req.psm = l2cap_pi(sk)->psm;
4036
4037 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
4038
4039 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4040 L2CAP_CONN_REQ, sizeof(req), &req);
4041 } else {
4042 l2cap_sock_clear_timer(sk);
4043 l2cap_sock_set_timer(sk, HZ / 10);
4044 }
4045 } else if (sk->sk_state == BT_CONNECT2) {
4046 struct l2cap_conn_rsp rsp;
4047 __u16 result;
4048
4049 if (!status) {
4050 sk->sk_state = BT_CONFIG;
4051 result = L2CAP_CR_SUCCESS;
4052 } else {
4053 sk->sk_state = BT_DISCONN;
4054 l2cap_sock_set_timer(sk, HZ / 10);
4055 result = L2CAP_CR_SEC_BLOCK;
4056 }
4057
4058 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4059 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4060 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004061 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004062 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4063 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004064 }
4065
Linus Torvalds1da177e2005-04-16 15:20:36 -07004066 bh_unlock_sock(sk);
4067 }
4068
4069 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004070
Linus Torvalds1da177e2005-04-16 15:20:36 -07004071 return 0;
4072}
4073
4074static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4075{
4076 struct l2cap_conn *conn = hcon->l2cap_data;
4077
4078 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4079 goto drop;
4080
4081 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4082
4083 if (flags & ACL_START) {
4084 struct l2cap_hdr *hdr;
4085 int len;
4086
4087 if (conn->rx_len) {
4088 BT_ERR("Unexpected start frame (len %d)", skb->len);
4089 kfree_skb(conn->rx_skb);
4090 conn->rx_skb = NULL;
4091 conn->rx_len = 0;
4092 l2cap_conn_unreliable(conn, ECOMM);
4093 }
4094
4095 if (skb->len < 2) {
4096 BT_ERR("Frame is too short (len %d)", skb->len);
4097 l2cap_conn_unreliable(conn, ECOMM);
4098 goto drop;
4099 }
4100
4101 hdr = (struct l2cap_hdr *) skb->data;
4102 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4103
4104 if (len == skb->len) {
4105 /* Complete frame received */
4106 l2cap_recv_frame(conn, skb);
4107 return 0;
4108 }
4109
4110 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4111
4112 if (skb->len > len) {
4113 BT_ERR("Frame is too long (len %d, expected len %d)",
4114 skb->len, len);
4115 l2cap_conn_unreliable(conn, ECOMM);
4116 goto drop;
4117 }
4118
4119 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004120 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4121 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004122 goto drop;
4123
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004124 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004125 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004126 conn->rx_len = len - skb->len;
4127 } else {
4128 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4129
4130 if (!conn->rx_len) {
4131 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4132 l2cap_conn_unreliable(conn, ECOMM);
4133 goto drop;
4134 }
4135
4136 if (skb->len > conn->rx_len) {
4137 BT_ERR("Fragment is too long (len %d, expected %d)",
4138 skb->len, conn->rx_len);
4139 kfree_skb(conn->rx_skb);
4140 conn->rx_skb = NULL;
4141 conn->rx_len = 0;
4142 l2cap_conn_unreliable(conn, ECOMM);
4143 goto drop;
4144 }
4145
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004146 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004147 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004148 conn->rx_len -= skb->len;
4149
4150 if (!conn->rx_len) {
4151 /* Complete frame received */
4152 l2cap_recv_frame(conn, conn->rx_skb);
4153 conn->rx_skb = NULL;
4154 }
4155 }
4156
4157drop:
4158 kfree_skb(skb);
4159 return 0;
4160}
4161
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004162static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004163{
4164 struct sock *sk;
4165 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004166
4167 read_lock_bh(&l2cap_sk_list.lock);
4168
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004169 sk_for_each(sk, node, &l2cap_sk_list.head) {
4170 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004171
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004172 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4173 batostr(&bt_sk(sk)->src),
4174 batostr(&bt_sk(sk)->dst),
4175 sk->sk_state, __le16_to_cpu(pi->psm),
4176 pi->scid, pi->dcid,
4177 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004178 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004179
Linus Torvalds1da177e2005-04-16 15:20:36 -07004180 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004181
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004182 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004183}
4184
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004185static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4186{
4187 return single_open(file, l2cap_debugfs_show, inode->i_private);
4188}
4189
4190static const struct file_operations l2cap_debugfs_fops = {
4191 .open = l2cap_debugfs_open,
4192 .read = seq_read,
4193 .llseek = seq_lseek,
4194 .release = single_release,
4195};
4196
4197static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004198
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004199static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004200 .family = PF_BLUETOOTH,
4201 .owner = THIS_MODULE,
4202 .release = l2cap_sock_release,
4203 .bind = l2cap_sock_bind,
4204 .connect = l2cap_sock_connect,
4205 .listen = l2cap_sock_listen,
4206 .accept = l2cap_sock_accept,
4207 .getname = l2cap_sock_getname,
4208 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004209 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004210 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004211 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004212 .mmap = sock_no_mmap,
4213 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004214 .shutdown = l2cap_sock_shutdown,
4215 .setsockopt = l2cap_sock_setsockopt,
4216 .getsockopt = l2cap_sock_getsockopt
4217};
4218
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004219static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004220 .family = PF_BLUETOOTH,
4221 .owner = THIS_MODULE,
4222 .create = l2cap_sock_create,
4223};
4224
4225static struct hci_proto l2cap_hci_proto = {
4226 .name = "L2CAP",
4227 .id = HCI_PROTO_L2CAP,
4228 .connect_ind = l2cap_connect_ind,
4229 .connect_cfm = l2cap_connect_cfm,
4230 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004231 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004232 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004233 .recv_acldata = l2cap_recv_acldata
4234};
4235
4236static int __init l2cap_init(void)
4237{
4238 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004239
Linus Torvalds1da177e2005-04-16 15:20:36 -07004240 err = proto_register(&l2cap_proto, 0);
4241 if (err < 0)
4242 return err;
4243
4244 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4245 if (err < 0) {
4246 BT_ERR("L2CAP socket registration failed");
4247 goto error;
4248 }
4249
4250 err = hci_register_proto(&l2cap_hci_proto);
4251 if (err < 0) {
4252 BT_ERR("L2CAP protocol registration failed");
4253 bt_sock_unregister(BTPROTO_L2CAP);
4254 goto error;
4255 }
4256
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004257 if (bt_debugfs) {
4258 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4259 bt_debugfs, NULL, &l2cap_debugfs_fops);
4260 if (!l2cap_debugfs)
4261 BT_ERR("Failed to create L2CAP debug file");
4262 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004263
4264 BT_INFO("L2CAP ver %s", VERSION);
4265 BT_INFO("L2CAP socket layer initialized");
4266
4267 return 0;
4268
4269error:
4270 proto_unregister(&l2cap_proto);
4271 return err;
4272}
4273
4274static void __exit l2cap_exit(void)
4275{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004276 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004277
4278 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4279 BT_ERR("L2CAP socket unregistration failed");
4280
4281 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4282 BT_ERR("L2CAP protocol unregistration failed");
4283
4284 proto_unregister(&l2cap_proto);
4285}
4286
4287void l2cap_load(void)
4288{
4289 /* Dummy function to trigger automatic L2CAP module loading by
4290 * other modules that use L2CAP sockets but don't use any other
4291 * symbols from it. */
4292 return;
4293}
4294EXPORT_SYMBOL(l2cap_load);
4295
4296module_init(l2cap_init);
4297module_exit(l2cap_exit);
4298
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004299module_param(enable_ertm, bool, 0644);
4300MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4301
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +02004302module_param(max_transmit, uint, 0644);
4303MODULE_PARM_DESC(max_transmit, "Max transmit value (default = 3)");
4304
Gustavo F. Padovan369ba302010-05-01 16:15:41 -03004305module_param(tx_window, uint, 0644);
4306MODULE_PARM_DESC(tx_window, "Transmission window size value (default = 63)");
4307
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004308MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004309MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4310MODULE_VERSION(VERSION);
4311MODULE_LICENSE("GPL");
4312MODULE_ALIAS("bt-proto-0");