blob: 555d9da1869b2fa3daca87eef3f88974a6edb0c8 [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>
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -030043#include <linux/uaccess.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030044#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070045#include <net/sock.h>
46
47#include <asm/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070048#include <asm/unaligned.h>
49
50#include <net/bluetooth/bluetooth.h>
51#include <net/bluetooth/hci_core.h>
52#include <net/bluetooth/l2cap.h>
53
Marcel Holtmann44dd46d2009-05-02 19:09:01 -070054#define VERSION "2.14"
55
56static int enable_ertm = 0;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020057
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070058static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Marcel Holtmanne1027a72009-02-09 09:18:02 +010059static u8 l2cap_fixed_chan[8] = { 0x02, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070060
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080061static const struct proto_ops l2cap_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070062
63static struct bt_sock_list l2cap_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070064 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070065};
66
Linus Torvalds1da177e2005-04-16 15:20:36 -070067static void __l2cap_sock_close(struct sock *sk, int reason);
68static void l2cap_sock_close(struct sock *sk);
69static void l2cap_sock_kill(struct sock *sk);
70
71static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
72 u8 code, u8 ident, u16 dlen, void *data);
73
74/* ---- L2CAP timers ---- */
75static void l2cap_sock_timeout(unsigned long arg)
76{
77 struct sock *sk = (struct sock *) arg;
Marcel Holtmannb1235d72008-07-14 20:13:54 +020078 int reason;
Linus Torvalds1da177e2005-04-16 15:20:36 -070079
80 BT_DBG("sock %p state %d", sk, sk->sk_state);
81
82 bh_lock_sock(sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +020083
Marcel Holtmannf62e4322009-01-15 21:58:44 +010084 if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
85 reason = ECONNREFUSED;
86 else if (sk->sk_state == BT_CONNECT &&
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +010087 l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
Marcel Holtmannb1235d72008-07-14 20:13:54 +020088 reason = ECONNREFUSED;
89 else
90 reason = ETIMEDOUT;
91
92 __l2cap_sock_close(sk, reason);
93
Linus Torvalds1da177e2005-04-16 15:20:36 -070094 bh_unlock_sock(sk);
95
96 l2cap_sock_kill(sk);
97 sock_put(sk);
98}
99
100static void l2cap_sock_set_timer(struct sock *sk, long timeout)
101{
102 BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
103 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
104}
105
106static void l2cap_sock_clear_timer(struct sock *sk)
107{
108 BT_DBG("sock %p state %d", sk, sk->sk_state);
109 sk_stop_timer(sk, &sk->sk_timer);
110}
111
Marcel Holtmann01394182006-07-03 10:02:46 +0200112/* ---- L2CAP channels ---- */
113static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
114{
115 struct sock *s;
116 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
117 if (l2cap_pi(s)->dcid == cid)
118 break;
119 }
120 return s;
121}
122
123static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
124{
125 struct sock *s;
126 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
127 if (l2cap_pi(s)->scid == cid)
128 break;
129 }
130 return s;
131}
132
133/* Find channel with given SCID.
134 * Returns locked socket */
135static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
136{
137 struct sock *s;
138 read_lock(&l->lock);
139 s = __l2cap_get_chan_by_scid(l, cid);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300140 if (s)
141 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200142 read_unlock(&l->lock);
143 return s;
144}
145
146static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
147{
148 struct sock *s;
149 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
150 if (l2cap_pi(s)->ident == ident)
151 break;
152 }
153 return s;
154}
155
156static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
157{
158 struct sock *s;
159 read_lock(&l->lock);
160 s = __l2cap_get_chan_by_ident(l, ident);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300161 if (s)
162 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200163 read_unlock(&l->lock);
164 return s;
165}
166
167static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
168{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300169 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200170
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300171 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300172 if (!__l2cap_get_chan_by_scid(l, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200173 return cid;
174 }
175
176 return 0;
177}
178
179static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
180{
181 sock_hold(sk);
182
183 if (l->head)
184 l2cap_pi(l->head)->prev_c = sk;
185
186 l2cap_pi(sk)->next_c = l->head;
187 l2cap_pi(sk)->prev_c = NULL;
188 l->head = sk;
189}
190
191static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
192{
193 struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
194
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200195 write_lock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200196 if (sk == l->head)
197 l->head = next;
198
199 if (next)
200 l2cap_pi(next)->prev_c = prev;
201 if (prev)
202 l2cap_pi(prev)->next_c = next;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200203 write_unlock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200204
205 __sock_put(sk);
206}
207
208static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
209{
210 struct l2cap_chan_list *l = &conn->chan_list;
211
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300212 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
213 l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200214
Marcel Holtmann2950f212009-02-12 14:02:50 +0100215 conn->disc_reason = 0x13;
216
Marcel Holtmann01394182006-07-03 10:02:46 +0200217 l2cap_pi(sk)->conn = conn;
218
219 if (sk->sk_type == SOCK_SEQPACKET) {
220 /* Alloc CID for connection-oriented socket */
221 l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
222 } else if (sk->sk_type == SOCK_DGRAM) {
223 /* Connectionless socket */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300224 l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
225 l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
Marcel Holtmann01394182006-07-03 10:02:46 +0200226 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
227 } else {
228 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300229 l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
230 l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
Marcel Holtmann01394182006-07-03 10:02:46 +0200231 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
232 }
233
234 __l2cap_chan_link(l, sk);
235
236 if (parent)
237 bt_accept_enqueue(parent, sk);
238}
239
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900240/* Delete channel.
Marcel Holtmann01394182006-07-03 10:02:46 +0200241 * Must be called on the locked socket. */
242static void l2cap_chan_del(struct sock *sk, int err)
243{
244 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
245 struct sock *parent = bt_sk(sk)->parent;
246
247 l2cap_sock_clear_timer(sk);
248
249 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
250
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900251 if (conn) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200252 /* Unlink from channel list */
253 l2cap_chan_unlink(&conn->chan_list, sk);
254 l2cap_pi(sk)->conn = NULL;
255 hci_conn_put(conn->hcon);
256 }
257
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200258 sk->sk_state = BT_CLOSED;
Marcel Holtmann01394182006-07-03 10:02:46 +0200259 sock_set_flag(sk, SOCK_ZAPPED);
260
261 if (err)
262 sk->sk_err = err;
263
264 if (parent) {
265 bt_accept_unlink(sk);
266 parent->sk_data_ready(parent, 0);
267 } else
268 sk->sk_state_change(sk);
269}
270
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200271/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100272static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200273{
274 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100275 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200276
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100277 if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
278 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
279 auth_type = HCI_AT_NO_BONDING_MITM;
280 else
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300281 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100282
283 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
284 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
285 } else {
286 switch (l2cap_pi(sk)->sec_level) {
287 case BT_SECURITY_HIGH:
288 auth_type = HCI_AT_GENERAL_BONDING_MITM;
289 break;
290 case BT_SECURITY_MEDIUM:
291 auth_type = HCI_AT_GENERAL_BONDING;
292 break;
293 default:
294 auth_type = HCI_AT_NO_BONDING;
295 break;
296 }
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100297 }
298
299 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
300 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200301}
302
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200303static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
304{
305 u8 id;
306
307 /* Get next available identificator.
308 * 1 - 128 are used by kernel.
309 * 129 - 199 are reserved.
310 * 200 - 254 are used by utilities like l2ping, etc.
311 */
312
313 spin_lock_bh(&conn->lock);
314
315 if (++conn->tx_ident > 128)
316 conn->tx_ident = 1;
317
318 id = conn->tx_ident;
319
320 spin_unlock_bh(&conn->lock);
321
322 return id;
323}
324
325static inline int l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
326{
327 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
328
329 BT_DBG("code 0x%2.2x", code);
330
331 if (!skb)
332 return -ENOMEM;
333
334 return hci_send_acl(conn->hcon, skb, 0);
335}
336
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300337static inline int l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
338{
339 struct sk_buff *skb;
340 struct l2cap_hdr *lh;
341 struct l2cap_conn *conn = pi->conn;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300342 int count, hlen = L2CAP_HDR_SIZE + 2;
343
344 if (pi->fcs == L2CAP_FCS_CRC16)
345 hlen += 2;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300346
347 BT_DBG("pi %p, control 0x%2.2x", pi, control);
348
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300349 count = min_t(unsigned int, conn->mtu, hlen);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300350 control |= L2CAP_CTRL_FRAME_TYPE;
351
352 skb = bt_skb_alloc(count, GFP_ATOMIC);
353 if (!skb)
354 return -ENOMEM;
355
356 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300357 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300358 lh->cid = cpu_to_le16(pi->dcid);
359 put_unaligned_le16(control, skb_put(skb, 2));
360
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300361 if (pi->fcs == L2CAP_FCS_CRC16) {
362 u16 fcs = crc16(0, (u8 *)lh, count - 2);
363 put_unaligned_le16(fcs, skb_put(skb, 2));
364 }
365
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300366 return hci_send_acl(pi->conn->hcon, skb, 0);
367}
368
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300369static inline int l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
370{
371 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY)
372 control |= L2CAP_SUPER_RCV_NOT_READY;
373 else
374 control |= L2CAP_SUPER_RCV_READY;
375
376 return l2cap_send_sframe(pi, control);
377}
378
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200379static void l2cap_do_start(struct sock *sk)
380{
381 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
382
383 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100384 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
385 return;
386
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100387 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200388 struct l2cap_conn_req req;
389 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
390 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200391
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200392 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200393
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200394 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200395 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200396 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200397 } else {
398 struct l2cap_info_req req;
399 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
400
401 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
402 conn->info_ident = l2cap_get_ident(conn);
403
404 mod_timer(&conn->info_timer, jiffies +
405 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
406
407 l2cap_send_cmd(conn, conn->info_ident,
408 L2CAP_INFO_REQ, sizeof(req), &req);
409 }
410}
411
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300412static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk)
413{
414 struct l2cap_disconn_req req;
415
416 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
417 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
418 l2cap_send_cmd(conn, l2cap_get_ident(conn),
419 L2CAP_DISCONN_REQ, sizeof(req), &req);
420}
421
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200423static void l2cap_conn_start(struct l2cap_conn *conn)
424{
425 struct l2cap_chan_list *l = &conn->chan_list;
426 struct sock *sk;
427
428 BT_DBG("conn %p", conn);
429
430 read_lock(&l->lock);
431
432 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
433 bh_lock_sock(sk);
434
435 if (sk->sk_type != SOCK_SEQPACKET) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200436 bh_unlock_sock(sk);
437 continue;
438 }
439
440 if (sk->sk_state == BT_CONNECT) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100441 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200442 struct l2cap_conn_req req;
443 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
444 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200445
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200446 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200447
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200448 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200449 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200450 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200451 } else if (sk->sk_state == BT_CONNECT2) {
452 struct l2cap_conn_rsp rsp;
453 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
454 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
455
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100456 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100457 if (bt_sk(sk)->defer_setup) {
458 struct sock *parent = bt_sk(sk)->parent;
459 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
460 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
461 parent->sk_data_ready(parent, 0);
462
463 } else {
464 sk->sk_state = BT_CONFIG;
465 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
466 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
467 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200468 } else {
469 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
470 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
471 }
472
473 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
474 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
475 }
476
477 bh_unlock_sock(sk);
478 }
479
480 read_unlock(&l->lock);
481}
482
483static void l2cap_conn_ready(struct l2cap_conn *conn)
484{
485 struct l2cap_chan_list *l = &conn->chan_list;
486 struct sock *sk;
487
488 BT_DBG("conn %p", conn);
489
490 read_lock(&l->lock);
491
492 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
493 bh_lock_sock(sk);
494
495 if (sk->sk_type != SOCK_SEQPACKET) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200496 l2cap_sock_clear_timer(sk);
497 sk->sk_state = BT_CONNECTED;
498 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200499 } else if (sk->sk_state == BT_CONNECT)
500 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200501
502 bh_unlock_sock(sk);
503 }
504
505 read_unlock(&l->lock);
506}
507
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200508/* Notify sockets that we cannot guaranty reliability anymore */
509static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
510{
511 struct l2cap_chan_list *l = &conn->chan_list;
512 struct sock *sk;
513
514 BT_DBG("conn %p", conn);
515
516 read_lock(&l->lock);
517
518 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100519 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200520 sk->sk_err = err;
521 }
522
523 read_unlock(&l->lock);
524}
525
526static void l2cap_info_timeout(unsigned long arg)
527{
528 struct l2cap_conn *conn = (void *) arg;
529
Marcel Holtmann984947d2009-02-06 23:35:19 +0100530 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100531 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100532
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200533 l2cap_conn_start(conn);
534}
535
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
537{
Marcel Holtmann01394182006-07-03 10:02:46 +0200538 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539
Marcel Holtmann01394182006-07-03 10:02:46 +0200540 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 return conn;
542
Marcel Holtmann01394182006-07-03 10:02:46 +0200543 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
544 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546
547 hcon->l2cap_data = conn;
548 conn->hcon = hcon;
549
Marcel Holtmann01394182006-07-03 10:02:46 +0200550 BT_DBG("hcon %p conn %p", hcon, conn);
551
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552 conn->mtu = hcon->hdev->acl_mtu;
553 conn->src = &hcon->hdev->bdaddr;
554 conn->dst = &hcon->dst;
555
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200556 conn->feat_mask = 0;
557
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200558 setup_timer(&conn->info_timer, l2cap_info_timeout,
559 (unsigned long) conn);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200560
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561 spin_lock_init(&conn->lock);
562 rwlock_init(&conn->chan_list.lock);
563
Marcel Holtmann2950f212009-02-12 14:02:50 +0100564 conn->disc_reason = 0x13;
565
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 return conn;
567}
568
Marcel Holtmann01394182006-07-03 10:02:46 +0200569static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570{
Marcel Holtmann01394182006-07-03 10:02:46 +0200571 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 struct sock *sk;
573
Marcel Holtmann01394182006-07-03 10:02:46 +0200574 if (!conn)
575 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576
577 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
578
Wei Yongjun7585b972009-02-25 18:29:52 +0800579 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580
581 /* Kill channels */
582 while ((sk = conn->chan_list.head)) {
583 bh_lock_sock(sk);
584 l2cap_chan_del(sk, err);
585 bh_unlock_sock(sk);
586 l2cap_sock_kill(sk);
587 }
588
Dave Young8e8440f2008-03-03 12:18:55 -0800589 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
590 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800591
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592 hcon->l2cap_data = NULL;
593 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594}
595
596static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
597{
598 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200599 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200601 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602}
603
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700605static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606{
607 struct sock *sk;
608 struct hlist_node *node;
609 sk_for_each(sk, node, &l2cap_sk_list.head)
610 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
611 goto found;
612 sk = NULL;
613found:
614 return sk;
615}
616
617/* Find socket with psm and source bdaddr.
618 * Returns closest match.
619 */
Al Viro8e036fc2007-07-29 00:16:36 -0700620static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621{
622 struct sock *sk = NULL, *sk1 = NULL;
623 struct hlist_node *node;
624
625 sk_for_each(sk, node, &l2cap_sk_list.head) {
626 if (state && sk->sk_state != state)
627 continue;
628
629 if (l2cap_pi(sk)->psm == psm) {
630 /* Exact match. */
631 if (!bacmp(&bt_sk(sk)->src, src))
632 break;
633
634 /* Closest match */
635 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
636 sk1 = sk;
637 }
638 }
639 return node ? sk : sk1;
640}
641
642/* Find socket with given address (psm, src).
643 * Returns locked socket */
Al Viro8e036fc2007-07-29 00:16:36 -0700644static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645{
646 struct sock *s;
647 read_lock(&l2cap_sk_list.lock);
648 s = __l2cap_get_sock_by_psm(state, psm, src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300649 if (s)
650 bh_lock_sock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651 read_unlock(&l2cap_sk_list.lock);
652 return s;
653}
654
655static void l2cap_sock_destruct(struct sock *sk)
656{
657 BT_DBG("sk %p", sk);
658
659 skb_queue_purge(&sk->sk_receive_queue);
660 skb_queue_purge(&sk->sk_write_queue);
661}
662
663static void l2cap_sock_cleanup_listen(struct sock *parent)
664{
665 struct sock *sk;
666
667 BT_DBG("parent %p", parent);
668
669 /* Close not yet accepted channels */
670 while ((sk = bt_accept_dequeue(parent, NULL)))
671 l2cap_sock_close(sk);
672
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200673 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674 sock_set_flag(parent, SOCK_ZAPPED);
675}
676
677/* Kill socket (only if zapped and orphan)
678 * Must be called on unlocked socket.
679 */
680static void l2cap_sock_kill(struct sock *sk)
681{
682 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
683 return;
684
685 BT_DBG("sk %p state %d", sk, sk->sk_state);
686
687 /* Kill poor orphan */
688 bt_sock_unlink(&l2cap_sk_list, sk);
689 sock_set_flag(sk, SOCK_DEAD);
690 sock_put(sk);
691}
692
693static void __l2cap_sock_close(struct sock *sk, int reason)
694{
695 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
696
697 switch (sk->sk_state) {
698 case BT_LISTEN:
699 l2cap_sock_cleanup_listen(sk);
700 break;
701
702 case BT_CONNECTED:
703 case BT_CONFIG:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704 if (sk->sk_type == SOCK_SEQPACKET) {
705 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706
707 sk->sk_state = BT_DISCONN;
708 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300709 l2cap_send_disconn_req(conn, sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200710 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712 break;
713
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100714 case BT_CONNECT2:
715 if (sk->sk_type == SOCK_SEQPACKET) {
716 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
717 struct l2cap_conn_rsp rsp;
718 __u16 result;
719
720 if (bt_sk(sk)->defer_setup)
721 result = L2CAP_CR_SEC_BLOCK;
722 else
723 result = L2CAP_CR_BAD_PSM;
724
725 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
726 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
727 rsp.result = cpu_to_le16(result);
728 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
729 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
730 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
731 } else
732 l2cap_chan_del(sk, reason);
733 break;
734
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735 case BT_CONNECT:
736 case BT_DISCONN:
737 l2cap_chan_del(sk, reason);
738 break;
739
740 default:
741 sock_set_flag(sk, SOCK_ZAPPED);
742 break;
743 }
744}
745
746/* Must be called on unlocked socket. */
747static void l2cap_sock_close(struct sock *sk)
748{
749 l2cap_sock_clear_timer(sk);
750 lock_sock(sk);
751 __l2cap_sock_close(sk, ECONNRESET);
752 release_sock(sk);
753 l2cap_sock_kill(sk);
754}
755
756static void l2cap_sock_init(struct sock *sk, struct sock *parent)
757{
758 struct l2cap_pinfo *pi = l2cap_pi(sk);
759
760 BT_DBG("sk %p", sk);
761
762 if (parent) {
763 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100764 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
765
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 pi->imtu = l2cap_pi(parent)->imtu;
767 pi->omtu = l2cap_pi(parent)->omtu;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700768 pi->mode = l2cap_pi(parent)->mode;
769 pi->fcs = l2cap_pi(parent)->fcs;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100770 pi->sec_level = l2cap_pi(parent)->sec_level;
771 pi->role_switch = l2cap_pi(parent)->role_switch;
772 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 } else {
774 pi->imtu = L2CAP_DEFAULT_MTU;
775 pi->omtu = 0;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700776 pi->mode = L2CAP_MODE_BASIC;
777 pi->fcs = L2CAP_FCS_CRC16;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100778 pi->sec_level = BT_SECURITY_LOW;
779 pi->role_switch = 0;
780 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781 }
782
783 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200784 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
786}
787
788static struct proto l2cap_proto = {
789 .name = "L2CAP",
790 .owner = THIS_MODULE,
791 .obj_size = sizeof(struct l2cap_pinfo)
792};
793
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700794static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795{
796 struct sock *sk;
797
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700798 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799 if (!sk)
800 return NULL;
801
802 sock_init_data(sock, sk);
803 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
804
805 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200806 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807
808 sock_reset_flag(sk, SOCK_ZAPPED);
809
810 sk->sk_protocol = proto;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200811 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200813 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814
815 bt_sock_link(&l2cap_sk_list, sk);
816 return sk;
817}
818
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700819static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820{
821 struct sock *sk;
822
823 BT_DBG("sock %p", sock);
824
825 sock->state = SS_UNCONNECTED;
826
827 if (sock->type != SOCK_SEQPACKET &&
828 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
829 return -ESOCKTNOSUPPORT;
830
831 if (sock->type == SOCK_RAW && !capable(CAP_NET_RAW))
832 return -EPERM;
833
834 sock->ops = &l2cap_sock_ops;
835
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700836 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837 if (!sk)
838 return -ENOMEM;
839
840 l2cap_sock_init(sk, NULL);
841 return 0;
842}
843
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100844static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100847 struct sockaddr_l2 la;
848 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100850 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851
852 if (!addr || addr->sa_family != AF_BLUETOOTH)
853 return -EINVAL;
854
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100855 memset(&la, 0, sizeof(la));
856 len = min_t(unsigned int, sizeof(la), alen);
857 memcpy(&la, addr, len);
858
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100859 if (la.l2_cid)
860 return -EINVAL;
861
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862 lock_sock(sk);
863
864 if (sk->sk_state != BT_OPEN) {
865 err = -EBADFD;
866 goto done;
867 }
868
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200869 if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
Marcel Holtmann847641d2007-01-22 22:00:45 +0100870 !capable(CAP_NET_BIND_SERVICE)) {
871 err = -EACCES;
872 goto done;
873 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900874
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 write_lock_bh(&l2cap_sk_list.lock);
876
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100877 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878 err = -EADDRINUSE;
879 } else {
880 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100881 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
882 l2cap_pi(sk)->psm = la.l2_psm;
883 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100885
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200886 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
887 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100888 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889 }
890
891 write_unlock_bh(&l2cap_sk_list.lock);
892
893done:
894 release_sock(sk);
895 return err;
896}
897
898static int l2cap_do_connect(struct sock *sk)
899{
900 bdaddr_t *src = &bt_sk(sk)->src;
901 bdaddr_t *dst = &bt_sk(sk)->dst;
902 struct l2cap_conn *conn;
903 struct hci_conn *hcon;
904 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200905 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +0200906 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100908 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
909 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300911 hdev = hci_get_route(dst, src);
912 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913 return -EHOSTUNREACH;
914
915 hci_dev_lock_bh(hdev);
916
917 err = -ENOMEM;
918
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100919 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100920 switch (l2cap_pi(sk)->sec_level) {
921 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100922 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100923 break;
924 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100925 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100926 break;
927 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100928 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100929 break;
930 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100931 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100932 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200933 auth_type = HCI_AT_NO_BONDING_MITM;
934 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200935 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +0100936
937 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
938 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100939 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100940 switch (l2cap_pi(sk)->sec_level) {
941 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100942 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100943 break;
944 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200945 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100946 break;
947 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100948 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100949 break;
950 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200951 }
952
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100953 hcon = hci_connect(hdev, ACL_LINK, dst,
954 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 if (!hcon)
956 goto done;
957
958 conn = l2cap_conn_add(hcon, 0);
959 if (!conn) {
960 hci_conn_put(hcon);
961 goto done;
962 }
963
964 err = 0;
965
966 /* Update source addr of the socket */
967 bacpy(src, conn->src);
968
969 l2cap_chan_add(conn, sk, NULL);
970
971 sk->sk_state = BT_CONNECT;
972 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
973
974 if (hcon->state == BT_CONNECTED) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200975 if (sk->sk_type != SOCK_SEQPACKET) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700976 l2cap_sock_clear_timer(sk);
977 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200978 } else
979 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980 }
981
982done:
983 hci_dev_unlock_bh(hdev);
984 hci_dev_put(hdev);
985 return err;
986}
987
988static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
989{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100991 struct sockaddr_l2 la;
992 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993
Linus Torvalds1da177e2005-04-16 15:20:36 -0700994 BT_DBG("sk %p", sk);
995
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100996 if (!addr || addr->sa_family != AF_BLUETOOTH)
997 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100999 memset(&la, 0, sizeof(la));
1000 len = min_t(unsigned int, sizeof(la), alen);
1001 memcpy(&la, addr, len);
1002
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001003 if (la.l2_cid)
1004 return -EINVAL;
1005
1006 lock_sock(sk);
1007
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001008 if (sk->sk_type == SOCK_SEQPACKET && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009 err = -EINVAL;
1010 goto done;
1011 }
1012
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001013 switch (l2cap_pi(sk)->mode) {
1014 case L2CAP_MODE_BASIC:
1015 break;
1016 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001017 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001018 if (enable_ertm)
1019 break;
1020 /* fall through */
1021 default:
1022 err = -ENOTSUPP;
1023 goto done;
1024 }
1025
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001026 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027 case BT_CONNECT:
1028 case BT_CONNECT2:
1029 case BT_CONFIG:
1030 /* Already connecting */
1031 goto wait;
1032
1033 case BT_CONNECTED:
1034 /* Already connected */
1035 goto done;
1036
1037 case BT_OPEN:
1038 case BT_BOUND:
1039 /* Can connect */
1040 break;
1041
1042 default:
1043 err = -EBADFD;
1044 goto done;
1045 }
1046
1047 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001048 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1049 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001051 err = l2cap_do_connect(sk);
1052 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053 goto done;
1054
1055wait:
1056 err = bt_sock_wait_state(sk, BT_CONNECTED,
1057 sock_sndtimeo(sk, flags & O_NONBLOCK));
1058done:
1059 release_sock(sk);
1060 return err;
1061}
1062
1063static int l2cap_sock_listen(struct socket *sock, int backlog)
1064{
1065 struct sock *sk = sock->sk;
1066 int err = 0;
1067
1068 BT_DBG("sk %p backlog %d", sk, backlog);
1069
1070 lock_sock(sk);
1071
1072 if (sk->sk_state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
1073 err = -EBADFD;
1074 goto done;
1075 }
1076
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001077 switch (l2cap_pi(sk)->mode) {
1078 case L2CAP_MODE_BASIC:
1079 break;
1080 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001081 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001082 if (enable_ertm)
1083 break;
1084 /* fall through */
1085 default:
1086 err = -ENOTSUPP;
1087 goto done;
1088 }
1089
Linus Torvalds1da177e2005-04-16 15:20:36 -07001090 if (!l2cap_pi(sk)->psm) {
1091 bdaddr_t *src = &bt_sk(sk)->src;
1092 u16 psm;
1093
1094 err = -EINVAL;
1095
1096 write_lock_bh(&l2cap_sk_list.lock);
1097
1098 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001099 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1100 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1101 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001102 err = 0;
1103 break;
1104 }
1105
1106 write_unlock_bh(&l2cap_sk_list.lock);
1107
1108 if (err < 0)
1109 goto done;
1110 }
1111
1112 sk->sk_max_ack_backlog = backlog;
1113 sk->sk_ack_backlog = 0;
1114 sk->sk_state = BT_LISTEN;
1115
1116done:
1117 release_sock(sk);
1118 return err;
1119}
1120
1121static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1122{
1123 DECLARE_WAITQUEUE(wait, current);
1124 struct sock *sk = sock->sk, *nsk;
1125 long timeo;
1126 int err = 0;
1127
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001128 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129
1130 if (sk->sk_state != BT_LISTEN) {
1131 err = -EBADFD;
1132 goto done;
1133 }
1134
1135 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1136
1137 BT_DBG("sk %p timeo %ld", sk, timeo);
1138
1139 /* Wait for an incoming connection. (wake-one). */
1140 add_wait_queue_exclusive(sk->sk_sleep, &wait);
1141 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1142 set_current_state(TASK_INTERRUPTIBLE);
1143 if (!timeo) {
1144 err = -EAGAIN;
1145 break;
1146 }
1147
1148 release_sock(sk);
1149 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001150 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151
1152 if (sk->sk_state != BT_LISTEN) {
1153 err = -EBADFD;
1154 break;
1155 }
1156
1157 if (signal_pending(current)) {
1158 err = sock_intr_errno(timeo);
1159 break;
1160 }
1161 }
1162 set_current_state(TASK_RUNNING);
1163 remove_wait_queue(sk->sk_sleep, &wait);
1164
1165 if (err)
1166 goto done;
1167
1168 newsock->state = SS_CONNECTED;
1169
1170 BT_DBG("new socket %p", nsk);
1171
1172done:
1173 release_sock(sk);
1174 return err;
1175}
1176
1177static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1178{
1179 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1180 struct sock *sk = sock->sk;
1181
1182 BT_DBG("sock %p, sk %p", sock, sk);
1183
1184 addr->sa_family = AF_BLUETOOTH;
1185 *len = sizeof(struct sockaddr_l2);
1186
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001187 if (peer) {
1188 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001190 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001191 } else {
1192 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001194 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001195 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197 return 0;
1198}
1199
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001200static void l2cap_monitor_timeout(unsigned long arg)
1201{
1202 struct sock *sk = (void *) arg;
1203 u16 control;
1204
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001205 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001206 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
1207 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
1208 return;
1209 }
1210
1211 l2cap_pi(sk)->retry_count++;
1212 __mod_monitor_timer();
1213
1214 control = L2CAP_CTRL_POLL;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001215 l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001216 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001217}
1218
1219static void l2cap_retrans_timeout(unsigned long arg)
1220{
1221 struct sock *sk = (void *) arg;
1222 u16 control;
1223
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001224 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001225 l2cap_pi(sk)->retry_count = 1;
1226 __mod_monitor_timer();
1227
1228 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1229
1230 control = L2CAP_CTRL_POLL;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001231 l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001232 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001233}
1234
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001235static void l2cap_drop_acked_frames(struct sock *sk)
1236{
1237 struct sk_buff *skb;
1238
1239 while ((skb = skb_peek(TX_QUEUE(sk)))) {
1240 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1241 break;
1242
1243 skb = skb_dequeue(TX_QUEUE(sk));
1244 kfree_skb(skb);
1245
1246 l2cap_pi(sk)->unacked_frames--;
1247 }
1248
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001249 if (!l2cap_pi(sk)->unacked_frames)
1250 del_timer(&l2cap_pi(sk)->retrans_timer);
1251
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001252 return;
1253}
1254
1255static inline int l2cap_do_send(struct sock *sk, struct sk_buff *skb)
1256{
1257 struct l2cap_pinfo *pi = l2cap_pi(sk);
1258 int err;
1259
1260 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1261
1262 err = hci_send_acl(pi->conn->hcon, skb, 0);
1263 if (err < 0)
1264 kfree_skb(skb);
1265
1266 return err;
1267}
1268
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001269static int l2cap_streaming_send(struct sock *sk)
1270{
1271 struct sk_buff *skb, *tx_skb;
1272 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001273 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001274 int err;
1275
1276 while ((skb = sk->sk_send_head)) {
1277 tx_skb = skb_clone(skb, GFP_ATOMIC);
1278
1279 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1280 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1281 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1282
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001283 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) {
1284 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1285 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1286 }
1287
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001288 err = l2cap_do_send(sk, tx_skb);
1289 if (err < 0) {
1290 l2cap_send_disconn_req(pi->conn, sk);
1291 return err;
1292 }
1293
1294 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1295
1296 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1297 sk->sk_send_head = NULL;
1298 else
1299 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1300
1301 skb = skb_dequeue(TX_QUEUE(sk));
1302 kfree_skb(skb);
1303 }
1304 return 0;
1305}
1306
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001307static int l2cap_retransmit_frame(struct sock *sk, u8 tx_seq)
1308{
1309 struct l2cap_pinfo *pi = l2cap_pi(sk);
1310 struct sk_buff *skb, *tx_skb;
1311 u16 control, fcs;
1312 int err;
1313
1314 skb = skb_peek(TX_QUEUE(sk));
1315 do {
1316 if (bt_cb(skb)->tx_seq != tx_seq) {
1317 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1318 break;
1319 skb = skb_queue_next(TX_QUEUE(sk), skb);
1320 continue;
1321 }
1322
1323 if (pi->remote_max_tx &&
1324 bt_cb(skb)->retries == pi->remote_max_tx) {
1325 l2cap_send_disconn_req(pi->conn, sk);
1326 break;
1327 }
1328
1329 tx_skb = skb_clone(skb, GFP_ATOMIC);
1330 bt_cb(skb)->retries++;
1331 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1332 control |= (pi->req_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1333 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1334 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1335
1336 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) {
1337 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1338 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1339 }
1340
1341 err = l2cap_do_send(sk, tx_skb);
1342 if (err < 0) {
1343 l2cap_send_disconn_req(pi->conn, sk);
1344 return err;
1345 }
1346 break;
1347 } while(1);
1348 return 0;
1349}
1350
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001351static int l2cap_ertm_send(struct sock *sk)
1352{
1353 struct sk_buff *skb, *tx_skb;
1354 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001355 u16 control, fcs;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001356 int err;
1357
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001358 if (pi->conn_state & L2CAP_CONN_WAIT_F)
1359 return 0;
1360
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03001361 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))
1362 && !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001363 tx_skb = skb_clone(skb, GFP_ATOMIC);
1364
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001365 if (pi->remote_max_tx &&
1366 bt_cb(skb)->retries == pi->remote_max_tx) {
1367 l2cap_send_disconn_req(pi->conn, sk);
1368 break;
1369 }
1370
1371 bt_cb(skb)->retries++;
1372
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001373 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1374 control |= (pi->req_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1375 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1376 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1377
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001378
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001379 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) {
1380 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1381 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1382 }
1383
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001384 err = l2cap_do_send(sk, tx_skb);
1385 if (err < 0) {
1386 l2cap_send_disconn_req(pi->conn, sk);
1387 return err;
1388 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001389 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001390
1391 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1392 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1393
1394 pi->unacked_frames++;
1395
1396 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1397 sk->sk_send_head = NULL;
1398 else
1399 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1400 }
1401
1402 return 0;
1403}
1404
1405static 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 -07001406{
1407 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001408 struct sk_buff **frag;
1409 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410
1411 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001412 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413 }
1414
1415 sent += count;
1416 len -= count;
1417
1418 /* Continuation fragments (no L2CAP header) */
1419 frag = &skb_shinfo(skb)->frag_list;
1420 while (len) {
1421 count = min_t(unsigned int, conn->mtu, len);
1422
1423 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1424 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001425 return -EFAULT;
1426 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1427 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428
1429 sent += count;
1430 len -= count;
1431
1432 frag = &(*frag)->next;
1433 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434
1435 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001436}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001438static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1439{
1440 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1441 struct sk_buff *skb;
1442 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1443 struct l2cap_hdr *lh;
1444
1445 BT_DBG("sk %p len %d", sk, (int)len);
1446
1447 count = min_t(unsigned int, (conn->mtu - hlen), len);
1448 skb = bt_skb_send_alloc(sk, count + hlen,
1449 msg->msg_flags & MSG_DONTWAIT, &err);
1450 if (!skb)
1451 return ERR_PTR(-ENOMEM);
1452
1453 /* Create L2CAP header */
1454 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1455 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1456 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1457 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1458
1459 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1460 if (unlikely(err < 0)) {
1461 kfree_skb(skb);
1462 return ERR_PTR(err);
1463 }
1464 return skb;
1465}
1466
1467static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1468{
1469 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1470 struct sk_buff *skb;
1471 int err, count, hlen = L2CAP_HDR_SIZE;
1472 struct l2cap_hdr *lh;
1473
1474 BT_DBG("sk %p len %d", sk, (int)len);
1475
1476 count = min_t(unsigned int, (conn->mtu - hlen), len);
1477 skb = bt_skb_send_alloc(sk, count + hlen,
1478 msg->msg_flags & MSG_DONTWAIT, &err);
1479 if (!skb)
1480 return ERR_PTR(-ENOMEM);
1481
1482 /* Create L2CAP header */
1483 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1484 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1485 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1486
1487 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1488 if (unlikely(err < 0)) {
1489 kfree_skb(skb);
1490 return ERR_PTR(err);
1491 }
1492 return skb;
1493}
1494
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001495static 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 -03001496{
1497 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1498 struct sk_buff *skb;
1499 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1500 struct l2cap_hdr *lh;
1501
1502 BT_DBG("sk %p len %d", sk, (int)len);
1503
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001504 if (sdulen)
1505 hlen += 2;
1506
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001507 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1508 hlen += 2;
1509
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001510 count = min_t(unsigned int, (conn->mtu - hlen), len);
1511 skb = bt_skb_send_alloc(sk, count + hlen,
1512 msg->msg_flags & MSG_DONTWAIT, &err);
1513 if (!skb)
1514 return ERR_PTR(-ENOMEM);
1515
1516 /* Create L2CAP header */
1517 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1518 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1519 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1520 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001521 if (sdulen)
1522 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001523
1524 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1525 if (unlikely(err < 0)) {
1526 kfree_skb(skb);
1527 return ERR_PTR(err);
1528 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001529
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001530 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1531 put_unaligned_le16(0, skb_put(skb, 2));
1532
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001533 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001534 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535}
1536
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001537static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1538{
1539 struct l2cap_pinfo *pi = l2cap_pi(sk);
1540 struct sk_buff *skb;
1541 struct sk_buff_head sar_queue;
1542 u16 control;
1543 size_t size = 0;
1544
1545 __skb_queue_head_init(&sar_queue);
1546 control = L2CAP_SDU_START;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001547 skb = l2cap_create_iframe_pdu(sk, msg, pi->max_pdu_size, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001548 if (IS_ERR(skb))
1549 return PTR_ERR(skb);
1550
1551 __skb_queue_tail(&sar_queue, skb);
1552 len -= pi->max_pdu_size;
1553 size +=pi->max_pdu_size;
1554 control = 0;
1555
1556 while (len > 0) {
1557 size_t buflen;
1558
1559 if (len > pi->max_pdu_size) {
1560 control |= L2CAP_SDU_CONTINUE;
1561 buflen = pi->max_pdu_size;
1562 } else {
1563 control |= L2CAP_SDU_END;
1564 buflen = len;
1565 }
1566
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001567 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001568 if (IS_ERR(skb)) {
1569 skb_queue_purge(&sar_queue);
1570 return PTR_ERR(skb);
1571 }
1572
1573 __skb_queue_tail(&sar_queue, skb);
1574 len -= buflen;
1575 size += buflen;
1576 control = 0;
1577 }
1578 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1579 if (sk->sk_send_head == NULL)
1580 sk->sk_send_head = sar_queue.next;
1581
1582 return size;
1583}
1584
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1586{
1587 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001588 struct l2cap_pinfo *pi = l2cap_pi(sk);
1589 struct sk_buff *skb;
1590 u16 control;
1591 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592
1593 BT_DBG("sock %p, sk %p", sock, sk);
1594
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001595 err = sock_error(sk);
1596 if (err)
1597 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598
1599 if (msg->msg_flags & MSG_OOB)
1600 return -EOPNOTSUPP;
1601
1602 /* Check outgoing MTU */
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001603 if (sk->sk_type == SOCK_SEQPACKET && pi->mode == L2CAP_MODE_BASIC
1604 && len > pi->omtu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605 return -EINVAL;
1606
1607 lock_sock(sk);
1608
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001609 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001610 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001611 goto done;
1612 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001614 /* Connectionless channel */
1615 if (sk->sk_type == SOCK_DGRAM) {
1616 skb = l2cap_create_connless_pdu(sk, msg, len);
1617 err = l2cap_do_send(sk, skb);
1618 goto done;
1619 }
1620
1621 switch (pi->mode) {
1622 case L2CAP_MODE_BASIC:
1623 /* Create a basic PDU */
1624 skb = l2cap_create_basic_pdu(sk, msg, len);
1625 if (IS_ERR(skb)) {
1626 err = PTR_ERR(skb);
1627 goto done;
1628 }
1629
1630 err = l2cap_do_send(sk, skb);
1631 if (!err)
1632 err = len;
1633 break;
1634
1635 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001636 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001637 /* Entire SDU fits into one PDU */
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001638 if (len <= pi->max_pdu_size) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001639 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001640 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001641 if (IS_ERR(skb)) {
1642 err = PTR_ERR(skb);
1643 goto done;
1644 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001645 __skb_queue_tail(TX_QUEUE(sk), skb);
1646 if (sk->sk_send_head == NULL)
1647 sk->sk_send_head = skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001648 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001649 /* Segment SDU into multiples PDUs */
1650 err = l2cap_sar_segment_sdu(sk, msg, len);
1651 if (err < 0)
1652 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001653 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001654
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001655 if (pi->mode == L2CAP_MODE_STREAMING)
1656 err = l2cap_streaming_send(sk);
1657 else
1658 err = l2cap_ertm_send(sk);
1659
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001660 if (!err)
1661 err = len;
1662 break;
1663
1664 default:
1665 BT_DBG("bad state %1.1x", pi->mode);
1666 err = -EINVAL;
1667 }
1668
1669done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670 release_sock(sk);
1671 return err;
1672}
1673
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001674static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1675{
1676 struct sock *sk = sock->sk;
1677
1678 lock_sock(sk);
1679
1680 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1681 struct l2cap_conn_rsp rsp;
1682
1683 sk->sk_state = BT_CONFIG;
1684
1685 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1686 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1687 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1688 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1689 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1690 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1691
1692 release_sock(sk);
1693 return 0;
1694 }
1695
1696 release_sock(sk);
1697
1698 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1699}
1700
David S. Millerb7058842009-09-30 16:12:20 -07001701static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702{
1703 struct sock *sk = sock->sk;
1704 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001705 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706 u32 opt;
1707
1708 BT_DBG("sk %p", sk);
1709
1710 lock_sock(sk);
1711
1712 switch (optname) {
1713 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001714 opts.imtu = l2cap_pi(sk)->imtu;
1715 opts.omtu = l2cap_pi(sk)->omtu;
1716 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001717 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001718 opts.fcs = l2cap_pi(sk)->fcs;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001719
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 len = min_t(unsigned int, sizeof(opts), optlen);
1721 if (copy_from_user((char *) &opts, optval, len)) {
1722 err = -EFAULT;
1723 break;
1724 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001725
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001726 l2cap_pi(sk)->imtu = opts.imtu;
1727 l2cap_pi(sk)->omtu = opts.omtu;
1728 l2cap_pi(sk)->mode = opts.mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001729 l2cap_pi(sk)->fcs = opts.fcs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730 break;
1731
1732 case L2CAP_LM:
1733 if (get_user(opt, (u32 __user *) optval)) {
1734 err = -EFAULT;
1735 break;
1736 }
1737
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001738 if (opt & L2CAP_LM_AUTH)
1739 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1740 if (opt & L2CAP_LM_ENCRYPT)
1741 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1742 if (opt & L2CAP_LM_SECURE)
1743 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1744
1745 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1746 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 break;
1748
1749 default:
1750 err = -ENOPROTOOPT;
1751 break;
1752 }
1753
1754 release_sock(sk);
1755 return err;
1756}
1757
David S. Millerb7058842009-09-30 16:12:20 -07001758static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001759{
1760 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001761 struct bt_security sec;
1762 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001763 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001764
1765 BT_DBG("sk %p", sk);
1766
1767 if (level == SOL_L2CAP)
1768 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1769
Marcel Holtmann0588d942009-01-16 10:06:13 +01001770 if (level != SOL_BLUETOOTH)
1771 return -ENOPROTOOPT;
1772
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001773 lock_sock(sk);
1774
1775 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001776 case BT_SECURITY:
Marcel Holtmann2526d3d2009-02-20 20:54:06 +01001777 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001778 err = -EINVAL;
1779 break;
1780 }
1781
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001782 sec.level = BT_SECURITY_LOW;
1783
1784 len = min_t(unsigned int, sizeof(sec), optlen);
1785 if (copy_from_user((char *) &sec, optval, len)) {
1786 err = -EFAULT;
1787 break;
1788 }
1789
1790 if (sec.level < BT_SECURITY_LOW ||
1791 sec.level > BT_SECURITY_HIGH) {
1792 err = -EINVAL;
1793 break;
1794 }
1795
1796 l2cap_pi(sk)->sec_level = sec.level;
1797 break;
1798
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001799 case BT_DEFER_SETUP:
1800 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1801 err = -EINVAL;
1802 break;
1803 }
1804
1805 if (get_user(opt, (u32 __user *) optval)) {
1806 err = -EFAULT;
1807 break;
1808 }
1809
1810 bt_sk(sk)->defer_setup = opt;
1811 break;
1812
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001813 default:
1814 err = -ENOPROTOOPT;
1815 break;
1816 }
1817
1818 release_sock(sk);
1819 return err;
1820}
1821
1822static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823{
1824 struct sock *sk = sock->sk;
1825 struct l2cap_options opts;
1826 struct l2cap_conninfo cinfo;
1827 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001828 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829
1830 BT_DBG("sk %p", sk);
1831
1832 if (get_user(len, optlen))
1833 return -EFAULT;
1834
1835 lock_sock(sk);
1836
1837 switch (optname) {
1838 case L2CAP_OPTIONS:
1839 opts.imtu = l2cap_pi(sk)->imtu;
1840 opts.omtu = l2cap_pi(sk)->omtu;
1841 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001842 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001843 opts.fcs = l2cap_pi(sk)->fcs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844
1845 len = min_t(unsigned int, len, sizeof(opts));
1846 if (copy_to_user(optval, (char *) &opts, len))
1847 err = -EFAULT;
1848
1849 break;
1850
1851 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001852 switch (l2cap_pi(sk)->sec_level) {
1853 case BT_SECURITY_LOW:
1854 opt = L2CAP_LM_AUTH;
1855 break;
1856 case BT_SECURITY_MEDIUM:
1857 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
1858 break;
1859 case BT_SECURITY_HIGH:
1860 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
1861 L2CAP_LM_SECURE;
1862 break;
1863 default:
1864 opt = 0;
1865 break;
1866 }
1867
1868 if (l2cap_pi(sk)->role_switch)
1869 opt |= L2CAP_LM_MASTER;
1870
1871 if (l2cap_pi(sk)->force_reliable)
1872 opt |= L2CAP_LM_RELIABLE;
1873
1874 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001875 err = -EFAULT;
1876 break;
1877
1878 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001879 if (sk->sk_state != BT_CONNECTED &&
1880 !(sk->sk_state == BT_CONNECT2 &&
1881 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882 err = -ENOTCONN;
1883 break;
1884 }
1885
1886 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
1887 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
1888
1889 len = min_t(unsigned int, len, sizeof(cinfo));
1890 if (copy_to_user(optval, (char *) &cinfo, len))
1891 err = -EFAULT;
1892
1893 break;
1894
1895 default:
1896 err = -ENOPROTOOPT;
1897 break;
1898 }
1899
1900 release_sock(sk);
1901 return err;
1902}
1903
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001904static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
1905{
1906 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001907 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001908 int len, err = 0;
1909
1910 BT_DBG("sk %p", sk);
1911
1912 if (level == SOL_L2CAP)
1913 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
1914
Marcel Holtmann0588d942009-01-16 10:06:13 +01001915 if (level != SOL_BLUETOOTH)
1916 return -ENOPROTOOPT;
1917
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001918 if (get_user(len, optlen))
1919 return -EFAULT;
1920
1921 lock_sock(sk);
1922
1923 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001924 case BT_SECURITY:
Marcel Holtmann2526d3d2009-02-20 20:54:06 +01001925 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001926 err = -EINVAL;
1927 break;
1928 }
1929
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001930 sec.level = l2cap_pi(sk)->sec_level;
1931
1932 len = min_t(unsigned int, len, sizeof(sec));
1933 if (copy_to_user(optval, (char *) &sec, len))
1934 err = -EFAULT;
1935
1936 break;
1937
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001938 case BT_DEFER_SETUP:
1939 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1940 err = -EINVAL;
1941 break;
1942 }
1943
1944 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
1945 err = -EFAULT;
1946
1947 break;
1948
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001949 default:
1950 err = -ENOPROTOOPT;
1951 break;
1952 }
1953
1954 release_sock(sk);
1955 return err;
1956}
1957
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958static int l2cap_sock_shutdown(struct socket *sock, int how)
1959{
1960 struct sock *sk = sock->sk;
1961 int err = 0;
1962
1963 BT_DBG("sock %p, sk %p", sock, sk);
1964
1965 if (!sk)
1966 return 0;
1967
1968 lock_sock(sk);
1969 if (!sk->sk_shutdown) {
1970 sk->sk_shutdown = SHUTDOWN_MASK;
1971 l2cap_sock_clear_timer(sk);
1972 __l2cap_sock_close(sk, 0);
1973
1974 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001975 err = bt_sock_wait_state(sk, BT_CLOSED,
1976 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977 }
1978 release_sock(sk);
1979 return err;
1980}
1981
1982static int l2cap_sock_release(struct socket *sock)
1983{
1984 struct sock *sk = sock->sk;
1985 int err;
1986
1987 BT_DBG("sock %p, sk %p", sock, sk);
1988
1989 if (!sk)
1990 return 0;
1991
1992 err = l2cap_sock_shutdown(sock, 2);
1993
1994 sock_orphan(sk);
1995 l2cap_sock_kill(sk);
1996 return err;
1997}
1998
Linus Torvalds1da177e2005-04-16 15:20:36 -07001999static void l2cap_chan_ready(struct sock *sk)
2000{
2001 struct sock *parent = bt_sk(sk)->parent;
2002
2003 BT_DBG("sk %p, parent %p", sk, parent);
2004
2005 l2cap_pi(sk)->conf_state = 0;
2006 l2cap_sock_clear_timer(sk);
2007
2008 if (!parent) {
2009 /* Outgoing channel.
2010 * Wake up socket sleeping on connect.
2011 */
2012 sk->sk_state = BT_CONNECTED;
2013 sk->sk_state_change(sk);
2014 } else {
2015 /* Incoming channel.
2016 * Wake up socket sleeping on accept.
2017 */
2018 parent->sk_data_ready(parent, 0);
2019 }
2020}
2021
2022/* Copy frame to all raw sockets on that connection */
2023static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2024{
2025 struct l2cap_chan_list *l = &conn->chan_list;
2026 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002027 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002028
2029 BT_DBG("conn %p", conn);
2030
2031 read_lock(&l->lock);
2032 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2033 if (sk->sk_type != SOCK_RAW)
2034 continue;
2035
2036 /* Don't send frame to the socket it came from */
2037 if (skb->sk == sk)
2038 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002039 nskb = skb_clone(skb, GFP_ATOMIC);
2040 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002041 continue;
2042
2043 if (sock_queue_rcv_skb(sk, nskb))
2044 kfree_skb(nskb);
2045 }
2046 read_unlock(&l->lock);
2047}
2048
2049/* ---- L2CAP signalling commands ---- */
2050static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2051 u8 code, u8 ident, u16 dlen, void *data)
2052{
2053 struct sk_buff *skb, **frag;
2054 struct l2cap_cmd_hdr *cmd;
2055 struct l2cap_hdr *lh;
2056 int len, count;
2057
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002058 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2059 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002060
2061 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2062 count = min_t(unsigned int, conn->mtu, len);
2063
2064 skb = bt_skb_alloc(count, GFP_ATOMIC);
2065 if (!skb)
2066 return NULL;
2067
2068 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002069 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002070 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002071
2072 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2073 cmd->code = code;
2074 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002075 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002076
2077 if (dlen) {
2078 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2079 memcpy(skb_put(skb, count), data, count);
2080 data += count;
2081 }
2082
2083 len -= skb->len;
2084
2085 /* Continuation fragments (no L2CAP header) */
2086 frag = &skb_shinfo(skb)->frag_list;
2087 while (len) {
2088 count = min_t(unsigned int, conn->mtu, len);
2089
2090 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2091 if (!*frag)
2092 goto fail;
2093
2094 memcpy(skb_put(*frag, count), data, count);
2095
2096 len -= count;
2097 data += count;
2098
2099 frag = &(*frag)->next;
2100 }
2101
2102 return skb;
2103
2104fail:
2105 kfree_skb(skb);
2106 return NULL;
2107}
2108
2109static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2110{
2111 struct l2cap_conf_opt *opt = *ptr;
2112 int len;
2113
2114 len = L2CAP_CONF_OPT_SIZE + opt->len;
2115 *ptr += len;
2116
2117 *type = opt->type;
2118 *olen = opt->len;
2119
2120 switch (opt->len) {
2121 case 1:
2122 *val = *((u8 *) opt->val);
2123 break;
2124
2125 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002126 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002127 break;
2128
2129 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002130 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002131 break;
2132
2133 default:
2134 *val = (unsigned long) opt->val;
2135 break;
2136 }
2137
2138 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2139 return len;
2140}
2141
Linus Torvalds1da177e2005-04-16 15:20:36 -07002142static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2143{
2144 struct l2cap_conf_opt *opt = *ptr;
2145
2146 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2147
2148 opt->type = type;
2149 opt->len = len;
2150
2151 switch (len) {
2152 case 1:
2153 *((u8 *) opt->val) = val;
2154 break;
2155
2156 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002157 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002158 break;
2159
2160 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002161 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002162 break;
2163
2164 default:
2165 memcpy(opt->val, (void *) val, len);
2166 break;
2167 }
2168
2169 *ptr += L2CAP_CONF_OPT_SIZE + len;
2170}
2171
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002172static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2173{
2174 u32 local_feat_mask = l2cap_feat_mask;
2175 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002176 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002177
2178 switch (mode) {
2179 case L2CAP_MODE_ERTM:
2180 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2181 case L2CAP_MODE_STREAMING:
2182 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2183 default:
2184 return 0x00;
2185 }
2186}
2187
2188static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2189{
2190 switch (mode) {
2191 case L2CAP_MODE_STREAMING:
2192 case L2CAP_MODE_ERTM:
2193 if (l2cap_mode_supported(mode, remote_feat_mask))
2194 return mode;
2195 /* fall through */
2196 default:
2197 return L2CAP_MODE_BASIC;
2198 }
2199}
2200
Linus Torvalds1da177e2005-04-16 15:20:36 -07002201static int l2cap_build_conf_req(struct sock *sk, void *data)
2202{
2203 struct l2cap_pinfo *pi = l2cap_pi(sk);
2204 struct l2cap_conf_req *req = data;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002205 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_ERTM };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002206 void *ptr = req->data;
2207
2208 BT_DBG("sk %p", sk);
2209
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002210 if (pi->num_conf_req || pi->num_conf_rsp)
2211 goto done;
2212
2213 switch (pi->mode) {
2214 case L2CAP_MODE_STREAMING:
2215 case L2CAP_MODE_ERTM:
2216 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002217 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2218 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002219 break;
2220 default:
2221 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2222 break;
2223 }
2224
2225done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002226 switch (pi->mode) {
2227 case L2CAP_MODE_BASIC:
2228 if (pi->imtu != L2CAP_DEFAULT_MTU)
2229 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2230 break;
2231
2232 case L2CAP_MODE_ERTM:
2233 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002234 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002235 rfc.max_transmit = L2CAP_DEFAULT_MAX_TX;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002236 rfc.retrans_timeout = 0;
2237 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002238 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002239
2240 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2241 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002242
2243 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2244 break;
2245
2246 if (pi->fcs == L2CAP_FCS_NONE ||
2247 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2248 pi->fcs = L2CAP_FCS_NONE;
2249 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2250 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002251 break;
2252
2253 case L2CAP_MODE_STREAMING:
2254 rfc.mode = L2CAP_MODE_STREAMING;
2255 rfc.txwin_size = 0;
2256 rfc.max_transmit = 0;
2257 rfc.retrans_timeout = 0;
2258 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002259 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002260
2261 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2262 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002263
2264 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2265 break;
2266
2267 if (pi->fcs == L2CAP_FCS_NONE ||
2268 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2269 pi->fcs = L2CAP_FCS_NONE;
2270 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2271 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002272 break;
2273 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002274
2275 /* FIXME: Need actual value of the flush timeout */
2276 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2277 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2278
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002279 req->dcid = cpu_to_le16(pi->dcid);
2280 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002281
2282 return ptr - data;
2283}
2284
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002285static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002286{
2287 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002288 struct l2cap_conf_rsp *rsp = data;
2289 void *ptr = rsp->data;
2290 void *req = pi->conf_req;
2291 int len = pi->conf_len;
2292 int type, hint, olen;
2293 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002294 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002295 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002296 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002297
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002298 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002299
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002300 while (len >= L2CAP_CONF_OPT_SIZE) {
2301 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002302
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002303 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002304 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002305
2306 switch (type) {
2307 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002308 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002309 break;
2310
2311 case L2CAP_CONF_FLUSH_TO:
2312 pi->flush_to = val;
2313 break;
2314
2315 case L2CAP_CONF_QOS:
2316 break;
2317
Marcel Holtmann6464f352007-10-20 13:39:51 +02002318 case L2CAP_CONF_RFC:
2319 if (olen == sizeof(rfc))
2320 memcpy(&rfc, (void *) val, olen);
2321 break;
2322
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002323 case L2CAP_CONF_FCS:
2324 if (val == L2CAP_FCS_NONE)
2325 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2326
2327 break;
2328
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002329 default:
2330 if (hint)
2331 break;
2332
2333 result = L2CAP_CONF_UNKNOWN;
2334 *((u8 *) ptr++) = type;
2335 break;
2336 }
2337 }
2338
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002339 if (pi->num_conf_rsp || pi->num_conf_req)
2340 goto done;
2341
2342 switch (pi->mode) {
2343 case L2CAP_MODE_STREAMING:
2344 case L2CAP_MODE_ERTM:
2345 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2346 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2347 return -ECONNREFUSED;
2348 break;
2349 default:
2350 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2351 break;
2352 }
2353
2354done:
2355 if (pi->mode != rfc.mode) {
2356 result = L2CAP_CONF_UNACCEPT;
2357 rfc.mode = pi->mode;
2358
2359 if (pi->num_conf_rsp == 1)
2360 return -ECONNREFUSED;
2361
2362 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2363 sizeof(rfc), (unsigned long) &rfc);
2364 }
2365
2366
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002367 if (result == L2CAP_CONF_SUCCESS) {
2368 /* Configure output options and let the other side know
2369 * which ones we don't like. */
2370
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002371 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2372 result = L2CAP_CONF_UNACCEPT;
2373 else {
2374 pi->omtu = mtu;
2375 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2376 }
2377 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002378
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002379 switch (rfc.mode) {
2380 case L2CAP_MODE_BASIC:
2381 pi->fcs = L2CAP_FCS_NONE;
2382 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2383 break;
2384
2385 case L2CAP_MODE_ERTM:
2386 pi->remote_tx_win = rfc.txwin_size;
2387 pi->remote_max_tx = rfc.max_transmit;
2388 pi->max_pdu_size = rfc.max_pdu_size;
2389
2390 rfc.retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
2391 rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
2392
2393 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2394 break;
2395
2396 case L2CAP_MODE_STREAMING:
2397 pi->remote_tx_win = rfc.txwin_size;
2398 pi->max_pdu_size = rfc.max_pdu_size;
2399
2400 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2401 break;
2402
2403 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002404 result = L2CAP_CONF_UNACCEPT;
2405
2406 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002407 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002408 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002409
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002410 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2411 sizeof(rfc), (unsigned long) &rfc);
2412
2413 if (result == L2CAP_CONF_SUCCESS)
2414 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2415 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002416 rsp->scid = cpu_to_le16(pi->dcid);
2417 rsp->result = cpu_to_le16(result);
2418 rsp->flags = cpu_to_le16(0x0000);
2419
2420 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002421}
2422
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002423static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2424{
2425 struct l2cap_pinfo *pi = l2cap_pi(sk);
2426 struct l2cap_conf_req *req = data;
2427 void *ptr = req->data;
2428 int type, olen;
2429 unsigned long val;
2430 struct l2cap_conf_rfc rfc;
2431
2432 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2433
2434 while (len >= L2CAP_CONF_OPT_SIZE) {
2435 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2436
2437 switch (type) {
2438 case L2CAP_CONF_MTU:
2439 if (val < L2CAP_DEFAULT_MIN_MTU) {
2440 *result = L2CAP_CONF_UNACCEPT;
2441 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2442 } else
2443 pi->omtu = val;
2444 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2445 break;
2446
2447 case L2CAP_CONF_FLUSH_TO:
2448 pi->flush_to = val;
2449 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2450 2, pi->flush_to);
2451 break;
2452
2453 case L2CAP_CONF_RFC:
2454 if (olen == sizeof(rfc))
2455 memcpy(&rfc, (void *)val, olen);
2456
2457 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2458 rfc.mode != pi->mode)
2459 return -ECONNREFUSED;
2460
2461 pi->mode = rfc.mode;
2462 pi->fcs = 0;
2463
2464 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2465 sizeof(rfc), (unsigned long) &rfc);
2466 break;
2467 }
2468 }
2469
2470 if (*result == L2CAP_CONF_SUCCESS) {
2471 switch (rfc.mode) {
2472 case L2CAP_MODE_ERTM:
2473 pi->remote_tx_win = rfc.txwin_size;
2474 pi->retrans_timeout = rfc.retrans_timeout;
2475 pi->monitor_timeout = rfc.monitor_timeout;
2476 pi->max_pdu_size = le16_to_cpu(rfc.max_pdu_size);
2477 break;
2478 case L2CAP_MODE_STREAMING:
2479 pi->max_pdu_size = le16_to_cpu(rfc.max_pdu_size);
2480 break;
2481 }
2482 }
2483
2484 req->dcid = cpu_to_le16(pi->dcid);
2485 req->flags = cpu_to_le16(0x0000);
2486
2487 return ptr - data;
2488}
2489
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002490static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002491{
2492 struct l2cap_conf_rsp *rsp = data;
2493 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002494
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002495 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002496
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002497 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002498 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002499 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002500
2501 return ptr - data;
2502}
2503
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002504static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2505{
2506 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2507
2508 if (rej->reason != 0x0000)
2509 return 0;
2510
2511 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2512 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002513 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002514
2515 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002516 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002517
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002518 l2cap_conn_start(conn);
2519 }
2520
2521 return 0;
2522}
2523
Linus Torvalds1da177e2005-04-16 15:20:36 -07002524static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2525{
2526 struct l2cap_chan_list *list = &conn->chan_list;
2527 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2528 struct l2cap_conn_rsp rsp;
2529 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002530 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002531
2532 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002533 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002534
2535 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2536
2537 /* Check if we have socket listening on psm */
2538 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2539 if (!parent) {
2540 result = L2CAP_CR_BAD_PSM;
2541 goto sendresp;
2542 }
2543
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002544 /* Check if the ACL is secure enough (if not SDP) */
2545 if (psm != cpu_to_le16(0x0001) &&
2546 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002547 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002548 result = L2CAP_CR_SEC_BLOCK;
2549 goto response;
2550 }
2551
Linus Torvalds1da177e2005-04-16 15:20:36 -07002552 result = L2CAP_CR_NO_MEM;
2553
2554 /* Check for backlog size */
2555 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002556 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002557 goto response;
2558 }
2559
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002560 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002561 if (!sk)
2562 goto response;
2563
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002564 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002565
2566 /* Check if we already have channel with that dcid */
2567 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002568 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002569 sock_set_flag(sk, SOCK_ZAPPED);
2570 l2cap_sock_kill(sk);
2571 goto response;
2572 }
2573
2574 hci_conn_hold(conn->hcon);
2575
2576 l2cap_sock_init(sk, parent);
2577 bacpy(&bt_sk(sk)->src, conn->src);
2578 bacpy(&bt_sk(sk)->dst, conn->dst);
2579 l2cap_pi(sk)->psm = psm;
2580 l2cap_pi(sk)->dcid = scid;
2581
2582 __l2cap_chan_add(conn, sk, parent);
2583 dcid = l2cap_pi(sk)->scid;
2584
2585 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2586
Linus Torvalds1da177e2005-04-16 15:20:36 -07002587 l2cap_pi(sk)->ident = cmd->ident;
2588
Marcel Holtmann984947d2009-02-06 23:35:19 +01002589 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002590 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002591 if (bt_sk(sk)->defer_setup) {
2592 sk->sk_state = BT_CONNECT2;
2593 result = L2CAP_CR_PEND;
2594 status = L2CAP_CS_AUTHOR_PEND;
2595 parent->sk_data_ready(parent, 0);
2596 } else {
2597 sk->sk_state = BT_CONFIG;
2598 result = L2CAP_CR_SUCCESS;
2599 status = L2CAP_CS_NO_INFO;
2600 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002601 } else {
2602 sk->sk_state = BT_CONNECT2;
2603 result = L2CAP_CR_PEND;
2604 status = L2CAP_CS_AUTHEN_PEND;
2605 }
2606 } else {
2607 sk->sk_state = BT_CONNECT2;
2608 result = L2CAP_CR_PEND;
2609 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002610 }
2611
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002612 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002613
2614response:
2615 bh_unlock_sock(parent);
2616
2617sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002618 rsp.scid = cpu_to_le16(scid);
2619 rsp.dcid = cpu_to_le16(dcid);
2620 rsp.result = cpu_to_le16(result);
2621 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002622 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002623
2624 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2625 struct l2cap_info_req info;
2626 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2627
2628 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2629 conn->info_ident = l2cap_get_ident(conn);
2630
2631 mod_timer(&conn->info_timer, jiffies +
2632 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2633
2634 l2cap_send_cmd(conn, conn->info_ident,
2635 L2CAP_INFO_REQ, sizeof(info), &info);
2636 }
2637
Linus Torvalds1da177e2005-04-16 15:20:36 -07002638 return 0;
2639}
2640
2641static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2642{
2643 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2644 u16 scid, dcid, result, status;
2645 struct sock *sk;
2646 u8 req[128];
2647
2648 scid = __le16_to_cpu(rsp->scid);
2649 dcid = __le16_to_cpu(rsp->dcid);
2650 result = __le16_to_cpu(rsp->result);
2651 status = __le16_to_cpu(rsp->status);
2652
2653 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2654
2655 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002656 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2657 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002658 return 0;
2659 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002660 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2661 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662 return 0;
2663 }
2664
2665 switch (result) {
2666 case L2CAP_CR_SUCCESS:
2667 sk->sk_state = BT_CONFIG;
2668 l2cap_pi(sk)->ident = 0;
2669 l2cap_pi(sk)->dcid = dcid;
2670 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2671
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002672 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2673
Linus Torvalds1da177e2005-04-16 15:20:36 -07002674 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2675 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002676 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002677 break;
2678
2679 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002680 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002681 break;
2682
2683 default:
2684 l2cap_chan_del(sk, ECONNREFUSED);
2685 break;
2686 }
2687
2688 bh_unlock_sock(sk);
2689 return 0;
2690}
2691
Al Viro88219a02007-07-29 00:17:25 -07002692static 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 -07002693{
2694 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2695 u16 dcid, flags;
2696 u8 rsp[64];
2697 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002698 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002699
2700 dcid = __le16_to_cpu(req->dcid);
2701 flags = __le16_to_cpu(req->flags);
2702
2703 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2704
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002705 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2706 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002707 return -ENOENT;
2708
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002709 if (sk->sk_state == BT_DISCONN)
2710 goto unlock;
2711
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002712 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002713 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002714 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2715 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2716 l2cap_build_conf_rsp(sk, rsp,
2717 L2CAP_CONF_REJECT, flags), rsp);
2718 goto unlock;
2719 }
2720
2721 /* Store config. */
2722 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2723 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002724
2725 if (flags & 0x0001) {
2726 /* Incomplete config. Send empty response. */
2727 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002728 l2cap_build_conf_rsp(sk, rsp,
2729 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002730 goto unlock;
2731 }
2732
2733 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002734 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002735 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002736 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002737 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002738 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002739
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002740 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002741 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002742
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002743 /* Reset config buffer. */
2744 l2cap_pi(sk)->conf_len = 0;
2745
Marcel Holtmann876d9482007-10-20 13:35:42 +02002746 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2747 goto unlock;
2748
Linus Torvalds1da177e2005-04-16 15:20:36 -07002749 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002750 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV)
2751 || l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
2752 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2753
Linus Torvalds1da177e2005-04-16 15:20:36 -07002754 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002755 l2cap_pi(sk)->next_tx_seq = 0;
2756 l2cap_pi(sk)->expected_ack_seq = 0;
2757 l2cap_pi(sk)->unacked_frames = 0;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002758
2759 setup_timer(&l2cap_pi(sk)->retrans_timer,
2760 l2cap_retrans_timeout, (unsigned long) sk);
2761 setup_timer(&l2cap_pi(sk)->monitor_timer,
2762 l2cap_monitor_timeout, (unsigned long) sk);
2763
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002764 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002765 __skb_queue_head_init(SREJ_QUEUE(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002766 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002767 goto unlock;
2768 }
2769
2770 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002771 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002772 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002773 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002774 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002775 }
2776
2777unlock:
2778 bh_unlock_sock(sk);
2779 return 0;
2780}
2781
2782static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2783{
2784 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2785 u16 scid, flags, result;
2786 struct sock *sk;
2787
2788 scid = __le16_to_cpu(rsp->scid);
2789 flags = __le16_to_cpu(rsp->flags);
2790 result = __le16_to_cpu(rsp->result);
2791
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002792 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2793 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002794
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002795 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2796 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002797 return 0;
2798
2799 switch (result) {
2800 case L2CAP_CONF_SUCCESS:
2801 break;
2802
2803 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002804 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
2805 int len = cmd->len - sizeof(*rsp);
2806 char req[64];
2807
2808 /* throw out any old stored conf requests */
2809 result = L2CAP_CONF_SUCCESS;
2810 len = l2cap_parse_conf_rsp(sk, rsp->data,
2811 len, req, &result);
2812 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002813 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002814 goto done;
2815 }
2816
2817 l2cap_send_cmd(conn, l2cap_get_ident(conn),
2818 L2CAP_CONF_REQ, len, req);
2819 l2cap_pi(sk)->num_conf_req++;
2820 if (result != L2CAP_CONF_SUCCESS)
2821 goto done;
2822 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002823 }
2824
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002825 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002826 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002827 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002828 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002829 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002830 goto done;
2831 }
2832
2833 if (flags & 0x01)
2834 goto done;
2835
Linus Torvalds1da177e2005-04-16 15:20:36 -07002836 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
2837
2838 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002839 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV)
2840 || l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
2841 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2842
Linus Torvalds1da177e2005-04-16 15:20:36 -07002843 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002844 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002845 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002846 l2cap_pi(sk)->num_to_ack = 0;
2847 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002848 __skb_queue_head_init(SREJ_QUEUE(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002849 l2cap_chan_ready(sk);
2850 }
2851
2852done:
2853 bh_unlock_sock(sk);
2854 return 0;
2855}
2856
2857static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2858{
2859 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
2860 struct l2cap_disconn_rsp rsp;
2861 u16 dcid, scid;
2862 struct sock *sk;
2863
2864 scid = __le16_to_cpu(req->scid);
2865 dcid = __le16_to_cpu(req->dcid);
2866
2867 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
2868
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002869 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2870 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002871 return 0;
2872
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002873 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
2874 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002875 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
2876
2877 sk->sk_shutdown = SHUTDOWN_MASK;
2878
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002879 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002880 skb_queue_purge(SREJ_QUEUE(sk));
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002881 del_timer(&l2cap_pi(sk)->retrans_timer);
2882 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002883
Linus Torvalds1da177e2005-04-16 15:20:36 -07002884 l2cap_chan_del(sk, ECONNRESET);
2885 bh_unlock_sock(sk);
2886
2887 l2cap_sock_kill(sk);
2888 return 0;
2889}
2890
2891static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2892{
2893 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
2894 u16 dcid, scid;
2895 struct sock *sk;
2896
2897 scid = __le16_to_cpu(rsp->scid);
2898 dcid = __le16_to_cpu(rsp->dcid);
2899
2900 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
2901
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002902 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2903 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002904 return 0;
2905
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002906 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002907 skb_queue_purge(SREJ_QUEUE(sk));
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002908 del_timer(&l2cap_pi(sk)->retrans_timer);
2909 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002910
Linus Torvalds1da177e2005-04-16 15:20:36 -07002911 l2cap_chan_del(sk, 0);
2912 bh_unlock_sock(sk);
2913
2914 l2cap_sock_kill(sk);
2915 return 0;
2916}
2917
2918static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2919{
2920 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002921 u16 type;
2922
2923 type = __le16_to_cpu(req->type);
2924
2925 BT_DBG("type 0x%4.4x", type);
2926
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002927 if (type == L2CAP_IT_FEAT_MASK) {
2928 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07002929 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002930 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2931 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2932 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07002933 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002934 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
2935 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03002936 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002937 l2cap_send_cmd(conn, cmd->ident,
2938 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002939 } else if (type == L2CAP_IT_FIXED_CHAN) {
2940 u8 buf[12];
2941 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2942 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
2943 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
2944 memcpy(buf + 4, l2cap_fixed_chan, 8);
2945 l2cap_send_cmd(conn, cmd->ident,
2946 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002947 } else {
2948 struct l2cap_info_rsp rsp;
2949 rsp.type = cpu_to_le16(type);
2950 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
2951 l2cap_send_cmd(conn, cmd->ident,
2952 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
2953 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002954
2955 return 0;
2956}
2957
2958static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2959{
2960 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
2961 u16 type, result;
2962
2963 type = __le16_to_cpu(rsp->type);
2964 result = __le16_to_cpu(rsp->result);
2965
2966 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
2967
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002968 del_timer(&conn->info_timer);
2969
Marcel Holtmann984947d2009-02-06 23:35:19 +01002970 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07002971 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002972
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002973 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002974 struct l2cap_info_req req;
2975 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
2976
2977 conn->info_ident = l2cap_get_ident(conn);
2978
2979 l2cap_send_cmd(conn, conn->info_ident,
2980 L2CAP_INFO_REQ, sizeof(req), &req);
2981 } else {
2982 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
2983 conn->info_ident = 0;
2984
2985 l2cap_conn_start(conn);
2986 }
2987 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01002988 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002989 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002990
2991 l2cap_conn_start(conn);
2992 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002993
Linus Torvalds1da177e2005-04-16 15:20:36 -07002994 return 0;
2995}
2996
2997static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
2998{
2999 u8 *data = skb->data;
3000 int len = skb->len;
3001 struct l2cap_cmd_hdr cmd;
3002 int err = 0;
3003
3004 l2cap_raw_recv(conn, skb);
3005
3006 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003007 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003008 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3009 data += L2CAP_CMD_HDR_SIZE;
3010 len -= L2CAP_CMD_HDR_SIZE;
3011
Al Viro88219a02007-07-29 00:17:25 -07003012 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003013
Al Viro88219a02007-07-29 00:17:25 -07003014 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 -07003015
Al Viro88219a02007-07-29 00:17:25 -07003016 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003017 BT_DBG("corrupted command");
3018 break;
3019 }
3020
3021 switch (cmd.code) {
3022 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003023 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003024 break;
3025
3026 case L2CAP_CONN_REQ:
3027 err = l2cap_connect_req(conn, &cmd, data);
3028 break;
3029
3030 case L2CAP_CONN_RSP:
3031 err = l2cap_connect_rsp(conn, &cmd, data);
3032 break;
3033
3034 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003035 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003036 break;
3037
3038 case L2CAP_CONF_RSP:
3039 err = l2cap_config_rsp(conn, &cmd, data);
3040 break;
3041
3042 case L2CAP_DISCONN_REQ:
3043 err = l2cap_disconnect_req(conn, &cmd, data);
3044 break;
3045
3046 case L2CAP_DISCONN_RSP:
3047 err = l2cap_disconnect_rsp(conn, &cmd, data);
3048 break;
3049
3050 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003051 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003052 break;
3053
3054 case L2CAP_ECHO_RSP:
3055 break;
3056
3057 case L2CAP_INFO_REQ:
3058 err = l2cap_information_req(conn, &cmd, data);
3059 break;
3060
3061 case L2CAP_INFO_RSP:
3062 err = l2cap_information_rsp(conn, &cmd, data);
3063 break;
3064
3065 default:
3066 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3067 err = -EINVAL;
3068 break;
3069 }
3070
3071 if (err) {
3072 struct l2cap_cmd_rej rej;
3073 BT_DBG("error %d", err);
3074
3075 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003076 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003077 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3078 }
3079
Al Viro88219a02007-07-29 00:17:25 -07003080 data += cmd_len;
3081 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003082 }
3083
3084 kfree_skb(skb);
3085}
3086
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003087static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3088{
3089 u16 our_fcs, rcv_fcs;
3090 int hdr_size = L2CAP_HDR_SIZE + 2;
3091
3092 if (pi->fcs == L2CAP_FCS_CRC16) {
3093 skb_trim(skb, skb->len - 2);
3094 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3095 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3096
3097 if (our_fcs != rcv_fcs)
3098 return -EINVAL;
3099 }
3100 return 0;
3101}
3102
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003103static void l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
3104{
3105 struct sk_buff *next_skb;
3106
3107 bt_cb(skb)->tx_seq = tx_seq;
3108 bt_cb(skb)->sar = sar;
3109
3110 next_skb = skb_peek(SREJ_QUEUE(sk));
3111 if (!next_skb) {
3112 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3113 return;
3114 }
3115
3116 do {
3117 if (bt_cb(next_skb)->tx_seq > tx_seq) {
3118 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
3119 return;
3120 }
3121
3122 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3123 break;
3124
3125 } while((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
3126
3127 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3128}
3129
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003130static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3131{
3132 struct l2cap_pinfo *pi = l2cap_pi(sk);
3133 struct sk_buff *_skb;
3134 int err = -EINVAL;
3135
3136 switch (control & L2CAP_CTRL_SAR) {
3137 case L2CAP_SDU_UNSEGMENTED:
3138 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3139 kfree_skb(pi->sdu);
3140 break;
3141 }
3142
3143 err = sock_queue_rcv_skb(sk, skb);
3144 if (!err)
3145 return 0;
3146
3147 break;
3148
3149 case L2CAP_SDU_START:
3150 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3151 kfree_skb(pi->sdu);
3152 break;
3153 }
3154
3155 pi->sdu_len = get_unaligned_le16(skb->data);
3156 skb_pull(skb, 2);
3157
3158 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3159 if (!pi->sdu) {
3160 err = -ENOMEM;
3161 break;
3162 }
3163
3164 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3165
3166 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3167 pi->partial_sdu_len = skb->len;
3168 err = 0;
3169 break;
3170
3171 case L2CAP_SDU_CONTINUE:
3172 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3173 break;
3174
3175 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3176
3177 pi->partial_sdu_len += skb->len;
3178 if (pi->partial_sdu_len > pi->sdu_len)
3179 kfree_skb(pi->sdu);
3180 else
3181 err = 0;
3182
3183 break;
3184
3185 case L2CAP_SDU_END:
3186 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3187 break;
3188
3189 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3190
3191 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3192 pi->partial_sdu_len += skb->len;
3193
3194 if (pi->partial_sdu_len == pi->sdu_len) {
3195 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3196 err = sock_queue_rcv_skb(sk, _skb);
3197 if (err < 0)
3198 kfree_skb(_skb);
3199 }
3200 kfree_skb(pi->sdu);
3201 err = 0;
3202
3203 break;
3204 }
3205
3206 kfree_skb(skb);
3207 return err;
3208}
3209
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003210static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3211{
3212 struct sk_buff *skb;
3213 u16 control = 0;
3214
3215 while((skb = skb_peek(SREJ_QUEUE(sk)))) {
3216 if (bt_cb(skb)->tx_seq != tx_seq)
3217 break;
3218
3219 skb = skb_dequeue(SREJ_QUEUE(sk));
3220 control |= bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3221 l2cap_sar_reassembly_sdu(sk, skb, control);
3222 l2cap_pi(sk)->buffer_seq_srej =
3223 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
3224 tx_seq++;
3225 }
3226}
3227
3228static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3229{
3230 struct l2cap_pinfo *pi = l2cap_pi(sk);
3231 struct srej_list *l, *tmp;
3232 u16 control;
3233
3234 list_for_each_entry_safe(l,tmp, SREJ_LIST(sk), list) {
3235 if (l->tx_seq == tx_seq) {
3236 list_del(&l->list);
3237 kfree(l);
3238 return;
3239 }
3240 control = L2CAP_SUPER_SELECT_REJECT;
3241 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3242 l2cap_send_sframe(pi, control);
3243 list_del(&l->list);
3244 list_add_tail(&l->list, SREJ_LIST(sk));
3245 }
3246}
3247
3248static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3249{
3250 struct l2cap_pinfo *pi = l2cap_pi(sk);
3251 struct srej_list *new;
3252 u16 control;
3253
3254 while (tx_seq != pi->expected_tx_seq) {
3255 control = L2CAP_SUPER_SELECT_REJECT;
3256 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003257 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
3258 control |= L2CAP_CTRL_POLL;
3259 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
3260 }
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003261 l2cap_send_sframe(pi, control);
3262
3263 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
3264 new->tx_seq = pi->expected_tx_seq++;
3265 list_add_tail(&new->list, SREJ_LIST(sk));
3266 }
3267 pi->expected_tx_seq++;
3268}
3269
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003270static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3271{
3272 struct l2cap_pinfo *pi = l2cap_pi(sk);
3273 u8 tx_seq = __get_txseq(rx_control);
3274 u16 tx_control = 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003275 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003276 int err = 0;
3277
3278 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3279
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003280 if (tx_seq == pi->expected_tx_seq)
3281 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003282
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003283 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3284 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003285
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003286 first = list_first_entry(SREJ_LIST(sk),
3287 struct srej_list, list);
3288 if (tx_seq == first->tx_seq) {
3289 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3290 l2cap_check_srej_gap(sk, tx_seq);
3291
3292 list_del(&first->list);
3293 kfree(first);
3294
3295 if (list_empty(SREJ_LIST(sk))) {
3296 pi->buffer_seq = pi->buffer_seq_srej;
3297 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
3298 }
3299 } else {
3300 struct srej_list *l;
3301 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3302
3303 list_for_each_entry(l, SREJ_LIST(sk), list) {
3304 if (l->tx_seq == tx_seq) {
3305 l2cap_resend_srejframe(sk, tx_seq);
3306 return 0;
3307 }
3308 }
3309 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003310 }
3311 } else {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003312 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003313
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003314 INIT_LIST_HEAD(SREJ_LIST(sk));
3315 pi->buffer_seq_srej = pi->buffer_seq;
3316
3317 __skb_queue_head_init(SREJ_QUEUE(sk));
3318 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3319
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003320 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3321
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003322 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003323 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003324 return 0;
3325
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003326expected:
3327 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3328
3329 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3330 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3331 return 0;
3332 }
3333
3334 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3335
3336 err = l2cap_sar_reassembly_sdu(sk, skb, rx_control);
3337 if (err < 0)
3338 return err;
3339
3340 pi->num_to_ack = (pi->num_to_ack + 1) % L2CAP_DEFAULT_NUM_TO_ACK;
3341 if (pi->num_to_ack == L2CAP_DEFAULT_NUM_TO_ACK - 1) {
3342 tx_control |= L2CAP_SUPER_RCV_READY;
3343 tx_control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3344 l2cap_send_sframe(pi, tx_control);
3345 }
3346 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003347}
3348
3349static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3350{
3351 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003352 u8 tx_seq = __get_reqseq(rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003353
3354 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3355
3356 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
3357 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003358 if (rx_control & L2CAP_CTRL_POLL) {
3359 u16 control = L2CAP_CTRL_FINAL;
Gustavo F. Padovanca42a612009-08-26 04:04:01 -03003360 control |= L2CAP_SUPER_RCV_READY |
3361 (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003362 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003363 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3364
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003365 } else if (rx_control & L2CAP_CTRL_FINAL) {
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003366 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovanca42a612009-08-26 04:04:01 -03003367 pi->expected_ack_seq = tx_seq;
3368 l2cap_drop_acked_frames(sk);
3369
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003370 if (!(pi->conn_state & L2CAP_CONN_WAIT_F))
3371 break;
3372
3373 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3374 del_timer(&pi->monitor_timer);
3375
3376 if (pi->unacked_frames > 0)
3377 __mod_retrans_timer();
3378 } else {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003379 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003380 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003381
3382 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY)
3383 && (pi->unacked_frames > 0))
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003384 __mod_retrans_timer();
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003385
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003386 l2cap_ertm_send(sk);
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003387 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003388 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003389 break;
3390
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003391 case L2CAP_SUPER_REJECT:
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003392 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3393
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003394 pi->expected_ack_seq = __get_reqseq(rx_control);
3395 l2cap_drop_acked_frames(sk);
3396
3397 sk->sk_send_head = TX_QUEUE(sk)->next;
3398 pi->next_tx_seq = pi->expected_ack_seq;
3399
3400 l2cap_ertm_send(sk);
3401
3402 break;
3403
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003404 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003405 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3406
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003407 if (rx_control & L2CAP_CTRL_POLL) {
3408 l2cap_retransmit_frame(sk, tx_seq);
3409 pi->expected_ack_seq = tx_seq;
3410 l2cap_drop_acked_frames(sk);
3411 l2cap_ertm_send(sk);
3412 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3413 pi->srej_save_reqseq = tx_seq;
3414 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3415 }
3416 } else if (rx_control & L2CAP_CTRL_FINAL) {
3417 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3418 pi->srej_save_reqseq == tx_seq)
3419 pi->srej_save_reqseq &= ~L2CAP_CONN_SREJ_ACT;
3420 else
3421 l2cap_retransmit_frame(sk, tx_seq);
3422 }
3423 else {
3424 l2cap_retransmit_frame(sk, tx_seq);
3425 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3426 pi->srej_save_reqseq = tx_seq;
3427 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3428 }
3429 }
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003430 break;
3431
3432 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003433 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
3434 pi->expected_ack_seq = tx_seq;
3435 l2cap_drop_acked_frames(sk);
3436
3437 del_timer(&l2cap_pi(sk)->retrans_timer);
3438 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03003439 u16 control = L2CAP_CTRL_FINAL;
3440 l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003441 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003442 break;
3443 }
3444
3445 return 0;
3446}
3447
Linus Torvalds1da177e2005-04-16 15:20:36 -07003448static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
3449{
3450 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003451 struct l2cap_pinfo *pi;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003452 u16 control, len;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003453 u8 tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003454 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003455
3456 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3457 if (!sk) {
3458 BT_DBG("unknown cid 0x%4.4x", cid);
3459 goto drop;
3460 }
3461
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003462 pi = l2cap_pi(sk);
3463
Linus Torvalds1da177e2005-04-16 15:20:36 -07003464 BT_DBG("sk %p, len %d", sk, skb->len);
3465
3466 if (sk->sk_state != BT_CONNECTED)
3467 goto drop;
3468
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003469 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003470 case L2CAP_MODE_BASIC:
3471 /* If socket recv buffers overflows we drop data here
3472 * which is *bad* because L2CAP has to be reliable.
3473 * But we don't have any other choice. L2CAP doesn't
3474 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003475
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003476 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003477 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003478
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003479 if (!sock_queue_rcv_skb(sk, skb))
3480 goto done;
3481 break;
3482
3483 case L2CAP_MODE_ERTM:
3484 control = get_unaligned_le16(skb->data);
3485 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003486 len = skb->len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003487
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003488 if (__is_sar_start(control))
3489 len -= 2;
3490
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003491 if (pi->fcs == L2CAP_FCS_CRC16)
3492 len -= 2;
3493
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003494 /*
3495 * We can just drop the corrupted I-frame here.
3496 * Receiver will miss it and start proper recovery
3497 * procedures and ask retransmission.
3498 */
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003499 if (len > L2CAP_DEFAULT_MAX_PDU_SIZE)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003500 goto drop;
3501
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003502 if (l2cap_check_fcs(pi, skb))
3503 goto drop;
3504
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003505 if (__is_iframe(control))
3506 err = l2cap_data_channel_iframe(sk, control, skb);
3507 else
3508 err = l2cap_data_channel_sframe(sk, control, skb);
3509
3510 if (!err)
3511 goto done;
3512 break;
3513
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003514 case L2CAP_MODE_STREAMING:
3515 control = get_unaligned_le16(skb->data);
3516 skb_pull(skb, 2);
3517 len = skb->len;
3518
3519 if (__is_sar_start(control))
3520 len -= 2;
3521
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003522 if (pi->fcs == L2CAP_FCS_CRC16)
3523 len -= 2;
3524
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003525 if (len > L2CAP_DEFAULT_MAX_PDU_SIZE || __is_sframe(control))
3526 goto drop;
3527
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003528 if (l2cap_check_fcs(pi, skb))
3529 goto drop;
3530
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003531 tx_seq = __get_txseq(control);
3532
3533 if (pi->expected_tx_seq == tx_seq)
3534 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3535 else
3536 pi->expected_tx_seq = tx_seq + 1;
3537
3538 err = l2cap_sar_reassembly_sdu(sk, skb, control);
3539
3540 goto done;
3541
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003542 default:
3543 BT_DBG("sk %p: bad mode 0x%2.2x", sk, l2cap_pi(sk)->mode);
3544 break;
3545 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003546
3547drop:
3548 kfree_skb(skb);
3549
3550done:
Marcel Holtmann01394182006-07-03 10:02:46 +02003551 if (sk)
3552 bh_unlock_sock(sk);
3553
Linus Torvalds1da177e2005-04-16 15:20:36 -07003554 return 0;
3555}
3556
Al Viro8e036fc2007-07-29 00:16:36 -07003557static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003558{
3559 struct sock *sk;
3560
3561 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
3562 if (!sk)
3563 goto drop;
3564
3565 BT_DBG("sk %p, len %d", sk, skb->len);
3566
3567 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
3568 goto drop;
3569
3570 if (l2cap_pi(sk)->imtu < skb->len)
3571 goto drop;
3572
3573 if (!sock_queue_rcv_skb(sk, skb))
3574 goto done;
3575
3576drop:
3577 kfree_skb(skb);
3578
3579done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003580 if (sk)
3581 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003582 return 0;
3583}
3584
3585static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
3586{
3587 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07003588 u16 cid, len;
3589 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003590
3591 skb_pull(skb, L2CAP_HDR_SIZE);
3592 cid = __le16_to_cpu(lh->cid);
3593 len = __le16_to_cpu(lh->len);
3594
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003595 if (len != skb->len) {
3596 kfree_skb(skb);
3597 return;
3598 }
3599
Linus Torvalds1da177e2005-04-16 15:20:36 -07003600 BT_DBG("len %d, cid 0x%4.4x", len, cid);
3601
3602 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003603 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003604 l2cap_sig_channel(conn, skb);
3605 break;
3606
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003607 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003608 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003609 skb_pull(skb, 2);
3610 l2cap_conless_channel(conn, psm, skb);
3611 break;
3612
3613 default:
3614 l2cap_data_channel(conn, cid, skb);
3615 break;
3616 }
3617}
3618
3619/* ---- L2CAP interface with lower layer (HCI) ---- */
3620
3621static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3622{
3623 int exact = 0, lm1 = 0, lm2 = 0;
3624 register struct sock *sk;
3625 struct hlist_node *node;
3626
3627 if (type != ACL_LINK)
3628 return 0;
3629
3630 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
3631
3632 /* Find listening sockets and check their link_mode */
3633 read_lock(&l2cap_sk_list.lock);
3634 sk_for_each(sk, node, &l2cap_sk_list.head) {
3635 if (sk->sk_state != BT_LISTEN)
3636 continue;
3637
3638 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003639 lm1 |= HCI_LM_ACCEPT;
3640 if (l2cap_pi(sk)->role_switch)
3641 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003642 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003643 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
3644 lm2 |= HCI_LM_ACCEPT;
3645 if (l2cap_pi(sk)->role_switch)
3646 lm2 |= HCI_LM_MASTER;
3647 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003648 }
3649 read_unlock(&l2cap_sk_list.lock);
3650
3651 return exact ? lm1 : lm2;
3652}
3653
3654static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
3655{
Marcel Holtmann01394182006-07-03 10:02:46 +02003656 struct l2cap_conn *conn;
3657
Linus Torvalds1da177e2005-04-16 15:20:36 -07003658 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
3659
3660 if (hcon->type != ACL_LINK)
3661 return 0;
3662
3663 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003664 conn = l2cap_conn_add(hcon, status);
3665 if (conn)
3666 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02003667 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003668 l2cap_conn_del(hcon, bt_err(status));
3669
3670 return 0;
3671}
3672
Marcel Holtmann2950f212009-02-12 14:02:50 +01003673static int l2cap_disconn_ind(struct hci_conn *hcon)
3674{
3675 struct l2cap_conn *conn = hcon->l2cap_data;
3676
3677 BT_DBG("hcon %p", hcon);
3678
3679 if (hcon->type != ACL_LINK || !conn)
3680 return 0x13;
3681
3682 return conn->disc_reason;
3683}
3684
3685static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003686{
3687 BT_DBG("hcon %p reason %d", hcon, reason);
3688
3689 if (hcon->type != ACL_LINK)
3690 return 0;
3691
3692 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02003693
Linus Torvalds1da177e2005-04-16 15:20:36 -07003694 return 0;
3695}
3696
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003697static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
3698{
Marcel Holtmann255c7602009-02-04 21:07:19 +01003699 if (sk->sk_type != SOCK_SEQPACKET)
3700 return;
3701
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003702 if (encrypt == 0x00) {
3703 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
3704 l2cap_sock_clear_timer(sk);
3705 l2cap_sock_set_timer(sk, HZ * 5);
3706 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
3707 __l2cap_sock_close(sk, ECONNREFUSED);
3708 } else {
3709 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
3710 l2cap_sock_clear_timer(sk);
3711 }
3712}
3713
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003714static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003715{
3716 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02003717 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003718 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003719
Marcel Holtmann01394182006-07-03 10:02:46 +02003720 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003721 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02003722
Linus Torvalds1da177e2005-04-16 15:20:36 -07003723 l = &conn->chan_list;
3724
3725 BT_DBG("conn %p", conn);
3726
3727 read_lock(&l->lock);
3728
3729 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
3730 bh_lock_sock(sk);
3731
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003732 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
3733 bh_unlock_sock(sk);
3734 continue;
3735 }
3736
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003737 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003738 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003739 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02003740 bh_unlock_sock(sk);
3741 continue;
3742 }
3743
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003744 if (sk->sk_state == BT_CONNECT) {
3745 if (!status) {
3746 struct l2cap_conn_req req;
3747 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
3748 req.psm = l2cap_pi(sk)->psm;
3749
3750 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
3751
3752 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3753 L2CAP_CONN_REQ, sizeof(req), &req);
3754 } else {
3755 l2cap_sock_clear_timer(sk);
3756 l2cap_sock_set_timer(sk, HZ / 10);
3757 }
3758 } else if (sk->sk_state == BT_CONNECT2) {
3759 struct l2cap_conn_rsp rsp;
3760 __u16 result;
3761
3762 if (!status) {
3763 sk->sk_state = BT_CONFIG;
3764 result = L2CAP_CR_SUCCESS;
3765 } else {
3766 sk->sk_state = BT_DISCONN;
3767 l2cap_sock_set_timer(sk, HZ / 10);
3768 result = L2CAP_CR_SEC_BLOCK;
3769 }
3770
3771 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
3772 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3773 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003774 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003775 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3776 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003777 }
3778
Linus Torvalds1da177e2005-04-16 15:20:36 -07003779 bh_unlock_sock(sk);
3780 }
3781
3782 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003783
Linus Torvalds1da177e2005-04-16 15:20:36 -07003784 return 0;
3785}
3786
3787static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
3788{
3789 struct l2cap_conn *conn = hcon->l2cap_data;
3790
3791 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
3792 goto drop;
3793
3794 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
3795
3796 if (flags & ACL_START) {
3797 struct l2cap_hdr *hdr;
3798 int len;
3799
3800 if (conn->rx_len) {
3801 BT_ERR("Unexpected start frame (len %d)", skb->len);
3802 kfree_skb(conn->rx_skb);
3803 conn->rx_skb = NULL;
3804 conn->rx_len = 0;
3805 l2cap_conn_unreliable(conn, ECOMM);
3806 }
3807
3808 if (skb->len < 2) {
3809 BT_ERR("Frame is too short (len %d)", skb->len);
3810 l2cap_conn_unreliable(conn, ECOMM);
3811 goto drop;
3812 }
3813
3814 hdr = (struct l2cap_hdr *) skb->data;
3815 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
3816
3817 if (len == skb->len) {
3818 /* Complete frame received */
3819 l2cap_recv_frame(conn, skb);
3820 return 0;
3821 }
3822
3823 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
3824
3825 if (skb->len > len) {
3826 BT_ERR("Frame is too long (len %d, expected len %d)",
3827 skb->len, len);
3828 l2cap_conn_unreliable(conn, ECOMM);
3829 goto drop;
3830 }
3831
3832 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003833 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
3834 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003835 goto drop;
3836
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03003837 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003838 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003839 conn->rx_len = len - skb->len;
3840 } else {
3841 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
3842
3843 if (!conn->rx_len) {
3844 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
3845 l2cap_conn_unreliable(conn, ECOMM);
3846 goto drop;
3847 }
3848
3849 if (skb->len > conn->rx_len) {
3850 BT_ERR("Fragment is too long (len %d, expected %d)",
3851 skb->len, conn->rx_len);
3852 kfree_skb(conn->rx_skb);
3853 conn->rx_skb = NULL;
3854 conn->rx_len = 0;
3855 l2cap_conn_unreliable(conn, ECOMM);
3856 goto drop;
3857 }
3858
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03003859 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003860 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003861 conn->rx_len -= skb->len;
3862
3863 if (!conn->rx_len) {
3864 /* Complete frame received */
3865 l2cap_recv_frame(conn, conn->rx_skb);
3866 conn->rx_skb = NULL;
3867 }
3868 }
3869
3870drop:
3871 kfree_skb(skb);
3872 return 0;
3873}
3874
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003875static ssize_t l2cap_sysfs_show(struct class *dev, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003876{
3877 struct sock *sk;
3878 struct hlist_node *node;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003879 char *str = buf;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003880
3881 read_lock_bh(&l2cap_sk_list.lock);
3882
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003883 sk_for_each(sk, node, &l2cap_sk_list.head) {
3884 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003885
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003886 str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003887 batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
Marcel Holtmannb4324b52009-06-07 18:06:51 +02003888 sk->sk_state, __le16_to_cpu(pi->psm), pi->scid,
3889 pi->dcid, pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003890 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003891
Linus Torvalds1da177e2005-04-16 15:20:36 -07003892 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003893
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003894 return str - buf;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003895}
3896
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003897static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003898
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08003899static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003900 .family = PF_BLUETOOTH,
3901 .owner = THIS_MODULE,
3902 .release = l2cap_sock_release,
3903 .bind = l2cap_sock_bind,
3904 .connect = l2cap_sock_connect,
3905 .listen = l2cap_sock_listen,
3906 .accept = l2cap_sock_accept,
3907 .getname = l2cap_sock_getname,
3908 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003909 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003910 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02003911 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003912 .mmap = sock_no_mmap,
3913 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003914 .shutdown = l2cap_sock_shutdown,
3915 .setsockopt = l2cap_sock_setsockopt,
3916 .getsockopt = l2cap_sock_getsockopt
3917};
3918
3919static struct net_proto_family l2cap_sock_family_ops = {
3920 .family = PF_BLUETOOTH,
3921 .owner = THIS_MODULE,
3922 .create = l2cap_sock_create,
3923};
3924
3925static struct hci_proto l2cap_hci_proto = {
3926 .name = "L2CAP",
3927 .id = HCI_PROTO_L2CAP,
3928 .connect_ind = l2cap_connect_ind,
3929 .connect_cfm = l2cap_connect_cfm,
3930 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01003931 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003932 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003933 .recv_acldata = l2cap_recv_acldata
3934};
3935
3936static int __init l2cap_init(void)
3937{
3938 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003939
Linus Torvalds1da177e2005-04-16 15:20:36 -07003940 err = proto_register(&l2cap_proto, 0);
3941 if (err < 0)
3942 return err;
3943
3944 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
3945 if (err < 0) {
3946 BT_ERR("L2CAP socket registration failed");
3947 goto error;
3948 }
3949
3950 err = hci_register_proto(&l2cap_hci_proto);
3951 if (err < 0) {
3952 BT_ERR("L2CAP protocol registration failed");
3953 bt_sock_unregister(BTPROTO_L2CAP);
3954 goto error;
3955 }
3956
Marcel Holtmanndf5c37e2006-10-15 17:30:45 +02003957 if (class_create_file(bt_class, &class_attr_l2cap) < 0)
3958 BT_ERR("Failed to create L2CAP info file");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003959
3960 BT_INFO("L2CAP ver %s", VERSION);
3961 BT_INFO("L2CAP socket layer initialized");
3962
3963 return 0;
3964
3965error:
3966 proto_unregister(&l2cap_proto);
3967 return err;
3968}
3969
3970static void __exit l2cap_exit(void)
3971{
Marcel Holtmanna91f2e32006-07-03 10:02:41 +02003972 class_remove_file(bt_class, &class_attr_l2cap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003973
3974 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
3975 BT_ERR("L2CAP socket unregistration failed");
3976
3977 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
3978 BT_ERR("L2CAP protocol unregistration failed");
3979
3980 proto_unregister(&l2cap_proto);
3981}
3982
3983void l2cap_load(void)
3984{
3985 /* Dummy function to trigger automatic L2CAP module loading by
3986 * other modules that use L2CAP sockets but don't use any other
3987 * symbols from it. */
3988 return;
3989}
3990EXPORT_SYMBOL(l2cap_load);
3991
3992module_init(l2cap_init);
3993module_exit(l2cap_exit);
3994
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003995module_param(enable_ertm, bool, 0644);
3996MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
3997
Marcel Holtmann63fbd242008-08-18 13:23:53 +02003998MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003999MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4000MODULE_VERSION(VERSION);
4001MODULE_LICENSE("GPL");
4002MODULE_ALIAS("bt-proto-0");