blob: 40fbf5cb1f7ed42f07f677a4502a3f9fe3747d3c [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. Padovanaf05b302009-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. Padovanaf05b302009-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. Padovanaf05b302009-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. Padovanaf05b302009-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. Padovanaf05b302009-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. Padovanaf05b302009-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
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200369static void l2cap_do_start(struct sock *sk)
370{
371 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
372
373 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100374 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
375 return;
376
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100377 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200378 struct l2cap_conn_req req;
379 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
380 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200381
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200382 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200383
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200384 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200385 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200386 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200387 } else {
388 struct l2cap_info_req req;
389 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
390
391 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
392 conn->info_ident = l2cap_get_ident(conn);
393
394 mod_timer(&conn->info_timer, jiffies +
395 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
396
397 l2cap_send_cmd(conn, conn->info_ident,
398 L2CAP_INFO_REQ, sizeof(req), &req);
399 }
400}
401
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300402static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk)
403{
404 struct l2cap_disconn_req req;
405
406 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
407 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
408 l2cap_send_cmd(conn, l2cap_get_ident(conn),
409 L2CAP_DISCONN_REQ, sizeof(req), &req);
410}
411
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200413static void l2cap_conn_start(struct l2cap_conn *conn)
414{
415 struct l2cap_chan_list *l = &conn->chan_list;
416 struct sock *sk;
417
418 BT_DBG("conn %p", conn);
419
420 read_lock(&l->lock);
421
422 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
423 bh_lock_sock(sk);
424
425 if (sk->sk_type != SOCK_SEQPACKET) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200426 bh_unlock_sock(sk);
427 continue;
428 }
429
430 if (sk->sk_state == BT_CONNECT) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100431 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200432 struct l2cap_conn_req req;
433 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
434 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200435
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200436 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200437
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200438 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200439 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200440 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200441 } else if (sk->sk_state == BT_CONNECT2) {
442 struct l2cap_conn_rsp rsp;
443 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
444 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
445
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100446 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100447 if (bt_sk(sk)->defer_setup) {
448 struct sock *parent = bt_sk(sk)->parent;
449 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
450 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
451 parent->sk_data_ready(parent, 0);
452
453 } else {
454 sk->sk_state = BT_CONFIG;
455 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
456 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
457 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200458 } else {
459 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
460 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
461 }
462
463 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
464 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
465 }
466
467 bh_unlock_sock(sk);
468 }
469
470 read_unlock(&l->lock);
471}
472
473static void l2cap_conn_ready(struct l2cap_conn *conn)
474{
475 struct l2cap_chan_list *l = &conn->chan_list;
476 struct sock *sk;
477
478 BT_DBG("conn %p", conn);
479
480 read_lock(&l->lock);
481
482 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
483 bh_lock_sock(sk);
484
485 if (sk->sk_type != SOCK_SEQPACKET) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200486 l2cap_sock_clear_timer(sk);
487 sk->sk_state = BT_CONNECTED;
488 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200489 } else if (sk->sk_state == BT_CONNECT)
490 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200491
492 bh_unlock_sock(sk);
493 }
494
495 read_unlock(&l->lock);
496}
497
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200498/* Notify sockets that we cannot guaranty reliability anymore */
499static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
500{
501 struct l2cap_chan_list *l = &conn->chan_list;
502 struct sock *sk;
503
504 BT_DBG("conn %p", conn);
505
506 read_lock(&l->lock);
507
508 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100509 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200510 sk->sk_err = err;
511 }
512
513 read_unlock(&l->lock);
514}
515
516static void l2cap_info_timeout(unsigned long arg)
517{
518 struct l2cap_conn *conn = (void *) arg;
519
Marcel Holtmann984947d2009-02-06 23:35:19 +0100520 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100521 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100522
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200523 l2cap_conn_start(conn);
524}
525
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
527{
Marcel Holtmann01394182006-07-03 10:02:46 +0200528 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529
Marcel Holtmann01394182006-07-03 10:02:46 +0200530 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531 return conn;
532
Marcel Holtmann01394182006-07-03 10:02:46 +0200533 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
534 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536
537 hcon->l2cap_data = conn;
538 conn->hcon = hcon;
539
Marcel Holtmann01394182006-07-03 10:02:46 +0200540 BT_DBG("hcon %p conn %p", hcon, conn);
541
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 conn->mtu = hcon->hdev->acl_mtu;
543 conn->src = &hcon->hdev->bdaddr;
544 conn->dst = &hcon->dst;
545
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200546 conn->feat_mask = 0;
547
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200548 setup_timer(&conn->info_timer, l2cap_info_timeout,
549 (unsigned long) conn);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200550
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 spin_lock_init(&conn->lock);
552 rwlock_init(&conn->chan_list.lock);
553
Marcel Holtmann2950f212009-02-12 14:02:50 +0100554 conn->disc_reason = 0x13;
555
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 return conn;
557}
558
Marcel Holtmann01394182006-07-03 10:02:46 +0200559static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560{
Marcel Holtmann01394182006-07-03 10:02:46 +0200561 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 struct sock *sk;
563
Marcel Holtmann01394182006-07-03 10:02:46 +0200564 if (!conn)
565 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566
567 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
568
Wei Yongjun7585b972009-02-25 18:29:52 +0800569 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570
571 /* Kill channels */
572 while ((sk = conn->chan_list.head)) {
573 bh_lock_sock(sk);
574 l2cap_chan_del(sk, err);
575 bh_unlock_sock(sk);
576 l2cap_sock_kill(sk);
577 }
578
Dave Young8e8440f2008-03-03 12:18:55 -0800579 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
580 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800581
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582 hcon->l2cap_data = NULL;
583 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584}
585
586static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
587{
588 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200589 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200591 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592}
593
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700595static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596{
597 struct sock *sk;
598 struct hlist_node *node;
599 sk_for_each(sk, node, &l2cap_sk_list.head)
600 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
601 goto found;
602 sk = NULL;
603found:
604 return sk;
605}
606
607/* Find socket with psm and source bdaddr.
608 * Returns closest match.
609 */
Al Viro8e036fc2007-07-29 00:16:36 -0700610static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611{
612 struct sock *sk = NULL, *sk1 = NULL;
613 struct hlist_node *node;
614
615 sk_for_each(sk, node, &l2cap_sk_list.head) {
616 if (state && sk->sk_state != state)
617 continue;
618
619 if (l2cap_pi(sk)->psm == psm) {
620 /* Exact match. */
621 if (!bacmp(&bt_sk(sk)->src, src))
622 break;
623
624 /* Closest match */
625 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
626 sk1 = sk;
627 }
628 }
629 return node ? sk : sk1;
630}
631
632/* Find socket with given address (psm, src).
633 * Returns locked socket */
Al Viro8e036fc2007-07-29 00:16:36 -0700634static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635{
636 struct sock *s;
637 read_lock(&l2cap_sk_list.lock);
638 s = __l2cap_get_sock_by_psm(state, psm, src);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300639 if (s)
640 bh_lock_sock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641 read_unlock(&l2cap_sk_list.lock);
642 return s;
643}
644
645static void l2cap_sock_destruct(struct sock *sk)
646{
647 BT_DBG("sk %p", sk);
648
649 skb_queue_purge(&sk->sk_receive_queue);
650 skb_queue_purge(&sk->sk_write_queue);
651}
652
653static void l2cap_sock_cleanup_listen(struct sock *parent)
654{
655 struct sock *sk;
656
657 BT_DBG("parent %p", parent);
658
659 /* Close not yet accepted channels */
660 while ((sk = bt_accept_dequeue(parent, NULL)))
661 l2cap_sock_close(sk);
662
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200663 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664 sock_set_flag(parent, SOCK_ZAPPED);
665}
666
667/* Kill socket (only if zapped and orphan)
668 * Must be called on unlocked socket.
669 */
670static void l2cap_sock_kill(struct sock *sk)
671{
672 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
673 return;
674
675 BT_DBG("sk %p state %d", sk, sk->sk_state);
676
677 /* Kill poor orphan */
678 bt_sock_unlink(&l2cap_sk_list, sk);
679 sock_set_flag(sk, SOCK_DEAD);
680 sock_put(sk);
681}
682
683static void __l2cap_sock_close(struct sock *sk, int reason)
684{
685 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
686
687 switch (sk->sk_state) {
688 case BT_LISTEN:
689 l2cap_sock_cleanup_listen(sk);
690 break;
691
692 case BT_CONNECTED:
693 case BT_CONFIG:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694 if (sk->sk_type == SOCK_SEQPACKET) {
695 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696
697 sk->sk_state = BT_DISCONN;
698 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300699 l2cap_send_disconn_req(conn, sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200700 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700702 break;
703
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100704 case BT_CONNECT2:
705 if (sk->sk_type == SOCK_SEQPACKET) {
706 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
707 struct l2cap_conn_rsp rsp;
708 __u16 result;
709
710 if (bt_sk(sk)->defer_setup)
711 result = L2CAP_CR_SEC_BLOCK;
712 else
713 result = L2CAP_CR_BAD_PSM;
714
715 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
716 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
717 rsp.result = cpu_to_le16(result);
718 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
719 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
720 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
721 } else
722 l2cap_chan_del(sk, reason);
723 break;
724
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725 case BT_CONNECT:
726 case BT_DISCONN:
727 l2cap_chan_del(sk, reason);
728 break;
729
730 default:
731 sock_set_flag(sk, SOCK_ZAPPED);
732 break;
733 }
734}
735
736/* Must be called on unlocked socket. */
737static void l2cap_sock_close(struct sock *sk)
738{
739 l2cap_sock_clear_timer(sk);
740 lock_sock(sk);
741 __l2cap_sock_close(sk, ECONNRESET);
742 release_sock(sk);
743 l2cap_sock_kill(sk);
744}
745
746static void l2cap_sock_init(struct sock *sk, struct sock *parent)
747{
748 struct l2cap_pinfo *pi = l2cap_pi(sk);
749
750 BT_DBG("sk %p", sk);
751
752 if (parent) {
753 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100754 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
755
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756 pi->imtu = l2cap_pi(parent)->imtu;
757 pi->omtu = l2cap_pi(parent)->omtu;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700758 pi->mode = l2cap_pi(parent)->mode;
759 pi->fcs = l2cap_pi(parent)->fcs;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100760 pi->sec_level = l2cap_pi(parent)->sec_level;
761 pi->role_switch = l2cap_pi(parent)->role_switch;
762 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763 } else {
764 pi->imtu = L2CAP_DEFAULT_MTU;
765 pi->omtu = 0;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700766 pi->mode = L2CAP_MODE_BASIC;
767 pi->fcs = L2CAP_FCS_CRC16;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100768 pi->sec_level = BT_SECURITY_LOW;
769 pi->role_switch = 0;
770 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 }
772
773 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200774 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
776}
777
778static struct proto l2cap_proto = {
779 .name = "L2CAP",
780 .owner = THIS_MODULE,
781 .obj_size = sizeof(struct l2cap_pinfo)
782};
783
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700784static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785{
786 struct sock *sk;
787
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700788 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 if (!sk)
790 return NULL;
791
792 sock_init_data(sock, sk);
793 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
794
795 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200796 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797
798 sock_reset_flag(sk, SOCK_ZAPPED);
799
800 sk->sk_protocol = proto;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200801 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200803 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804
805 bt_sock_link(&l2cap_sk_list, sk);
806 return sk;
807}
808
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700809static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810{
811 struct sock *sk;
812
813 BT_DBG("sock %p", sock);
814
815 sock->state = SS_UNCONNECTED;
816
817 if (sock->type != SOCK_SEQPACKET &&
818 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
819 return -ESOCKTNOSUPPORT;
820
821 if (sock->type == SOCK_RAW && !capable(CAP_NET_RAW))
822 return -EPERM;
823
824 sock->ops = &l2cap_sock_ops;
825
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700826 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827 if (!sk)
828 return -ENOMEM;
829
830 l2cap_sock_init(sk, NULL);
831 return 0;
832}
833
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100834static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100837 struct sockaddr_l2 la;
838 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100840 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841
842 if (!addr || addr->sa_family != AF_BLUETOOTH)
843 return -EINVAL;
844
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100845 memset(&la, 0, sizeof(la));
846 len = min_t(unsigned int, sizeof(la), alen);
847 memcpy(&la, addr, len);
848
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100849 if (la.l2_cid)
850 return -EINVAL;
851
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852 lock_sock(sk);
853
854 if (sk->sk_state != BT_OPEN) {
855 err = -EBADFD;
856 goto done;
857 }
858
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200859 if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
Marcel Holtmann847641d2007-01-22 22:00:45 +0100860 !capable(CAP_NET_BIND_SERVICE)) {
861 err = -EACCES;
862 goto done;
863 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900864
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865 write_lock_bh(&l2cap_sk_list.lock);
866
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100867 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868 err = -EADDRINUSE;
869 } else {
870 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100871 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
872 l2cap_pi(sk)->psm = la.l2_psm;
873 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100875
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200876 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
877 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100878 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879 }
880
881 write_unlock_bh(&l2cap_sk_list.lock);
882
883done:
884 release_sock(sk);
885 return err;
886}
887
888static int l2cap_do_connect(struct sock *sk)
889{
890 bdaddr_t *src = &bt_sk(sk)->src;
891 bdaddr_t *dst = &bt_sk(sk)->dst;
892 struct l2cap_conn *conn;
893 struct hci_conn *hcon;
894 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200895 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +0200896 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100898 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
899 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300901 hdev = hci_get_route(dst, src);
902 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 return -EHOSTUNREACH;
904
905 hci_dev_lock_bh(hdev);
906
907 err = -ENOMEM;
908
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100909 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100910 switch (l2cap_pi(sk)->sec_level) {
911 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100912 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100913 break;
914 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100915 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100916 break;
917 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100918 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100919 break;
920 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100921 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100922 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200923 auth_type = HCI_AT_NO_BONDING_MITM;
924 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200925 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +0100926
927 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
928 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100929 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100930 switch (l2cap_pi(sk)->sec_level) {
931 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100932 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100933 break;
934 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200935 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100936 break;
937 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100938 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100939 break;
940 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200941 }
942
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100943 hcon = hci_connect(hdev, ACL_LINK, dst,
944 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945 if (!hcon)
946 goto done;
947
948 conn = l2cap_conn_add(hcon, 0);
949 if (!conn) {
950 hci_conn_put(hcon);
951 goto done;
952 }
953
954 err = 0;
955
956 /* Update source addr of the socket */
957 bacpy(src, conn->src);
958
959 l2cap_chan_add(conn, sk, NULL);
960
961 sk->sk_state = BT_CONNECT;
962 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
963
964 if (hcon->state == BT_CONNECTED) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200965 if (sk->sk_type != SOCK_SEQPACKET) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966 l2cap_sock_clear_timer(sk);
967 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200968 } else
969 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970 }
971
972done:
973 hci_dev_unlock_bh(hdev);
974 hci_dev_put(hdev);
975 return err;
976}
977
978static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
979{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100981 struct sockaddr_l2 la;
982 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984 BT_DBG("sk %p", sk);
985
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100986 if (!addr || addr->sa_family != AF_BLUETOOTH)
987 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100989 memset(&la, 0, sizeof(la));
990 len = min_t(unsigned int, sizeof(la), alen);
991 memcpy(&la, addr, len);
992
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100993 if (la.l2_cid)
994 return -EINVAL;
995
996 lock_sock(sk);
997
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100998 if (sk->sk_type == SOCK_SEQPACKET && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700999 err = -EINVAL;
1000 goto done;
1001 }
1002
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001003 switch (l2cap_pi(sk)->mode) {
1004 case L2CAP_MODE_BASIC:
1005 break;
1006 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001007 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001008 if (enable_ertm)
1009 break;
1010 /* fall through */
1011 default:
1012 err = -ENOTSUPP;
1013 goto done;
1014 }
1015
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001016 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017 case BT_CONNECT:
1018 case BT_CONNECT2:
1019 case BT_CONFIG:
1020 /* Already connecting */
1021 goto wait;
1022
1023 case BT_CONNECTED:
1024 /* Already connected */
1025 goto done;
1026
1027 case BT_OPEN:
1028 case BT_BOUND:
1029 /* Can connect */
1030 break;
1031
1032 default:
1033 err = -EBADFD;
1034 goto done;
1035 }
1036
1037 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001038 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1039 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001040
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001041 err = l2cap_do_connect(sk);
1042 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001043 goto done;
1044
1045wait:
1046 err = bt_sock_wait_state(sk, BT_CONNECTED,
1047 sock_sndtimeo(sk, flags & O_NONBLOCK));
1048done:
1049 release_sock(sk);
1050 return err;
1051}
1052
1053static int l2cap_sock_listen(struct socket *sock, int backlog)
1054{
1055 struct sock *sk = sock->sk;
1056 int err = 0;
1057
1058 BT_DBG("sk %p backlog %d", sk, backlog);
1059
1060 lock_sock(sk);
1061
1062 if (sk->sk_state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
1063 err = -EBADFD;
1064 goto done;
1065 }
1066
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001067 switch (l2cap_pi(sk)->mode) {
1068 case L2CAP_MODE_BASIC:
1069 break;
1070 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001071 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001072 if (enable_ertm)
1073 break;
1074 /* fall through */
1075 default:
1076 err = -ENOTSUPP;
1077 goto done;
1078 }
1079
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080 if (!l2cap_pi(sk)->psm) {
1081 bdaddr_t *src = &bt_sk(sk)->src;
1082 u16 psm;
1083
1084 err = -EINVAL;
1085
1086 write_lock_bh(&l2cap_sk_list.lock);
1087
1088 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001089 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1090 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1091 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092 err = 0;
1093 break;
1094 }
1095
1096 write_unlock_bh(&l2cap_sk_list.lock);
1097
1098 if (err < 0)
1099 goto done;
1100 }
1101
1102 sk->sk_max_ack_backlog = backlog;
1103 sk->sk_ack_backlog = 0;
1104 sk->sk_state = BT_LISTEN;
1105
1106done:
1107 release_sock(sk);
1108 return err;
1109}
1110
1111static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1112{
1113 DECLARE_WAITQUEUE(wait, current);
1114 struct sock *sk = sock->sk, *nsk;
1115 long timeo;
1116 int err = 0;
1117
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001118 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119
1120 if (sk->sk_state != BT_LISTEN) {
1121 err = -EBADFD;
1122 goto done;
1123 }
1124
1125 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1126
1127 BT_DBG("sk %p timeo %ld", sk, timeo);
1128
1129 /* Wait for an incoming connection. (wake-one). */
1130 add_wait_queue_exclusive(sk->sk_sleep, &wait);
1131 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1132 set_current_state(TASK_INTERRUPTIBLE);
1133 if (!timeo) {
1134 err = -EAGAIN;
1135 break;
1136 }
1137
1138 release_sock(sk);
1139 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001140 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141
1142 if (sk->sk_state != BT_LISTEN) {
1143 err = -EBADFD;
1144 break;
1145 }
1146
1147 if (signal_pending(current)) {
1148 err = sock_intr_errno(timeo);
1149 break;
1150 }
1151 }
1152 set_current_state(TASK_RUNNING);
1153 remove_wait_queue(sk->sk_sleep, &wait);
1154
1155 if (err)
1156 goto done;
1157
1158 newsock->state = SS_CONNECTED;
1159
1160 BT_DBG("new socket %p", nsk);
1161
1162done:
1163 release_sock(sk);
1164 return err;
1165}
1166
1167static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1168{
1169 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1170 struct sock *sk = sock->sk;
1171
1172 BT_DBG("sock %p, sk %p", sock, sk);
1173
1174 addr->sa_family = AF_BLUETOOTH;
1175 *len = sizeof(struct sockaddr_l2);
1176
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001177 if (peer) {
1178 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001180 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001181 } else {
1182 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001184 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001185 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187 return 0;
1188}
1189
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001190static void l2cap_monitor_timeout(unsigned long arg)
1191{
1192 struct sock *sk = (void *) arg;
1193 u16 control;
1194
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001195 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001196 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
1197 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
1198 return;
1199 }
1200
1201 l2cap_pi(sk)->retry_count++;
1202 __mod_monitor_timer();
1203
1204 control = L2CAP_CTRL_POLL;
1205 control |= L2CAP_SUPER_RCV_READY;
1206 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001207 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001208}
1209
1210static void l2cap_retrans_timeout(unsigned long arg)
1211{
1212 struct sock *sk = (void *) arg;
1213 u16 control;
1214
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001215 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001216 l2cap_pi(sk)->retry_count = 1;
1217 __mod_monitor_timer();
1218
1219 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1220
1221 control = L2CAP_CTRL_POLL;
1222 control |= L2CAP_SUPER_RCV_READY;
1223 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001224 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001225}
1226
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001227static void l2cap_drop_acked_frames(struct sock *sk)
1228{
1229 struct sk_buff *skb;
1230
1231 while ((skb = skb_peek(TX_QUEUE(sk)))) {
1232 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1233 break;
1234
1235 skb = skb_dequeue(TX_QUEUE(sk));
1236 kfree_skb(skb);
1237
1238 l2cap_pi(sk)->unacked_frames--;
1239 }
1240
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001241 if (!l2cap_pi(sk)->unacked_frames)
1242 del_timer(&l2cap_pi(sk)->retrans_timer);
1243
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001244 return;
1245}
1246
1247static inline int l2cap_do_send(struct sock *sk, struct sk_buff *skb)
1248{
1249 struct l2cap_pinfo *pi = l2cap_pi(sk);
1250 int err;
1251
1252 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1253
1254 err = hci_send_acl(pi->conn->hcon, skb, 0);
1255 if (err < 0)
1256 kfree_skb(skb);
1257
1258 return err;
1259}
1260
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001261static int l2cap_streaming_send(struct sock *sk)
1262{
1263 struct sk_buff *skb, *tx_skb;
1264 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001265 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001266 int err;
1267
1268 while ((skb = sk->sk_send_head)) {
1269 tx_skb = skb_clone(skb, GFP_ATOMIC);
1270
1271 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1272 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1273 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1274
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001275 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) {
1276 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1277 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1278 }
1279
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001280 err = l2cap_do_send(sk, tx_skb);
1281 if (err < 0) {
1282 l2cap_send_disconn_req(pi->conn, sk);
1283 return err;
1284 }
1285
1286 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1287
1288 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1289 sk->sk_send_head = NULL;
1290 else
1291 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1292
1293 skb = skb_dequeue(TX_QUEUE(sk));
1294 kfree_skb(skb);
1295 }
1296 return 0;
1297}
1298
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001299static int l2cap_retransmit_frame(struct sock *sk, u8 tx_seq)
1300{
1301 struct l2cap_pinfo *pi = l2cap_pi(sk);
1302 struct sk_buff *skb, *tx_skb;
1303 u16 control, fcs;
1304 int err;
1305
1306 skb = skb_peek(TX_QUEUE(sk));
1307 do {
1308 if (bt_cb(skb)->tx_seq != tx_seq) {
1309 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1310 break;
1311 skb = skb_queue_next(TX_QUEUE(sk), skb);
1312 continue;
1313 }
1314
1315 if (pi->remote_max_tx &&
1316 bt_cb(skb)->retries == pi->remote_max_tx) {
1317 l2cap_send_disconn_req(pi->conn, sk);
1318 break;
1319 }
1320
1321 tx_skb = skb_clone(skb, GFP_ATOMIC);
1322 bt_cb(skb)->retries++;
1323 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1324 control |= (pi->req_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1325 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1326 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1327
1328 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) {
1329 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1330 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1331 }
1332
1333 err = l2cap_do_send(sk, tx_skb);
1334 if (err < 0) {
1335 l2cap_send_disconn_req(pi->conn, sk);
1336 return err;
1337 }
1338 break;
1339 } while(1);
1340 return 0;
1341}
1342
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001343static int l2cap_ertm_send(struct sock *sk)
1344{
1345 struct sk_buff *skb, *tx_skb;
1346 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001347 u16 control, fcs;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001348 int err;
1349
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001350 if (pi->conn_state & L2CAP_CONN_WAIT_F)
1351 return 0;
1352
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03001353 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))
1354 && !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001355 tx_skb = skb_clone(skb, GFP_ATOMIC);
1356
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001357 if (pi->remote_max_tx &&
1358 bt_cb(skb)->retries == pi->remote_max_tx) {
1359 l2cap_send_disconn_req(pi->conn, sk);
1360 break;
1361 }
1362
1363 bt_cb(skb)->retries++;
1364
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001365 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1366 control |= (pi->req_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1367 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1368 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1369
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001370
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001371 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) {
1372 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1373 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1374 }
1375
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001376 err = l2cap_do_send(sk, tx_skb);
1377 if (err < 0) {
1378 l2cap_send_disconn_req(pi->conn, sk);
1379 return err;
1380 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001381 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001382
1383 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1384 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1385
1386 pi->unacked_frames++;
1387
1388 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1389 sk->sk_send_head = NULL;
1390 else
1391 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1392 }
1393
1394 return 0;
1395}
1396
1397static 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 -07001398{
1399 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001400 struct sk_buff **frag;
1401 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402
1403 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001404 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405 }
1406
1407 sent += count;
1408 len -= count;
1409
1410 /* Continuation fragments (no L2CAP header) */
1411 frag = &skb_shinfo(skb)->frag_list;
1412 while (len) {
1413 count = min_t(unsigned int, conn->mtu, len);
1414
1415 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1416 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001417 return -EFAULT;
1418 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1419 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420
1421 sent += count;
1422 len -= count;
1423
1424 frag = &(*frag)->next;
1425 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426
1427 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001428}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001430static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1431{
1432 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1433 struct sk_buff *skb;
1434 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1435 struct l2cap_hdr *lh;
1436
1437 BT_DBG("sk %p len %d", sk, (int)len);
1438
1439 count = min_t(unsigned int, (conn->mtu - hlen), len);
1440 skb = bt_skb_send_alloc(sk, count + hlen,
1441 msg->msg_flags & MSG_DONTWAIT, &err);
1442 if (!skb)
1443 return ERR_PTR(-ENOMEM);
1444
1445 /* Create L2CAP header */
1446 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1447 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1448 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1449 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1450
1451 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1452 if (unlikely(err < 0)) {
1453 kfree_skb(skb);
1454 return ERR_PTR(err);
1455 }
1456 return skb;
1457}
1458
1459static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1460{
1461 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1462 struct sk_buff *skb;
1463 int err, count, hlen = L2CAP_HDR_SIZE;
1464 struct l2cap_hdr *lh;
1465
1466 BT_DBG("sk %p len %d", sk, (int)len);
1467
1468 count = min_t(unsigned int, (conn->mtu - hlen), len);
1469 skb = bt_skb_send_alloc(sk, count + hlen,
1470 msg->msg_flags & MSG_DONTWAIT, &err);
1471 if (!skb)
1472 return ERR_PTR(-ENOMEM);
1473
1474 /* Create L2CAP header */
1475 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1476 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1477 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1478
1479 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1480 if (unlikely(err < 0)) {
1481 kfree_skb(skb);
1482 return ERR_PTR(err);
1483 }
1484 return skb;
1485}
1486
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001487static 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 -03001488{
1489 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1490 struct sk_buff *skb;
1491 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1492 struct l2cap_hdr *lh;
1493
1494 BT_DBG("sk %p len %d", sk, (int)len);
1495
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001496 if (sdulen)
1497 hlen += 2;
1498
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001499 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1500 hlen += 2;
1501
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001502 count = min_t(unsigned int, (conn->mtu - hlen), len);
1503 skb = bt_skb_send_alloc(sk, count + hlen,
1504 msg->msg_flags & MSG_DONTWAIT, &err);
1505 if (!skb)
1506 return ERR_PTR(-ENOMEM);
1507
1508 /* Create L2CAP header */
1509 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1510 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1511 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1512 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001513 if (sdulen)
1514 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001515
1516 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1517 if (unlikely(err < 0)) {
1518 kfree_skb(skb);
1519 return ERR_PTR(err);
1520 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001521
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001522 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1523 put_unaligned_le16(0, skb_put(skb, 2));
1524
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001525 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001526 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527}
1528
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001529static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1530{
1531 struct l2cap_pinfo *pi = l2cap_pi(sk);
1532 struct sk_buff *skb;
1533 struct sk_buff_head sar_queue;
1534 u16 control;
1535 size_t size = 0;
1536
1537 __skb_queue_head_init(&sar_queue);
1538 control = L2CAP_SDU_START;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001539 skb = l2cap_create_iframe_pdu(sk, msg, pi->max_pdu_size, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001540 if (IS_ERR(skb))
1541 return PTR_ERR(skb);
1542
1543 __skb_queue_tail(&sar_queue, skb);
1544 len -= pi->max_pdu_size;
1545 size +=pi->max_pdu_size;
1546 control = 0;
1547
1548 while (len > 0) {
1549 size_t buflen;
1550
1551 if (len > pi->max_pdu_size) {
1552 control |= L2CAP_SDU_CONTINUE;
1553 buflen = pi->max_pdu_size;
1554 } else {
1555 control |= L2CAP_SDU_END;
1556 buflen = len;
1557 }
1558
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001559 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001560 if (IS_ERR(skb)) {
1561 skb_queue_purge(&sar_queue);
1562 return PTR_ERR(skb);
1563 }
1564
1565 __skb_queue_tail(&sar_queue, skb);
1566 len -= buflen;
1567 size += buflen;
1568 control = 0;
1569 }
1570 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1571 if (sk->sk_send_head == NULL)
1572 sk->sk_send_head = sar_queue.next;
1573
1574 return size;
1575}
1576
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1578{
1579 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001580 struct l2cap_pinfo *pi = l2cap_pi(sk);
1581 struct sk_buff *skb;
1582 u16 control;
1583 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584
1585 BT_DBG("sock %p, sk %p", sock, sk);
1586
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001587 err = sock_error(sk);
1588 if (err)
1589 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590
1591 if (msg->msg_flags & MSG_OOB)
1592 return -EOPNOTSUPP;
1593
1594 /* Check outgoing MTU */
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001595 if (sk->sk_type == SOCK_SEQPACKET && pi->mode == L2CAP_MODE_BASIC
1596 && len > pi->omtu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597 return -EINVAL;
1598
1599 lock_sock(sk);
1600
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001601 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001603 goto done;
1604 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001606 /* Connectionless channel */
1607 if (sk->sk_type == SOCK_DGRAM) {
1608 skb = l2cap_create_connless_pdu(sk, msg, len);
1609 err = l2cap_do_send(sk, skb);
1610 goto done;
1611 }
1612
1613 switch (pi->mode) {
1614 case L2CAP_MODE_BASIC:
1615 /* Create a basic PDU */
1616 skb = l2cap_create_basic_pdu(sk, msg, len);
1617 if (IS_ERR(skb)) {
1618 err = PTR_ERR(skb);
1619 goto done;
1620 }
1621
1622 err = l2cap_do_send(sk, skb);
1623 if (!err)
1624 err = len;
1625 break;
1626
1627 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001628 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001629 /* Entire SDU fits into one PDU */
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001630 if (len <= pi->max_pdu_size) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001631 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001632 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001633 if (IS_ERR(skb)) {
1634 err = PTR_ERR(skb);
1635 goto done;
1636 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001637 __skb_queue_tail(TX_QUEUE(sk), skb);
1638 if (sk->sk_send_head == NULL)
1639 sk->sk_send_head = skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001640 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001641 /* Segment SDU into multiples PDUs */
1642 err = l2cap_sar_segment_sdu(sk, msg, len);
1643 if (err < 0)
1644 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001645 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001646
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001647 if (pi->mode == L2CAP_MODE_STREAMING)
1648 err = l2cap_streaming_send(sk);
1649 else
1650 err = l2cap_ertm_send(sk);
1651
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001652 if (!err)
1653 err = len;
1654 break;
1655
1656 default:
1657 BT_DBG("bad state %1.1x", pi->mode);
1658 err = -EINVAL;
1659 }
1660
1661done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662 release_sock(sk);
1663 return err;
1664}
1665
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001666static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1667{
1668 struct sock *sk = sock->sk;
1669
1670 lock_sock(sk);
1671
1672 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1673 struct l2cap_conn_rsp rsp;
1674
1675 sk->sk_state = BT_CONFIG;
1676
1677 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1678 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1679 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1680 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1681 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1682 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1683
1684 release_sock(sk);
1685 return 0;
1686 }
1687
1688 release_sock(sk);
1689
1690 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1691}
1692
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001693static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694{
1695 struct sock *sk = sock->sk;
1696 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001697 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 u32 opt;
1699
1700 BT_DBG("sk %p", sk);
1701
1702 lock_sock(sk);
1703
1704 switch (optname) {
1705 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001706 opts.imtu = l2cap_pi(sk)->imtu;
1707 opts.omtu = l2cap_pi(sk)->omtu;
1708 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001709 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001710 opts.fcs = l2cap_pi(sk)->fcs;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001711
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712 len = min_t(unsigned int, sizeof(opts), optlen);
1713 if (copy_from_user((char *) &opts, optval, len)) {
1714 err = -EFAULT;
1715 break;
1716 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001717
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001718 l2cap_pi(sk)->imtu = opts.imtu;
1719 l2cap_pi(sk)->omtu = opts.omtu;
1720 l2cap_pi(sk)->mode = opts.mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001721 l2cap_pi(sk)->fcs = opts.fcs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 break;
1723
1724 case L2CAP_LM:
1725 if (get_user(opt, (u32 __user *) optval)) {
1726 err = -EFAULT;
1727 break;
1728 }
1729
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001730 if (opt & L2CAP_LM_AUTH)
1731 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1732 if (opt & L2CAP_LM_ENCRYPT)
1733 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1734 if (opt & L2CAP_LM_SECURE)
1735 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1736
1737 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1738 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 break;
1740
1741 default:
1742 err = -ENOPROTOOPT;
1743 break;
1744 }
1745
1746 release_sock(sk);
1747 return err;
1748}
1749
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001750static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
1751{
1752 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001753 struct bt_security sec;
1754 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001755 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001756
1757 BT_DBG("sk %p", sk);
1758
1759 if (level == SOL_L2CAP)
1760 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1761
Marcel Holtmann0588d942009-01-16 10:06:13 +01001762 if (level != SOL_BLUETOOTH)
1763 return -ENOPROTOOPT;
1764
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001765 lock_sock(sk);
1766
1767 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001768 case BT_SECURITY:
Marcel Holtmann2526d3d2009-02-20 20:54:06 +01001769 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001770 err = -EINVAL;
1771 break;
1772 }
1773
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001774 sec.level = BT_SECURITY_LOW;
1775
1776 len = min_t(unsigned int, sizeof(sec), optlen);
1777 if (copy_from_user((char *) &sec, optval, len)) {
1778 err = -EFAULT;
1779 break;
1780 }
1781
1782 if (sec.level < BT_SECURITY_LOW ||
1783 sec.level > BT_SECURITY_HIGH) {
1784 err = -EINVAL;
1785 break;
1786 }
1787
1788 l2cap_pi(sk)->sec_level = sec.level;
1789 break;
1790
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001791 case BT_DEFER_SETUP:
1792 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1793 err = -EINVAL;
1794 break;
1795 }
1796
1797 if (get_user(opt, (u32 __user *) optval)) {
1798 err = -EFAULT;
1799 break;
1800 }
1801
1802 bt_sk(sk)->defer_setup = opt;
1803 break;
1804
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001805 default:
1806 err = -ENOPROTOOPT;
1807 break;
1808 }
1809
1810 release_sock(sk);
1811 return err;
1812}
1813
1814static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815{
1816 struct sock *sk = sock->sk;
1817 struct l2cap_options opts;
1818 struct l2cap_conninfo cinfo;
1819 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001820 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821
1822 BT_DBG("sk %p", sk);
1823
1824 if (get_user(len, optlen))
1825 return -EFAULT;
1826
1827 lock_sock(sk);
1828
1829 switch (optname) {
1830 case L2CAP_OPTIONS:
1831 opts.imtu = l2cap_pi(sk)->imtu;
1832 opts.omtu = l2cap_pi(sk)->omtu;
1833 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001834 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001835 opts.fcs = l2cap_pi(sk)->fcs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836
1837 len = min_t(unsigned int, len, sizeof(opts));
1838 if (copy_to_user(optval, (char *) &opts, len))
1839 err = -EFAULT;
1840
1841 break;
1842
1843 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001844 switch (l2cap_pi(sk)->sec_level) {
1845 case BT_SECURITY_LOW:
1846 opt = L2CAP_LM_AUTH;
1847 break;
1848 case BT_SECURITY_MEDIUM:
1849 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
1850 break;
1851 case BT_SECURITY_HIGH:
1852 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
1853 L2CAP_LM_SECURE;
1854 break;
1855 default:
1856 opt = 0;
1857 break;
1858 }
1859
1860 if (l2cap_pi(sk)->role_switch)
1861 opt |= L2CAP_LM_MASTER;
1862
1863 if (l2cap_pi(sk)->force_reliable)
1864 opt |= L2CAP_LM_RELIABLE;
1865
1866 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867 err = -EFAULT;
1868 break;
1869
1870 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001871 if (sk->sk_state != BT_CONNECTED &&
1872 !(sk->sk_state == BT_CONNECT2 &&
1873 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001874 err = -ENOTCONN;
1875 break;
1876 }
1877
1878 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
1879 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
1880
1881 len = min_t(unsigned int, len, sizeof(cinfo));
1882 if (copy_to_user(optval, (char *) &cinfo, len))
1883 err = -EFAULT;
1884
1885 break;
1886
1887 default:
1888 err = -ENOPROTOOPT;
1889 break;
1890 }
1891
1892 release_sock(sk);
1893 return err;
1894}
1895
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001896static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
1897{
1898 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001899 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001900 int len, err = 0;
1901
1902 BT_DBG("sk %p", sk);
1903
1904 if (level == SOL_L2CAP)
1905 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
1906
Marcel Holtmann0588d942009-01-16 10:06:13 +01001907 if (level != SOL_BLUETOOTH)
1908 return -ENOPROTOOPT;
1909
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001910 if (get_user(len, optlen))
1911 return -EFAULT;
1912
1913 lock_sock(sk);
1914
1915 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001916 case BT_SECURITY:
Marcel Holtmann2526d3d2009-02-20 20:54:06 +01001917 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001918 err = -EINVAL;
1919 break;
1920 }
1921
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001922 sec.level = l2cap_pi(sk)->sec_level;
1923
1924 len = min_t(unsigned int, len, sizeof(sec));
1925 if (copy_to_user(optval, (char *) &sec, len))
1926 err = -EFAULT;
1927
1928 break;
1929
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001930 case BT_DEFER_SETUP:
1931 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1932 err = -EINVAL;
1933 break;
1934 }
1935
1936 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
1937 err = -EFAULT;
1938
1939 break;
1940
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001941 default:
1942 err = -ENOPROTOOPT;
1943 break;
1944 }
1945
1946 release_sock(sk);
1947 return err;
1948}
1949
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950static int l2cap_sock_shutdown(struct socket *sock, int how)
1951{
1952 struct sock *sk = sock->sk;
1953 int err = 0;
1954
1955 BT_DBG("sock %p, sk %p", sock, sk);
1956
1957 if (!sk)
1958 return 0;
1959
1960 lock_sock(sk);
1961 if (!sk->sk_shutdown) {
1962 sk->sk_shutdown = SHUTDOWN_MASK;
1963 l2cap_sock_clear_timer(sk);
1964 __l2cap_sock_close(sk, 0);
1965
1966 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001967 err = bt_sock_wait_state(sk, BT_CLOSED,
1968 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969 }
1970 release_sock(sk);
1971 return err;
1972}
1973
1974static int l2cap_sock_release(struct socket *sock)
1975{
1976 struct sock *sk = sock->sk;
1977 int err;
1978
1979 BT_DBG("sock %p, sk %p", sock, sk);
1980
1981 if (!sk)
1982 return 0;
1983
1984 err = l2cap_sock_shutdown(sock, 2);
1985
1986 sock_orphan(sk);
1987 l2cap_sock_kill(sk);
1988 return err;
1989}
1990
Linus Torvalds1da177e2005-04-16 15:20:36 -07001991static void l2cap_chan_ready(struct sock *sk)
1992{
1993 struct sock *parent = bt_sk(sk)->parent;
1994
1995 BT_DBG("sk %p, parent %p", sk, parent);
1996
1997 l2cap_pi(sk)->conf_state = 0;
1998 l2cap_sock_clear_timer(sk);
1999
2000 if (!parent) {
2001 /* Outgoing channel.
2002 * Wake up socket sleeping on connect.
2003 */
2004 sk->sk_state = BT_CONNECTED;
2005 sk->sk_state_change(sk);
2006 } else {
2007 /* Incoming channel.
2008 * Wake up socket sleeping on accept.
2009 */
2010 parent->sk_data_ready(parent, 0);
2011 }
2012}
2013
2014/* Copy frame to all raw sockets on that connection */
2015static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2016{
2017 struct l2cap_chan_list *l = &conn->chan_list;
2018 struct sk_buff *nskb;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002019 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020
2021 BT_DBG("conn %p", conn);
2022
2023 read_lock(&l->lock);
2024 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2025 if (sk->sk_type != SOCK_RAW)
2026 continue;
2027
2028 /* Don't send frame to the socket it came from */
2029 if (skb->sk == sk)
2030 continue;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002031 nskb = skb_clone(skb, GFP_ATOMIC);
2032 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002033 continue;
2034
2035 if (sock_queue_rcv_skb(sk, nskb))
2036 kfree_skb(nskb);
2037 }
2038 read_unlock(&l->lock);
2039}
2040
2041/* ---- L2CAP signalling commands ---- */
2042static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2043 u8 code, u8 ident, u16 dlen, void *data)
2044{
2045 struct sk_buff *skb, **frag;
2046 struct l2cap_cmd_hdr *cmd;
2047 struct l2cap_hdr *lh;
2048 int len, count;
2049
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002050 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2051 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002052
2053 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2054 count = min_t(unsigned int, conn->mtu, len);
2055
2056 skb = bt_skb_alloc(count, GFP_ATOMIC);
2057 if (!skb)
2058 return NULL;
2059
2060 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002061 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002062 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002063
2064 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2065 cmd->code = code;
2066 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002067 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002068
2069 if (dlen) {
2070 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2071 memcpy(skb_put(skb, count), data, count);
2072 data += count;
2073 }
2074
2075 len -= skb->len;
2076
2077 /* Continuation fragments (no L2CAP header) */
2078 frag = &skb_shinfo(skb)->frag_list;
2079 while (len) {
2080 count = min_t(unsigned int, conn->mtu, len);
2081
2082 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2083 if (!*frag)
2084 goto fail;
2085
2086 memcpy(skb_put(*frag, count), data, count);
2087
2088 len -= count;
2089 data += count;
2090
2091 frag = &(*frag)->next;
2092 }
2093
2094 return skb;
2095
2096fail:
2097 kfree_skb(skb);
2098 return NULL;
2099}
2100
2101static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2102{
2103 struct l2cap_conf_opt *opt = *ptr;
2104 int len;
2105
2106 len = L2CAP_CONF_OPT_SIZE + opt->len;
2107 *ptr += len;
2108
2109 *type = opt->type;
2110 *olen = opt->len;
2111
2112 switch (opt->len) {
2113 case 1:
2114 *val = *((u8 *) opt->val);
2115 break;
2116
2117 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002118 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002119 break;
2120
2121 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002122 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002123 break;
2124
2125 default:
2126 *val = (unsigned long) opt->val;
2127 break;
2128 }
2129
2130 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2131 return len;
2132}
2133
Linus Torvalds1da177e2005-04-16 15:20:36 -07002134static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2135{
2136 struct l2cap_conf_opt *opt = *ptr;
2137
2138 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2139
2140 opt->type = type;
2141 opt->len = len;
2142
2143 switch (len) {
2144 case 1:
2145 *((u8 *) opt->val) = val;
2146 break;
2147
2148 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002149 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002150 break;
2151
2152 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002153 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002154 break;
2155
2156 default:
2157 memcpy(opt->val, (void *) val, len);
2158 break;
2159 }
2160
2161 *ptr += L2CAP_CONF_OPT_SIZE + len;
2162}
2163
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002164static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2165{
2166 u32 local_feat_mask = l2cap_feat_mask;
2167 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002168 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002169
2170 switch (mode) {
2171 case L2CAP_MODE_ERTM:
2172 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2173 case L2CAP_MODE_STREAMING:
2174 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2175 default:
2176 return 0x00;
2177 }
2178}
2179
2180static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2181{
2182 switch (mode) {
2183 case L2CAP_MODE_STREAMING:
2184 case L2CAP_MODE_ERTM:
2185 if (l2cap_mode_supported(mode, remote_feat_mask))
2186 return mode;
2187 /* fall through */
2188 default:
2189 return L2CAP_MODE_BASIC;
2190 }
2191}
2192
Linus Torvalds1da177e2005-04-16 15:20:36 -07002193static int l2cap_build_conf_req(struct sock *sk, void *data)
2194{
2195 struct l2cap_pinfo *pi = l2cap_pi(sk);
2196 struct l2cap_conf_req *req = data;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002197 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_ERTM };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002198 void *ptr = req->data;
2199
2200 BT_DBG("sk %p", sk);
2201
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002202 if (pi->num_conf_req || pi->num_conf_rsp)
2203 goto done;
2204
2205 switch (pi->mode) {
2206 case L2CAP_MODE_STREAMING:
2207 case L2CAP_MODE_ERTM:
2208 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002209 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2210 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002211 break;
2212 default:
2213 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2214 break;
2215 }
2216
2217done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002218 switch (pi->mode) {
2219 case L2CAP_MODE_BASIC:
2220 if (pi->imtu != L2CAP_DEFAULT_MTU)
2221 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2222 break;
2223
2224 case L2CAP_MODE_ERTM:
2225 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002226 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002227 rfc.max_transmit = L2CAP_DEFAULT_MAX_TX;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002228 rfc.retrans_timeout = 0;
2229 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002230 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002231
2232 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2233 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002234
2235 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2236 break;
2237
2238 if (pi->fcs == L2CAP_FCS_NONE ||
2239 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2240 pi->fcs = L2CAP_FCS_NONE;
2241 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2242 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002243 break;
2244
2245 case L2CAP_MODE_STREAMING:
2246 rfc.mode = L2CAP_MODE_STREAMING;
2247 rfc.txwin_size = 0;
2248 rfc.max_transmit = 0;
2249 rfc.retrans_timeout = 0;
2250 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002251 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002252
2253 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2254 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002255
2256 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2257 break;
2258
2259 if (pi->fcs == L2CAP_FCS_NONE ||
2260 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2261 pi->fcs = L2CAP_FCS_NONE;
2262 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2263 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002264 break;
2265 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002266
2267 /* FIXME: Need actual value of the flush timeout */
2268 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2269 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2270
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002271 req->dcid = cpu_to_le16(pi->dcid);
2272 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002273
2274 return ptr - data;
2275}
2276
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002277static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002278{
2279 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002280 struct l2cap_conf_rsp *rsp = data;
2281 void *ptr = rsp->data;
2282 void *req = pi->conf_req;
2283 int len = pi->conf_len;
2284 int type, hint, olen;
2285 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002286 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002287 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002288 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002289
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002290 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002291
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002292 while (len >= L2CAP_CONF_OPT_SIZE) {
2293 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002294
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002295 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002296 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002297
2298 switch (type) {
2299 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002300 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002301 break;
2302
2303 case L2CAP_CONF_FLUSH_TO:
2304 pi->flush_to = val;
2305 break;
2306
2307 case L2CAP_CONF_QOS:
2308 break;
2309
Marcel Holtmann6464f352007-10-20 13:39:51 +02002310 case L2CAP_CONF_RFC:
2311 if (olen == sizeof(rfc))
2312 memcpy(&rfc, (void *) val, olen);
2313 break;
2314
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002315 case L2CAP_CONF_FCS:
2316 if (val == L2CAP_FCS_NONE)
2317 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2318
2319 break;
2320
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002321 default:
2322 if (hint)
2323 break;
2324
2325 result = L2CAP_CONF_UNKNOWN;
2326 *((u8 *) ptr++) = type;
2327 break;
2328 }
2329 }
2330
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002331 if (pi->num_conf_rsp || pi->num_conf_req)
2332 goto done;
2333
2334 switch (pi->mode) {
2335 case L2CAP_MODE_STREAMING:
2336 case L2CAP_MODE_ERTM:
2337 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2338 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2339 return -ECONNREFUSED;
2340 break;
2341 default:
2342 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2343 break;
2344 }
2345
2346done:
2347 if (pi->mode != rfc.mode) {
2348 result = L2CAP_CONF_UNACCEPT;
2349 rfc.mode = pi->mode;
2350
2351 if (pi->num_conf_rsp == 1)
2352 return -ECONNREFUSED;
2353
2354 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2355 sizeof(rfc), (unsigned long) &rfc);
2356 }
2357
2358
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002359 if (result == L2CAP_CONF_SUCCESS) {
2360 /* Configure output options and let the other side know
2361 * which ones we don't like. */
2362
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002363 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2364 result = L2CAP_CONF_UNACCEPT;
2365 else {
2366 pi->omtu = mtu;
2367 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2368 }
2369 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002370
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002371 switch (rfc.mode) {
2372 case L2CAP_MODE_BASIC:
2373 pi->fcs = L2CAP_FCS_NONE;
2374 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2375 break;
2376
2377 case L2CAP_MODE_ERTM:
2378 pi->remote_tx_win = rfc.txwin_size;
2379 pi->remote_max_tx = rfc.max_transmit;
2380 pi->max_pdu_size = rfc.max_pdu_size;
2381
2382 rfc.retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
2383 rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
2384
2385 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2386 break;
2387
2388 case L2CAP_MODE_STREAMING:
2389 pi->remote_tx_win = rfc.txwin_size;
2390 pi->max_pdu_size = rfc.max_pdu_size;
2391
2392 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2393 break;
2394
2395 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002396 result = L2CAP_CONF_UNACCEPT;
2397
2398 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002399 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002400 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002401
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002402 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2403 sizeof(rfc), (unsigned long) &rfc);
2404
2405 if (result == L2CAP_CONF_SUCCESS)
2406 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2407 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002408 rsp->scid = cpu_to_le16(pi->dcid);
2409 rsp->result = cpu_to_le16(result);
2410 rsp->flags = cpu_to_le16(0x0000);
2411
2412 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002413}
2414
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002415static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2416{
2417 struct l2cap_pinfo *pi = l2cap_pi(sk);
2418 struct l2cap_conf_req *req = data;
2419 void *ptr = req->data;
2420 int type, olen;
2421 unsigned long val;
2422 struct l2cap_conf_rfc rfc;
2423
2424 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2425
2426 while (len >= L2CAP_CONF_OPT_SIZE) {
2427 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2428
2429 switch (type) {
2430 case L2CAP_CONF_MTU:
2431 if (val < L2CAP_DEFAULT_MIN_MTU) {
2432 *result = L2CAP_CONF_UNACCEPT;
2433 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2434 } else
2435 pi->omtu = val;
2436 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2437 break;
2438
2439 case L2CAP_CONF_FLUSH_TO:
2440 pi->flush_to = val;
2441 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2442 2, pi->flush_to);
2443 break;
2444
2445 case L2CAP_CONF_RFC:
2446 if (olen == sizeof(rfc))
2447 memcpy(&rfc, (void *)val, olen);
2448
2449 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2450 rfc.mode != pi->mode)
2451 return -ECONNREFUSED;
2452
2453 pi->mode = rfc.mode;
2454 pi->fcs = 0;
2455
2456 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2457 sizeof(rfc), (unsigned long) &rfc);
2458 break;
2459 }
2460 }
2461
2462 if (*result == L2CAP_CONF_SUCCESS) {
2463 switch (rfc.mode) {
2464 case L2CAP_MODE_ERTM:
2465 pi->remote_tx_win = rfc.txwin_size;
2466 pi->retrans_timeout = rfc.retrans_timeout;
2467 pi->monitor_timeout = rfc.monitor_timeout;
2468 pi->max_pdu_size = le16_to_cpu(rfc.max_pdu_size);
2469 break;
2470 case L2CAP_MODE_STREAMING:
2471 pi->max_pdu_size = le16_to_cpu(rfc.max_pdu_size);
2472 break;
2473 }
2474 }
2475
2476 req->dcid = cpu_to_le16(pi->dcid);
2477 req->flags = cpu_to_le16(0x0000);
2478
2479 return ptr - data;
2480}
2481
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002482static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002483{
2484 struct l2cap_conf_rsp *rsp = data;
2485 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002486
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002487 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002488
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002489 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002490 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002491 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002492
2493 return ptr - data;
2494}
2495
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002496static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2497{
2498 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2499
2500 if (rej->reason != 0x0000)
2501 return 0;
2502
2503 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2504 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002505 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002506
2507 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002508 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002509
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002510 l2cap_conn_start(conn);
2511 }
2512
2513 return 0;
2514}
2515
Linus Torvalds1da177e2005-04-16 15:20:36 -07002516static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2517{
2518 struct l2cap_chan_list *list = &conn->chan_list;
2519 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2520 struct l2cap_conn_rsp rsp;
2521 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002522 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002523
2524 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002525 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002526
2527 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2528
2529 /* Check if we have socket listening on psm */
2530 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2531 if (!parent) {
2532 result = L2CAP_CR_BAD_PSM;
2533 goto sendresp;
2534 }
2535
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002536 /* Check if the ACL is secure enough (if not SDP) */
2537 if (psm != cpu_to_le16(0x0001) &&
2538 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002539 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002540 result = L2CAP_CR_SEC_BLOCK;
2541 goto response;
2542 }
2543
Linus Torvalds1da177e2005-04-16 15:20:36 -07002544 result = L2CAP_CR_NO_MEM;
2545
2546 /* Check for backlog size */
2547 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002548 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002549 goto response;
2550 }
2551
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002552 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002553 if (!sk)
2554 goto response;
2555
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002556 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002557
2558 /* Check if we already have channel with that dcid */
2559 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002560 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002561 sock_set_flag(sk, SOCK_ZAPPED);
2562 l2cap_sock_kill(sk);
2563 goto response;
2564 }
2565
2566 hci_conn_hold(conn->hcon);
2567
2568 l2cap_sock_init(sk, parent);
2569 bacpy(&bt_sk(sk)->src, conn->src);
2570 bacpy(&bt_sk(sk)->dst, conn->dst);
2571 l2cap_pi(sk)->psm = psm;
2572 l2cap_pi(sk)->dcid = scid;
2573
2574 __l2cap_chan_add(conn, sk, parent);
2575 dcid = l2cap_pi(sk)->scid;
2576
2577 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2578
Linus Torvalds1da177e2005-04-16 15:20:36 -07002579 l2cap_pi(sk)->ident = cmd->ident;
2580
Marcel Holtmann984947d2009-02-06 23:35:19 +01002581 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002582 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002583 if (bt_sk(sk)->defer_setup) {
2584 sk->sk_state = BT_CONNECT2;
2585 result = L2CAP_CR_PEND;
2586 status = L2CAP_CS_AUTHOR_PEND;
2587 parent->sk_data_ready(parent, 0);
2588 } else {
2589 sk->sk_state = BT_CONFIG;
2590 result = L2CAP_CR_SUCCESS;
2591 status = L2CAP_CS_NO_INFO;
2592 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002593 } else {
2594 sk->sk_state = BT_CONNECT2;
2595 result = L2CAP_CR_PEND;
2596 status = L2CAP_CS_AUTHEN_PEND;
2597 }
2598 } else {
2599 sk->sk_state = BT_CONNECT2;
2600 result = L2CAP_CR_PEND;
2601 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002602 }
2603
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002604 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002605
2606response:
2607 bh_unlock_sock(parent);
2608
2609sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002610 rsp.scid = cpu_to_le16(scid);
2611 rsp.dcid = cpu_to_le16(dcid);
2612 rsp.result = cpu_to_le16(result);
2613 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002614 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002615
2616 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2617 struct l2cap_info_req info;
2618 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2619
2620 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2621 conn->info_ident = l2cap_get_ident(conn);
2622
2623 mod_timer(&conn->info_timer, jiffies +
2624 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2625
2626 l2cap_send_cmd(conn, conn->info_ident,
2627 L2CAP_INFO_REQ, sizeof(info), &info);
2628 }
2629
Linus Torvalds1da177e2005-04-16 15:20:36 -07002630 return 0;
2631}
2632
2633static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2634{
2635 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2636 u16 scid, dcid, result, status;
2637 struct sock *sk;
2638 u8 req[128];
2639
2640 scid = __le16_to_cpu(rsp->scid);
2641 dcid = __le16_to_cpu(rsp->dcid);
2642 result = __le16_to_cpu(rsp->result);
2643 status = __le16_to_cpu(rsp->status);
2644
2645 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2646
2647 if (scid) {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002648 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2649 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002650 return 0;
2651 } else {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002652 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2653 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002654 return 0;
2655 }
2656
2657 switch (result) {
2658 case L2CAP_CR_SUCCESS:
2659 sk->sk_state = BT_CONFIG;
2660 l2cap_pi(sk)->ident = 0;
2661 l2cap_pi(sk)->dcid = dcid;
2662 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2663
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002664 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2665
Linus Torvalds1da177e2005-04-16 15:20:36 -07002666 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2667 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002668 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002669 break;
2670
2671 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002672 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002673 break;
2674
2675 default:
2676 l2cap_chan_del(sk, ECONNREFUSED);
2677 break;
2678 }
2679
2680 bh_unlock_sock(sk);
2681 return 0;
2682}
2683
Al Viro88219a02007-07-29 00:17:25 -07002684static 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 -07002685{
2686 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2687 u16 dcid, flags;
2688 u8 rsp[64];
2689 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002690 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002691
2692 dcid = __le16_to_cpu(req->dcid);
2693 flags = __le16_to_cpu(req->flags);
2694
2695 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2696
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002697 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2698 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002699 return -ENOENT;
2700
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002701 if (sk->sk_state == BT_DISCONN)
2702 goto unlock;
2703
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002704 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002705 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002706 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2707 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2708 l2cap_build_conf_rsp(sk, rsp,
2709 L2CAP_CONF_REJECT, flags), rsp);
2710 goto unlock;
2711 }
2712
2713 /* Store config. */
2714 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2715 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002716
2717 if (flags & 0x0001) {
2718 /* Incomplete config. Send empty response. */
2719 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002720 l2cap_build_conf_rsp(sk, rsp,
2721 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002722 goto unlock;
2723 }
2724
2725 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002726 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002727 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002728 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002729 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002730 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002731
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002732 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002733 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002734
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002735 /* Reset config buffer. */
2736 l2cap_pi(sk)->conf_len = 0;
2737
Marcel Holtmann876d9482007-10-20 13:35:42 +02002738 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2739 goto unlock;
2740
Linus Torvalds1da177e2005-04-16 15:20:36 -07002741 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002742 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV)
2743 || l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
2744 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2745
Linus Torvalds1da177e2005-04-16 15:20:36 -07002746 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002747 l2cap_pi(sk)->next_tx_seq = 0;
2748 l2cap_pi(sk)->expected_ack_seq = 0;
2749 l2cap_pi(sk)->unacked_frames = 0;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002750
2751 setup_timer(&l2cap_pi(sk)->retrans_timer,
2752 l2cap_retrans_timeout, (unsigned long) sk);
2753 setup_timer(&l2cap_pi(sk)->monitor_timer,
2754 l2cap_monitor_timeout, (unsigned long) sk);
2755
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002756 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002757 __skb_queue_head_init(SREJ_QUEUE(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002758 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002759 goto unlock;
2760 }
2761
2762 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002763 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002764 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002765 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002766 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002767 }
2768
2769unlock:
2770 bh_unlock_sock(sk);
2771 return 0;
2772}
2773
2774static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2775{
2776 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2777 u16 scid, flags, result;
2778 struct sock *sk;
2779
2780 scid = __le16_to_cpu(rsp->scid);
2781 flags = __le16_to_cpu(rsp->flags);
2782 result = __le16_to_cpu(rsp->result);
2783
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002784 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2785 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002786
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002787 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2788 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002789 return 0;
2790
2791 switch (result) {
2792 case L2CAP_CONF_SUCCESS:
2793 break;
2794
2795 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002796 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
2797 int len = cmd->len - sizeof(*rsp);
2798 char req[64];
2799
2800 /* throw out any old stored conf requests */
2801 result = L2CAP_CONF_SUCCESS;
2802 len = l2cap_parse_conf_rsp(sk, rsp->data,
2803 len, req, &result);
2804 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002805 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002806 goto done;
2807 }
2808
2809 l2cap_send_cmd(conn, l2cap_get_ident(conn),
2810 L2CAP_CONF_REQ, len, req);
2811 l2cap_pi(sk)->num_conf_req++;
2812 if (result != L2CAP_CONF_SUCCESS)
2813 goto done;
2814 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002815 }
2816
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002817 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002818 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002819 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002820 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002821 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002822 goto done;
2823 }
2824
2825 if (flags & 0x01)
2826 goto done;
2827
Linus Torvalds1da177e2005-04-16 15:20:36 -07002828 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
2829
2830 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002831 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV)
2832 || l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
2833 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2834
Linus Torvalds1da177e2005-04-16 15:20:36 -07002835 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002836 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002837 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002838 l2cap_pi(sk)->num_to_ack = 0;
2839 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002840 __skb_queue_head_init(SREJ_QUEUE(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002841 l2cap_chan_ready(sk);
2842 }
2843
2844done:
2845 bh_unlock_sock(sk);
2846 return 0;
2847}
2848
2849static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2850{
2851 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
2852 struct l2cap_disconn_rsp rsp;
2853 u16 dcid, scid;
2854 struct sock *sk;
2855
2856 scid = __le16_to_cpu(req->scid);
2857 dcid = __le16_to_cpu(req->dcid);
2858
2859 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
2860
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002861 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2862 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002863 return 0;
2864
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002865 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
2866 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002867 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
2868
2869 sk->sk_shutdown = SHUTDOWN_MASK;
2870
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002871 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002872 skb_queue_purge(SREJ_QUEUE(sk));
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002873 del_timer(&l2cap_pi(sk)->retrans_timer);
2874 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002875
Linus Torvalds1da177e2005-04-16 15:20:36 -07002876 l2cap_chan_del(sk, ECONNRESET);
2877 bh_unlock_sock(sk);
2878
2879 l2cap_sock_kill(sk);
2880 return 0;
2881}
2882
2883static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2884{
2885 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
2886 u16 dcid, scid;
2887 struct sock *sk;
2888
2889 scid = __le16_to_cpu(rsp->scid);
2890 dcid = __le16_to_cpu(rsp->dcid);
2891
2892 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
2893
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002894 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2895 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002896 return 0;
2897
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002898 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002899 skb_queue_purge(SREJ_QUEUE(sk));
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002900 del_timer(&l2cap_pi(sk)->retrans_timer);
2901 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002902
Linus Torvalds1da177e2005-04-16 15:20:36 -07002903 l2cap_chan_del(sk, 0);
2904 bh_unlock_sock(sk);
2905
2906 l2cap_sock_kill(sk);
2907 return 0;
2908}
2909
2910static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2911{
2912 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002913 u16 type;
2914
2915 type = __le16_to_cpu(req->type);
2916
2917 BT_DBG("type 0x%4.4x", type);
2918
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002919 if (type == L2CAP_IT_FEAT_MASK) {
2920 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07002921 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002922 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2923 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2924 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07002925 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002926 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
2927 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03002928 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002929 l2cap_send_cmd(conn, cmd->ident,
2930 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002931 } else if (type == L2CAP_IT_FIXED_CHAN) {
2932 u8 buf[12];
2933 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2934 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
2935 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
2936 memcpy(buf + 4, l2cap_fixed_chan, 8);
2937 l2cap_send_cmd(conn, cmd->ident,
2938 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002939 } else {
2940 struct l2cap_info_rsp rsp;
2941 rsp.type = cpu_to_le16(type);
2942 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
2943 l2cap_send_cmd(conn, cmd->ident,
2944 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
2945 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002946
2947 return 0;
2948}
2949
2950static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2951{
2952 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
2953 u16 type, result;
2954
2955 type = __le16_to_cpu(rsp->type);
2956 result = __le16_to_cpu(rsp->result);
2957
2958 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
2959
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002960 del_timer(&conn->info_timer);
2961
Marcel Holtmann984947d2009-02-06 23:35:19 +01002962 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07002963 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002964
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002965 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002966 struct l2cap_info_req req;
2967 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
2968
2969 conn->info_ident = l2cap_get_ident(conn);
2970
2971 l2cap_send_cmd(conn, conn->info_ident,
2972 L2CAP_INFO_REQ, sizeof(req), &req);
2973 } else {
2974 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
2975 conn->info_ident = 0;
2976
2977 l2cap_conn_start(conn);
2978 }
2979 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01002980 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002981 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002982
2983 l2cap_conn_start(conn);
2984 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002985
Linus Torvalds1da177e2005-04-16 15:20:36 -07002986 return 0;
2987}
2988
2989static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
2990{
2991 u8 *data = skb->data;
2992 int len = skb->len;
2993 struct l2cap_cmd_hdr cmd;
2994 int err = 0;
2995
2996 l2cap_raw_recv(conn, skb);
2997
2998 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07002999 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003000 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3001 data += L2CAP_CMD_HDR_SIZE;
3002 len -= L2CAP_CMD_HDR_SIZE;
3003
Al Viro88219a02007-07-29 00:17:25 -07003004 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003005
Al Viro88219a02007-07-29 00:17:25 -07003006 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 -07003007
Al Viro88219a02007-07-29 00:17:25 -07003008 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003009 BT_DBG("corrupted command");
3010 break;
3011 }
3012
3013 switch (cmd.code) {
3014 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003015 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003016 break;
3017
3018 case L2CAP_CONN_REQ:
3019 err = l2cap_connect_req(conn, &cmd, data);
3020 break;
3021
3022 case L2CAP_CONN_RSP:
3023 err = l2cap_connect_rsp(conn, &cmd, data);
3024 break;
3025
3026 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003027 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003028 break;
3029
3030 case L2CAP_CONF_RSP:
3031 err = l2cap_config_rsp(conn, &cmd, data);
3032 break;
3033
3034 case L2CAP_DISCONN_REQ:
3035 err = l2cap_disconnect_req(conn, &cmd, data);
3036 break;
3037
3038 case L2CAP_DISCONN_RSP:
3039 err = l2cap_disconnect_rsp(conn, &cmd, data);
3040 break;
3041
3042 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003043 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003044 break;
3045
3046 case L2CAP_ECHO_RSP:
3047 break;
3048
3049 case L2CAP_INFO_REQ:
3050 err = l2cap_information_req(conn, &cmd, data);
3051 break;
3052
3053 case L2CAP_INFO_RSP:
3054 err = l2cap_information_rsp(conn, &cmd, data);
3055 break;
3056
3057 default:
3058 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3059 err = -EINVAL;
3060 break;
3061 }
3062
3063 if (err) {
3064 struct l2cap_cmd_rej rej;
3065 BT_DBG("error %d", err);
3066
3067 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003068 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003069 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3070 }
3071
Al Viro88219a02007-07-29 00:17:25 -07003072 data += cmd_len;
3073 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003074 }
3075
3076 kfree_skb(skb);
3077}
3078
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003079static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3080{
3081 u16 our_fcs, rcv_fcs;
3082 int hdr_size = L2CAP_HDR_SIZE + 2;
3083
3084 if (pi->fcs == L2CAP_FCS_CRC16) {
3085 skb_trim(skb, skb->len - 2);
3086 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3087 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3088
3089 if (our_fcs != rcv_fcs)
3090 return -EINVAL;
3091 }
3092 return 0;
3093}
3094
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003095static void l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
3096{
3097 struct sk_buff *next_skb;
3098
3099 bt_cb(skb)->tx_seq = tx_seq;
3100 bt_cb(skb)->sar = sar;
3101
3102 next_skb = skb_peek(SREJ_QUEUE(sk));
3103 if (!next_skb) {
3104 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3105 return;
3106 }
3107
3108 do {
3109 if (bt_cb(next_skb)->tx_seq > tx_seq) {
3110 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
3111 return;
3112 }
3113
3114 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3115 break;
3116
3117 } while((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
3118
3119 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3120}
3121
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003122static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3123{
3124 struct l2cap_pinfo *pi = l2cap_pi(sk);
3125 struct sk_buff *_skb;
3126 int err = -EINVAL;
3127
3128 switch (control & L2CAP_CTRL_SAR) {
3129 case L2CAP_SDU_UNSEGMENTED:
3130 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3131 kfree_skb(pi->sdu);
3132 break;
3133 }
3134
3135 err = sock_queue_rcv_skb(sk, skb);
3136 if (!err)
3137 return 0;
3138
3139 break;
3140
3141 case L2CAP_SDU_START:
3142 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3143 kfree_skb(pi->sdu);
3144 break;
3145 }
3146
3147 pi->sdu_len = get_unaligned_le16(skb->data);
3148 skb_pull(skb, 2);
3149
3150 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3151 if (!pi->sdu) {
3152 err = -ENOMEM;
3153 break;
3154 }
3155
3156 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3157
3158 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3159 pi->partial_sdu_len = skb->len;
3160 err = 0;
3161 break;
3162
3163 case L2CAP_SDU_CONTINUE:
3164 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3165 break;
3166
3167 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3168
3169 pi->partial_sdu_len += skb->len;
3170 if (pi->partial_sdu_len > pi->sdu_len)
3171 kfree_skb(pi->sdu);
3172 else
3173 err = 0;
3174
3175 break;
3176
3177 case L2CAP_SDU_END:
3178 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3179 break;
3180
3181 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3182
3183 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3184 pi->partial_sdu_len += skb->len;
3185
3186 if (pi->partial_sdu_len == pi->sdu_len) {
3187 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3188 err = sock_queue_rcv_skb(sk, _skb);
3189 if (err < 0)
3190 kfree_skb(_skb);
3191 }
3192 kfree_skb(pi->sdu);
3193 err = 0;
3194
3195 break;
3196 }
3197
3198 kfree_skb(skb);
3199 return err;
3200}
3201
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003202static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3203{
3204 struct sk_buff *skb;
3205 u16 control = 0;
3206
3207 while((skb = skb_peek(SREJ_QUEUE(sk)))) {
3208 if (bt_cb(skb)->tx_seq != tx_seq)
3209 break;
3210
3211 skb = skb_dequeue(SREJ_QUEUE(sk));
3212 control |= bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3213 l2cap_sar_reassembly_sdu(sk, skb, control);
3214 l2cap_pi(sk)->buffer_seq_srej =
3215 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
3216 tx_seq++;
3217 }
3218}
3219
3220static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3221{
3222 struct l2cap_pinfo *pi = l2cap_pi(sk);
3223 struct srej_list *l, *tmp;
3224 u16 control;
3225
3226 list_for_each_entry_safe(l,tmp, SREJ_LIST(sk), list) {
3227 if (l->tx_seq == tx_seq) {
3228 list_del(&l->list);
3229 kfree(l);
3230 return;
3231 }
3232 control = L2CAP_SUPER_SELECT_REJECT;
3233 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3234 l2cap_send_sframe(pi, control);
3235 list_del(&l->list);
3236 list_add_tail(&l->list, SREJ_LIST(sk));
3237 }
3238}
3239
3240static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3241{
3242 struct l2cap_pinfo *pi = l2cap_pi(sk);
3243 struct srej_list *new;
3244 u16 control;
3245
3246 while (tx_seq != pi->expected_tx_seq) {
3247 control = L2CAP_SUPER_SELECT_REJECT;
3248 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003249 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
3250 control |= L2CAP_CTRL_POLL;
3251 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
3252 }
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003253 l2cap_send_sframe(pi, control);
3254
3255 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
3256 new->tx_seq = pi->expected_tx_seq++;
3257 list_add_tail(&new->list, SREJ_LIST(sk));
3258 }
3259 pi->expected_tx_seq++;
3260}
3261
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003262static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3263{
3264 struct l2cap_pinfo *pi = l2cap_pi(sk);
3265 u8 tx_seq = __get_txseq(rx_control);
3266 u16 tx_control = 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003267 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003268 int err = 0;
3269
3270 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3271
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003272 if (tx_seq == pi->expected_tx_seq)
3273 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003274
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003275 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3276 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003277
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003278 first = list_first_entry(SREJ_LIST(sk),
3279 struct srej_list, list);
3280 if (tx_seq == first->tx_seq) {
3281 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3282 l2cap_check_srej_gap(sk, tx_seq);
3283
3284 list_del(&first->list);
3285 kfree(first);
3286
3287 if (list_empty(SREJ_LIST(sk))) {
3288 pi->buffer_seq = pi->buffer_seq_srej;
3289 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
3290 }
3291 } else {
3292 struct srej_list *l;
3293 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3294
3295 list_for_each_entry(l, SREJ_LIST(sk), list) {
3296 if (l->tx_seq == tx_seq) {
3297 l2cap_resend_srejframe(sk, tx_seq);
3298 return 0;
3299 }
3300 }
3301 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003302 }
3303 } else {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003304 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003305
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003306 INIT_LIST_HEAD(SREJ_LIST(sk));
3307 pi->buffer_seq_srej = pi->buffer_seq;
3308
3309 __skb_queue_head_init(SREJ_QUEUE(sk));
3310 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3311
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003312 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3313
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003314 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003315 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003316 return 0;
3317
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003318expected:
3319 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3320
3321 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3322 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3323 return 0;
3324 }
3325
3326 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3327
3328 err = l2cap_sar_reassembly_sdu(sk, skb, rx_control);
3329 if (err < 0)
3330 return err;
3331
3332 pi->num_to_ack = (pi->num_to_ack + 1) % L2CAP_DEFAULT_NUM_TO_ACK;
3333 if (pi->num_to_ack == L2CAP_DEFAULT_NUM_TO_ACK - 1) {
3334 tx_control |= L2CAP_SUPER_RCV_READY;
3335 tx_control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3336 l2cap_send_sframe(pi, tx_control);
3337 }
3338 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003339}
3340
3341static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3342{
3343 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003344 u8 tx_seq = __get_reqseq(rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003345
3346 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3347
3348 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
3349 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003350 if (rx_control & L2CAP_CTRL_POLL) {
3351 u16 control = L2CAP_CTRL_FINAL;
Gustavo F. Padovanca42a612009-08-26 04:04:01 -03003352 control |= L2CAP_SUPER_RCV_READY |
3353 (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003354 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003355 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3356
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003357 } else if (rx_control & L2CAP_CTRL_FINAL) {
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003358 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovanca42a612009-08-26 04:04:01 -03003359 pi->expected_ack_seq = tx_seq;
3360 l2cap_drop_acked_frames(sk);
3361
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003362 if (!(pi->conn_state & L2CAP_CONN_WAIT_F))
3363 break;
3364
3365 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3366 del_timer(&pi->monitor_timer);
3367
3368 if (pi->unacked_frames > 0)
3369 __mod_retrans_timer();
3370 } else {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003371 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003372 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003373
3374 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY)
3375 && (pi->unacked_frames > 0))
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003376 __mod_retrans_timer();
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003377
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003378 l2cap_ertm_send(sk);
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003379 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003380 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003381 break;
3382
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003383 case L2CAP_SUPER_REJECT:
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003384 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3385
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003386 pi->expected_ack_seq = __get_reqseq(rx_control);
3387 l2cap_drop_acked_frames(sk);
3388
3389 sk->sk_send_head = TX_QUEUE(sk)->next;
3390 pi->next_tx_seq = pi->expected_ack_seq;
3391
3392 l2cap_ertm_send(sk);
3393
3394 break;
3395
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003396 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003397 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3398
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003399 if (rx_control & L2CAP_CTRL_POLL) {
3400 l2cap_retransmit_frame(sk, tx_seq);
3401 pi->expected_ack_seq = tx_seq;
3402 l2cap_drop_acked_frames(sk);
3403 l2cap_ertm_send(sk);
3404 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3405 pi->srej_save_reqseq = tx_seq;
3406 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3407 }
3408 } else if (rx_control & L2CAP_CTRL_FINAL) {
3409 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3410 pi->srej_save_reqseq == tx_seq)
3411 pi->srej_save_reqseq &= ~L2CAP_CONN_SREJ_ACT;
3412 else
3413 l2cap_retransmit_frame(sk, tx_seq);
3414 }
3415 else {
3416 l2cap_retransmit_frame(sk, tx_seq);
3417 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3418 pi->srej_save_reqseq = tx_seq;
3419 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3420 }
3421 }
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003422 break;
3423
3424 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003425 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
3426 pi->expected_ack_seq = tx_seq;
3427 l2cap_drop_acked_frames(sk);
3428
3429 del_timer(&l2cap_pi(sk)->retrans_timer);
3430 if (rx_control & L2CAP_CTRL_POLL) {
3431 u16 control = L2CAP_CTRL_FINAL | L2CAP_SUPER_RCV_READY;
3432 l2cap_send_sframe(l2cap_pi(sk), control);
3433 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003434 break;
3435 }
3436
3437 return 0;
3438}
3439
Linus Torvalds1da177e2005-04-16 15:20:36 -07003440static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
3441{
3442 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003443 struct l2cap_pinfo *pi;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003444 u16 control, len;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003445 u8 tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003446 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003447
3448 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3449 if (!sk) {
3450 BT_DBG("unknown cid 0x%4.4x", cid);
3451 goto drop;
3452 }
3453
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003454 pi = l2cap_pi(sk);
3455
Linus Torvalds1da177e2005-04-16 15:20:36 -07003456 BT_DBG("sk %p, len %d", sk, skb->len);
3457
3458 if (sk->sk_state != BT_CONNECTED)
3459 goto drop;
3460
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003461 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003462 case L2CAP_MODE_BASIC:
3463 /* If socket recv buffers overflows we drop data here
3464 * which is *bad* because L2CAP has to be reliable.
3465 * But we don't have any other choice. L2CAP doesn't
3466 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003467
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003468 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003469 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003470
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003471 if (!sock_queue_rcv_skb(sk, skb))
3472 goto done;
3473 break;
3474
3475 case L2CAP_MODE_ERTM:
3476 control = get_unaligned_le16(skb->data);
3477 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003478 len = skb->len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003479
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003480 if (__is_sar_start(control))
3481 len -= 2;
3482
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003483 if (pi->fcs == L2CAP_FCS_CRC16)
3484 len -= 2;
3485
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003486 /*
3487 * We can just drop the corrupted I-frame here.
3488 * Receiver will miss it and start proper recovery
3489 * procedures and ask retransmission.
3490 */
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003491 if (len > L2CAP_DEFAULT_MAX_PDU_SIZE)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003492 goto drop;
3493
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003494 if (l2cap_check_fcs(pi, skb))
3495 goto drop;
3496
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003497 if (__is_iframe(control))
3498 err = l2cap_data_channel_iframe(sk, control, skb);
3499 else
3500 err = l2cap_data_channel_sframe(sk, control, skb);
3501
3502 if (!err)
3503 goto done;
3504 break;
3505
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003506 case L2CAP_MODE_STREAMING:
3507 control = get_unaligned_le16(skb->data);
3508 skb_pull(skb, 2);
3509 len = skb->len;
3510
3511 if (__is_sar_start(control))
3512 len -= 2;
3513
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003514 if (pi->fcs == L2CAP_FCS_CRC16)
3515 len -= 2;
3516
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003517 if (len > L2CAP_DEFAULT_MAX_PDU_SIZE || __is_sframe(control))
3518 goto drop;
3519
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003520 if (l2cap_check_fcs(pi, skb))
3521 goto drop;
3522
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003523 tx_seq = __get_txseq(control);
3524
3525 if (pi->expected_tx_seq == tx_seq)
3526 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3527 else
3528 pi->expected_tx_seq = tx_seq + 1;
3529
3530 err = l2cap_sar_reassembly_sdu(sk, skb, control);
3531
3532 goto done;
3533
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003534 default:
3535 BT_DBG("sk %p: bad mode 0x%2.2x", sk, l2cap_pi(sk)->mode);
3536 break;
3537 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003538
3539drop:
3540 kfree_skb(skb);
3541
3542done:
Marcel Holtmann01394182006-07-03 10:02:46 +02003543 if (sk)
3544 bh_unlock_sock(sk);
3545
Linus Torvalds1da177e2005-04-16 15:20:36 -07003546 return 0;
3547}
3548
Al Viro8e036fc2007-07-29 00:16:36 -07003549static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003550{
3551 struct sock *sk;
3552
3553 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
3554 if (!sk)
3555 goto drop;
3556
3557 BT_DBG("sk %p, len %d", sk, skb->len);
3558
3559 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
3560 goto drop;
3561
3562 if (l2cap_pi(sk)->imtu < skb->len)
3563 goto drop;
3564
3565 if (!sock_queue_rcv_skb(sk, skb))
3566 goto done;
3567
3568drop:
3569 kfree_skb(skb);
3570
3571done:
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003572 if (sk)
3573 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003574 return 0;
3575}
3576
3577static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
3578{
3579 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07003580 u16 cid, len;
3581 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003582
3583 skb_pull(skb, L2CAP_HDR_SIZE);
3584 cid = __le16_to_cpu(lh->cid);
3585 len = __le16_to_cpu(lh->len);
3586
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003587 if (len != skb->len) {
3588 kfree_skb(skb);
3589 return;
3590 }
3591
Linus Torvalds1da177e2005-04-16 15:20:36 -07003592 BT_DBG("len %d, cid 0x%4.4x", len, cid);
3593
3594 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003595 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003596 l2cap_sig_channel(conn, skb);
3597 break;
3598
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003599 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003600 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003601 skb_pull(skb, 2);
3602 l2cap_conless_channel(conn, psm, skb);
3603 break;
3604
3605 default:
3606 l2cap_data_channel(conn, cid, skb);
3607 break;
3608 }
3609}
3610
3611/* ---- L2CAP interface with lower layer (HCI) ---- */
3612
3613static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3614{
3615 int exact = 0, lm1 = 0, lm2 = 0;
3616 register struct sock *sk;
3617 struct hlist_node *node;
3618
3619 if (type != ACL_LINK)
3620 return 0;
3621
3622 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
3623
3624 /* Find listening sockets and check their link_mode */
3625 read_lock(&l2cap_sk_list.lock);
3626 sk_for_each(sk, node, &l2cap_sk_list.head) {
3627 if (sk->sk_state != BT_LISTEN)
3628 continue;
3629
3630 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003631 lm1 |= HCI_LM_ACCEPT;
3632 if (l2cap_pi(sk)->role_switch)
3633 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003634 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003635 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
3636 lm2 |= HCI_LM_ACCEPT;
3637 if (l2cap_pi(sk)->role_switch)
3638 lm2 |= HCI_LM_MASTER;
3639 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003640 }
3641 read_unlock(&l2cap_sk_list.lock);
3642
3643 return exact ? lm1 : lm2;
3644}
3645
3646static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
3647{
Marcel Holtmann01394182006-07-03 10:02:46 +02003648 struct l2cap_conn *conn;
3649
Linus Torvalds1da177e2005-04-16 15:20:36 -07003650 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
3651
3652 if (hcon->type != ACL_LINK)
3653 return 0;
3654
3655 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003656 conn = l2cap_conn_add(hcon, status);
3657 if (conn)
3658 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02003659 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003660 l2cap_conn_del(hcon, bt_err(status));
3661
3662 return 0;
3663}
3664
Marcel Holtmann2950f212009-02-12 14:02:50 +01003665static int l2cap_disconn_ind(struct hci_conn *hcon)
3666{
3667 struct l2cap_conn *conn = hcon->l2cap_data;
3668
3669 BT_DBG("hcon %p", hcon);
3670
3671 if (hcon->type != ACL_LINK || !conn)
3672 return 0x13;
3673
3674 return conn->disc_reason;
3675}
3676
3677static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003678{
3679 BT_DBG("hcon %p reason %d", hcon, reason);
3680
3681 if (hcon->type != ACL_LINK)
3682 return 0;
3683
3684 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02003685
Linus Torvalds1da177e2005-04-16 15:20:36 -07003686 return 0;
3687}
3688
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003689static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
3690{
Marcel Holtmann255c7602009-02-04 21:07:19 +01003691 if (sk->sk_type != SOCK_SEQPACKET)
3692 return;
3693
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003694 if (encrypt == 0x00) {
3695 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
3696 l2cap_sock_clear_timer(sk);
3697 l2cap_sock_set_timer(sk, HZ * 5);
3698 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
3699 __l2cap_sock_close(sk, ECONNREFUSED);
3700 } else {
3701 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
3702 l2cap_sock_clear_timer(sk);
3703 }
3704}
3705
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003706static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003707{
3708 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02003709 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003710 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003711
Marcel Holtmann01394182006-07-03 10:02:46 +02003712 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003713 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02003714
Linus Torvalds1da177e2005-04-16 15:20:36 -07003715 l = &conn->chan_list;
3716
3717 BT_DBG("conn %p", conn);
3718
3719 read_lock(&l->lock);
3720
3721 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
3722 bh_lock_sock(sk);
3723
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003724 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
3725 bh_unlock_sock(sk);
3726 continue;
3727 }
3728
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003729 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003730 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003731 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02003732 bh_unlock_sock(sk);
3733 continue;
3734 }
3735
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003736 if (sk->sk_state == BT_CONNECT) {
3737 if (!status) {
3738 struct l2cap_conn_req req;
3739 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
3740 req.psm = l2cap_pi(sk)->psm;
3741
3742 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
3743
3744 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3745 L2CAP_CONN_REQ, sizeof(req), &req);
3746 } else {
3747 l2cap_sock_clear_timer(sk);
3748 l2cap_sock_set_timer(sk, HZ / 10);
3749 }
3750 } else if (sk->sk_state == BT_CONNECT2) {
3751 struct l2cap_conn_rsp rsp;
3752 __u16 result;
3753
3754 if (!status) {
3755 sk->sk_state = BT_CONFIG;
3756 result = L2CAP_CR_SUCCESS;
3757 } else {
3758 sk->sk_state = BT_DISCONN;
3759 l2cap_sock_set_timer(sk, HZ / 10);
3760 result = L2CAP_CR_SEC_BLOCK;
3761 }
3762
3763 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
3764 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3765 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003766 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003767 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3768 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003769 }
3770
Linus Torvalds1da177e2005-04-16 15:20:36 -07003771 bh_unlock_sock(sk);
3772 }
3773
3774 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003775
Linus Torvalds1da177e2005-04-16 15:20:36 -07003776 return 0;
3777}
3778
3779static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
3780{
3781 struct l2cap_conn *conn = hcon->l2cap_data;
3782
3783 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
3784 goto drop;
3785
3786 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
3787
3788 if (flags & ACL_START) {
3789 struct l2cap_hdr *hdr;
3790 int len;
3791
3792 if (conn->rx_len) {
3793 BT_ERR("Unexpected start frame (len %d)", skb->len);
3794 kfree_skb(conn->rx_skb);
3795 conn->rx_skb = NULL;
3796 conn->rx_len = 0;
3797 l2cap_conn_unreliable(conn, ECOMM);
3798 }
3799
3800 if (skb->len < 2) {
3801 BT_ERR("Frame is too short (len %d)", skb->len);
3802 l2cap_conn_unreliable(conn, ECOMM);
3803 goto drop;
3804 }
3805
3806 hdr = (struct l2cap_hdr *) skb->data;
3807 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
3808
3809 if (len == skb->len) {
3810 /* Complete frame received */
3811 l2cap_recv_frame(conn, skb);
3812 return 0;
3813 }
3814
3815 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
3816
3817 if (skb->len > len) {
3818 BT_ERR("Frame is too long (len %d, expected len %d)",
3819 skb->len, len);
3820 l2cap_conn_unreliable(conn, ECOMM);
3821 goto drop;
3822 }
3823
3824 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003825 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
3826 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003827 goto drop;
3828
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03003829 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003830 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003831 conn->rx_len = len - skb->len;
3832 } else {
3833 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
3834
3835 if (!conn->rx_len) {
3836 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
3837 l2cap_conn_unreliable(conn, ECOMM);
3838 goto drop;
3839 }
3840
3841 if (skb->len > conn->rx_len) {
3842 BT_ERR("Fragment is too long (len %d, expected %d)",
3843 skb->len, conn->rx_len);
3844 kfree_skb(conn->rx_skb);
3845 conn->rx_skb = NULL;
3846 conn->rx_len = 0;
3847 l2cap_conn_unreliable(conn, ECOMM);
3848 goto drop;
3849 }
3850
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03003851 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003852 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003853 conn->rx_len -= skb->len;
3854
3855 if (!conn->rx_len) {
3856 /* Complete frame received */
3857 l2cap_recv_frame(conn, conn->rx_skb);
3858 conn->rx_skb = NULL;
3859 }
3860 }
3861
3862drop:
3863 kfree_skb(skb);
3864 return 0;
3865}
3866
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003867static ssize_t l2cap_sysfs_show(struct class *dev, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003868{
3869 struct sock *sk;
3870 struct hlist_node *node;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003871 char *str = buf;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003872
3873 read_lock_bh(&l2cap_sk_list.lock);
3874
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003875 sk_for_each(sk, node, &l2cap_sk_list.head) {
3876 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003877
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003878 str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003879 batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
Marcel Holtmannb4324b52009-06-07 18:06:51 +02003880 sk->sk_state, __le16_to_cpu(pi->psm), pi->scid,
3881 pi->dcid, pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003882 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003883
Linus Torvalds1da177e2005-04-16 15:20:36 -07003884 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003885
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003886 return str - buf;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003887}
3888
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003889static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003890
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08003891static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003892 .family = PF_BLUETOOTH,
3893 .owner = THIS_MODULE,
3894 .release = l2cap_sock_release,
3895 .bind = l2cap_sock_bind,
3896 .connect = l2cap_sock_connect,
3897 .listen = l2cap_sock_listen,
3898 .accept = l2cap_sock_accept,
3899 .getname = l2cap_sock_getname,
3900 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003901 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003902 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02003903 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003904 .mmap = sock_no_mmap,
3905 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003906 .shutdown = l2cap_sock_shutdown,
3907 .setsockopt = l2cap_sock_setsockopt,
3908 .getsockopt = l2cap_sock_getsockopt
3909};
3910
3911static struct net_proto_family l2cap_sock_family_ops = {
3912 .family = PF_BLUETOOTH,
3913 .owner = THIS_MODULE,
3914 .create = l2cap_sock_create,
3915};
3916
3917static struct hci_proto l2cap_hci_proto = {
3918 .name = "L2CAP",
3919 .id = HCI_PROTO_L2CAP,
3920 .connect_ind = l2cap_connect_ind,
3921 .connect_cfm = l2cap_connect_cfm,
3922 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01003923 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003924 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003925 .recv_acldata = l2cap_recv_acldata
3926};
3927
3928static int __init l2cap_init(void)
3929{
3930 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003931
Linus Torvalds1da177e2005-04-16 15:20:36 -07003932 err = proto_register(&l2cap_proto, 0);
3933 if (err < 0)
3934 return err;
3935
3936 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
3937 if (err < 0) {
3938 BT_ERR("L2CAP socket registration failed");
3939 goto error;
3940 }
3941
3942 err = hci_register_proto(&l2cap_hci_proto);
3943 if (err < 0) {
3944 BT_ERR("L2CAP protocol registration failed");
3945 bt_sock_unregister(BTPROTO_L2CAP);
3946 goto error;
3947 }
3948
Marcel Holtmanndf5c37e2006-10-15 17:30:45 +02003949 if (class_create_file(bt_class, &class_attr_l2cap) < 0)
3950 BT_ERR("Failed to create L2CAP info file");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003951
3952 BT_INFO("L2CAP ver %s", VERSION);
3953 BT_INFO("L2CAP socket layer initialized");
3954
3955 return 0;
3956
3957error:
3958 proto_unregister(&l2cap_proto);
3959 return err;
3960}
3961
3962static void __exit l2cap_exit(void)
3963{
Marcel Holtmanna91f2e32006-07-03 10:02:41 +02003964 class_remove_file(bt_class, &class_attr_l2cap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003965
3966 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
3967 BT_ERR("L2CAP socket unregistration failed");
3968
3969 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
3970 BT_ERR("L2CAP protocol unregistration failed");
3971
3972 proto_unregister(&l2cap_proto);
3973}
3974
3975void l2cap_load(void)
3976{
3977 /* Dummy function to trigger automatic L2CAP module loading by
3978 * other modules that use L2CAP sockets but don't use any other
3979 * symbols from it. */
3980 return;
3981}
3982EXPORT_SYMBOL(l2cap_load);
3983
3984module_init(l2cap_init);
3985module_exit(l2cap_exit);
3986
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003987module_param(enable_ertm, bool, 0644);
3988MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
3989
Marcel Holtmann63fbd242008-08-18 13:23:53 +02003990MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003991MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
3992MODULE_VERSION(VERSION);
3993MODULE_LICENSE("GPL");
3994MODULE_ALIAS("bt-proto-0");