blob: 03006568f8a197c1790320d80184286204c02e34 [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. Padovanaf05b302009-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;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020060
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070061static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Marcel Holtmanne1027a72009-02-09 09:18:02 +010062static u8 l2cap_fixed_chan[8] = { 0x02, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070063
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080064static const struct proto_ops l2cap_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070065
66static struct bt_sock_list l2cap_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070067 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070068};
69
Linus Torvalds1da177e2005-04-16 15:20:36 -070070static void __l2cap_sock_close(struct sock *sk, int reason);
71static void l2cap_sock_close(struct sock *sk);
72static void l2cap_sock_kill(struct sock *sk);
73
74static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
75 u8 code, u8 ident, u16 dlen, void *data);
76
77/* ---- L2CAP timers ---- */
78static void l2cap_sock_timeout(unsigned long arg)
79{
80 struct sock *sk = (struct sock *) arg;
Marcel Holtmannb1235d72008-07-14 20:13:54 +020081 int reason;
Linus Torvalds1da177e2005-04-16 15:20:36 -070082
83 BT_DBG("sock %p state %d", sk, sk->sk_state);
84
85 bh_lock_sock(sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +020086
Marcel Holtmannf62e4322009-01-15 21:58:44 +010087 if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
88 reason = ECONNREFUSED;
89 else if (sk->sk_state == BT_CONNECT &&
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +010090 l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
Marcel Holtmannb1235d72008-07-14 20:13:54 +020091 reason = ECONNREFUSED;
92 else
93 reason = ETIMEDOUT;
94
95 __l2cap_sock_close(sk, reason);
96
Linus Torvalds1da177e2005-04-16 15:20:36 -070097 bh_unlock_sock(sk);
98
99 l2cap_sock_kill(sk);
100 sock_put(sk);
101}
102
103static void l2cap_sock_set_timer(struct sock *sk, long timeout)
104{
105 BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
106 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
107}
108
109static void l2cap_sock_clear_timer(struct sock *sk)
110{
111 BT_DBG("sock %p state %d", sk, sk->sk_state);
112 sk_stop_timer(sk, &sk->sk_timer);
113}
114
Marcel Holtmann01394182006-07-03 10:02:46 +0200115/* ---- L2CAP channels ---- */
116static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
117{
118 struct sock *s;
119 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
120 if (l2cap_pi(s)->dcid == cid)
121 break;
122 }
123 return s;
124}
125
126static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
127{
128 struct sock *s;
129 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
130 if (l2cap_pi(s)->scid == cid)
131 break;
132 }
133 return s;
134}
135
136/* Find channel with given SCID.
137 * Returns locked socket */
138static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
139{
140 struct sock *s;
141 read_lock(&l->lock);
142 s = __l2cap_get_chan_by_scid(l, cid);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300143 if (s)
144 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200145 read_unlock(&l->lock);
146 return s;
147}
148
149static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
150{
151 struct sock *s;
152 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
153 if (l2cap_pi(s)->ident == ident)
154 break;
155 }
156 return s;
157}
158
159static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
160{
161 struct sock *s;
162 read_lock(&l->lock);
163 s = __l2cap_get_chan_by_ident(l, ident);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300164 if (s)
165 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200166 read_unlock(&l->lock);
167 return s;
168}
169
170static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
171{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300172 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200173
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300174 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300175 if (!__l2cap_get_chan_by_scid(l, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200176 return cid;
177 }
178
179 return 0;
180}
181
182static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
183{
184 sock_hold(sk);
185
186 if (l->head)
187 l2cap_pi(l->head)->prev_c = sk;
188
189 l2cap_pi(sk)->next_c = l->head;
190 l2cap_pi(sk)->prev_c = NULL;
191 l->head = sk;
192}
193
194static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
195{
196 struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
197
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200198 write_lock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200199 if (sk == l->head)
200 l->head = next;
201
202 if (next)
203 l2cap_pi(next)->prev_c = prev;
204 if (prev)
205 l2cap_pi(prev)->next_c = next;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200206 write_unlock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200207
208 __sock_put(sk);
209}
210
211static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
212{
213 struct l2cap_chan_list *l = &conn->chan_list;
214
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300215 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
216 l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200217
Marcel Holtmann2950f212009-02-12 14:02:50 +0100218 conn->disc_reason = 0x13;
219
Marcel Holtmann01394182006-07-03 10:02:46 +0200220 l2cap_pi(sk)->conn = conn;
221
222 if (sk->sk_type == SOCK_SEQPACKET) {
223 /* Alloc CID for connection-oriented socket */
224 l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
225 } else if (sk->sk_type == SOCK_DGRAM) {
226 /* Connectionless socket */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300227 l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
228 l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
Marcel Holtmann01394182006-07-03 10:02:46 +0200229 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
230 } else {
231 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300232 l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
233 l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
Marcel Holtmann01394182006-07-03 10:02:46 +0200234 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
235 }
236
237 __l2cap_chan_link(l, sk);
238
239 if (parent)
240 bt_accept_enqueue(parent, sk);
241}
242
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900243/* Delete channel.
Marcel Holtmann01394182006-07-03 10:02:46 +0200244 * Must be called on the locked socket. */
245static void l2cap_chan_del(struct sock *sk, int err)
246{
247 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
248 struct sock *parent = bt_sk(sk)->parent;
249
250 l2cap_sock_clear_timer(sk);
251
252 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
253
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900254 if (conn) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200255 /* Unlink from channel list */
256 l2cap_chan_unlink(&conn->chan_list, sk);
257 l2cap_pi(sk)->conn = NULL;
258 hci_conn_put(conn->hcon);
259 }
260
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200261 sk->sk_state = BT_CLOSED;
Marcel Holtmann01394182006-07-03 10:02:46 +0200262 sock_set_flag(sk, SOCK_ZAPPED);
263
264 if (err)
265 sk->sk_err = err;
266
267 if (parent) {
268 bt_accept_unlink(sk);
269 parent->sk_data_ready(parent, 0);
270 } else
271 sk->sk_state_change(sk);
272}
273
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200274/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100275static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200276{
277 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100278 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200279
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100280 if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
281 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
282 auth_type = HCI_AT_NO_BONDING_MITM;
283 else
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300284 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100285
286 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
287 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
288 } else {
289 switch (l2cap_pi(sk)->sec_level) {
290 case BT_SECURITY_HIGH:
291 auth_type = HCI_AT_GENERAL_BONDING_MITM;
292 break;
293 case BT_SECURITY_MEDIUM:
294 auth_type = HCI_AT_GENERAL_BONDING;
295 break;
296 default:
297 auth_type = HCI_AT_NO_BONDING;
298 break;
299 }
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100300 }
301
302 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
303 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200304}
305
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200306static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
307{
308 u8 id;
309
310 /* Get next available identificator.
311 * 1 - 128 are used by kernel.
312 * 129 - 199 are reserved.
313 * 200 - 254 are used by utilities like l2ping, etc.
314 */
315
316 spin_lock_bh(&conn->lock);
317
318 if (++conn->tx_ident > 128)
319 conn->tx_ident = 1;
320
321 id = conn->tx_ident;
322
323 spin_unlock_bh(&conn->lock);
324
325 return id;
326}
327
328static inline int l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
329{
330 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
331
332 BT_DBG("code 0x%2.2x", code);
333
334 if (!skb)
335 return -ENOMEM;
336
337 return hci_send_acl(conn->hcon, skb, 0);
338}
339
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300340static inline int l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
341{
342 struct sk_buff *skb;
343 struct l2cap_hdr *lh;
344 struct l2cap_conn *conn = pi->conn;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300345 int count, hlen = L2CAP_HDR_SIZE + 2;
346
347 if (pi->fcs == L2CAP_FCS_CRC16)
348 hlen += 2;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300349
350 BT_DBG("pi %p, control 0x%2.2x", pi, control);
351
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300352 count = min_t(unsigned int, conn->mtu, hlen);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300353 control |= L2CAP_CTRL_FRAME_TYPE;
354
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -0300355 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
356 control |= L2CAP_CTRL_FINAL;
357 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
358 }
359
Gustavo F. Padovanf0946cc2010-05-01 16:15:37 -0300360 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
361 control |= L2CAP_CTRL_POLL;
362 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
363 }
364
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300365 skb = bt_skb_alloc(count, GFP_ATOMIC);
366 if (!skb)
367 return -ENOMEM;
368
369 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300370 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300371 lh->cid = cpu_to_le16(pi->dcid);
372 put_unaligned_le16(control, skb_put(skb, 2));
373
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300374 if (pi->fcs == L2CAP_FCS_CRC16) {
375 u16 fcs = crc16(0, (u8 *)lh, count - 2);
376 put_unaligned_le16(fcs, skb_put(skb, 2));
377 }
378
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300379 return hci_send_acl(pi->conn->hcon, skb, 0);
380}
381
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300382static inline int l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
383{
384 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY)
385 control |= L2CAP_SUPER_RCV_NOT_READY;
386 else
387 control |= L2CAP_SUPER_RCV_READY;
388
Gustavo F. Padovan2ab25cd2009-10-03 02:34:40 -0300389 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
390
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300391 return l2cap_send_sframe(pi, control);
392}
393
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200394static void l2cap_do_start(struct sock *sk)
395{
396 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
397
398 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100399 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
400 return;
401
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100402 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200403 struct l2cap_conn_req req;
404 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
405 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200406
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200407 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200408
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200409 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200410 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200411 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200412 } else {
413 struct l2cap_info_req req;
414 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
415
416 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
417 conn->info_ident = l2cap_get_ident(conn);
418
419 mod_timer(&conn->info_timer, jiffies +
420 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
421
422 l2cap_send_cmd(conn, conn->info_ident,
423 L2CAP_INFO_REQ, sizeof(req), &req);
424 }
425}
426
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300427static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk)
428{
429 struct l2cap_disconn_req req;
430
431 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
432 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
433 l2cap_send_cmd(conn, l2cap_get_ident(conn),
434 L2CAP_DISCONN_REQ, sizeof(req), &req);
435}
436
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200438static void l2cap_conn_start(struct l2cap_conn *conn)
439{
440 struct l2cap_chan_list *l = &conn->chan_list;
441 struct sock *sk;
442
443 BT_DBG("conn %p", conn);
444
445 read_lock(&l->lock);
446
447 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
448 bh_lock_sock(sk);
449
450 if (sk->sk_type != SOCK_SEQPACKET) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200451 bh_unlock_sock(sk);
452 continue;
453 }
454
455 if (sk->sk_state == BT_CONNECT) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100456 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200457 struct l2cap_conn_req req;
458 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
459 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200460
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200461 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200462
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200463 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200464 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200465 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200466 } else if (sk->sk_state == BT_CONNECT2) {
467 struct l2cap_conn_rsp rsp;
468 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
469 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
470
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100471 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100472 if (bt_sk(sk)->defer_setup) {
473 struct sock *parent = bt_sk(sk)->parent;
474 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
475 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
476 parent->sk_data_ready(parent, 0);
477
478 } else {
479 sk->sk_state = BT_CONFIG;
480 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
481 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
482 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200483 } else {
484 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
485 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
486 }
487
488 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
489 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
490 }
491
492 bh_unlock_sock(sk);
493 }
494
495 read_unlock(&l->lock);
496}
497
498static void l2cap_conn_ready(struct l2cap_conn *conn)
499{
500 struct l2cap_chan_list *l = &conn->chan_list;
501 struct sock *sk;
502
503 BT_DBG("conn %p", conn);
504
505 read_lock(&l->lock);
506
507 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
508 bh_lock_sock(sk);
509
510 if (sk->sk_type != SOCK_SEQPACKET) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200511 l2cap_sock_clear_timer(sk);
512 sk->sk_state = BT_CONNECTED;
513 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200514 } else if (sk->sk_state == BT_CONNECT)
515 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200516
517 bh_unlock_sock(sk);
518 }
519
520 read_unlock(&l->lock);
521}
522
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200523/* Notify sockets that we cannot guaranty reliability anymore */
524static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
525{
526 struct l2cap_chan_list *l = &conn->chan_list;
527 struct sock *sk;
528
529 BT_DBG("conn %p", conn);
530
531 read_lock(&l->lock);
532
533 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100534 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200535 sk->sk_err = err;
536 }
537
538 read_unlock(&l->lock);
539}
540
541static void l2cap_info_timeout(unsigned long arg)
542{
543 struct l2cap_conn *conn = (void *) arg;
544
Marcel Holtmann984947d2009-02-06 23:35:19 +0100545 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100546 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100547
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200548 l2cap_conn_start(conn);
549}
550
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
552{
Marcel Holtmann01394182006-07-03 10:02:46 +0200553 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554
Marcel Holtmann01394182006-07-03 10:02:46 +0200555 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 return conn;
557
Marcel Holtmann01394182006-07-03 10:02:46 +0200558 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
559 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561
562 hcon->l2cap_data = conn;
563 conn->hcon = hcon;
564
Marcel Holtmann01394182006-07-03 10:02:46 +0200565 BT_DBG("hcon %p conn %p", hcon, conn);
566
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 conn->mtu = hcon->hdev->acl_mtu;
568 conn->src = &hcon->hdev->bdaddr;
569 conn->dst = &hcon->dst;
570
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200571 conn->feat_mask = 0;
572
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573 spin_lock_init(&conn->lock);
574 rwlock_init(&conn->chan_list.lock);
575
Dave Young45054dc2009-10-18 20:28:30 +0000576 setup_timer(&conn->info_timer, l2cap_info_timeout,
577 (unsigned long) conn);
578
Marcel Holtmann2950f212009-02-12 14:02:50 +0100579 conn->disc_reason = 0x13;
580
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 return conn;
582}
583
Marcel Holtmann01394182006-07-03 10:02:46 +0200584static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585{
Marcel Holtmann01394182006-07-03 10:02:46 +0200586 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587 struct sock *sk;
588
Marcel Holtmann01394182006-07-03 10:02:46 +0200589 if (!conn)
590 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591
592 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
593
Wei Yongjun7585b972009-02-25 18:29:52 +0800594 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595
596 /* Kill channels */
597 while ((sk = conn->chan_list.head)) {
598 bh_lock_sock(sk);
599 l2cap_chan_del(sk, err);
600 bh_unlock_sock(sk);
601 l2cap_sock_kill(sk);
602 }
603
Dave Young8e8440f2008-03-03 12:18:55 -0800604 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
605 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800606
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 hcon->l2cap_data = NULL;
608 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609}
610
611static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
612{
613 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200614 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200616 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617}
618
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700620static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621{
622 struct sock *sk;
623 struct hlist_node *node;
624 sk_for_each(sk, node, &l2cap_sk_list.head)
625 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
626 goto found;
627 sk = NULL;
628found:
629 return sk;
630}
631
632/* Find socket with psm and source bdaddr.
633 * Returns closest match.
634 */
Al Viro8e036fc2007-07-29 00:16:36 -0700635static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636{
637 struct sock *sk = NULL, *sk1 = NULL;
638 struct hlist_node *node;
639
640 sk_for_each(sk, node, &l2cap_sk_list.head) {
641 if (state && sk->sk_state != state)
642 continue;
643
644 if (l2cap_pi(sk)->psm == psm) {
645 /* Exact match. */
646 if (!bacmp(&bt_sk(sk)->src, src))
647 break;
648
649 /* Closest match */
650 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
651 sk1 = sk;
652 }
653 }
654 return node ? sk : sk1;
655}
656
657/* Find socket with given address (psm, src).
658 * Returns locked socket */
Al Viro8e036fc2007-07-29 00:16:36 -0700659static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660{
661 struct sock *s;
662 read_lock(&l2cap_sk_list.lock);
663 s = __l2cap_get_sock_by_psm(state, psm, src);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300664 if (s)
665 bh_lock_sock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666 read_unlock(&l2cap_sk_list.lock);
667 return s;
668}
669
670static void l2cap_sock_destruct(struct sock *sk)
671{
672 BT_DBG("sk %p", sk);
673
674 skb_queue_purge(&sk->sk_receive_queue);
675 skb_queue_purge(&sk->sk_write_queue);
676}
677
678static void l2cap_sock_cleanup_listen(struct sock *parent)
679{
680 struct sock *sk;
681
682 BT_DBG("parent %p", parent);
683
684 /* Close not yet accepted channels */
685 while ((sk = bt_accept_dequeue(parent, NULL)))
686 l2cap_sock_close(sk);
687
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200688 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689 sock_set_flag(parent, SOCK_ZAPPED);
690}
691
692/* Kill socket (only if zapped and orphan)
693 * Must be called on unlocked socket.
694 */
695static void l2cap_sock_kill(struct sock *sk)
696{
697 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
698 return;
699
700 BT_DBG("sk %p state %d", sk, sk->sk_state);
701
702 /* Kill poor orphan */
703 bt_sock_unlink(&l2cap_sk_list, sk);
704 sock_set_flag(sk, SOCK_DEAD);
705 sock_put(sk);
706}
707
708static void __l2cap_sock_close(struct sock *sk, int reason)
709{
710 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
711
712 switch (sk->sk_state) {
713 case BT_LISTEN:
714 l2cap_sock_cleanup_listen(sk);
715 break;
716
717 case BT_CONNECTED:
718 case BT_CONFIG:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719 if (sk->sk_type == SOCK_SEQPACKET) {
720 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721
722 sk->sk_state = BT_DISCONN;
723 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300724 l2cap_send_disconn_req(conn, sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200725 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727 break;
728
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100729 case BT_CONNECT2:
730 if (sk->sk_type == SOCK_SEQPACKET) {
731 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
732 struct l2cap_conn_rsp rsp;
733 __u16 result;
734
735 if (bt_sk(sk)->defer_setup)
736 result = L2CAP_CR_SEC_BLOCK;
737 else
738 result = L2CAP_CR_BAD_PSM;
739
740 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
741 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
742 rsp.result = cpu_to_le16(result);
743 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
744 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
745 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
746 } else
747 l2cap_chan_del(sk, reason);
748 break;
749
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750 case BT_CONNECT:
751 case BT_DISCONN:
752 l2cap_chan_del(sk, reason);
753 break;
754
755 default:
756 sock_set_flag(sk, SOCK_ZAPPED);
757 break;
758 }
759}
760
761/* Must be called on unlocked socket. */
762static void l2cap_sock_close(struct sock *sk)
763{
764 l2cap_sock_clear_timer(sk);
765 lock_sock(sk);
766 __l2cap_sock_close(sk, ECONNRESET);
767 release_sock(sk);
768 l2cap_sock_kill(sk);
769}
770
771static void l2cap_sock_init(struct sock *sk, struct sock *parent)
772{
773 struct l2cap_pinfo *pi = l2cap_pi(sk);
774
775 BT_DBG("sk %p", sk);
776
777 if (parent) {
778 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100779 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
780
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781 pi->imtu = l2cap_pi(parent)->imtu;
782 pi->omtu = l2cap_pi(parent)->omtu;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700783 pi->mode = l2cap_pi(parent)->mode;
784 pi->fcs = l2cap_pi(parent)->fcs;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100785 pi->sec_level = l2cap_pi(parent)->sec_level;
786 pi->role_switch = l2cap_pi(parent)->role_switch;
787 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788 } else {
789 pi->imtu = L2CAP_DEFAULT_MTU;
790 pi->omtu = 0;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700791 pi->mode = L2CAP_MODE_BASIC;
792 pi->fcs = L2CAP_FCS_CRC16;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100793 pi->sec_level = BT_SECURITY_LOW;
794 pi->role_switch = 0;
795 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796 }
797
798 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200799 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Dave Young45054dc2009-10-18 20:28:30 +0000801 skb_queue_head_init(TX_QUEUE(sk));
802 skb_queue_head_init(SREJ_QUEUE(sk));
803 INIT_LIST_HEAD(SREJ_LIST(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804}
805
806static struct proto l2cap_proto = {
807 .name = "L2CAP",
808 .owner = THIS_MODULE,
809 .obj_size = sizeof(struct l2cap_pinfo)
810};
811
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700812static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813{
814 struct sock *sk;
815
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700816 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817 if (!sk)
818 return NULL;
819
820 sock_init_data(sock, sk);
821 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
822
823 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200824 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825
826 sock_reset_flag(sk, SOCK_ZAPPED);
827
828 sk->sk_protocol = proto;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200829 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200831 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832
833 bt_sock_link(&l2cap_sk_list, sk);
834 return sk;
835}
836
Eric Paris3f378b62009-11-05 22:18:14 -0800837static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
838 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839{
840 struct sock *sk;
841
842 BT_DBG("sock %p", sock);
843
844 sock->state = SS_UNCONNECTED;
845
846 if (sock->type != SOCK_SEQPACKET &&
847 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
848 return -ESOCKTNOSUPPORT;
849
Eric Parisc84b3262009-11-05 20:45:52 -0800850 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 return -EPERM;
852
853 sock->ops = &l2cap_sock_ops;
854
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700855 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 if (!sk)
857 return -ENOMEM;
858
859 l2cap_sock_init(sk, NULL);
860 return 0;
861}
862
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100863static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100866 struct sockaddr_l2 la;
867 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100869 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870
871 if (!addr || addr->sa_family != AF_BLUETOOTH)
872 return -EINVAL;
873
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100874 memset(&la, 0, sizeof(la));
875 len = min_t(unsigned int, sizeof(la), alen);
876 memcpy(&la, addr, len);
877
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100878 if (la.l2_cid)
879 return -EINVAL;
880
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881 lock_sock(sk);
882
883 if (sk->sk_state != BT_OPEN) {
884 err = -EBADFD;
885 goto done;
886 }
887
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200888 if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
Marcel Holtmann847641d2007-01-22 22:00:45 +0100889 !capable(CAP_NET_BIND_SERVICE)) {
890 err = -EACCES;
891 goto done;
892 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900893
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894 write_lock_bh(&l2cap_sk_list.lock);
895
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100896 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897 err = -EADDRINUSE;
898 } else {
899 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100900 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
901 l2cap_pi(sk)->psm = la.l2_psm;
902 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100904
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200905 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
906 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100907 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908 }
909
910 write_unlock_bh(&l2cap_sk_list.lock);
911
912done:
913 release_sock(sk);
914 return err;
915}
916
917static int l2cap_do_connect(struct sock *sk)
918{
919 bdaddr_t *src = &bt_sk(sk)->src;
920 bdaddr_t *dst = &bt_sk(sk)->dst;
921 struct l2cap_conn *conn;
922 struct hci_conn *hcon;
923 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200924 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +0200925 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100927 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
928 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300930 hdev = hci_get_route(dst, src);
931 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700932 return -EHOSTUNREACH;
933
934 hci_dev_lock_bh(hdev);
935
936 err = -ENOMEM;
937
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100938 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100939 switch (l2cap_pi(sk)->sec_level) {
940 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100941 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100942 break;
943 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100944 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100945 break;
946 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100947 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100948 break;
949 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100950 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100951 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200952 auth_type = HCI_AT_NO_BONDING_MITM;
953 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200954 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +0100955
956 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
957 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100958 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100959 switch (l2cap_pi(sk)->sec_level) {
960 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100961 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100962 break;
963 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200964 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100965 break;
966 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100967 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100968 break;
969 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200970 }
971
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100972 hcon = hci_connect(hdev, ACL_LINK, dst,
973 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974 if (!hcon)
975 goto done;
976
977 conn = l2cap_conn_add(hcon, 0);
978 if (!conn) {
979 hci_conn_put(hcon);
980 goto done;
981 }
982
983 err = 0;
984
985 /* Update source addr of the socket */
986 bacpy(src, conn->src);
987
988 l2cap_chan_add(conn, sk, NULL);
989
990 sk->sk_state = BT_CONNECT;
991 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
992
993 if (hcon->state == BT_CONNECTED) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200994 if (sk->sk_type != SOCK_SEQPACKET) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995 l2cap_sock_clear_timer(sk);
996 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200997 } else
998 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700999 }
1000
1001done:
1002 hci_dev_unlock_bh(hdev);
1003 hci_dev_put(hdev);
1004 return err;
1005}
1006
1007static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
1008{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001010 struct sockaddr_l2 la;
1011 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 BT_DBG("sk %p", sk);
1014
Changli Gao6503d962010-03-31 22:58:26 +00001015 if (!addr || alen < sizeof(addr->sa_family) ||
1016 addr->sa_family != AF_BLUETOOTH)
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001017 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001019 memset(&la, 0, sizeof(la));
1020 len = min_t(unsigned int, sizeof(la), alen);
1021 memcpy(&la, addr, len);
1022
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001023 if (la.l2_cid)
1024 return -EINVAL;
1025
1026 lock_sock(sk);
1027
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001028 if (sk->sk_type == SOCK_SEQPACKET && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029 err = -EINVAL;
1030 goto done;
1031 }
1032
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001033 switch (l2cap_pi(sk)->mode) {
1034 case L2CAP_MODE_BASIC:
1035 break;
1036 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001037 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001038 if (enable_ertm)
1039 break;
1040 /* fall through */
1041 default:
1042 err = -ENOTSUPP;
1043 goto done;
1044 }
1045
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001046 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 case BT_CONNECT:
1048 case BT_CONNECT2:
1049 case BT_CONFIG:
1050 /* Already connecting */
1051 goto wait;
1052
1053 case BT_CONNECTED:
1054 /* Already connected */
1055 goto done;
1056
1057 case BT_OPEN:
1058 case BT_BOUND:
1059 /* Can connect */
1060 break;
1061
1062 default:
1063 err = -EBADFD;
1064 goto done;
1065 }
1066
1067 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001068 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1069 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001071 err = l2cap_do_connect(sk);
1072 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 goto done;
1074
1075wait:
1076 err = bt_sock_wait_state(sk, BT_CONNECTED,
1077 sock_sndtimeo(sk, flags & O_NONBLOCK));
1078done:
1079 release_sock(sk);
1080 return err;
1081}
1082
1083static int l2cap_sock_listen(struct socket *sock, int backlog)
1084{
1085 struct sock *sk = sock->sk;
1086 int err = 0;
1087
1088 BT_DBG("sk %p backlog %d", sk, backlog);
1089
1090 lock_sock(sk);
1091
1092 if (sk->sk_state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
1093 err = -EBADFD;
1094 goto done;
1095 }
1096
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001097 switch (l2cap_pi(sk)->mode) {
1098 case L2CAP_MODE_BASIC:
1099 break;
1100 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001101 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001102 if (enable_ertm)
1103 break;
1104 /* fall through */
1105 default:
1106 err = -ENOTSUPP;
1107 goto done;
1108 }
1109
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110 if (!l2cap_pi(sk)->psm) {
1111 bdaddr_t *src = &bt_sk(sk)->src;
1112 u16 psm;
1113
1114 err = -EINVAL;
1115
1116 write_lock_bh(&l2cap_sk_list.lock);
1117
1118 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001119 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1120 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1121 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122 err = 0;
1123 break;
1124 }
1125
1126 write_unlock_bh(&l2cap_sk_list.lock);
1127
1128 if (err < 0)
1129 goto done;
1130 }
1131
1132 sk->sk_max_ack_backlog = backlog;
1133 sk->sk_ack_backlog = 0;
1134 sk->sk_state = BT_LISTEN;
1135
1136done:
1137 release_sock(sk);
1138 return err;
1139}
1140
1141static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1142{
1143 DECLARE_WAITQUEUE(wait, current);
1144 struct sock *sk = sock->sk, *nsk;
1145 long timeo;
1146 int err = 0;
1147
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001148 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149
1150 if (sk->sk_state != BT_LISTEN) {
1151 err = -EBADFD;
1152 goto done;
1153 }
1154
1155 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1156
1157 BT_DBG("sk %p timeo %ld", sk, timeo);
1158
1159 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +00001160 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1162 set_current_state(TASK_INTERRUPTIBLE);
1163 if (!timeo) {
1164 err = -EAGAIN;
1165 break;
1166 }
1167
1168 release_sock(sk);
1169 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001170 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171
1172 if (sk->sk_state != BT_LISTEN) {
1173 err = -EBADFD;
1174 break;
1175 }
1176
1177 if (signal_pending(current)) {
1178 err = sock_intr_errno(timeo);
1179 break;
1180 }
1181 }
1182 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +00001183 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001184
1185 if (err)
1186 goto done;
1187
1188 newsock->state = SS_CONNECTED;
1189
1190 BT_DBG("new socket %p", nsk);
1191
1192done:
1193 release_sock(sk);
1194 return err;
1195}
1196
1197static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1198{
1199 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1200 struct sock *sk = sock->sk;
1201
1202 BT_DBG("sock %p, sk %p", sock, sk);
1203
1204 addr->sa_family = AF_BLUETOOTH;
1205 *len = sizeof(struct sockaddr_l2);
1206
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001207 if (peer) {
1208 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001210 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001211 } else {
1212 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001214 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001215 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217 return 0;
1218}
1219
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001220static void l2cap_monitor_timeout(unsigned long arg)
1221{
1222 struct sock *sk = (void *) arg;
1223 u16 control;
1224
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001225 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001226 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
1227 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001228 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001229 return;
1230 }
1231
1232 l2cap_pi(sk)->retry_count++;
1233 __mod_monitor_timer();
1234
1235 control = L2CAP_CTRL_POLL;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001236 l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001237 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001238}
1239
1240static void l2cap_retrans_timeout(unsigned long arg)
1241{
1242 struct sock *sk = (void *) arg;
1243 u16 control;
1244
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001245 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001246 l2cap_pi(sk)->retry_count = 1;
1247 __mod_monitor_timer();
1248
1249 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1250
1251 control = L2CAP_CTRL_POLL;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001252 l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001253 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001254}
1255
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001256static void l2cap_drop_acked_frames(struct sock *sk)
1257{
1258 struct sk_buff *skb;
1259
1260 while ((skb = skb_peek(TX_QUEUE(sk)))) {
1261 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1262 break;
1263
1264 skb = skb_dequeue(TX_QUEUE(sk));
1265 kfree_skb(skb);
1266
1267 l2cap_pi(sk)->unacked_frames--;
1268 }
1269
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001270 if (!l2cap_pi(sk)->unacked_frames)
1271 del_timer(&l2cap_pi(sk)->retrans_timer);
1272
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001273 return;
1274}
1275
1276static inline int l2cap_do_send(struct sock *sk, struct sk_buff *skb)
1277{
1278 struct l2cap_pinfo *pi = l2cap_pi(sk);
1279 int err;
1280
1281 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1282
1283 err = hci_send_acl(pi->conn->hcon, skb, 0);
1284 if (err < 0)
1285 kfree_skb(skb);
1286
1287 return err;
1288}
1289
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001290static int l2cap_streaming_send(struct sock *sk)
1291{
1292 struct sk_buff *skb, *tx_skb;
1293 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001294 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001295 int err;
1296
1297 while ((skb = sk->sk_send_head)) {
1298 tx_skb = skb_clone(skb, GFP_ATOMIC);
1299
1300 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1301 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1302 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1303
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001304 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001305 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1306 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1307 }
1308
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001309 err = l2cap_do_send(sk, tx_skb);
1310 if (err < 0) {
1311 l2cap_send_disconn_req(pi->conn, sk);
1312 return err;
1313 }
1314
1315 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1316
1317 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1318 sk->sk_send_head = NULL;
1319 else
1320 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1321
1322 skb = skb_dequeue(TX_QUEUE(sk));
1323 kfree_skb(skb);
1324 }
1325 return 0;
1326}
1327
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001328static int l2cap_retransmit_frame(struct sock *sk, u8 tx_seq)
1329{
1330 struct l2cap_pinfo *pi = l2cap_pi(sk);
1331 struct sk_buff *skb, *tx_skb;
1332 u16 control, fcs;
1333 int err;
1334
1335 skb = skb_peek(TX_QUEUE(sk));
1336 do {
1337 if (bt_cb(skb)->tx_seq != tx_seq) {
1338 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1339 break;
1340 skb = skb_queue_next(TX_QUEUE(sk), skb);
1341 continue;
1342 }
1343
1344 if (pi->remote_max_tx &&
1345 bt_cb(skb)->retries == pi->remote_max_tx) {
1346 l2cap_send_disconn_req(pi->conn, sk);
1347 break;
1348 }
1349
1350 tx_skb = skb_clone(skb, GFP_ATOMIC);
1351 bt_cb(skb)->retries++;
1352 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001353 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001354 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1355 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1356
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001357 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001358 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1359 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1360 }
1361
1362 err = l2cap_do_send(sk, tx_skb);
1363 if (err < 0) {
1364 l2cap_send_disconn_req(pi->conn, sk);
1365 return err;
1366 }
1367 break;
1368 } while(1);
1369 return 0;
1370}
1371
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001372static int l2cap_ertm_send(struct sock *sk)
1373{
1374 struct sk_buff *skb, *tx_skb;
1375 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001376 u16 control, fcs;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001377 int err, nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001378
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001379 if (pi->conn_state & L2CAP_CONN_WAIT_F)
1380 return 0;
1381
Joe Perchesf64f9e72009-11-29 16:55:45 -08001382 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) &&
1383 !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001384
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001385 if (pi->remote_max_tx &&
1386 bt_cb(skb)->retries == pi->remote_max_tx) {
1387 l2cap_send_disconn_req(pi->conn, sk);
1388 break;
1389 }
1390
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001391 tx_skb = skb_clone(skb, GFP_ATOMIC);
1392
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001393 bt_cb(skb)->retries++;
1394
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001395 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001396 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1397 control |= L2CAP_CTRL_FINAL;
1398 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1399 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001400 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001401 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1402 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1403
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001404
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001405 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001406 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1407 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1408 }
1409
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001410 err = l2cap_do_send(sk, tx_skb);
1411 if (err < 0) {
1412 l2cap_send_disconn_req(pi->conn, sk);
1413 return err;
1414 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001415 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001416
1417 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1418 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1419
1420 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001421 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001422
1423 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1424 sk->sk_send_head = NULL;
1425 else
1426 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001427
1428 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001429 }
1430
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001431 return nsent;
1432}
1433
1434static int l2cap_send_ack(struct l2cap_pinfo *pi)
1435{
1436 struct sock *sk = (struct sock *)pi;
1437 u16 control = 0;
1438
1439 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1440
1441 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1442 control |= L2CAP_SUPER_RCV_NOT_READY;
1443 return l2cap_send_sframe(pi, control);
1444 } else if (l2cap_ertm_send(sk) == 0) {
1445 control |= L2CAP_SUPER_RCV_READY;
1446 return l2cap_send_sframe(pi, control);
1447 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001448 return 0;
1449}
1450
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001451static int l2cap_send_srejtail(struct sock *sk)
1452{
1453 struct srej_list *tail;
1454 u16 control;
1455
1456 control = L2CAP_SUPER_SELECT_REJECT;
1457 control |= L2CAP_CTRL_FINAL;
1458
1459 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1460 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1461
1462 l2cap_send_sframe(l2cap_pi(sk), control);
1463
1464 return 0;
1465}
1466
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001467static 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 -07001468{
1469 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001470 struct sk_buff **frag;
1471 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472
1473 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001474 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475 }
1476
1477 sent += count;
1478 len -= count;
1479
1480 /* Continuation fragments (no L2CAP header) */
1481 frag = &skb_shinfo(skb)->frag_list;
1482 while (len) {
1483 count = min_t(unsigned int, conn->mtu, len);
1484
1485 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1486 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001487 return -EFAULT;
1488 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1489 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001490
1491 sent += count;
1492 len -= count;
1493
1494 frag = &(*frag)->next;
1495 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496
1497 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001498}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001500static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1501{
1502 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1503 struct sk_buff *skb;
1504 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1505 struct l2cap_hdr *lh;
1506
1507 BT_DBG("sk %p len %d", sk, (int)len);
1508
1509 count = min_t(unsigned int, (conn->mtu - hlen), len);
1510 skb = bt_skb_send_alloc(sk, count + hlen,
1511 msg->msg_flags & MSG_DONTWAIT, &err);
1512 if (!skb)
1513 return ERR_PTR(-ENOMEM);
1514
1515 /* Create L2CAP header */
1516 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1517 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1518 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1519 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1520
1521 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1522 if (unlikely(err < 0)) {
1523 kfree_skb(skb);
1524 return ERR_PTR(err);
1525 }
1526 return skb;
1527}
1528
1529static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1530{
1531 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1532 struct sk_buff *skb;
1533 int err, count, hlen = L2CAP_HDR_SIZE;
1534 struct l2cap_hdr *lh;
1535
1536 BT_DBG("sk %p len %d", sk, (int)len);
1537
1538 count = min_t(unsigned int, (conn->mtu - hlen), len);
1539 skb = bt_skb_send_alloc(sk, count + hlen,
1540 msg->msg_flags & MSG_DONTWAIT, &err);
1541 if (!skb)
1542 return ERR_PTR(-ENOMEM);
1543
1544 /* Create L2CAP header */
1545 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1546 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1547 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1548
1549 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1550 if (unlikely(err < 0)) {
1551 kfree_skb(skb);
1552 return ERR_PTR(err);
1553 }
1554 return skb;
1555}
1556
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001557static 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 -03001558{
1559 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1560 struct sk_buff *skb;
1561 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1562 struct l2cap_hdr *lh;
1563
1564 BT_DBG("sk %p len %d", sk, (int)len);
1565
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001566 if (sdulen)
1567 hlen += 2;
1568
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001569 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1570 hlen += 2;
1571
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001572 count = min_t(unsigned int, (conn->mtu - hlen), len);
1573 skb = bt_skb_send_alloc(sk, count + hlen,
1574 msg->msg_flags & MSG_DONTWAIT, &err);
1575 if (!skb)
1576 return ERR_PTR(-ENOMEM);
1577
1578 /* Create L2CAP header */
1579 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1580 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1581 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1582 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001583 if (sdulen)
1584 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001585
1586 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1587 if (unlikely(err < 0)) {
1588 kfree_skb(skb);
1589 return ERR_PTR(err);
1590 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001591
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001592 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1593 put_unaligned_le16(0, skb_put(skb, 2));
1594
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001595 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001596 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597}
1598
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001599static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1600{
1601 struct l2cap_pinfo *pi = l2cap_pi(sk);
1602 struct sk_buff *skb;
1603 struct sk_buff_head sar_queue;
1604 u16 control;
1605 size_t size = 0;
1606
1607 __skb_queue_head_init(&sar_queue);
1608 control = L2CAP_SDU_START;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001609 skb = l2cap_create_iframe_pdu(sk, msg, pi->max_pdu_size, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001610 if (IS_ERR(skb))
1611 return PTR_ERR(skb);
1612
1613 __skb_queue_tail(&sar_queue, skb);
1614 len -= pi->max_pdu_size;
1615 size +=pi->max_pdu_size;
1616 control = 0;
1617
1618 while (len > 0) {
1619 size_t buflen;
1620
1621 if (len > pi->max_pdu_size) {
1622 control |= L2CAP_SDU_CONTINUE;
1623 buflen = pi->max_pdu_size;
1624 } else {
1625 control |= L2CAP_SDU_END;
1626 buflen = len;
1627 }
1628
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001629 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001630 if (IS_ERR(skb)) {
1631 skb_queue_purge(&sar_queue);
1632 return PTR_ERR(skb);
1633 }
1634
1635 __skb_queue_tail(&sar_queue, skb);
1636 len -= buflen;
1637 size += buflen;
1638 control = 0;
1639 }
1640 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1641 if (sk->sk_send_head == NULL)
1642 sk->sk_send_head = sar_queue.next;
1643
1644 return size;
1645}
1646
Linus Torvalds1da177e2005-04-16 15:20:36 -07001647static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1648{
1649 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001650 struct l2cap_pinfo *pi = l2cap_pi(sk);
1651 struct sk_buff *skb;
1652 u16 control;
1653 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654
1655 BT_DBG("sock %p, sk %p", sock, sk);
1656
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001657 err = sock_error(sk);
1658 if (err)
1659 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660
1661 if (msg->msg_flags & MSG_OOB)
1662 return -EOPNOTSUPP;
1663
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664 lock_sock(sk);
1665
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001666 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001668 goto done;
1669 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001671 /* Connectionless channel */
1672 if (sk->sk_type == SOCK_DGRAM) {
1673 skb = l2cap_create_connless_pdu(sk, msg, len);
Dan Carpenter477fffb2010-04-21 23:52:01 +00001674 if (IS_ERR(skb))
1675 err = PTR_ERR(skb);
1676 else
1677 err = l2cap_do_send(sk, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001678 goto done;
1679 }
1680
1681 switch (pi->mode) {
1682 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001683 /* Check outgoing MTU */
1684 if (len > pi->omtu) {
1685 err = -EINVAL;
1686 goto done;
1687 }
1688
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001689 /* Create a basic PDU */
1690 skb = l2cap_create_basic_pdu(sk, msg, len);
1691 if (IS_ERR(skb)) {
1692 err = PTR_ERR(skb);
1693 goto done;
1694 }
1695
1696 err = l2cap_do_send(sk, skb);
1697 if (!err)
1698 err = len;
1699 break;
1700
1701 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001702 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001703 /* Entire SDU fits into one PDU */
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001704 if (len <= pi->max_pdu_size) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001705 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001706 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001707 if (IS_ERR(skb)) {
1708 err = PTR_ERR(skb);
1709 goto done;
1710 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001711 __skb_queue_tail(TX_QUEUE(sk), skb);
1712 if (sk->sk_send_head == NULL)
1713 sk->sk_send_head = skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001714 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001715 /* Segment SDU into multiples PDUs */
1716 err = l2cap_sar_segment_sdu(sk, msg, len);
1717 if (err < 0)
1718 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001719 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001720
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001721 if (pi->mode == L2CAP_MODE_STREAMING)
1722 err = l2cap_streaming_send(sk);
1723 else
1724 err = l2cap_ertm_send(sk);
1725
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001726 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001727 err = len;
1728 break;
1729
1730 default:
1731 BT_DBG("bad state %1.1x", pi->mode);
1732 err = -EINVAL;
1733 }
1734
1735done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736 release_sock(sk);
1737 return err;
1738}
1739
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001740static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1741{
1742 struct sock *sk = sock->sk;
1743
1744 lock_sock(sk);
1745
1746 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1747 struct l2cap_conn_rsp rsp;
1748
1749 sk->sk_state = BT_CONFIG;
1750
1751 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1752 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1753 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1754 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1755 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1756 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1757
1758 release_sock(sk);
1759 return 0;
1760 }
1761
1762 release_sock(sk);
1763
1764 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1765}
1766
David S. Millerb7058842009-09-30 16:12:20 -07001767static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768{
1769 struct sock *sk = sock->sk;
1770 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001771 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772 u32 opt;
1773
1774 BT_DBG("sk %p", sk);
1775
1776 lock_sock(sk);
1777
1778 switch (optname) {
1779 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001780 opts.imtu = l2cap_pi(sk)->imtu;
1781 opts.omtu = l2cap_pi(sk)->omtu;
1782 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001783 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001784 opts.fcs = l2cap_pi(sk)->fcs;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001785
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786 len = min_t(unsigned int, sizeof(opts), optlen);
1787 if (copy_from_user((char *) &opts, optval, len)) {
1788 err = -EFAULT;
1789 break;
1790 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001791
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001792 l2cap_pi(sk)->imtu = opts.imtu;
1793 l2cap_pi(sk)->omtu = opts.omtu;
1794 l2cap_pi(sk)->mode = opts.mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001795 l2cap_pi(sk)->fcs = opts.fcs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796 break;
1797
1798 case L2CAP_LM:
1799 if (get_user(opt, (u32 __user *) optval)) {
1800 err = -EFAULT;
1801 break;
1802 }
1803
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001804 if (opt & L2CAP_LM_AUTH)
1805 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1806 if (opt & L2CAP_LM_ENCRYPT)
1807 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1808 if (opt & L2CAP_LM_SECURE)
1809 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1810
1811 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1812 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813 break;
1814
1815 default:
1816 err = -ENOPROTOOPT;
1817 break;
1818 }
1819
1820 release_sock(sk);
1821 return err;
1822}
1823
David S. Millerb7058842009-09-30 16:12:20 -07001824static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001825{
1826 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001827 struct bt_security sec;
1828 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001829 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001830
1831 BT_DBG("sk %p", sk);
1832
1833 if (level == SOL_L2CAP)
1834 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1835
Marcel Holtmann0588d942009-01-16 10:06:13 +01001836 if (level != SOL_BLUETOOTH)
1837 return -ENOPROTOOPT;
1838
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001839 lock_sock(sk);
1840
1841 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001842 case BT_SECURITY:
Marcel Holtmann2526d3d2009-02-20 20:54:06 +01001843 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001844 err = -EINVAL;
1845 break;
1846 }
1847
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001848 sec.level = BT_SECURITY_LOW;
1849
1850 len = min_t(unsigned int, sizeof(sec), optlen);
1851 if (copy_from_user((char *) &sec, optval, len)) {
1852 err = -EFAULT;
1853 break;
1854 }
1855
1856 if (sec.level < BT_SECURITY_LOW ||
1857 sec.level > BT_SECURITY_HIGH) {
1858 err = -EINVAL;
1859 break;
1860 }
1861
1862 l2cap_pi(sk)->sec_level = sec.level;
1863 break;
1864
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001865 case BT_DEFER_SETUP:
1866 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1867 err = -EINVAL;
1868 break;
1869 }
1870
1871 if (get_user(opt, (u32 __user *) optval)) {
1872 err = -EFAULT;
1873 break;
1874 }
1875
1876 bt_sk(sk)->defer_setup = opt;
1877 break;
1878
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001879 default:
1880 err = -ENOPROTOOPT;
1881 break;
1882 }
1883
1884 release_sock(sk);
1885 return err;
1886}
1887
1888static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889{
1890 struct sock *sk = sock->sk;
1891 struct l2cap_options opts;
1892 struct l2cap_conninfo cinfo;
1893 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001894 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895
1896 BT_DBG("sk %p", sk);
1897
1898 if (get_user(len, optlen))
1899 return -EFAULT;
1900
1901 lock_sock(sk);
1902
1903 switch (optname) {
1904 case L2CAP_OPTIONS:
1905 opts.imtu = l2cap_pi(sk)->imtu;
1906 opts.omtu = l2cap_pi(sk)->omtu;
1907 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001908 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001909 opts.fcs = l2cap_pi(sk)->fcs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910
1911 len = min_t(unsigned int, len, sizeof(opts));
1912 if (copy_to_user(optval, (char *) &opts, len))
1913 err = -EFAULT;
1914
1915 break;
1916
1917 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001918 switch (l2cap_pi(sk)->sec_level) {
1919 case BT_SECURITY_LOW:
1920 opt = L2CAP_LM_AUTH;
1921 break;
1922 case BT_SECURITY_MEDIUM:
1923 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
1924 break;
1925 case BT_SECURITY_HIGH:
1926 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
1927 L2CAP_LM_SECURE;
1928 break;
1929 default:
1930 opt = 0;
1931 break;
1932 }
1933
1934 if (l2cap_pi(sk)->role_switch)
1935 opt |= L2CAP_LM_MASTER;
1936
1937 if (l2cap_pi(sk)->force_reliable)
1938 opt |= L2CAP_LM_RELIABLE;
1939
1940 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001941 err = -EFAULT;
1942 break;
1943
1944 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001945 if (sk->sk_state != BT_CONNECTED &&
1946 !(sk->sk_state == BT_CONNECT2 &&
1947 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948 err = -ENOTCONN;
1949 break;
1950 }
1951
1952 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
1953 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
1954
1955 len = min_t(unsigned int, len, sizeof(cinfo));
1956 if (copy_to_user(optval, (char *) &cinfo, len))
1957 err = -EFAULT;
1958
1959 break;
1960
1961 default:
1962 err = -ENOPROTOOPT;
1963 break;
1964 }
1965
1966 release_sock(sk);
1967 return err;
1968}
1969
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001970static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
1971{
1972 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001973 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001974 int len, err = 0;
1975
1976 BT_DBG("sk %p", sk);
1977
1978 if (level == SOL_L2CAP)
1979 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
1980
Marcel Holtmann0588d942009-01-16 10:06:13 +01001981 if (level != SOL_BLUETOOTH)
1982 return -ENOPROTOOPT;
1983
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001984 if (get_user(len, optlen))
1985 return -EFAULT;
1986
1987 lock_sock(sk);
1988
1989 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001990 case BT_SECURITY:
Marcel Holtmann2526d3d2009-02-20 20:54:06 +01001991 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001992 err = -EINVAL;
1993 break;
1994 }
1995
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001996 sec.level = l2cap_pi(sk)->sec_level;
1997
1998 len = min_t(unsigned int, len, sizeof(sec));
1999 if (copy_to_user(optval, (char *) &sec, len))
2000 err = -EFAULT;
2001
2002 break;
2003
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002004 case BT_DEFER_SETUP:
2005 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2006 err = -EINVAL;
2007 break;
2008 }
2009
2010 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2011 err = -EFAULT;
2012
2013 break;
2014
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002015 default:
2016 err = -ENOPROTOOPT;
2017 break;
2018 }
2019
2020 release_sock(sk);
2021 return err;
2022}
2023
Linus Torvalds1da177e2005-04-16 15:20:36 -07002024static int l2cap_sock_shutdown(struct socket *sock, int how)
2025{
2026 struct sock *sk = sock->sk;
2027 int err = 0;
2028
2029 BT_DBG("sock %p, sk %p", sock, sk);
2030
2031 if (!sk)
2032 return 0;
2033
2034 lock_sock(sk);
2035 if (!sk->sk_shutdown) {
2036 sk->sk_shutdown = SHUTDOWN_MASK;
2037 l2cap_sock_clear_timer(sk);
2038 __l2cap_sock_close(sk, 0);
2039
2040 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002041 err = bt_sock_wait_state(sk, BT_CLOSED,
2042 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002043 }
2044 release_sock(sk);
2045 return err;
2046}
2047
2048static int l2cap_sock_release(struct socket *sock)
2049{
2050 struct sock *sk = sock->sk;
2051 int err;
2052
2053 BT_DBG("sock %p, sk %p", sock, sk);
2054
2055 if (!sk)
2056 return 0;
2057
2058 err = l2cap_sock_shutdown(sock, 2);
2059
2060 sock_orphan(sk);
2061 l2cap_sock_kill(sk);
2062 return err;
2063}
2064
Linus Torvalds1da177e2005-04-16 15:20:36 -07002065static void l2cap_chan_ready(struct sock *sk)
2066{
2067 struct sock *parent = bt_sk(sk)->parent;
2068
2069 BT_DBG("sk %p, parent %p", sk, parent);
2070
2071 l2cap_pi(sk)->conf_state = 0;
2072 l2cap_sock_clear_timer(sk);
2073
2074 if (!parent) {
2075 /* Outgoing channel.
2076 * Wake up socket sleeping on connect.
2077 */
2078 sk->sk_state = BT_CONNECTED;
2079 sk->sk_state_change(sk);
2080 } else {
2081 /* Incoming channel.
2082 * Wake up socket sleeping on accept.
2083 */
2084 parent->sk_data_ready(parent, 0);
2085 }
2086}
2087
2088/* Copy frame to all raw sockets on that connection */
2089static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2090{
2091 struct l2cap_chan_list *l = &conn->chan_list;
2092 struct sk_buff *nskb;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002093 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002094
2095 BT_DBG("conn %p", conn);
2096
2097 read_lock(&l->lock);
2098 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2099 if (sk->sk_type != SOCK_RAW)
2100 continue;
2101
2102 /* Don't send frame to the socket it came from */
2103 if (skb->sk == sk)
2104 continue;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002105 nskb = skb_clone(skb, GFP_ATOMIC);
2106 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002107 continue;
2108
2109 if (sock_queue_rcv_skb(sk, nskb))
2110 kfree_skb(nskb);
2111 }
2112 read_unlock(&l->lock);
2113}
2114
2115/* ---- L2CAP signalling commands ---- */
2116static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2117 u8 code, u8 ident, u16 dlen, void *data)
2118{
2119 struct sk_buff *skb, **frag;
2120 struct l2cap_cmd_hdr *cmd;
2121 struct l2cap_hdr *lh;
2122 int len, count;
2123
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002124 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2125 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002126
2127 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2128 count = min_t(unsigned int, conn->mtu, len);
2129
2130 skb = bt_skb_alloc(count, GFP_ATOMIC);
2131 if (!skb)
2132 return NULL;
2133
2134 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002135 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002136 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002137
2138 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2139 cmd->code = code;
2140 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002141 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002142
2143 if (dlen) {
2144 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2145 memcpy(skb_put(skb, count), data, count);
2146 data += count;
2147 }
2148
2149 len -= skb->len;
2150
2151 /* Continuation fragments (no L2CAP header) */
2152 frag = &skb_shinfo(skb)->frag_list;
2153 while (len) {
2154 count = min_t(unsigned int, conn->mtu, len);
2155
2156 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2157 if (!*frag)
2158 goto fail;
2159
2160 memcpy(skb_put(*frag, count), data, count);
2161
2162 len -= count;
2163 data += count;
2164
2165 frag = &(*frag)->next;
2166 }
2167
2168 return skb;
2169
2170fail:
2171 kfree_skb(skb);
2172 return NULL;
2173}
2174
2175static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2176{
2177 struct l2cap_conf_opt *opt = *ptr;
2178 int len;
2179
2180 len = L2CAP_CONF_OPT_SIZE + opt->len;
2181 *ptr += len;
2182
2183 *type = opt->type;
2184 *olen = opt->len;
2185
2186 switch (opt->len) {
2187 case 1:
2188 *val = *((u8 *) opt->val);
2189 break;
2190
2191 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002192 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002193 break;
2194
2195 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002196 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002197 break;
2198
2199 default:
2200 *val = (unsigned long) opt->val;
2201 break;
2202 }
2203
2204 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2205 return len;
2206}
2207
Linus Torvalds1da177e2005-04-16 15:20:36 -07002208static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2209{
2210 struct l2cap_conf_opt *opt = *ptr;
2211
2212 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2213
2214 opt->type = type;
2215 opt->len = len;
2216
2217 switch (len) {
2218 case 1:
2219 *((u8 *) opt->val) = val;
2220 break;
2221
2222 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002223 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002224 break;
2225
2226 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002227 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002228 break;
2229
2230 default:
2231 memcpy(opt->val, (void *) val, len);
2232 break;
2233 }
2234
2235 *ptr += L2CAP_CONF_OPT_SIZE + len;
2236}
2237
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002238static void l2cap_ack_timeout(unsigned long arg)
2239{
2240 struct sock *sk = (void *) arg;
2241
2242 bh_lock_sock(sk);
2243 l2cap_send_ack(l2cap_pi(sk));
2244 bh_unlock_sock(sk);
2245}
2246
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002247static inline void l2cap_ertm_init(struct sock *sk)
2248{
2249 l2cap_pi(sk)->expected_ack_seq = 0;
2250 l2cap_pi(sk)->unacked_frames = 0;
2251 l2cap_pi(sk)->buffer_seq = 0;
2252 l2cap_pi(sk)->num_to_ack = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002253 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002254
2255 setup_timer(&l2cap_pi(sk)->retrans_timer,
2256 l2cap_retrans_timeout, (unsigned long) sk);
2257 setup_timer(&l2cap_pi(sk)->monitor_timer,
2258 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002259 setup_timer(&l2cap_pi(sk)->ack_timer,
2260 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002261
2262 __skb_queue_head_init(SREJ_QUEUE(sk));
2263}
2264
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002265static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2266{
2267 u32 local_feat_mask = l2cap_feat_mask;
2268 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002269 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002270
2271 switch (mode) {
2272 case L2CAP_MODE_ERTM:
2273 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2274 case L2CAP_MODE_STREAMING:
2275 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2276 default:
2277 return 0x00;
2278 }
2279}
2280
2281static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2282{
2283 switch (mode) {
2284 case L2CAP_MODE_STREAMING:
2285 case L2CAP_MODE_ERTM:
2286 if (l2cap_mode_supported(mode, remote_feat_mask))
2287 return mode;
2288 /* fall through */
2289 default:
2290 return L2CAP_MODE_BASIC;
2291 }
2292}
2293
Linus Torvalds1da177e2005-04-16 15:20:36 -07002294static int l2cap_build_conf_req(struct sock *sk, void *data)
2295{
2296 struct l2cap_pinfo *pi = l2cap_pi(sk);
2297 struct l2cap_conf_req *req = data;
Gustavo F. Padovana0e55a32009-09-29 01:42:23 -03002298 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002299 void *ptr = req->data;
2300
2301 BT_DBG("sk %p", sk);
2302
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002303 if (pi->num_conf_req || pi->num_conf_rsp)
2304 goto done;
2305
2306 switch (pi->mode) {
2307 case L2CAP_MODE_STREAMING:
2308 case L2CAP_MODE_ERTM:
2309 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002310 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2311 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002312 break;
2313 default:
2314 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2315 break;
2316 }
2317
2318done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002319 switch (pi->mode) {
2320 case L2CAP_MODE_BASIC:
2321 if (pi->imtu != L2CAP_DEFAULT_MTU)
2322 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2323 break;
2324
2325 case L2CAP_MODE_ERTM:
2326 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002327 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +02002328 rfc.max_transmit = max_transmit;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002329 rfc.retrans_timeout = 0;
2330 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002331 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002332 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
2333 rfc.max_pdu_size = pi->conn->mtu - 10;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002334
2335 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2336 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002337
2338 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2339 break;
2340
2341 if (pi->fcs == L2CAP_FCS_NONE ||
2342 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2343 pi->fcs = L2CAP_FCS_NONE;
2344 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2345 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002346 break;
2347
2348 case L2CAP_MODE_STREAMING:
2349 rfc.mode = L2CAP_MODE_STREAMING;
2350 rfc.txwin_size = 0;
2351 rfc.max_transmit = 0;
2352 rfc.retrans_timeout = 0;
2353 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002354 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002355 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
2356 rfc.max_pdu_size = pi->conn->mtu - 10;
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002357
2358 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2359 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002360
2361 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2362 break;
2363
2364 if (pi->fcs == L2CAP_FCS_NONE ||
2365 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2366 pi->fcs = L2CAP_FCS_NONE;
2367 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2368 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002369 break;
2370 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002371
2372 /* FIXME: Need actual value of the flush timeout */
2373 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2374 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2375
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002376 req->dcid = cpu_to_le16(pi->dcid);
2377 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002378
2379 return ptr - data;
2380}
2381
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002382static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002383{
2384 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002385 struct l2cap_conf_rsp *rsp = data;
2386 void *ptr = rsp->data;
2387 void *req = pi->conf_req;
2388 int len = pi->conf_len;
2389 int type, hint, olen;
2390 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002391 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002392 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002393 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002394
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002395 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002396
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002397 while (len >= L2CAP_CONF_OPT_SIZE) {
2398 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002399
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002400 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002401 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002402
2403 switch (type) {
2404 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002405 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002406 break;
2407
2408 case L2CAP_CONF_FLUSH_TO:
2409 pi->flush_to = val;
2410 break;
2411
2412 case L2CAP_CONF_QOS:
2413 break;
2414
Marcel Holtmann6464f352007-10-20 13:39:51 +02002415 case L2CAP_CONF_RFC:
2416 if (olen == sizeof(rfc))
2417 memcpy(&rfc, (void *) val, olen);
2418 break;
2419
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002420 case L2CAP_CONF_FCS:
2421 if (val == L2CAP_FCS_NONE)
2422 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2423
2424 break;
2425
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002426 default:
2427 if (hint)
2428 break;
2429
2430 result = L2CAP_CONF_UNKNOWN;
2431 *((u8 *) ptr++) = type;
2432 break;
2433 }
2434 }
2435
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002436 if (pi->num_conf_rsp || pi->num_conf_req)
2437 goto done;
2438
2439 switch (pi->mode) {
2440 case L2CAP_MODE_STREAMING:
2441 case L2CAP_MODE_ERTM:
2442 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2443 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2444 return -ECONNREFUSED;
2445 break;
2446 default:
2447 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2448 break;
2449 }
2450
2451done:
2452 if (pi->mode != rfc.mode) {
2453 result = L2CAP_CONF_UNACCEPT;
2454 rfc.mode = pi->mode;
2455
2456 if (pi->num_conf_rsp == 1)
2457 return -ECONNREFUSED;
2458
2459 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2460 sizeof(rfc), (unsigned long) &rfc);
2461 }
2462
2463
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002464 if (result == L2CAP_CONF_SUCCESS) {
2465 /* Configure output options and let the other side know
2466 * which ones we don't like. */
2467
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002468 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2469 result = L2CAP_CONF_UNACCEPT;
2470 else {
2471 pi->omtu = mtu;
2472 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2473 }
2474 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002475
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002476 switch (rfc.mode) {
2477 case L2CAP_MODE_BASIC:
2478 pi->fcs = L2CAP_FCS_NONE;
2479 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2480 break;
2481
2482 case L2CAP_MODE_ERTM:
2483 pi->remote_tx_win = rfc.txwin_size;
2484 pi->remote_max_tx = rfc.max_transmit;
2485 pi->max_pdu_size = rfc.max_pdu_size;
2486
2487 rfc.retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
2488 rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
2489
2490 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002491
2492 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2493 sizeof(rfc), (unsigned long) &rfc);
2494
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002495 break;
2496
2497 case L2CAP_MODE_STREAMING:
2498 pi->remote_tx_win = rfc.txwin_size;
2499 pi->max_pdu_size = rfc.max_pdu_size;
2500
2501 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002502
2503 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2504 sizeof(rfc), (unsigned long) &rfc);
2505
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002506 break;
2507
2508 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002509 result = L2CAP_CONF_UNACCEPT;
2510
2511 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002512 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002513 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002514
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002515 if (result == L2CAP_CONF_SUCCESS)
2516 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2517 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002518 rsp->scid = cpu_to_le16(pi->dcid);
2519 rsp->result = cpu_to_le16(result);
2520 rsp->flags = cpu_to_le16(0x0000);
2521
2522 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002523}
2524
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002525static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2526{
2527 struct l2cap_pinfo *pi = l2cap_pi(sk);
2528 struct l2cap_conf_req *req = data;
2529 void *ptr = req->data;
2530 int type, olen;
2531 unsigned long val;
2532 struct l2cap_conf_rfc rfc;
2533
2534 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2535
2536 while (len >= L2CAP_CONF_OPT_SIZE) {
2537 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2538
2539 switch (type) {
2540 case L2CAP_CONF_MTU:
2541 if (val < L2CAP_DEFAULT_MIN_MTU) {
2542 *result = L2CAP_CONF_UNACCEPT;
2543 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2544 } else
2545 pi->omtu = val;
2546 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2547 break;
2548
2549 case L2CAP_CONF_FLUSH_TO:
2550 pi->flush_to = val;
2551 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2552 2, pi->flush_to);
2553 break;
2554
2555 case L2CAP_CONF_RFC:
2556 if (olen == sizeof(rfc))
2557 memcpy(&rfc, (void *)val, olen);
2558
2559 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2560 rfc.mode != pi->mode)
2561 return -ECONNREFUSED;
2562
2563 pi->mode = rfc.mode;
2564 pi->fcs = 0;
2565
2566 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2567 sizeof(rfc), (unsigned long) &rfc);
2568 break;
2569 }
2570 }
2571
2572 if (*result == L2CAP_CONF_SUCCESS) {
2573 switch (rfc.mode) {
2574 case L2CAP_MODE_ERTM:
2575 pi->remote_tx_win = rfc.txwin_size;
2576 pi->retrans_timeout = rfc.retrans_timeout;
2577 pi->monitor_timeout = rfc.monitor_timeout;
2578 pi->max_pdu_size = le16_to_cpu(rfc.max_pdu_size);
2579 break;
2580 case L2CAP_MODE_STREAMING:
2581 pi->max_pdu_size = le16_to_cpu(rfc.max_pdu_size);
2582 break;
2583 }
2584 }
2585
2586 req->dcid = cpu_to_le16(pi->dcid);
2587 req->flags = cpu_to_le16(0x0000);
2588
2589 return ptr - data;
2590}
2591
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002592static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002593{
2594 struct l2cap_conf_rsp *rsp = data;
2595 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002596
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002597 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002598
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002599 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002600 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002601 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002602
2603 return ptr - data;
2604}
2605
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002606static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2607{
2608 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2609
2610 if (rej->reason != 0x0000)
2611 return 0;
2612
2613 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2614 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002615 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002616
2617 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002618 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002619
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002620 l2cap_conn_start(conn);
2621 }
2622
2623 return 0;
2624}
2625
Linus Torvalds1da177e2005-04-16 15:20:36 -07002626static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2627{
2628 struct l2cap_chan_list *list = &conn->chan_list;
2629 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2630 struct l2cap_conn_rsp rsp;
2631 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002632 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002633
2634 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002635 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636
2637 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2638
2639 /* Check if we have socket listening on psm */
2640 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2641 if (!parent) {
2642 result = L2CAP_CR_BAD_PSM;
2643 goto sendresp;
2644 }
2645
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002646 /* Check if the ACL is secure enough (if not SDP) */
2647 if (psm != cpu_to_le16(0x0001) &&
2648 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002649 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002650 result = L2CAP_CR_SEC_BLOCK;
2651 goto response;
2652 }
2653
Linus Torvalds1da177e2005-04-16 15:20:36 -07002654 result = L2CAP_CR_NO_MEM;
2655
2656 /* Check for backlog size */
2657 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002658 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002659 goto response;
2660 }
2661
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002662 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002663 if (!sk)
2664 goto response;
2665
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002666 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002667
2668 /* Check if we already have channel with that dcid */
2669 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002670 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002671 sock_set_flag(sk, SOCK_ZAPPED);
2672 l2cap_sock_kill(sk);
2673 goto response;
2674 }
2675
2676 hci_conn_hold(conn->hcon);
2677
2678 l2cap_sock_init(sk, parent);
2679 bacpy(&bt_sk(sk)->src, conn->src);
2680 bacpy(&bt_sk(sk)->dst, conn->dst);
2681 l2cap_pi(sk)->psm = psm;
2682 l2cap_pi(sk)->dcid = scid;
2683
2684 __l2cap_chan_add(conn, sk, parent);
2685 dcid = l2cap_pi(sk)->scid;
2686
2687 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2688
Linus Torvalds1da177e2005-04-16 15:20:36 -07002689 l2cap_pi(sk)->ident = cmd->ident;
2690
Marcel Holtmann984947d2009-02-06 23:35:19 +01002691 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002692 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002693 if (bt_sk(sk)->defer_setup) {
2694 sk->sk_state = BT_CONNECT2;
2695 result = L2CAP_CR_PEND;
2696 status = L2CAP_CS_AUTHOR_PEND;
2697 parent->sk_data_ready(parent, 0);
2698 } else {
2699 sk->sk_state = BT_CONFIG;
2700 result = L2CAP_CR_SUCCESS;
2701 status = L2CAP_CS_NO_INFO;
2702 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002703 } else {
2704 sk->sk_state = BT_CONNECT2;
2705 result = L2CAP_CR_PEND;
2706 status = L2CAP_CS_AUTHEN_PEND;
2707 }
2708 } else {
2709 sk->sk_state = BT_CONNECT2;
2710 result = L2CAP_CR_PEND;
2711 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002712 }
2713
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002714 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002715
2716response:
2717 bh_unlock_sock(parent);
2718
2719sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002720 rsp.scid = cpu_to_le16(scid);
2721 rsp.dcid = cpu_to_le16(dcid);
2722 rsp.result = cpu_to_le16(result);
2723 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002724 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002725
2726 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2727 struct l2cap_info_req info;
2728 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2729
2730 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2731 conn->info_ident = l2cap_get_ident(conn);
2732
2733 mod_timer(&conn->info_timer, jiffies +
2734 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2735
2736 l2cap_send_cmd(conn, conn->info_ident,
2737 L2CAP_INFO_REQ, sizeof(info), &info);
2738 }
2739
Linus Torvalds1da177e2005-04-16 15:20:36 -07002740 return 0;
2741}
2742
2743static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2744{
2745 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2746 u16 scid, dcid, result, status;
2747 struct sock *sk;
2748 u8 req[128];
2749
2750 scid = __le16_to_cpu(rsp->scid);
2751 dcid = __le16_to_cpu(rsp->dcid);
2752 result = __le16_to_cpu(rsp->result);
2753 status = __le16_to_cpu(rsp->status);
2754
2755 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2756
2757 if (scid) {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002758 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2759 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002760 return 0;
2761 } else {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002762 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2763 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002764 return 0;
2765 }
2766
2767 switch (result) {
2768 case L2CAP_CR_SUCCESS:
2769 sk->sk_state = BT_CONFIG;
2770 l2cap_pi(sk)->ident = 0;
2771 l2cap_pi(sk)->dcid = dcid;
2772 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2773
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002774 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2775
Linus Torvalds1da177e2005-04-16 15:20:36 -07002776 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2777 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002778 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002779 break;
2780
2781 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002782 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002783 break;
2784
2785 default:
2786 l2cap_chan_del(sk, ECONNREFUSED);
2787 break;
2788 }
2789
2790 bh_unlock_sock(sk);
2791 return 0;
2792}
2793
Al Viro88219a02007-07-29 00:17:25 -07002794static 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 -07002795{
2796 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2797 u16 dcid, flags;
2798 u8 rsp[64];
2799 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002800 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002801
2802 dcid = __le16_to_cpu(req->dcid);
2803 flags = __le16_to_cpu(req->flags);
2804
2805 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2806
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002807 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2808 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002809 return -ENOENT;
2810
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002811 if (sk->sk_state == BT_DISCONN)
2812 goto unlock;
2813
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002814 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002815 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002816 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2817 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2818 l2cap_build_conf_rsp(sk, rsp,
2819 L2CAP_CONF_REJECT, flags), rsp);
2820 goto unlock;
2821 }
2822
2823 /* Store config. */
2824 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2825 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002826
2827 if (flags & 0x0001) {
2828 /* Incomplete config. Send empty response. */
2829 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002830 l2cap_build_conf_rsp(sk, rsp,
2831 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002832 goto unlock;
2833 }
2834
2835 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002836 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002837 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002838 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002839 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002840 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002841
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002842 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002843 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002844
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002845 /* Reset config buffer. */
2846 l2cap_pi(sk)->conf_len = 0;
2847
Marcel Holtmann876d9482007-10-20 13:35:42 +02002848 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2849 goto unlock;
2850
Linus Torvalds1da177e2005-04-16 15:20:36 -07002851 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002852 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
2853 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002854 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2855
Linus Torvalds1da177e2005-04-16 15:20:36 -07002856 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002857
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002858 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002859 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002860 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002861 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2862 l2cap_ertm_init(sk);
2863
Linus Torvalds1da177e2005-04-16 15:20:36 -07002864 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002865 goto unlock;
2866 }
2867
2868 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002869 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002870 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002871 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002872 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002873 }
2874
2875unlock:
2876 bh_unlock_sock(sk);
2877 return 0;
2878}
2879
2880static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2881{
2882 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2883 u16 scid, flags, result;
2884 struct sock *sk;
2885
2886 scid = __le16_to_cpu(rsp->scid);
2887 flags = __le16_to_cpu(rsp->flags);
2888 result = __le16_to_cpu(rsp->result);
2889
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002890 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2891 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002892
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002893 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2894 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002895 return 0;
2896
2897 switch (result) {
2898 case L2CAP_CONF_SUCCESS:
2899 break;
2900
2901 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002902 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
2903 int len = cmd->len - sizeof(*rsp);
2904 char req[64];
2905
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02002906 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
2907 l2cap_send_disconn_req(conn, sk);
2908 goto done;
2909 }
2910
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002911 /* throw out any old stored conf requests */
2912 result = L2CAP_CONF_SUCCESS;
2913 len = l2cap_parse_conf_rsp(sk, rsp->data,
2914 len, req, &result);
2915 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002916 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002917 goto done;
2918 }
2919
2920 l2cap_send_cmd(conn, l2cap_get_ident(conn),
2921 L2CAP_CONF_REQ, len, req);
2922 l2cap_pi(sk)->num_conf_req++;
2923 if (result != L2CAP_CONF_SUCCESS)
2924 goto done;
2925 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002926 }
2927
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002928 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002929 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002930 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002931 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002932 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002933 goto done;
2934 }
2935
2936 if (flags & 0x01)
2937 goto done;
2938
Linus Torvalds1da177e2005-04-16 15:20:36 -07002939 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
2940
2941 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002942 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
2943 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002944 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2945
Linus Torvalds1da177e2005-04-16 15:20:36 -07002946 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002947 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002948 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002949 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002950 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2951 l2cap_ertm_init(sk);
2952
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953 l2cap_chan_ready(sk);
2954 }
2955
2956done:
2957 bh_unlock_sock(sk);
2958 return 0;
2959}
2960
2961static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2962{
2963 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
2964 struct l2cap_disconn_rsp rsp;
2965 u16 dcid, scid;
2966 struct sock *sk;
2967
2968 scid = __le16_to_cpu(req->scid);
2969 dcid = __le16_to_cpu(req->dcid);
2970
2971 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
2972
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002973 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2974 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002975 return 0;
2976
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002977 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
2978 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
2980
2981 sk->sk_shutdown = SHUTDOWN_MASK;
2982
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002983 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002984
2985 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
2986 skb_queue_purge(SREJ_QUEUE(sk));
2987 del_timer(&l2cap_pi(sk)->retrans_timer);
2988 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002989 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002990 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002991
Linus Torvalds1da177e2005-04-16 15:20:36 -07002992 l2cap_chan_del(sk, ECONNRESET);
2993 bh_unlock_sock(sk);
2994
2995 l2cap_sock_kill(sk);
2996 return 0;
2997}
2998
2999static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3000{
3001 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3002 u16 dcid, scid;
3003 struct sock *sk;
3004
3005 scid = __le16_to_cpu(rsp->scid);
3006 dcid = __le16_to_cpu(rsp->dcid);
3007
3008 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3009
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003010 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3011 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003012 return 0;
3013
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003014 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003015
3016 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3017 skb_queue_purge(SREJ_QUEUE(sk));
3018 del_timer(&l2cap_pi(sk)->retrans_timer);
3019 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003020 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003021 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003022
Linus Torvalds1da177e2005-04-16 15:20:36 -07003023 l2cap_chan_del(sk, 0);
3024 bh_unlock_sock(sk);
3025
3026 l2cap_sock_kill(sk);
3027 return 0;
3028}
3029
3030static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3031{
3032 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003033 u16 type;
3034
3035 type = __le16_to_cpu(req->type);
3036
3037 BT_DBG("type 0x%4.4x", type);
3038
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003039 if (type == L2CAP_IT_FEAT_MASK) {
3040 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003041 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003042 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3043 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3044 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003045 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003046 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3047 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003048 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003049 l2cap_send_cmd(conn, cmd->ident,
3050 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003051 } else if (type == L2CAP_IT_FIXED_CHAN) {
3052 u8 buf[12];
3053 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3054 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3055 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3056 memcpy(buf + 4, l2cap_fixed_chan, 8);
3057 l2cap_send_cmd(conn, cmd->ident,
3058 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003059 } else {
3060 struct l2cap_info_rsp rsp;
3061 rsp.type = cpu_to_le16(type);
3062 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3063 l2cap_send_cmd(conn, cmd->ident,
3064 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3065 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003066
3067 return 0;
3068}
3069
3070static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3071{
3072 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3073 u16 type, result;
3074
3075 type = __le16_to_cpu(rsp->type);
3076 result = __le16_to_cpu(rsp->result);
3077
3078 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3079
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003080 del_timer(&conn->info_timer);
3081
Marcel Holtmann984947d2009-02-06 23:35:19 +01003082 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003083 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003084
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003085 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003086 struct l2cap_info_req req;
3087 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3088
3089 conn->info_ident = l2cap_get_ident(conn);
3090
3091 l2cap_send_cmd(conn, conn->info_ident,
3092 L2CAP_INFO_REQ, sizeof(req), &req);
3093 } else {
3094 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3095 conn->info_ident = 0;
3096
3097 l2cap_conn_start(conn);
3098 }
3099 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003100 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003101 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003102
3103 l2cap_conn_start(conn);
3104 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003105
Linus Torvalds1da177e2005-04-16 15:20:36 -07003106 return 0;
3107}
3108
3109static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3110{
3111 u8 *data = skb->data;
3112 int len = skb->len;
3113 struct l2cap_cmd_hdr cmd;
3114 int err = 0;
3115
3116 l2cap_raw_recv(conn, skb);
3117
3118 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003119 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003120 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3121 data += L2CAP_CMD_HDR_SIZE;
3122 len -= L2CAP_CMD_HDR_SIZE;
3123
Al Viro88219a02007-07-29 00:17:25 -07003124 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003125
Al Viro88219a02007-07-29 00:17:25 -07003126 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 -07003127
Al Viro88219a02007-07-29 00:17:25 -07003128 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003129 BT_DBG("corrupted command");
3130 break;
3131 }
3132
3133 switch (cmd.code) {
3134 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003135 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003136 break;
3137
3138 case L2CAP_CONN_REQ:
3139 err = l2cap_connect_req(conn, &cmd, data);
3140 break;
3141
3142 case L2CAP_CONN_RSP:
3143 err = l2cap_connect_rsp(conn, &cmd, data);
3144 break;
3145
3146 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003147 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003148 break;
3149
3150 case L2CAP_CONF_RSP:
3151 err = l2cap_config_rsp(conn, &cmd, data);
3152 break;
3153
3154 case L2CAP_DISCONN_REQ:
3155 err = l2cap_disconnect_req(conn, &cmd, data);
3156 break;
3157
3158 case L2CAP_DISCONN_RSP:
3159 err = l2cap_disconnect_rsp(conn, &cmd, data);
3160 break;
3161
3162 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003163 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003164 break;
3165
3166 case L2CAP_ECHO_RSP:
3167 break;
3168
3169 case L2CAP_INFO_REQ:
3170 err = l2cap_information_req(conn, &cmd, data);
3171 break;
3172
3173 case L2CAP_INFO_RSP:
3174 err = l2cap_information_rsp(conn, &cmd, data);
3175 break;
3176
3177 default:
3178 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3179 err = -EINVAL;
3180 break;
3181 }
3182
3183 if (err) {
3184 struct l2cap_cmd_rej rej;
3185 BT_DBG("error %d", err);
3186
3187 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003188 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003189 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3190 }
3191
Al Viro88219a02007-07-29 00:17:25 -07003192 data += cmd_len;
3193 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003194 }
3195
3196 kfree_skb(skb);
3197}
3198
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003199static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3200{
3201 u16 our_fcs, rcv_fcs;
3202 int hdr_size = L2CAP_HDR_SIZE + 2;
3203
3204 if (pi->fcs == L2CAP_FCS_CRC16) {
3205 skb_trim(skb, skb->len - 2);
3206 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3207 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3208
3209 if (our_fcs != rcv_fcs)
3210 return -EINVAL;
3211 }
3212 return 0;
3213}
3214
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003215static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3216{
3217 struct l2cap_pinfo *pi = l2cap_pi(sk);
3218 u16 control = 0;
3219
3220 pi->frames_sent = 0;
3221 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3222
3223 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3224
3225 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3226 control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL;
3227 l2cap_send_sframe(pi, control);
3228 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
3229 }
3230
3231 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0)
3232 __mod_retrans_timer();
3233
3234 l2cap_ertm_send(sk);
3235
3236 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3237 pi->frames_sent == 0) {
3238 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003239 l2cap_send_sframe(pi, control);
3240 }
3241}
3242
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003243static void l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
3244{
3245 struct sk_buff *next_skb;
3246
3247 bt_cb(skb)->tx_seq = tx_seq;
3248 bt_cb(skb)->sar = sar;
3249
3250 next_skb = skb_peek(SREJ_QUEUE(sk));
3251 if (!next_skb) {
3252 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3253 return;
3254 }
3255
3256 do {
3257 if (bt_cb(next_skb)->tx_seq > tx_seq) {
3258 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
3259 return;
3260 }
3261
3262 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3263 break;
3264
3265 } while((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
3266
3267 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3268}
3269
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003270static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3271{
3272 struct l2cap_pinfo *pi = l2cap_pi(sk);
3273 struct sk_buff *_skb;
3274 int err = -EINVAL;
3275
3276 switch (control & L2CAP_CTRL_SAR) {
3277 case L2CAP_SDU_UNSEGMENTED:
3278 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3279 kfree_skb(pi->sdu);
3280 break;
3281 }
3282
3283 err = sock_queue_rcv_skb(sk, skb);
3284 if (!err)
3285 return 0;
3286
3287 break;
3288
3289 case L2CAP_SDU_START:
3290 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3291 kfree_skb(pi->sdu);
3292 break;
3293 }
3294
3295 pi->sdu_len = get_unaligned_le16(skb->data);
3296 skb_pull(skb, 2);
3297
3298 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3299 if (!pi->sdu) {
3300 err = -ENOMEM;
3301 break;
3302 }
3303
3304 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3305
3306 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3307 pi->partial_sdu_len = skb->len;
3308 err = 0;
3309 break;
3310
3311 case L2CAP_SDU_CONTINUE:
3312 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3313 break;
3314
3315 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3316
3317 pi->partial_sdu_len += skb->len;
3318 if (pi->partial_sdu_len > pi->sdu_len)
3319 kfree_skb(pi->sdu);
3320 else
3321 err = 0;
3322
3323 break;
3324
3325 case L2CAP_SDU_END:
3326 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3327 break;
3328
3329 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3330
3331 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3332 pi->partial_sdu_len += skb->len;
3333
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003334 if (pi->partial_sdu_len > pi->imtu)
3335 goto drop;
3336
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003337 if (pi->partial_sdu_len == pi->sdu_len) {
3338 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3339 err = sock_queue_rcv_skb(sk, _skb);
3340 if (err < 0)
3341 kfree_skb(_skb);
3342 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003343 err = 0;
3344
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003345drop:
3346 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003347 break;
3348 }
3349
3350 kfree_skb(skb);
3351 return err;
3352}
3353
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003354static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3355{
3356 struct sk_buff *skb;
3357 u16 control = 0;
3358
3359 while((skb = skb_peek(SREJ_QUEUE(sk)))) {
3360 if (bt_cb(skb)->tx_seq != tx_seq)
3361 break;
3362
3363 skb = skb_dequeue(SREJ_QUEUE(sk));
3364 control |= bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3365 l2cap_sar_reassembly_sdu(sk, skb, control);
3366 l2cap_pi(sk)->buffer_seq_srej =
3367 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
3368 tx_seq++;
3369 }
3370}
3371
3372static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3373{
3374 struct l2cap_pinfo *pi = l2cap_pi(sk);
3375 struct srej_list *l, *tmp;
3376 u16 control;
3377
3378 list_for_each_entry_safe(l,tmp, SREJ_LIST(sk), list) {
3379 if (l->tx_seq == tx_seq) {
3380 list_del(&l->list);
3381 kfree(l);
3382 return;
3383 }
3384 control = L2CAP_SUPER_SELECT_REJECT;
3385 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3386 l2cap_send_sframe(pi, control);
3387 list_del(&l->list);
3388 list_add_tail(&l->list, SREJ_LIST(sk));
3389 }
3390}
3391
3392static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3393{
3394 struct l2cap_pinfo *pi = l2cap_pi(sk);
3395 struct srej_list *new;
3396 u16 control;
3397
3398 while (tx_seq != pi->expected_tx_seq) {
3399 control = L2CAP_SUPER_SELECT_REJECT;
3400 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3401 l2cap_send_sframe(pi, control);
3402
3403 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
3404 new->tx_seq = pi->expected_tx_seq++;
3405 list_add_tail(&new->list, SREJ_LIST(sk));
3406 }
3407 pi->expected_tx_seq++;
3408}
3409
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003410static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3411{
3412 struct l2cap_pinfo *pi = l2cap_pi(sk);
3413 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003414 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003415 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003416 int err = 0;
3417
3418 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3419
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003420 if (L2CAP_CTRL_FINAL & rx_control) {
3421 del_timer(&pi->monitor_timer);
3422 if (pi->unacked_frames > 0)
3423 __mod_retrans_timer();
3424 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3425 }
3426
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003427 pi->expected_ack_seq = req_seq;
3428 l2cap_drop_acked_frames(sk);
3429
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003430 if (tx_seq == pi->expected_tx_seq)
3431 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003432
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003433 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3434 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003435
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003436 first = list_first_entry(SREJ_LIST(sk),
3437 struct srej_list, list);
3438 if (tx_seq == first->tx_seq) {
3439 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3440 l2cap_check_srej_gap(sk, tx_seq);
3441
3442 list_del(&first->list);
3443 kfree(first);
3444
3445 if (list_empty(SREJ_LIST(sk))) {
3446 pi->buffer_seq = pi->buffer_seq_srej;
3447 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
3448 }
3449 } else {
3450 struct srej_list *l;
3451 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3452
3453 list_for_each_entry(l, SREJ_LIST(sk), list) {
3454 if (l->tx_seq == tx_seq) {
3455 l2cap_resend_srejframe(sk, tx_seq);
3456 return 0;
3457 }
3458 }
3459 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003460 }
3461 } else {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003462 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003463
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003464 INIT_LIST_HEAD(SREJ_LIST(sk));
3465 pi->buffer_seq_srej = pi->buffer_seq;
3466
3467 __skb_queue_head_init(SREJ_QUEUE(sk));
3468 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3469
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003470 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3471
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003472 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003473 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003474 return 0;
3475
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003476expected:
3477 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3478
3479 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3480 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3481 return 0;
3482 }
3483
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003484 if (rx_control & L2CAP_CTRL_FINAL) {
3485 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3486 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3487 else {
3488 sk->sk_send_head = TX_QUEUE(sk)->next;
3489 pi->next_tx_seq = pi->expected_ack_seq;
3490 l2cap_ertm_send(sk);
3491 }
3492 }
3493
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003494 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3495
3496 err = l2cap_sar_reassembly_sdu(sk, skb, rx_control);
3497 if (err < 0)
3498 return err;
3499
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003500 __mod_ack_timer();
3501
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003502 pi->num_to_ack = (pi->num_to_ack + 1) % L2CAP_DEFAULT_NUM_TO_ACK;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003503 if (pi->num_to_ack == L2CAP_DEFAULT_NUM_TO_ACK - 1)
3504 l2cap_send_ack(pi);
3505
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003506 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003507}
3508
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003509static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003510{
3511 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003512
3513 pi->expected_ack_seq = __get_reqseq(rx_control);
3514 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003515
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003516 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003517 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3518 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3519 (pi->unacked_frames > 0))
3520 __mod_retrans_timer();
3521
3522 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3523 l2cap_send_srejtail(sk);
3524 } else {
3525 l2cap_send_i_or_rr_or_rnr(sk);
3526 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3527 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003528
3529 } else if (rx_control & L2CAP_CTRL_FINAL) {
3530 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003531
3532 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3533 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3534 else {
3535 sk->sk_send_head = TX_QUEUE(sk)->next;
3536 pi->next_tx_seq = pi->expected_ack_seq;
3537 l2cap_ertm_send(sk);
3538 }
3539
3540 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003541 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3542 (pi->unacked_frames > 0))
3543 __mod_retrans_timer();
3544
3545 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3546 if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
3547 l2cap_send_ack(pi);
3548 else
3549 l2cap_ertm_send(sk);
3550 }
3551}
3552
3553static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3554{
3555 struct l2cap_pinfo *pi = l2cap_pi(sk);
3556 u8 tx_seq = __get_reqseq(rx_control);
3557
3558 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3559
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03003560 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003561 l2cap_drop_acked_frames(sk);
3562
3563 if (rx_control & L2CAP_CTRL_FINAL) {
3564 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3565 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3566 else {
3567 sk->sk_send_head = TX_QUEUE(sk)->next;
3568 pi->next_tx_seq = pi->expected_ack_seq;
3569 l2cap_ertm_send(sk);
3570 }
3571 } else {
3572 sk->sk_send_head = TX_QUEUE(sk)->next;
3573 pi->next_tx_seq = pi->expected_ack_seq;
3574 l2cap_ertm_send(sk);
3575
3576 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3577 pi->srej_save_reqseq = tx_seq;
3578 pi->conn_state |= L2CAP_CONN_REJ_ACT;
3579 }
3580 }
3581}
3582static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
3583{
3584 struct l2cap_pinfo *pi = l2cap_pi(sk);
3585 u8 tx_seq = __get_reqseq(rx_control);
3586
3587 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3588
3589 if (rx_control & L2CAP_CTRL_POLL) {
3590 pi->expected_ack_seq = tx_seq;
3591 l2cap_drop_acked_frames(sk);
3592 l2cap_retransmit_frame(sk, tx_seq);
3593 l2cap_ertm_send(sk);
3594 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3595 pi->srej_save_reqseq = tx_seq;
3596 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3597 }
3598 } else if (rx_control & L2CAP_CTRL_FINAL) {
3599 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3600 pi->srej_save_reqseq == tx_seq)
3601 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
3602 else
3603 l2cap_retransmit_frame(sk, tx_seq);
3604 } else {
3605 l2cap_retransmit_frame(sk, tx_seq);
3606 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3607 pi->srej_save_reqseq = tx_seq;
3608 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3609 }
3610 }
3611}
3612
3613static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
3614{
3615 struct l2cap_pinfo *pi = l2cap_pi(sk);
3616 u8 tx_seq = __get_reqseq(rx_control);
3617
3618 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
3619 pi->expected_ack_seq = tx_seq;
3620 l2cap_drop_acked_frames(sk);
3621
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003622 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
3623 del_timer(&pi->retrans_timer);
3624 if (rx_control & L2CAP_CTRL_POLL) {
3625 u16 control = L2CAP_CTRL_FINAL;
3626 l2cap_send_rr_or_rnr(pi, control);
3627 }
3628 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003629 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003630
3631 if (rx_control & L2CAP_CTRL_POLL)
3632 l2cap_send_srejtail(sk);
3633 else
3634 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003635}
3636
3637static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3638{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003639 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3640
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003641 if (L2CAP_CTRL_FINAL & rx_control) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003642 del_timer(&l2cap_pi(sk)->monitor_timer);
3643 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003644 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003645 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003646 }
3647
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003648 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
3649 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003650 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003651 break;
3652
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003653 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003654 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003655 break;
3656
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003657 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003658 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003659 break;
3660
3661 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003662 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003663 break;
3664 }
3665
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03003666 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003667 return 0;
3668}
3669
Linus Torvalds1da177e2005-04-16 15:20:36 -07003670static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
3671{
3672 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003673 struct l2cap_pinfo *pi;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003674 u16 control, len;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003675 u8 tx_seq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003676
3677 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3678 if (!sk) {
3679 BT_DBG("unknown cid 0x%4.4x", cid);
3680 goto drop;
3681 }
3682
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003683 pi = l2cap_pi(sk);
3684
Linus Torvalds1da177e2005-04-16 15:20:36 -07003685 BT_DBG("sk %p, len %d", sk, skb->len);
3686
3687 if (sk->sk_state != BT_CONNECTED)
3688 goto drop;
3689
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003690 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003691 case L2CAP_MODE_BASIC:
3692 /* If socket recv buffers overflows we drop data here
3693 * which is *bad* because L2CAP has to be reliable.
3694 * But we don't have any other choice. L2CAP doesn't
3695 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003696
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003697 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003698 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003699
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003700 if (!sock_queue_rcv_skb(sk, skb))
3701 goto done;
3702 break;
3703
3704 case L2CAP_MODE_ERTM:
3705 control = get_unaligned_le16(skb->data);
3706 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003707 len = skb->len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003708
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003709 if (__is_sar_start(control))
3710 len -= 2;
3711
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003712 if (pi->fcs == L2CAP_FCS_CRC16)
3713 len -= 2;
3714
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003715 /*
3716 * We can just drop the corrupted I-frame here.
3717 * Receiver will miss it and start proper recovery
3718 * procedures and ask retransmission.
3719 */
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003720 if (len > L2CAP_DEFAULT_MAX_PDU_SIZE)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003721 goto drop;
3722
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003723 if (l2cap_check_fcs(pi, skb))
3724 goto drop;
3725
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003726 if (__is_iframe(control)) {
3727 if (len < 4)
3728 goto drop;
3729
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003730 l2cap_data_channel_iframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003731 } else {
3732 if (len != 0)
3733 goto drop;
3734
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003735 l2cap_data_channel_sframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003736 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003737
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003738 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003739
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003740 case L2CAP_MODE_STREAMING:
3741 control = get_unaligned_le16(skb->data);
3742 skb_pull(skb, 2);
3743 len = skb->len;
3744
3745 if (__is_sar_start(control))
3746 len -= 2;
3747
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003748 if (pi->fcs == L2CAP_FCS_CRC16)
3749 len -= 2;
3750
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003751 if (len > L2CAP_DEFAULT_MAX_PDU_SIZE || len < 4
3752 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003753 goto drop;
3754
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003755 if (l2cap_check_fcs(pi, skb))
3756 goto drop;
3757
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003758 tx_seq = __get_txseq(control);
3759
3760 if (pi->expected_tx_seq == tx_seq)
3761 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3762 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03003763 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003764
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003765 l2cap_sar_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003766
3767 goto done;
3768
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003769 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03003770 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003771 break;
3772 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003773
3774drop:
3775 kfree_skb(skb);
3776
3777done:
Marcel Holtmann01394182006-07-03 10:02:46 +02003778 if (sk)
3779 bh_unlock_sock(sk);
3780
Linus Torvalds1da177e2005-04-16 15:20:36 -07003781 return 0;
3782}
3783
Al Viro8e036fc2007-07-29 00:16:36 -07003784static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003785{
3786 struct sock *sk;
3787
3788 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
3789 if (!sk)
3790 goto drop;
3791
3792 BT_DBG("sk %p, len %d", sk, skb->len);
3793
3794 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
3795 goto drop;
3796
3797 if (l2cap_pi(sk)->imtu < skb->len)
3798 goto drop;
3799
3800 if (!sock_queue_rcv_skb(sk, skb))
3801 goto done;
3802
3803drop:
3804 kfree_skb(skb);
3805
3806done:
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003807 if (sk)
3808 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003809 return 0;
3810}
3811
3812static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
3813{
3814 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07003815 u16 cid, len;
3816 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003817
3818 skb_pull(skb, L2CAP_HDR_SIZE);
3819 cid = __le16_to_cpu(lh->cid);
3820 len = __le16_to_cpu(lh->len);
3821
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003822 if (len != skb->len) {
3823 kfree_skb(skb);
3824 return;
3825 }
3826
Linus Torvalds1da177e2005-04-16 15:20:36 -07003827 BT_DBG("len %d, cid 0x%4.4x", len, cid);
3828
3829 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003830 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003831 l2cap_sig_channel(conn, skb);
3832 break;
3833
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003834 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003835 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003836 skb_pull(skb, 2);
3837 l2cap_conless_channel(conn, psm, skb);
3838 break;
3839
3840 default:
3841 l2cap_data_channel(conn, cid, skb);
3842 break;
3843 }
3844}
3845
3846/* ---- L2CAP interface with lower layer (HCI) ---- */
3847
3848static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3849{
3850 int exact = 0, lm1 = 0, lm2 = 0;
3851 register struct sock *sk;
3852 struct hlist_node *node;
3853
3854 if (type != ACL_LINK)
3855 return 0;
3856
3857 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
3858
3859 /* Find listening sockets and check their link_mode */
3860 read_lock(&l2cap_sk_list.lock);
3861 sk_for_each(sk, node, &l2cap_sk_list.head) {
3862 if (sk->sk_state != BT_LISTEN)
3863 continue;
3864
3865 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003866 lm1 |= HCI_LM_ACCEPT;
3867 if (l2cap_pi(sk)->role_switch)
3868 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003869 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003870 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
3871 lm2 |= HCI_LM_ACCEPT;
3872 if (l2cap_pi(sk)->role_switch)
3873 lm2 |= HCI_LM_MASTER;
3874 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003875 }
3876 read_unlock(&l2cap_sk_list.lock);
3877
3878 return exact ? lm1 : lm2;
3879}
3880
3881static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
3882{
Marcel Holtmann01394182006-07-03 10:02:46 +02003883 struct l2cap_conn *conn;
3884
Linus Torvalds1da177e2005-04-16 15:20:36 -07003885 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
3886
3887 if (hcon->type != ACL_LINK)
3888 return 0;
3889
3890 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003891 conn = l2cap_conn_add(hcon, status);
3892 if (conn)
3893 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02003894 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003895 l2cap_conn_del(hcon, bt_err(status));
3896
3897 return 0;
3898}
3899
Marcel Holtmann2950f212009-02-12 14:02:50 +01003900static int l2cap_disconn_ind(struct hci_conn *hcon)
3901{
3902 struct l2cap_conn *conn = hcon->l2cap_data;
3903
3904 BT_DBG("hcon %p", hcon);
3905
3906 if (hcon->type != ACL_LINK || !conn)
3907 return 0x13;
3908
3909 return conn->disc_reason;
3910}
3911
3912static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003913{
3914 BT_DBG("hcon %p reason %d", hcon, reason);
3915
3916 if (hcon->type != ACL_LINK)
3917 return 0;
3918
3919 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02003920
Linus Torvalds1da177e2005-04-16 15:20:36 -07003921 return 0;
3922}
3923
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003924static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
3925{
Marcel Holtmann255c7602009-02-04 21:07:19 +01003926 if (sk->sk_type != SOCK_SEQPACKET)
3927 return;
3928
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003929 if (encrypt == 0x00) {
3930 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
3931 l2cap_sock_clear_timer(sk);
3932 l2cap_sock_set_timer(sk, HZ * 5);
3933 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
3934 __l2cap_sock_close(sk, ECONNREFUSED);
3935 } else {
3936 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
3937 l2cap_sock_clear_timer(sk);
3938 }
3939}
3940
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003941static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003942{
3943 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02003944 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003945 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003946
Marcel Holtmann01394182006-07-03 10:02:46 +02003947 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003948 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02003949
Linus Torvalds1da177e2005-04-16 15:20:36 -07003950 l = &conn->chan_list;
3951
3952 BT_DBG("conn %p", conn);
3953
3954 read_lock(&l->lock);
3955
3956 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
3957 bh_lock_sock(sk);
3958
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003959 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
3960 bh_unlock_sock(sk);
3961 continue;
3962 }
3963
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003964 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003965 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003966 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02003967 bh_unlock_sock(sk);
3968 continue;
3969 }
3970
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003971 if (sk->sk_state == BT_CONNECT) {
3972 if (!status) {
3973 struct l2cap_conn_req req;
3974 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
3975 req.psm = l2cap_pi(sk)->psm;
3976
3977 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
3978
3979 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3980 L2CAP_CONN_REQ, sizeof(req), &req);
3981 } else {
3982 l2cap_sock_clear_timer(sk);
3983 l2cap_sock_set_timer(sk, HZ / 10);
3984 }
3985 } else if (sk->sk_state == BT_CONNECT2) {
3986 struct l2cap_conn_rsp rsp;
3987 __u16 result;
3988
3989 if (!status) {
3990 sk->sk_state = BT_CONFIG;
3991 result = L2CAP_CR_SUCCESS;
3992 } else {
3993 sk->sk_state = BT_DISCONN;
3994 l2cap_sock_set_timer(sk, HZ / 10);
3995 result = L2CAP_CR_SEC_BLOCK;
3996 }
3997
3998 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
3999 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4000 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004001 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004002 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4003 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004004 }
4005
Linus Torvalds1da177e2005-04-16 15:20:36 -07004006 bh_unlock_sock(sk);
4007 }
4008
4009 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004010
Linus Torvalds1da177e2005-04-16 15:20:36 -07004011 return 0;
4012}
4013
4014static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4015{
4016 struct l2cap_conn *conn = hcon->l2cap_data;
4017
4018 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4019 goto drop;
4020
4021 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4022
4023 if (flags & ACL_START) {
4024 struct l2cap_hdr *hdr;
4025 int len;
4026
4027 if (conn->rx_len) {
4028 BT_ERR("Unexpected start frame (len %d)", skb->len);
4029 kfree_skb(conn->rx_skb);
4030 conn->rx_skb = NULL;
4031 conn->rx_len = 0;
4032 l2cap_conn_unreliable(conn, ECOMM);
4033 }
4034
4035 if (skb->len < 2) {
4036 BT_ERR("Frame is too short (len %d)", skb->len);
4037 l2cap_conn_unreliable(conn, ECOMM);
4038 goto drop;
4039 }
4040
4041 hdr = (struct l2cap_hdr *) skb->data;
4042 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4043
4044 if (len == skb->len) {
4045 /* Complete frame received */
4046 l2cap_recv_frame(conn, skb);
4047 return 0;
4048 }
4049
4050 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4051
4052 if (skb->len > len) {
4053 BT_ERR("Frame is too long (len %d, expected len %d)",
4054 skb->len, len);
4055 l2cap_conn_unreliable(conn, ECOMM);
4056 goto drop;
4057 }
4058
4059 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03004060 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4061 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004062 goto drop;
4063
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004064 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004065 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004066 conn->rx_len = len - skb->len;
4067 } else {
4068 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4069
4070 if (!conn->rx_len) {
4071 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4072 l2cap_conn_unreliable(conn, ECOMM);
4073 goto drop;
4074 }
4075
4076 if (skb->len > conn->rx_len) {
4077 BT_ERR("Fragment is too long (len %d, expected %d)",
4078 skb->len, conn->rx_len);
4079 kfree_skb(conn->rx_skb);
4080 conn->rx_skb = NULL;
4081 conn->rx_len = 0;
4082 l2cap_conn_unreliable(conn, ECOMM);
4083 goto drop;
4084 }
4085
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004086 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004087 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004088 conn->rx_len -= skb->len;
4089
4090 if (!conn->rx_len) {
4091 /* Complete frame received */
4092 l2cap_recv_frame(conn, conn->rx_skb);
4093 conn->rx_skb = NULL;
4094 }
4095 }
4096
4097drop:
4098 kfree_skb(skb);
4099 return 0;
4100}
4101
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004102static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004103{
4104 struct sock *sk;
4105 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004106
4107 read_lock_bh(&l2cap_sk_list.lock);
4108
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004109 sk_for_each(sk, node, &l2cap_sk_list.head) {
4110 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004111
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004112 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4113 batostr(&bt_sk(sk)->src),
4114 batostr(&bt_sk(sk)->dst),
4115 sk->sk_state, __le16_to_cpu(pi->psm),
4116 pi->scid, pi->dcid,
4117 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004118 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004119
Linus Torvalds1da177e2005-04-16 15:20:36 -07004120 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004121
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004122 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004123}
4124
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004125static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4126{
4127 return single_open(file, l2cap_debugfs_show, inode->i_private);
4128}
4129
4130static const struct file_operations l2cap_debugfs_fops = {
4131 .open = l2cap_debugfs_open,
4132 .read = seq_read,
4133 .llseek = seq_lseek,
4134 .release = single_release,
4135};
4136
4137static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004138
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004139static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004140 .family = PF_BLUETOOTH,
4141 .owner = THIS_MODULE,
4142 .release = l2cap_sock_release,
4143 .bind = l2cap_sock_bind,
4144 .connect = l2cap_sock_connect,
4145 .listen = l2cap_sock_listen,
4146 .accept = l2cap_sock_accept,
4147 .getname = l2cap_sock_getname,
4148 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004149 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004150 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004151 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004152 .mmap = sock_no_mmap,
4153 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004154 .shutdown = l2cap_sock_shutdown,
4155 .setsockopt = l2cap_sock_setsockopt,
4156 .getsockopt = l2cap_sock_getsockopt
4157};
4158
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004159static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004160 .family = PF_BLUETOOTH,
4161 .owner = THIS_MODULE,
4162 .create = l2cap_sock_create,
4163};
4164
4165static struct hci_proto l2cap_hci_proto = {
4166 .name = "L2CAP",
4167 .id = HCI_PROTO_L2CAP,
4168 .connect_ind = l2cap_connect_ind,
4169 .connect_cfm = l2cap_connect_cfm,
4170 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004171 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004172 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004173 .recv_acldata = l2cap_recv_acldata
4174};
4175
4176static int __init l2cap_init(void)
4177{
4178 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004179
Linus Torvalds1da177e2005-04-16 15:20:36 -07004180 err = proto_register(&l2cap_proto, 0);
4181 if (err < 0)
4182 return err;
4183
4184 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4185 if (err < 0) {
4186 BT_ERR("L2CAP socket registration failed");
4187 goto error;
4188 }
4189
4190 err = hci_register_proto(&l2cap_hci_proto);
4191 if (err < 0) {
4192 BT_ERR("L2CAP protocol registration failed");
4193 bt_sock_unregister(BTPROTO_L2CAP);
4194 goto error;
4195 }
4196
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004197 if (bt_debugfs) {
4198 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4199 bt_debugfs, NULL, &l2cap_debugfs_fops);
4200 if (!l2cap_debugfs)
4201 BT_ERR("Failed to create L2CAP debug file");
4202 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004203
4204 BT_INFO("L2CAP ver %s", VERSION);
4205 BT_INFO("L2CAP socket layer initialized");
4206
4207 return 0;
4208
4209error:
4210 proto_unregister(&l2cap_proto);
4211 return err;
4212}
4213
4214static void __exit l2cap_exit(void)
4215{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004216 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004217
4218 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4219 BT_ERR("L2CAP socket unregistration failed");
4220
4221 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4222 BT_ERR("L2CAP protocol unregistration failed");
4223
4224 proto_unregister(&l2cap_proto);
4225}
4226
4227void l2cap_load(void)
4228{
4229 /* Dummy function to trigger automatic L2CAP module loading by
4230 * other modules that use L2CAP sockets but don't use any other
4231 * symbols from it. */
4232 return;
4233}
4234EXPORT_SYMBOL(l2cap_load);
4235
4236module_init(l2cap_init);
4237module_exit(l2cap_exit);
4238
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004239module_param(enable_ertm, bool, 0644);
4240MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4241
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +02004242module_param(max_transmit, uint, 0644);
4243MODULE_PARM_DESC(max_transmit, "Max transmit value (default = 3)");
4244
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004245MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004246MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4247MODULE_VERSION(VERSION);
4248MODULE_LICENSE("GPL");
4249MODULE_ALIAS("bt-proto-0");