blob: e5847c5849d7d88ff08cb7fb919beb7add0ee688 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth L2CAP core and sockets. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
Randy Dunlap4fc268d2006-01-11 12:17:47 -080030#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/errno.h>
32#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/sched.h>
34#include <linux/slab.h>
35#include <linux/poll.h>
36#include <linux/fcntl.h>
37#include <linux/init.h>
38#include <linux/interrupt.h>
39#include <linux/socket.h>
40#include <linux/skbuff.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <linux/list.h>
Marcel Holtmannbe9d1222005-11-08 09:57:38 -080042#include <linux/device.h>
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -030043#include <linux/uaccess.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030044#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070045#include <net/sock.h>
46
47#include <asm/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070048#include <asm/unaligned.h>
49
50#include <net/bluetooth/bluetooth.h>
51#include <net/bluetooth/hci_core.h>
52#include <net/bluetooth/l2cap.h>
53
Marcel Holtmann44dd46d2009-05-02 19:09:01 -070054#define VERSION "2.14"
55
56static int enable_ertm = 0;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020057
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070058static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Marcel Holtmanne1027a72009-02-09 09:18:02 +010059static u8 l2cap_fixed_chan[8] = { 0x02, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070060
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080061static const struct proto_ops l2cap_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070062
63static struct bt_sock_list l2cap_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070064 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070065};
66
Linus Torvalds1da177e2005-04-16 15:20:36 -070067static void __l2cap_sock_close(struct sock *sk, int reason);
68static void l2cap_sock_close(struct sock *sk);
69static void l2cap_sock_kill(struct sock *sk);
70
71static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
72 u8 code, u8 ident, u16 dlen, void *data);
73
74/* ---- L2CAP timers ---- */
75static void l2cap_sock_timeout(unsigned long arg)
76{
77 struct sock *sk = (struct sock *) arg;
Marcel Holtmannb1235d72008-07-14 20:13:54 +020078 int reason;
Linus Torvalds1da177e2005-04-16 15:20:36 -070079
80 BT_DBG("sock %p state %d", sk, sk->sk_state);
81
82 bh_lock_sock(sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +020083
Marcel Holtmannf62e4322009-01-15 21:58:44 +010084 if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
85 reason = ECONNREFUSED;
86 else if (sk->sk_state == BT_CONNECT &&
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +010087 l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
Marcel Holtmannb1235d72008-07-14 20:13:54 +020088 reason = ECONNREFUSED;
89 else
90 reason = ETIMEDOUT;
91
92 __l2cap_sock_close(sk, reason);
93
Linus Torvalds1da177e2005-04-16 15:20:36 -070094 bh_unlock_sock(sk);
95
96 l2cap_sock_kill(sk);
97 sock_put(sk);
98}
99
100static void l2cap_sock_set_timer(struct sock *sk, long timeout)
101{
102 BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
103 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
104}
105
106static void l2cap_sock_clear_timer(struct sock *sk)
107{
108 BT_DBG("sock %p state %d", sk, sk->sk_state);
109 sk_stop_timer(sk, &sk->sk_timer);
110}
111
Marcel Holtmann01394182006-07-03 10:02:46 +0200112/* ---- L2CAP channels ---- */
113static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
114{
115 struct sock *s;
116 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
117 if (l2cap_pi(s)->dcid == cid)
118 break;
119 }
120 return s;
121}
122
123static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
124{
125 struct sock *s;
126 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
127 if (l2cap_pi(s)->scid == cid)
128 break;
129 }
130 return s;
131}
132
133/* Find channel with given SCID.
134 * Returns locked socket */
135static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
136{
137 struct sock *s;
138 read_lock(&l->lock);
139 s = __l2cap_get_chan_by_scid(l, cid);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300140 if (s)
141 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200142 read_unlock(&l->lock);
143 return s;
144}
145
146static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
147{
148 struct sock *s;
149 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
150 if (l2cap_pi(s)->ident == ident)
151 break;
152 }
153 return s;
154}
155
156static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
157{
158 struct sock *s;
159 read_lock(&l->lock);
160 s = __l2cap_get_chan_by_ident(l, ident);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300161 if (s)
162 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200163 read_unlock(&l->lock);
164 return s;
165}
166
167static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
168{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300169 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200170
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300171 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300172 if (!__l2cap_get_chan_by_scid(l, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200173 return cid;
174 }
175
176 return 0;
177}
178
179static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
180{
181 sock_hold(sk);
182
183 if (l->head)
184 l2cap_pi(l->head)->prev_c = sk;
185
186 l2cap_pi(sk)->next_c = l->head;
187 l2cap_pi(sk)->prev_c = NULL;
188 l->head = sk;
189}
190
191static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
192{
193 struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
194
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200195 write_lock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200196 if (sk == l->head)
197 l->head = next;
198
199 if (next)
200 l2cap_pi(next)->prev_c = prev;
201 if (prev)
202 l2cap_pi(prev)->next_c = next;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200203 write_unlock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200204
205 __sock_put(sk);
206}
207
208static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
209{
210 struct l2cap_chan_list *l = &conn->chan_list;
211
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300212 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
213 l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200214
Marcel Holtmann2950f212009-02-12 14:02:50 +0100215 conn->disc_reason = 0x13;
216
Marcel Holtmann01394182006-07-03 10:02:46 +0200217 l2cap_pi(sk)->conn = conn;
218
219 if (sk->sk_type == SOCK_SEQPACKET) {
220 /* Alloc CID for connection-oriented socket */
221 l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
222 } else if (sk->sk_type == SOCK_DGRAM) {
223 /* Connectionless socket */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300224 l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
225 l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
Marcel Holtmann01394182006-07-03 10:02:46 +0200226 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
227 } else {
228 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300229 l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
230 l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
Marcel Holtmann01394182006-07-03 10:02:46 +0200231 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
232 }
233
234 __l2cap_chan_link(l, sk);
235
236 if (parent)
237 bt_accept_enqueue(parent, sk);
238}
239
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900240/* Delete channel.
Marcel Holtmann01394182006-07-03 10:02:46 +0200241 * Must be called on the locked socket. */
242static void l2cap_chan_del(struct sock *sk, int err)
243{
244 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
245 struct sock *parent = bt_sk(sk)->parent;
246
247 l2cap_sock_clear_timer(sk);
248
249 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
250
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900251 if (conn) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200252 /* Unlink from channel list */
253 l2cap_chan_unlink(&conn->chan_list, sk);
254 l2cap_pi(sk)->conn = NULL;
255 hci_conn_put(conn->hcon);
256 }
257
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200258 sk->sk_state = BT_CLOSED;
Marcel Holtmann01394182006-07-03 10:02:46 +0200259 sock_set_flag(sk, SOCK_ZAPPED);
260
261 if (err)
262 sk->sk_err = err;
263
264 if (parent) {
265 bt_accept_unlink(sk);
266 parent->sk_data_ready(parent, 0);
267 } else
268 sk->sk_state_change(sk);
269}
270
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200271/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100272static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200273{
274 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100275 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200276
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100277 if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
278 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
279 auth_type = HCI_AT_NO_BONDING_MITM;
280 else
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300281 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100282
283 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
284 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
285 } else {
286 switch (l2cap_pi(sk)->sec_level) {
287 case BT_SECURITY_HIGH:
288 auth_type = HCI_AT_GENERAL_BONDING_MITM;
289 break;
290 case BT_SECURITY_MEDIUM:
291 auth_type = HCI_AT_GENERAL_BONDING;
292 break;
293 default:
294 auth_type = HCI_AT_NO_BONDING;
295 break;
296 }
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100297 }
298
299 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
300 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200301}
302
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200303static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
304{
305 u8 id;
306
307 /* Get next available identificator.
308 * 1 - 128 are used by kernel.
309 * 129 - 199 are reserved.
310 * 200 - 254 are used by utilities like l2ping, etc.
311 */
312
313 spin_lock_bh(&conn->lock);
314
315 if (++conn->tx_ident > 128)
316 conn->tx_ident = 1;
317
318 id = conn->tx_ident;
319
320 spin_unlock_bh(&conn->lock);
321
322 return id;
323}
324
325static inline int l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
326{
327 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
328
329 BT_DBG("code 0x%2.2x", code);
330
331 if (!skb)
332 return -ENOMEM;
333
334 return hci_send_acl(conn->hcon, skb, 0);
335}
336
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300337static inline int l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
338{
339 struct sk_buff *skb;
340 struct l2cap_hdr *lh;
341 struct l2cap_conn *conn = pi->conn;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300342 int count, hlen = L2CAP_HDR_SIZE + 2;
343
344 if (pi->fcs == L2CAP_FCS_CRC16)
345 hlen += 2;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300346
347 BT_DBG("pi %p, control 0x%2.2x", pi, control);
348
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300349 count = min_t(unsigned int, conn->mtu, hlen);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300350 control |= L2CAP_CTRL_FRAME_TYPE;
351
352 skb = bt_skb_alloc(count, GFP_ATOMIC);
353 if (!skb)
354 return -ENOMEM;
355
356 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300357 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300358 lh->cid = cpu_to_le16(pi->dcid);
359 put_unaligned_le16(control, skb_put(skb, 2));
360
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300361 if (pi->fcs == L2CAP_FCS_CRC16) {
362 u16 fcs = crc16(0, (u8 *)lh, count - 2);
363 put_unaligned_le16(fcs, skb_put(skb, 2));
364 }
365
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300366 return hci_send_acl(pi->conn->hcon, skb, 0);
367}
368
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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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. Padovan1c2acff2009-08-20 22:25:57 -03001353 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
1354 tx_skb = skb_clone(skb, GFP_ATOMIC);
1355
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001356 if (pi->remote_max_tx &&
1357 bt_cb(skb)->retries == pi->remote_max_tx) {
1358 l2cap_send_disconn_req(pi->conn, sk);
1359 break;
1360 }
1361
1362 bt_cb(skb)->retries++;
1363
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001364 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1365 control |= (pi->req_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1366 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1367 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1368
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001369
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001370 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) {
1371 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1372 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1373 }
1374
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001375 err = l2cap_do_send(sk, tx_skb);
1376 if (err < 0) {
1377 l2cap_send_disconn_req(pi->conn, sk);
1378 return err;
1379 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001380 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001381
1382 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1383 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1384
1385 pi->unacked_frames++;
1386
1387 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1388 sk->sk_send_head = NULL;
1389 else
1390 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1391 }
1392
1393 return 0;
1394}
1395
1396static 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 -07001397{
1398 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001399 struct sk_buff **frag;
1400 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401
1402 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001403 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404 }
1405
1406 sent += count;
1407 len -= count;
1408
1409 /* Continuation fragments (no L2CAP header) */
1410 frag = &skb_shinfo(skb)->frag_list;
1411 while (len) {
1412 count = min_t(unsigned int, conn->mtu, len);
1413
1414 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1415 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001416 return -EFAULT;
1417 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1418 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419
1420 sent += count;
1421 len -= count;
1422
1423 frag = &(*frag)->next;
1424 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425
1426 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001427}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001429static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1430{
1431 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1432 struct sk_buff *skb;
1433 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1434 struct l2cap_hdr *lh;
1435
1436 BT_DBG("sk %p len %d", sk, (int)len);
1437
1438 count = min_t(unsigned int, (conn->mtu - hlen), len);
1439 skb = bt_skb_send_alloc(sk, count + hlen,
1440 msg->msg_flags & MSG_DONTWAIT, &err);
1441 if (!skb)
1442 return ERR_PTR(-ENOMEM);
1443
1444 /* Create L2CAP header */
1445 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1446 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1447 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1448 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1449
1450 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1451 if (unlikely(err < 0)) {
1452 kfree_skb(skb);
1453 return ERR_PTR(err);
1454 }
1455 return skb;
1456}
1457
1458static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1459{
1460 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1461 struct sk_buff *skb;
1462 int err, count, hlen = L2CAP_HDR_SIZE;
1463 struct l2cap_hdr *lh;
1464
1465 BT_DBG("sk %p len %d", sk, (int)len);
1466
1467 count = min_t(unsigned int, (conn->mtu - hlen), len);
1468 skb = bt_skb_send_alloc(sk, count + hlen,
1469 msg->msg_flags & MSG_DONTWAIT, &err);
1470 if (!skb)
1471 return ERR_PTR(-ENOMEM);
1472
1473 /* Create L2CAP header */
1474 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1475 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1476 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1477
1478 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1479 if (unlikely(err < 0)) {
1480 kfree_skb(skb);
1481 return ERR_PTR(err);
1482 }
1483 return skb;
1484}
1485
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001486static 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 -03001487{
1488 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1489 struct sk_buff *skb;
1490 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1491 struct l2cap_hdr *lh;
1492
1493 BT_DBG("sk %p len %d", sk, (int)len);
1494
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001495 if (sdulen)
1496 hlen += 2;
1497
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001498 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1499 hlen += 2;
1500
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001501 count = min_t(unsigned int, (conn->mtu - hlen), len);
1502 skb = bt_skb_send_alloc(sk, count + hlen,
1503 msg->msg_flags & MSG_DONTWAIT, &err);
1504 if (!skb)
1505 return ERR_PTR(-ENOMEM);
1506
1507 /* Create L2CAP header */
1508 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1509 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1510 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1511 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001512 if (sdulen)
1513 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001514
1515 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1516 if (unlikely(err < 0)) {
1517 kfree_skb(skb);
1518 return ERR_PTR(err);
1519 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001520
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001521 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1522 put_unaligned_le16(0, skb_put(skb, 2));
1523
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001524 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001525 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526}
1527
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001528static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1529{
1530 struct l2cap_pinfo *pi = l2cap_pi(sk);
1531 struct sk_buff *skb;
1532 struct sk_buff_head sar_queue;
1533 u16 control;
1534 size_t size = 0;
1535
1536 __skb_queue_head_init(&sar_queue);
1537 control = L2CAP_SDU_START;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001538 skb = l2cap_create_iframe_pdu(sk, msg, pi->max_pdu_size, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001539 if (IS_ERR(skb))
1540 return PTR_ERR(skb);
1541
1542 __skb_queue_tail(&sar_queue, skb);
1543 len -= pi->max_pdu_size;
1544 size +=pi->max_pdu_size;
1545 control = 0;
1546
1547 while (len > 0) {
1548 size_t buflen;
1549
1550 if (len > pi->max_pdu_size) {
1551 control |= L2CAP_SDU_CONTINUE;
1552 buflen = pi->max_pdu_size;
1553 } else {
1554 control |= L2CAP_SDU_END;
1555 buflen = len;
1556 }
1557
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001558 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001559 if (IS_ERR(skb)) {
1560 skb_queue_purge(&sar_queue);
1561 return PTR_ERR(skb);
1562 }
1563
1564 __skb_queue_tail(&sar_queue, skb);
1565 len -= buflen;
1566 size += buflen;
1567 control = 0;
1568 }
1569 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1570 if (sk->sk_send_head == NULL)
1571 sk->sk_send_head = sar_queue.next;
1572
1573 return size;
1574}
1575
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1577{
1578 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001579 struct l2cap_pinfo *pi = l2cap_pi(sk);
1580 struct sk_buff *skb;
1581 u16 control;
1582 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583
1584 BT_DBG("sock %p, sk %p", sock, sk);
1585
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001586 err = sock_error(sk);
1587 if (err)
1588 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589
1590 if (msg->msg_flags & MSG_OOB)
1591 return -EOPNOTSUPP;
1592
1593 /* Check outgoing MTU */
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001594 if (sk->sk_type == SOCK_SEQPACKET && pi->mode == L2CAP_MODE_BASIC
1595 && len > pi->omtu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596 return -EINVAL;
1597
1598 lock_sock(sk);
1599
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001600 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001602 goto done;
1603 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001605 /* Connectionless channel */
1606 if (sk->sk_type == SOCK_DGRAM) {
1607 skb = l2cap_create_connless_pdu(sk, msg, len);
1608 err = l2cap_do_send(sk, skb);
1609 goto done;
1610 }
1611
1612 switch (pi->mode) {
1613 case L2CAP_MODE_BASIC:
1614 /* Create a basic PDU */
1615 skb = l2cap_create_basic_pdu(sk, msg, len);
1616 if (IS_ERR(skb)) {
1617 err = PTR_ERR(skb);
1618 goto done;
1619 }
1620
1621 err = l2cap_do_send(sk, skb);
1622 if (!err)
1623 err = len;
1624 break;
1625
1626 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001627 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001628 /* Entire SDU fits into one PDU */
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001629 if (len <= pi->max_pdu_size) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001630 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001631 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001632 if (IS_ERR(skb)) {
1633 err = PTR_ERR(skb);
1634 goto done;
1635 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001636 __skb_queue_tail(TX_QUEUE(sk), skb);
1637 if (sk->sk_send_head == NULL)
1638 sk->sk_send_head = skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001639 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001640 /* Segment SDU into multiples PDUs */
1641 err = l2cap_sar_segment_sdu(sk, msg, len);
1642 if (err < 0)
1643 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001644 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001645
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001646 if (pi->mode == L2CAP_MODE_STREAMING)
1647 err = l2cap_streaming_send(sk);
1648 else
1649 err = l2cap_ertm_send(sk);
1650
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001651 if (!err)
1652 err = len;
1653 break;
1654
1655 default:
1656 BT_DBG("bad state %1.1x", pi->mode);
1657 err = -EINVAL;
1658 }
1659
1660done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661 release_sock(sk);
1662 return err;
1663}
1664
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001665static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1666{
1667 struct sock *sk = sock->sk;
1668
1669 lock_sock(sk);
1670
1671 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1672 struct l2cap_conn_rsp rsp;
1673
1674 sk->sk_state = BT_CONFIG;
1675
1676 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1677 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1678 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1679 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1680 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1681 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1682
1683 release_sock(sk);
1684 return 0;
1685 }
1686
1687 release_sock(sk);
1688
1689 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1690}
1691
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001692static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693{
1694 struct sock *sk = sock->sk;
1695 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001696 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697 u32 opt;
1698
1699 BT_DBG("sk %p", sk);
1700
1701 lock_sock(sk);
1702
1703 switch (optname) {
1704 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001705 opts.imtu = l2cap_pi(sk)->imtu;
1706 opts.omtu = l2cap_pi(sk)->omtu;
1707 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001708 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001709 opts.fcs = l2cap_pi(sk)->fcs;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001710
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711 len = min_t(unsigned int, sizeof(opts), optlen);
1712 if (copy_from_user((char *) &opts, optval, len)) {
1713 err = -EFAULT;
1714 break;
1715 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001716
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001717 l2cap_pi(sk)->imtu = opts.imtu;
1718 l2cap_pi(sk)->omtu = opts.omtu;
1719 l2cap_pi(sk)->mode = opts.mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001720 l2cap_pi(sk)->fcs = opts.fcs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 break;
1722
1723 case L2CAP_LM:
1724 if (get_user(opt, (u32 __user *) optval)) {
1725 err = -EFAULT;
1726 break;
1727 }
1728
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001729 if (opt & L2CAP_LM_AUTH)
1730 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1731 if (opt & L2CAP_LM_ENCRYPT)
1732 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1733 if (opt & L2CAP_LM_SECURE)
1734 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1735
1736 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1737 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 break;
1739
1740 default:
1741 err = -ENOPROTOOPT;
1742 break;
1743 }
1744
1745 release_sock(sk);
1746 return err;
1747}
1748
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001749static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
1750{
1751 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001752 struct bt_security sec;
1753 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001754 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001755
1756 BT_DBG("sk %p", sk);
1757
1758 if (level == SOL_L2CAP)
1759 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1760
Marcel Holtmann0588d942009-01-16 10:06:13 +01001761 if (level != SOL_BLUETOOTH)
1762 return -ENOPROTOOPT;
1763
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001764 lock_sock(sk);
1765
1766 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001767 case BT_SECURITY:
Marcel Holtmann2526d3d2009-02-20 20:54:06 +01001768 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001769 err = -EINVAL;
1770 break;
1771 }
1772
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001773 sec.level = BT_SECURITY_LOW;
1774
1775 len = min_t(unsigned int, sizeof(sec), optlen);
1776 if (copy_from_user((char *) &sec, optval, len)) {
1777 err = -EFAULT;
1778 break;
1779 }
1780
1781 if (sec.level < BT_SECURITY_LOW ||
1782 sec.level > BT_SECURITY_HIGH) {
1783 err = -EINVAL;
1784 break;
1785 }
1786
1787 l2cap_pi(sk)->sec_level = sec.level;
1788 break;
1789
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001790 case BT_DEFER_SETUP:
1791 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1792 err = -EINVAL;
1793 break;
1794 }
1795
1796 if (get_user(opt, (u32 __user *) optval)) {
1797 err = -EFAULT;
1798 break;
1799 }
1800
1801 bt_sk(sk)->defer_setup = opt;
1802 break;
1803
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001804 default:
1805 err = -ENOPROTOOPT;
1806 break;
1807 }
1808
1809 release_sock(sk);
1810 return err;
1811}
1812
1813static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814{
1815 struct sock *sk = sock->sk;
1816 struct l2cap_options opts;
1817 struct l2cap_conninfo cinfo;
1818 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001819 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820
1821 BT_DBG("sk %p", sk);
1822
1823 if (get_user(len, optlen))
1824 return -EFAULT;
1825
1826 lock_sock(sk);
1827
1828 switch (optname) {
1829 case L2CAP_OPTIONS:
1830 opts.imtu = l2cap_pi(sk)->imtu;
1831 opts.omtu = l2cap_pi(sk)->omtu;
1832 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001833 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001834 opts.fcs = l2cap_pi(sk)->fcs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835
1836 len = min_t(unsigned int, len, sizeof(opts));
1837 if (copy_to_user(optval, (char *) &opts, len))
1838 err = -EFAULT;
1839
1840 break;
1841
1842 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001843 switch (l2cap_pi(sk)->sec_level) {
1844 case BT_SECURITY_LOW:
1845 opt = L2CAP_LM_AUTH;
1846 break;
1847 case BT_SECURITY_MEDIUM:
1848 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
1849 break;
1850 case BT_SECURITY_HIGH:
1851 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
1852 L2CAP_LM_SECURE;
1853 break;
1854 default:
1855 opt = 0;
1856 break;
1857 }
1858
1859 if (l2cap_pi(sk)->role_switch)
1860 opt |= L2CAP_LM_MASTER;
1861
1862 if (l2cap_pi(sk)->force_reliable)
1863 opt |= L2CAP_LM_RELIABLE;
1864
1865 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001866 err = -EFAULT;
1867 break;
1868
1869 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001870 if (sk->sk_state != BT_CONNECTED &&
1871 !(sk->sk_state == BT_CONNECT2 &&
1872 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873 err = -ENOTCONN;
1874 break;
1875 }
1876
1877 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
1878 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
1879
1880 len = min_t(unsigned int, len, sizeof(cinfo));
1881 if (copy_to_user(optval, (char *) &cinfo, len))
1882 err = -EFAULT;
1883
1884 break;
1885
1886 default:
1887 err = -ENOPROTOOPT;
1888 break;
1889 }
1890
1891 release_sock(sk);
1892 return err;
1893}
1894
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001895static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
1896{
1897 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001898 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001899 int len, err = 0;
1900
1901 BT_DBG("sk %p", sk);
1902
1903 if (level == SOL_L2CAP)
1904 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
1905
Marcel Holtmann0588d942009-01-16 10:06:13 +01001906 if (level != SOL_BLUETOOTH)
1907 return -ENOPROTOOPT;
1908
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001909 if (get_user(len, optlen))
1910 return -EFAULT;
1911
1912 lock_sock(sk);
1913
1914 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001915 case BT_SECURITY:
Marcel Holtmann2526d3d2009-02-20 20:54:06 +01001916 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001917 err = -EINVAL;
1918 break;
1919 }
1920
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001921 sec.level = l2cap_pi(sk)->sec_level;
1922
1923 len = min_t(unsigned int, len, sizeof(sec));
1924 if (copy_to_user(optval, (char *) &sec, len))
1925 err = -EFAULT;
1926
1927 break;
1928
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001929 case BT_DEFER_SETUP:
1930 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1931 err = -EINVAL;
1932 break;
1933 }
1934
1935 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
1936 err = -EFAULT;
1937
1938 break;
1939
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001940 default:
1941 err = -ENOPROTOOPT;
1942 break;
1943 }
1944
1945 release_sock(sk);
1946 return err;
1947}
1948
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949static int l2cap_sock_shutdown(struct socket *sock, int how)
1950{
1951 struct sock *sk = sock->sk;
1952 int err = 0;
1953
1954 BT_DBG("sock %p, sk %p", sock, sk);
1955
1956 if (!sk)
1957 return 0;
1958
1959 lock_sock(sk);
1960 if (!sk->sk_shutdown) {
1961 sk->sk_shutdown = SHUTDOWN_MASK;
1962 l2cap_sock_clear_timer(sk);
1963 __l2cap_sock_close(sk, 0);
1964
1965 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001966 err = bt_sock_wait_state(sk, BT_CLOSED,
1967 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001968 }
1969 release_sock(sk);
1970 return err;
1971}
1972
1973static int l2cap_sock_release(struct socket *sock)
1974{
1975 struct sock *sk = sock->sk;
1976 int err;
1977
1978 BT_DBG("sock %p, sk %p", sock, sk);
1979
1980 if (!sk)
1981 return 0;
1982
1983 err = l2cap_sock_shutdown(sock, 2);
1984
1985 sock_orphan(sk);
1986 l2cap_sock_kill(sk);
1987 return err;
1988}
1989
Linus Torvalds1da177e2005-04-16 15:20:36 -07001990static void l2cap_chan_ready(struct sock *sk)
1991{
1992 struct sock *parent = bt_sk(sk)->parent;
1993
1994 BT_DBG("sk %p, parent %p", sk, parent);
1995
1996 l2cap_pi(sk)->conf_state = 0;
1997 l2cap_sock_clear_timer(sk);
1998
1999 if (!parent) {
2000 /* Outgoing channel.
2001 * Wake up socket sleeping on connect.
2002 */
2003 sk->sk_state = BT_CONNECTED;
2004 sk->sk_state_change(sk);
2005 } else {
2006 /* Incoming channel.
2007 * Wake up socket sleeping on accept.
2008 */
2009 parent->sk_data_ready(parent, 0);
2010 }
2011}
2012
2013/* Copy frame to all raw sockets on that connection */
2014static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2015{
2016 struct l2cap_chan_list *l = &conn->chan_list;
2017 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002018 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002019
2020 BT_DBG("conn %p", conn);
2021
2022 read_lock(&l->lock);
2023 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2024 if (sk->sk_type != SOCK_RAW)
2025 continue;
2026
2027 /* Don't send frame to the socket it came from */
2028 if (skb->sk == sk)
2029 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002030 nskb = skb_clone(skb, GFP_ATOMIC);
2031 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002032 continue;
2033
2034 if (sock_queue_rcv_skb(sk, nskb))
2035 kfree_skb(nskb);
2036 }
2037 read_unlock(&l->lock);
2038}
2039
2040/* ---- L2CAP signalling commands ---- */
2041static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2042 u8 code, u8 ident, u16 dlen, void *data)
2043{
2044 struct sk_buff *skb, **frag;
2045 struct l2cap_cmd_hdr *cmd;
2046 struct l2cap_hdr *lh;
2047 int len, count;
2048
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002049 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2050 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002051
2052 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2053 count = min_t(unsigned int, conn->mtu, len);
2054
2055 skb = bt_skb_alloc(count, GFP_ATOMIC);
2056 if (!skb)
2057 return NULL;
2058
2059 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002060 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002061 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002062
2063 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2064 cmd->code = code;
2065 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002066 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002067
2068 if (dlen) {
2069 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2070 memcpy(skb_put(skb, count), data, count);
2071 data += count;
2072 }
2073
2074 len -= skb->len;
2075
2076 /* Continuation fragments (no L2CAP header) */
2077 frag = &skb_shinfo(skb)->frag_list;
2078 while (len) {
2079 count = min_t(unsigned int, conn->mtu, len);
2080
2081 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2082 if (!*frag)
2083 goto fail;
2084
2085 memcpy(skb_put(*frag, count), data, count);
2086
2087 len -= count;
2088 data += count;
2089
2090 frag = &(*frag)->next;
2091 }
2092
2093 return skb;
2094
2095fail:
2096 kfree_skb(skb);
2097 return NULL;
2098}
2099
2100static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2101{
2102 struct l2cap_conf_opt *opt = *ptr;
2103 int len;
2104
2105 len = L2CAP_CONF_OPT_SIZE + opt->len;
2106 *ptr += len;
2107
2108 *type = opt->type;
2109 *olen = opt->len;
2110
2111 switch (opt->len) {
2112 case 1:
2113 *val = *((u8 *) opt->val);
2114 break;
2115
2116 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002117 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002118 break;
2119
2120 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002121 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002122 break;
2123
2124 default:
2125 *val = (unsigned long) opt->val;
2126 break;
2127 }
2128
2129 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2130 return len;
2131}
2132
Linus Torvalds1da177e2005-04-16 15:20:36 -07002133static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2134{
2135 struct l2cap_conf_opt *opt = *ptr;
2136
2137 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2138
2139 opt->type = type;
2140 opt->len = len;
2141
2142 switch (len) {
2143 case 1:
2144 *((u8 *) opt->val) = val;
2145 break;
2146
2147 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002148 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002149 break;
2150
2151 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002152 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002153 break;
2154
2155 default:
2156 memcpy(opt->val, (void *) val, len);
2157 break;
2158 }
2159
2160 *ptr += L2CAP_CONF_OPT_SIZE + len;
2161}
2162
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002163static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2164{
2165 u32 local_feat_mask = l2cap_feat_mask;
2166 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002167 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002168
2169 switch (mode) {
2170 case L2CAP_MODE_ERTM:
2171 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2172 case L2CAP_MODE_STREAMING:
2173 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2174 default:
2175 return 0x00;
2176 }
2177}
2178
2179static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2180{
2181 switch (mode) {
2182 case L2CAP_MODE_STREAMING:
2183 case L2CAP_MODE_ERTM:
2184 if (l2cap_mode_supported(mode, remote_feat_mask))
2185 return mode;
2186 /* fall through */
2187 default:
2188 return L2CAP_MODE_BASIC;
2189 }
2190}
2191
Linus Torvalds1da177e2005-04-16 15:20:36 -07002192static int l2cap_build_conf_req(struct sock *sk, void *data)
2193{
2194 struct l2cap_pinfo *pi = l2cap_pi(sk);
2195 struct l2cap_conf_req *req = data;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002196 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_ERTM };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002197 void *ptr = req->data;
2198
2199 BT_DBG("sk %p", sk);
2200
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002201 if (pi->num_conf_req || pi->num_conf_rsp)
2202 goto done;
2203
2204 switch (pi->mode) {
2205 case L2CAP_MODE_STREAMING:
2206 case L2CAP_MODE_ERTM:
2207 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002208 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2209 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002210 break;
2211 default:
2212 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2213 break;
2214 }
2215
2216done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002217 switch (pi->mode) {
2218 case L2CAP_MODE_BASIC:
2219 if (pi->imtu != L2CAP_DEFAULT_MTU)
2220 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2221 break;
2222
2223 case L2CAP_MODE_ERTM:
2224 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002225 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002226 rfc.max_transmit = L2CAP_DEFAULT_MAX_TX;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002227 rfc.retrans_timeout = 0;
2228 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002229 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002230
2231 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2232 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002233
2234 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2235 break;
2236
2237 if (pi->fcs == L2CAP_FCS_NONE ||
2238 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2239 pi->fcs = L2CAP_FCS_NONE;
2240 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2241 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002242 break;
2243
2244 case L2CAP_MODE_STREAMING:
2245 rfc.mode = L2CAP_MODE_STREAMING;
2246 rfc.txwin_size = 0;
2247 rfc.max_transmit = 0;
2248 rfc.retrans_timeout = 0;
2249 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002250 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002251
2252 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2253 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002254
2255 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2256 break;
2257
2258 if (pi->fcs == L2CAP_FCS_NONE ||
2259 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2260 pi->fcs = L2CAP_FCS_NONE;
2261 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2262 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002263 break;
2264 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002265
2266 /* FIXME: Need actual value of the flush timeout */
2267 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2268 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2269
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002270 req->dcid = cpu_to_le16(pi->dcid);
2271 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002272
2273 return ptr - data;
2274}
2275
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002276static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002277{
2278 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002279 struct l2cap_conf_rsp *rsp = data;
2280 void *ptr = rsp->data;
2281 void *req = pi->conf_req;
2282 int len = pi->conf_len;
2283 int type, hint, olen;
2284 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002285 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002286 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002287 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002288
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002289 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002290
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002291 while (len >= L2CAP_CONF_OPT_SIZE) {
2292 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002293
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002294 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002295 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002296
2297 switch (type) {
2298 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002299 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002300 break;
2301
2302 case L2CAP_CONF_FLUSH_TO:
2303 pi->flush_to = val;
2304 break;
2305
2306 case L2CAP_CONF_QOS:
2307 break;
2308
Marcel Holtmann6464f352007-10-20 13:39:51 +02002309 case L2CAP_CONF_RFC:
2310 if (olen == sizeof(rfc))
2311 memcpy(&rfc, (void *) val, olen);
2312 break;
2313
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002314 case L2CAP_CONF_FCS:
2315 if (val == L2CAP_FCS_NONE)
2316 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2317
2318 break;
2319
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002320 default:
2321 if (hint)
2322 break;
2323
2324 result = L2CAP_CONF_UNKNOWN;
2325 *((u8 *) ptr++) = type;
2326 break;
2327 }
2328 }
2329
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002330 if (pi->num_conf_rsp || pi->num_conf_req)
2331 goto done;
2332
2333 switch (pi->mode) {
2334 case L2CAP_MODE_STREAMING:
2335 case L2CAP_MODE_ERTM:
2336 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2337 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2338 return -ECONNREFUSED;
2339 break;
2340 default:
2341 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2342 break;
2343 }
2344
2345done:
2346 if (pi->mode != rfc.mode) {
2347 result = L2CAP_CONF_UNACCEPT;
2348 rfc.mode = pi->mode;
2349
2350 if (pi->num_conf_rsp == 1)
2351 return -ECONNREFUSED;
2352
2353 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2354 sizeof(rfc), (unsigned long) &rfc);
2355 }
2356
2357
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002358 if (result == L2CAP_CONF_SUCCESS) {
2359 /* Configure output options and let the other side know
2360 * which ones we don't like. */
2361
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002362 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2363 result = L2CAP_CONF_UNACCEPT;
2364 else {
2365 pi->omtu = mtu;
2366 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2367 }
2368 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002369
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002370 switch (rfc.mode) {
2371 case L2CAP_MODE_BASIC:
2372 pi->fcs = L2CAP_FCS_NONE;
2373 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2374 break;
2375
2376 case L2CAP_MODE_ERTM:
2377 pi->remote_tx_win = rfc.txwin_size;
2378 pi->remote_max_tx = rfc.max_transmit;
2379 pi->max_pdu_size = rfc.max_pdu_size;
2380
2381 rfc.retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
2382 rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
2383
2384 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2385 break;
2386
2387 case L2CAP_MODE_STREAMING:
2388 pi->remote_tx_win = rfc.txwin_size;
2389 pi->max_pdu_size = rfc.max_pdu_size;
2390
2391 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2392 break;
2393
2394 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002395 result = L2CAP_CONF_UNACCEPT;
2396
2397 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002398 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002399 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002400
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002401 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2402 sizeof(rfc), (unsigned long) &rfc);
2403
2404 if (result == L2CAP_CONF_SUCCESS)
2405 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2406 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002407 rsp->scid = cpu_to_le16(pi->dcid);
2408 rsp->result = cpu_to_le16(result);
2409 rsp->flags = cpu_to_le16(0x0000);
2410
2411 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002412}
2413
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002414static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2415{
2416 struct l2cap_pinfo *pi = l2cap_pi(sk);
2417 struct l2cap_conf_req *req = data;
2418 void *ptr = req->data;
2419 int type, olen;
2420 unsigned long val;
2421 struct l2cap_conf_rfc rfc;
2422
2423 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2424
2425 while (len >= L2CAP_CONF_OPT_SIZE) {
2426 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2427
2428 switch (type) {
2429 case L2CAP_CONF_MTU:
2430 if (val < L2CAP_DEFAULT_MIN_MTU) {
2431 *result = L2CAP_CONF_UNACCEPT;
2432 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2433 } else
2434 pi->omtu = val;
2435 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2436 break;
2437
2438 case L2CAP_CONF_FLUSH_TO:
2439 pi->flush_to = val;
2440 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2441 2, pi->flush_to);
2442 break;
2443
2444 case L2CAP_CONF_RFC:
2445 if (olen == sizeof(rfc))
2446 memcpy(&rfc, (void *)val, olen);
2447
2448 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2449 rfc.mode != pi->mode)
2450 return -ECONNREFUSED;
2451
2452 pi->mode = rfc.mode;
2453 pi->fcs = 0;
2454
2455 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2456 sizeof(rfc), (unsigned long) &rfc);
2457 break;
2458 }
2459 }
2460
2461 if (*result == L2CAP_CONF_SUCCESS) {
2462 switch (rfc.mode) {
2463 case L2CAP_MODE_ERTM:
2464 pi->remote_tx_win = rfc.txwin_size;
2465 pi->retrans_timeout = rfc.retrans_timeout;
2466 pi->monitor_timeout = rfc.monitor_timeout;
2467 pi->max_pdu_size = le16_to_cpu(rfc.max_pdu_size);
2468 break;
2469 case L2CAP_MODE_STREAMING:
2470 pi->max_pdu_size = le16_to_cpu(rfc.max_pdu_size);
2471 break;
2472 }
2473 }
2474
2475 req->dcid = cpu_to_le16(pi->dcid);
2476 req->flags = cpu_to_le16(0x0000);
2477
2478 return ptr - data;
2479}
2480
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002481static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002482{
2483 struct l2cap_conf_rsp *rsp = data;
2484 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002485
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002486 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002487
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002488 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002489 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002490 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002491
2492 return ptr - data;
2493}
2494
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002495static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2496{
2497 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2498
2499 if (rej->reason != 0x0000)
2500 return 0;
2501
2502 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2503 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002504 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002505
2506 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002507 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002508
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002509 l2cap_conn_start(conn);
2510 }
2511
2512 return 0;
2513}
2514
Linus Torvalds1da177e2005-04-16 15:20:36 -07002515static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2516{
2517 struct l2cap_chan_list *list = &conn->chan_list;
2518 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2519 struct l2cap_conn_rsp rsp;
2520 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002521 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002522
2523 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002524 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002525
2526 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2527
2528 /* Check if we have socket listening on psm */
2529 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2530 if (!parent) {
2531 result = L2CAP_CR_BAD_PSM;
2532 goto sendresp;
2533 }
2534
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002535 /* Check if the ACL is secure enough (if not SDP) */
2536 if (psm != cpu_to_le16(0x0001) &&
2537 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002538 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002539 result = L2CAP_CR_SEC_BLOCK;
2540 goto response;
2541 }
2542
Linus Torvalds1da177e2005-04-16 15:20:36 -07002543 result = L2CAP_CR_NO_MEM;
2544
2545 /* Check for backlog size */
2546 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002547 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002548 goto response;
2549 }
2550
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002551 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002552 if (!sk)
2553 goto response;
2554
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002555 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002556
2557 /* Check if we already have channel with that dcid */
2558 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002559 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002560 sock_set_flag(sk, SOCK_ZAPPED);
2561 l2cap_sock_kill(sk);
2562 goto response;
2563 }
2564
2565 hci_conn_hold(conn->hcon);
2566
2567 l2cap_sock_init(sk, parent);
2568 bacpy(&bt_sk(sk)->src, conn->src);
2569 bacpy(&bt_sk(sk)->dst, conn->dst);
2570 l2cap_pi(sk)->psm = psm;
2571 l2cap_pi(sk)->dcid = scid;
2572
2573 __l2cap_chan_add(conn, sk, parent);
2574 dcid = l2cap_pi(sk)->scid;
2575
2576 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2577
Linus Torvalds1da177e2005-04-16 15:20:36 -07002578 l2cap_pi(sk)->ident = cmd->ident;
2579
Marcel Holtmann984947d2009-02-06 23:35:19 +01002580 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002581 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002582 if (bt_sk(sk)->defer_setup) {
2583 sk->sk_state = BT_CONNECT2;
2584 result = L2CAP_CR_PEND;
2585 status = L2CAP_CS_AUTHOR_PEND;
2586 parent->sk_data_ready(parent, 0);
2587 } else {
2588 sk->sk_state = BT_CONFIG;
2589 result = L2CAP_CR_SUCCESS;
2590 status = L2CAP_CS_NO_INFO;
2591 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002592 } else {
2593 sk->sk_state = BT_CONNECT2;
2594 result = L2CAP_CR_PEND;
2595 status = L2CAP_CS_AUTHEN_PEND;
2596 }
2597 } else {
2598 sk->sk_state = BT_CONNECT2;
2599 result = L2CAP_CR_PEND;
2600 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002601 }
2602
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002603 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604
2605response:
2606 bh_unlock_sock(parent);
2607
2608sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002609 rsp.scid = cpu_to_le16(scid);
2610 rsp.dcid = cpu_to_le16(dcid);
2611 rsp.result = cpu_to_le16(result);
2612 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002613 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002614
2615 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2616 struct l2cap_info_req info;
2617 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2618
2619 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2620 conn->info_ident = l2cap_get_ident(conn);
2621
2622 mod_timer(&conn->info_timer, jiffies +
2623 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2624
2625 l2cap_send_cmd(conn, conn->info_ident,
2626 L2CAP_INFO_REQ, sizeof(info), &info);
2627 }
2628
Linus Torvalds1da177e2005-04-16 15:20:36 -07002629 return 0;
2630}
2631
2632static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2633{
2634 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2635 u16 scid, dcid, result, status;
2636 struct sock *sk;
2637 u8 req[128];
2638
2639 scid = __le16_to_cpu(rsp->scid);
2640 dcid = __le16_to_cpu(rsp->dcid);
2641 result = __le16_to_cpu(rsp->result);
2642 status = __le16_to_cpu(rsp->status);
2643
2644 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2645
2646 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002647 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2648 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002649 return 0;
2650 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002651 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2652 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002653 return 0;
2654 }
2655
2656 switch (result) {
2657 case L2CAP_CR_SUCCESS:
2658 sk->sk_state = BT_CONFIG;
2659 l2cap_pi(sk)->ident = 0;
2660 l2cap_pi(sk)->dcid = dcid;
2661 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2662
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002663 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2664
Linus Torvalds1da177e2005-04-16 15:20:36 -07002665 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2666 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002667 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002668 break;
2669
2670 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002671 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002672 break;
2673
2674 default:
2675 l2cap_chan_del(sk, ECONNREFUSED);
2676 break;
2677 }
2678
2679 bh_unlock_sock(sk);
2680 return 0;
2681}
2682
Al Viro88219a02007-07-29 00:17:25 -07002683static 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 -07002684{
2685 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2686 u16 dcid, flags;
2687 u8 rsp[64];
2688 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002689 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002690
2691 dcid = __le16_to_cpu(req->dcid);
2692 flags = __le16_to_cpu(req->flags);
2693
2694 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2695
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002696 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2697 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002698 return -ENOENT;
2699
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002700 if (sk->sk_state == BT_DISCONN)
2701 goto unlock;
2702
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002703 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002704 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002705 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2706 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2707 l2cap_build_conf_rsp(sk, rsp,
2708 L2CAP_CONF_REJECT, flags), rsp);
2709 goto unlock;
2710 }
2711
2712 /* Store config. */
2713 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2714 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002715
2716 if (flags & 0x0001) {
2717 /* Incomplete config. Send empty response. */
2718 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002719 l2cap_build_conf_rsp(sk, rsp,
2720 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002721 goto unlock;
2722 }
2723
2724 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002725 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002726 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002727 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002728 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002729 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002730
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002731 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002732 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002733
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002734 /* Reset config buffer. */
2735 l2cap_pi(sk)->conf_len = 0;
2736
Marcel Holtmann876d9482007-10-20 13:35:42 +02002737 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2738 goto unlock;
2739
Linus Torvalds1da177e2005-04-16 15:20:36 -07002740 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002741 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV)
2742 || l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
2743 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2744
Linus Torvalds1da177e2005-04-16 15:20:36 -07002745 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002746 l2cap_pi(sk)->next_tx_seq = 0;
2747 l2cap_pi(sk)->expected_ack_seq = 0;
2748 l2cap_pi(sk)->unacked_frames = 0;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002749
2750 setup_timer(&l2cap_pi(sk)->retrans_timer,
2751 l2cap_retrans_timeout, (unsigned long) sk);
2752 setup_timer(&l2cap_pi(sk)->monitor_timer,
2753 l2cap_monitor_timeout, (unsigned long) sk);
2754
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002755 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002756 __skb_queue_head_init(SREJ_QUEUE(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002757 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002758 goto unlock;
2759 }
2760
2761 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002762 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002763 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002764 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002765 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002766 }
2767
2768unlock:
2769 bh_unlock_sock(sk);
2770 return 0;
2771}
2772
2773static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2774{
2775 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2776 u16 scid, flags, result;
2777 struct sock *sk;
2778
2779 scid = __le16_to_cpu(rsp->scid);
2780 flags = __le16_to_cpu(rsp->flags);
2781 result = __le16_to_cpu(rsp->result);
2782
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002783 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2784 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002785
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002786 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2787 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002788 return 0;
2789
2790 switch (result) {
2791 case L2CAP_CONF_SUCCESS:
2792 break;
2793
2794 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002795 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
2796 int len = cmd->len - sizeof(*rsp);
2797 char req[64];
2798
2799 /* throw out any old stored conf requests */
2800 result = L2CAP_CONF_SUCCESS;
2801 len = l2cap_parse_conf_rsp(sk, rsp->data,
2802 len, req, &result);
2803 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002804 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002805 goto done;
2806 }
2807
2808 l2cap_send_cmd(conn, l2cap_get_ident(conn),
2809 L2CAP_CONF_REQ, len, req);
2810 l2cap_pi(sk)->num_conf_req++;
2811 if (result != L2CAP_CONF_SUCCESS)
2812 goto done;
2813 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002814 }
2815
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002816 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002818 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002819 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002820 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002821 goto done;
2822 }
2823
2824 if (flags & 0x01)
2825 goto done;
2826
Linus Torvalds1da177e2005-04-16 15:20:36 -07002827 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
2828
2829 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002830 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV)
2831 || l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
2832 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2833
Linus Torvalds1da177e2005-04-16 15:20:36 -07002834 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002835 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002836 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002837 l2cap_pi(sk)->num_to_ack = 0;
2838 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002839 __skb_queue_head_init(SREJ_QUEUE(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002840 l2cap_chan_ready(sk);
2841 }
2842
2843done:
2844 bh_unlock_sock(sk);
2845 return 0;
2846}
2847
2848static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2849{
2850 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
2851 struct l2cap_disconn_rsp rsp;
2852 u16 dcid, scid;
2853 struct sock *sk;
2854
2855 scid = __le16_to_cpu(req->scid);
2856 dcid = __le16_to_cpu(req->dcid);
2857
2858 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
2859
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002860 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2861 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002862 return 0;
2863
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002864 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
2865 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002866 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
2867
2868 sk->sk_shutdown = SHUTDOWN_MASK;
2869
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002870 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002871 skb_queue_purge(SREJ_QUEUE(sk));
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002872 del_timer(&l2cap_pi(sk)->retrans_timer);
2873 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002874
Linus Torvalds1da177e2005-04-16 15:20:36 -07002875 l2cap_chan_del(sk, ECONNRESET);
2876 bh_unlock_sock(sk);
2877
2878 l2cap_sock_kill(sk);
2879 return 0;
2880}
2881
2882static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2883{
2884 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
2885 u16 dcid, scid;
2886 struct sock *sk;
2887
2888 scid = __le16_to_cpu(rsp->scid);
2889 dcid = __le16_to_cpu(rsp->dcid);
2890
2891 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
2892
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002893 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2894 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002895 return 0;
2896
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002897 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002898 skb_queue_purge(SREJ_QUEUE(sk));
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002899 del_timer(&l2cap_pi(sk)->retrans_timer);
2900 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002901
Linus Torvalds1da177e2005-04-16 15:20:36 -07002902 l2cap_chan_del(sk, 0);
2903 bh_unlock_sock(sk);
2904
2905 l2cap_sock_kill(sk);
2906 return 0;
2907}
2908
2909static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2910{
2911 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002912 u16 type;
2913
2914 type = __le16_to_cpu(req->type);
2915
2916 BT_DBG("type 0x%4.4x", type);
2917
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002918 if (type == L2CAP_IT_FEAT_MASK) {
2919 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07002920 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002921 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2922 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2923 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07002924 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002925 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
2926 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03002927 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002928 l2cap_send_cmd(conn, cmd->ident,
2929 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002930 } else if (type == L2CAP_IT_FIXED_CHAN) {
2931 u8 buf[12];
2932 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2933 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
2934 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
2935 memcpy(buf + 4, l2cap_fixed_chan, 8);
2936 l2cap_send_cmd(conn, cmd->ident,
2937 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002938 } else {
2939 struct l2cap_info_rsp rsp;
2940 rsp.type = cpu_to_le16(type);
2941 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
2942 l2cap_send_cmd(conn, cmd->ident,
2943 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
2944 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002945
2946 return 0;
2947}
2948
2949static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2950{
2951 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
2952 u16 type, result;
2953
2954 type = __le16_to_cpu(rsp->type);
2955 result = __le16_to_cpu(rsp->result);
2956
2957 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
2958
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002959 del_timer(&conn->info_timer);
2960
Marcel Holtmann984947d2009-02-06 23:35:19 +01002961 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07002962 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002963
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002964 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002965 struct l2cap_info_req req;
2966 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
2967
2968 conn->info_ident = l2cap_get_ident(conn);
2969
2970 l2cap_send_cmd(conn, conn->info_ident,
2971 L2CAP_INFO_REQ, sizeof(req), &req);
2972 } else {
2973 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
2974 conn->info_ident = 0;
2975
2976 l2cap_conn_start(conn);
2977 }
2978 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01002979 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002980 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002981
2982 l2cap_conn_start(conn);
2983 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002984
Linus Torvalds1da177e2005-04-16 15:20:36 -07002985 return 0;
2986}
2987
2988static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
2989{
2990 u8 *data = skb->data;
2991 int len = skb->len;
2992 struct l2cap_cmd_hdr cmd;
2993 int err = 0;
2994
2995 l2cap_raw_recv(conn, skb);
2996
2997 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07002998 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002999 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3000 data += L2CAP_CMD_HDR_SIZE;
3001 len -= L2CAP_CMD_HDR_SIZE;
3002
Al Viro88219a02007-07-29 00:17:25 -07003003 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003004
Al Viro88219a02007-07-29 00:17:25 -07003005 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 -07003006
Al Viro88219a02007-07-29 00:17:25 -07003007 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003008 BT_DBG("corrupted command");
3009 break;
3010 }
3011
3012 switch (cmd.code) {
3013 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003014 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003015 break;
3016
3017 case L2CAP_CONN_REQ:
3018 err = l2cap_connect_req(conn, &cmd, data);
3019 break;
3020
3021 case L2CAP_CONN_RSP:
3022 err = l2cap_connect_rsp(conn, &cmd, data);
3023 break;
3024
3025 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003026 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003027 break;
3028
3029 case L2CAP_CONF_RSP:
3030 err = l2cap_config_rsp(conn, &cmd, data);
3031 break;
3032
3033 case L2CAP_DISCONN_REQ:
3034 err = l2cap_disconnect_req(conn, &cmd, data);
3035 break;
3036
3037 case L2CAP_DISCONN_RSP:
3038 err = l2cap_disconnect_rsp(conn, &cmd, data);
3039 break;
3040
3041 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003042 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003043 break;
3044
3045 case L2CAP_ECHO_RSP:
3046 break;
3047
3048 case L2CAP_INFO_REQ:
3049 err = l2cap_information_req(conn, &cmd, data);
3050 break;
3051
3052 case L2CAP_INFO_RSP:
3053 err = l2cap_information_rsp(conn, &cmd, data);
3054 break;
3055
3056 default:
3057 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3058 err = -EINVAL;
3059 break;
3060 }
3061
3062 if (err) {
3063 struct l2cap_cmd_rej rej;
3064 BT_DBG("error %d", err);
3065
3066 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003067 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003068 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3069 }
3070
Al Viro88219a02007-07-29 00:17:25 -07003071 data += cmd_len;
3072 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003073 }
3074
3075 kfree_skb(skb);
3076}
3077
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003078static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3079{
3080 u16 our_fcs, rcv_fcs;
3081 int hdr_size = L2CAP_HDR_SIZE + 2;
3082
3083 if (pi->fcs == L2CAP_FCS_CRC16) {
3084 skb_trim(skb, skb->len - 2);
3085 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3086 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3087
3088 if (our_fcs != rcv_fcs)
3089 return -EINVAL;
3090 }
3091 return 0;
3092}
3093
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003094static void l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
3095{
3096 struct sk_buff *next_skb;
3097
3098 bt_cb(skb)->tx_seq = tx_seq;
3099 bt_cb(skb)->sar = sar;
3100
3101 next_skb = skb_peek(SREJ_QUEUE(sk));
3102 if (!next_skb) {
3103 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3104 return;
3105 }
3106
3107 do {
3108 if (bt_cb(next_skb)->tx_seq > tx_seq) {
3109 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
3110 return;
3111 }
3112
3113 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3114 break;
3115
3116 } while((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
3117
3118 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3119}
3120
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003121static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3122{
3123 struct l2cap_pinfo *pi = l2cap_pi(sk);
3124 struct sk_buff *_skb;
3125 int err = -EINVAL;
3126
3127 switch (control & L2CAP_CTRL_SAR) {
3128 case L2CAP_SDU_UNSEGMENTED:
3129 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3130 kfree_skb(pi->sdu);
3131 break;
3132 }
3133
3134 err = sock_queue_rcv_skb(sk, skb);
3135 if (!err)
3136 return 0;
3137
3138 break;
3139
3140 case L2CAP_SDU_START:
3141 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3142 kfree_skb(pi->sdu);
3143 break;
3144 }
3145
3146 pi->sdu_len = get_unaligned_le16(skb->data);
3147 skb_pull(skb, 2);
3148
3149 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3150 if (!pi->sdu) {
3151 err = -ENOMEM;
3152 break;
3153 }
3154
3155 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3156
3157 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3158 pi->partial_sdu_len = skb->len;
3159 err = 0;
3160 break;
3161
3162 case L2CAP_SDU_CONTINUE:
3163 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3164 break;
3165
3166 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3167
3168 pi->partial_sdu_len += skb->len;
3169 if (pi->partial_sdu_len > pi->sdu_len)
3170 kfree_skb(pi->sdu);
3171 else
3172 err = 0;
3173
3174 break;
3175
3176 case L2CAP_SDU_END:
3177 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3178 break;
3179
3180 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3181
3182 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3183 pi->partial_sdu_len += skb->len;
3184
3185 if (pi->partial_sdu_len == pi->sdu_len) {
3186 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3187 err = sock_queue_rcv_skb(sk, _skb);
3188 if (err < 0)
3189 kfree_skb(_skb);
3190 }
3191 kfree_skb(pi->sdu);
3192 err = 0;
3193
3194 break;
3195 }
3196
3197 kfree_skb(skb);
3198 return err;
3199}
3200
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003201static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3202{
3203 struct sk_buff *skb;
3204 u16 control = 0;
3205
3206 while((skb = skb_peek(SREJ_QUEUE(sk)))) {
3207 if (bt_cb(skb)->tx_seq != tx_seq)
3208 break;
3209
3210 skb = skb_dequeue(SREJ_QUEUE(sk));
3211 control |= bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3212 l2cap_sar_reassembly_sdu(sk, skb, control);
3213 l2cap_pi(sk)->buffer_seq_srej =
3214 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
3215 tx_seq++;
3216 }
3217}
3218
3219static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3220{
3221 struct l2cap_pinfo *pi = l2cap_pi(sk);
3222 struct srej_list *l, *tmp;
3223 u16 control;
3224
3225 list_for_each_entry_safe(l,tmp, SREJ_LIST(sk), list) {
3226 if (l->tx_seq == tx_seq) {
3227 list_del(&l->list);
3228 kfree(l);
3229 return;
3230 }
3231 control = L2CAP_SUPER_SELECT_REJECT;
3232 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3233 l2cap_send_sframe(pi, control);
3234 list_del(&l->list);
3235 list_add_tail(&l->list, SREJ_LIST(sk));
3236 }
3237}
3238
3239static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3240{
3241 struct l2cap_pinfo *pi = l2cap_pi(sk);
3242 struct srej_list *new;
3243 u16 control;
3244
3245 while (tx_seq != pi->expected_tx_seq) {
3246 control = L2CAP_SUPER_SELECT_REJECT;
3247 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003248 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
3249 control |= L2CAP_CTRL_POLL;
3250 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
3251 }
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003252 l2cap_send_sframe(pi, control);
3253
3254 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
3255 new->tx_seq = pi->expected_tx_seq++;
3256 list_add_tail(&new->list, SREJ_LIST(sk));
3257 }
3258 pi->expected_tx_seq++;
3259}
3260
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003261static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3262{
3263 struct l2cap_pinfo *pi = l2cap_pi(sk);
3264 u8 tx_seq = __get_txseq(rx_control);
3265 u16 tx_control = 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003266 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003267 int err = 0;
3268
3269 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3270
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003271 if (tx_seq == pi->expected_tx_seq)
3272 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003273
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003274 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3275 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003276
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003277 first = list_first_entry(SREJ_LIST(sk),
3278 struct srej_list, list);
3279 if (tx_seq == first->tx_seq) {
3280 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3281 l2cap_check_srej_gap(sk, tx_seq);
3282
3283 list_del(&first->list);
3284 kfree(first);
3285
3286 if (list_empty(SREJ_LIST(sk))) {
3287 pi->buffer_seq = pi->buffer_seq_srej;
3288 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
3289 }
3290 } else {
3291 struct srej_list *l;
3292 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3293
3294 list_for_each_entry(l, SREJ_LIST(sk), list) {
3295 if (l->tx_seq == tx_seq) {
3296 l2cap_resend_srejframe(sk, tx_seq);
3297 return 0;
3298 }
3299 }
3300 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003301 }
3302 } else {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003303 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003304
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003305 INIT_LIST_HEAD(SREJ_LIST(sk));
3306 pi->buffer_seq_srej = pi->buffer_seq;
3307
3308 __skb_queue_head_init(SREJ_QUEUE(sk));
3309 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3310
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003311 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3312
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003313 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003314 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003315 return 0;
3316
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003317expected:
3318 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3319
3320 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3321 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3322 return 0;
3323 }
3324
3325 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3326
3327 err = l2cap_sar_reassembly_sdu(sk, skb, rx_control);
3328 if (err < 0)
3329 return err;
3330
3331 pi->num_to_ack = (pi->num_to_ack + 1) % L2CAP_DEFAULT_NUM_TO_ACK;
3332 if (pi->num_to_ack == L2CAP_DEFAULT_NUM_TO_ACK - 1) {
3333 tx_control |= L2CAP_SUPER_RCV_READY;
3334 tx_control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3335 l2cap_send_sframe(pi, tx_control);
3336 }
3337 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003338}
3339
3340static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3341{
3342 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003343 u8 tx_seq = __get_reqseq(rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003344
3345 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3346
3347 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
3348 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003349 if (rx_control & L2CAP_CTRL_POLL) {
3350 u16 control = L2CAP_CTRL_FINAL;
3351 control |= L2CAP_SUPER_RCV_READY;
3352 l2cap_send_sframe(l2cap_pi(sk), control);
3353 } else if (rx_control & L2CAP_CTRL_FINAL) {
3354 if (!(pi->conn_state & L2CAP_CONN_WAIT_F))
3355 break;
3356
3357 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3358 del_timer(&pi->monitor_timer);
3359
3360 if (pi->unacked_frames > 0)
3361 __mod_retrans_timer();
3362 } else {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003363 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003364 l2cap_drop_acked_frames(sk);
3365 if (pi->unacked_frames > 0)
3366 __mod_retrans_timer();
3367 l2cap_ertm_send(sk);
3368 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003369 break;
3370
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003371 case L2CAP_SUPER_REJECT:
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003372 pi->expected_ack_seq = __get_reqseq(rx_control);
3373 l2cap_drop_acked_frames(sk);
3374
3375 sk->sk_send_head = TX_QUEUE(sk)->next;
3376 pi->next_tx_seq = pi->expected_ack_seq;
3377
3378 l2cap_ertm_send(sk);
3379
3380 break;
3381
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003382 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003383 if (rx_control & L2CAP_CTRL_POLL) {
3384 l2cap_retransmit_frame(sk, tx_seq);
3385 pi->expected_ack_seq = tx_seq;
3386 l2cap_drop_acked_frames(sk);
3387 l2cap_ertm_send(sk);
3388 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3389 pi->srej_save_reqseq = tx_seq;
3390 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3391 }
3392 } else if (rx_control & L2CAP_CTRL_FINAL) {
3393 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3394 pi->srej_save_reqseq == tx_seq)
3395 pi->srej_save_reqseq &= ~L2CAP_CONN_SREJ_ACT;
3396 else
3397 l2cap_retransmit_frame(sk, tx_seq);
3398 }
3399 else {
3400 l2cap_retransmit_frame(sk, tx_seq);
3401 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3402 pi->srej_save_reqseq = tx_seq;
3403 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3404 }
3405 }
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003406 break;
3407
3408 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003409 break;
3410 }
3411
3412 return 0;
3413}
3414
Linus Torvalds1da177e2005-04-16 15:20:36 -07003415static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
3416{
3417 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003418 struct l2cap_pinfo *pi;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003419 u16 control, len;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003420 u8 tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003421 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003422
3423 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3424 if (!sk) {
3425 BT_DBG("unknown cid 0x%4.4x", cid);
3426 goto drop;
3427 }
3428
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003429 pi = l2cap_pi(sk);
3430
Linus Torvalds1da177e2005-04-16 15:20:36 -07003431 BT_DBG("sk %p, len %d", sk, skb->len);
3432
3433 if (sk->sk_state != BT_CONNECTED)
3434 goto drop;
3435
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003436 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003437 case L2CAP_MODE_BASIC:
3438 /* If socket recv buffers overflows we drop data here
3439 * which is *bad* because L2CAP has to be reliable.
3440 * But we don't have any other choice. L2CAP doesn't
3441 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003442
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003443 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003444 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003445
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003446 if (!sock_queue_rcv_skb(sk, skb))
3447 goto done;
3448 break;
3449
3450 case L2CAP_MODE_ERTM:
3451 control = get_unaligned_le16(skb->data);
3452 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003453 len = skb->len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003454
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003455 if (__is_sar_start(control))
3456 len -= 2;
3457
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003458 if (pi->fcs == L2CAP_FCS_CRC16)
3459 len -= 2;
3460
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003461 /*
3462 * We can just drop the corrupted I-frame here.
3463 * Receiver will miss it and start proper recovery
3464 * procedures and ask retransmission.
3465 */
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003466 if (len > L2CAP_DEFAULT_MAX_PDU_SIZE)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003467 goto drop;
3468
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003469 if (l2cap_check_fcs(pi, skb))
3470 goto drop;
3471
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003472 if (__is_iframe(control))
3473 err = l2cap_data_channel_iframe(sk, control, skb);
3474 else
3475 err = l2cap_data_channel_sframe(sk, control, skb);
3476
3477 if (!err)
3478 goto done;
3479 break;
3480
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003481 case L2CAP_MODE_STREAMING:
3482 control = get_unaligned_le16(skb->data);
3483 skb_pull(skb, 2);
3484 len = skb->len;
3485
3486 if (__is_sar_start(control))
3487 len -= 2;
3488
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003489 if (pi->fcs == L2CAP_FCS_CRC16)
3490 len -= 2;
3491
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003492 if (len > L2CAP_DEFAULT_MAX_PDU_SIZE || __is_sframe(control))
3493 goto drop;
3494
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003495 if (l2cap_check_fcs(pi, skb))
3496 goto drop;
3497
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003498 tx_seq = __get_txseq(control);
3499
3500 if (pi->expected_tx_seq == tx_seq)
3501 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3502 else
3503 pi->expected_tx_seq = tx_seq + 1;
3504
3505 err = l2cap_sar_reassembly_sdu(sk, skb, control);
3506
3507 goto done;
3508
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003509 default:
3510 BT_DBG("sk %p: bad mode 0x%2.2x", sk, l2cap_pi(sk)->mode);
3511 break;
3512 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003513
3514drop:
3515 kfree_skb(skb);
3516
3517done:
Marcel Holtmann01394182006-07-03 10:02:46 +02003518 if (sk)
3519 bh_unlock_sock(sk);
3520
Linus Torvalds1da177e2005-04-16 15:20:36 -07003521 return 0;
3522}
3523
Al Viro8e036fc2007-07-29 00:16:36 -07003524static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003525{
3526 struct sock *sk;
3527
3528 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
3529 if (!sk)
3530 goto drop;
3531
3532 BT_DBG("sk %p, len %d", sk, skb->len);
3533
3534 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
3535 goto drop;
3536
3537 if (l2cap_pi(sk)->imtu < skb->len)
3538 goto drop;
3539
3540 if (!sock_queue_rcv_skb(sk, skb))
3541 goto done;
3542
3543drop:
3544 kfree_skb(skb);
3545
3546done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003547 if (sk)
3548 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003549 return 0;
3550}
3551
3552static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
3553{
3554 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07003555 u16 cid, len;
3556 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003557
3558 skb_pull(skb, L2CAP_HDR_SIZE);
3559 cid = __le16_to_cpu(lh->cid);
3560 len = __le16_to_cpu(lh->len);
3561
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003562 if (len != skb->len) {
3563 kfree_skb(skb);
3564 return;
3565 }
3566
Linus Torvalds1da177e2005-04-16 15:20:36 -07003567 BT_DBG("len %d, cid 0x%4.4x", len, cid);
3568
3569 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003570 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003571 l2cap_sig_channel(conn, skb);
3572 break;
3573
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003574 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003575 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003576 skb_pull(skb, 2);
3577 l2cap_conless_channel(conn, psm, skb);
3578 break;
3579
3580 default:
3581 l2cap_data_channel(conn, cid, skb);
3582 break;
3583 }
3584}
3585
3586/* ---- L2CAP interface with lower layer (HCI) ---- */
3587
3588static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3589{
3590 int exact = 0, lm1 = 0, lm2 = 0;
3591 register struct sock *sk;
3592 struct hlist_node *node;
3593
3594 if (type != ACL_LINK)
3595 return 0;
3596
3597 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
3598
3599 /* Find listening sockets and check their link_mode */
3600 read_lock(&l2cap_sk_list.lock);
3601 sk_for_each(sk, node, &l2cap_sk_list.head) {
3602 if (sk->sk_state != BT_LISTEN)
3603 continue;
3604
3605 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003606 lm1 |= HCI_LM_ACCEPT;
3607 if (l2cap_pi(sk)->role_switch)
3608 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003609 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003610 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
3611 lm2 |= HCI_LM_ACCEPT;
3612 if (l2cap_pi(sk)->role_switch)
3613 lm2 |= HCI_LM_MASTER;
3614 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003615 }
3616 read_unlock(&l2cap_sk_list.lock);
3617
3618 return exact ? lm1 : lm2;
3619}
3620
3621static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
3622{
Marcel Holtmann01394182006-07-03 10:02:46 +02003623 struct l2cap_conn *conn;
3624
Linus Torvalds1da177e2005-04-16 15:20:36 -07003625 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
3626
3627 if (hcon->type != ACL_LINK)
3628 return 0;
3629
3630 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003631 conn = l2cap_conn_add(hcon, status);
3632 if (conn)
3633 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02003634 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003635 l2cap_conn_del(hcon, bt_err(status));
3636
3637 return 0;
3638}
3639
Marcel Holtmann2950f212009-02-12 14:02:50 +01003640static int l2cap_disconn_ind(struct hci_conn *hcon)
3641{
3642 struct l2cap_conn *conn = hcon->l2cap_data;
3643
3644 BT_DBG("hcon %p", hcon);
3645
3646 if (hcon->type != ACL_LINK || !conn)
3647 return 0x13;
3648
3649 return conn->disc_reason;
3650}
3651
3652static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003653{
3654 BT_DBG("hcon %p reason %d", hcon, reason);
3655
3656 if (hcon->type != ACL_LINK)
3657 return 0;
3658
3659 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02003660
Linus Torvalds1da177e2005-04-16 15:20:36 -07003661 return 0;
3662}
3663
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003664static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
3665{
Marcel Holtmann255c7602009-02-04 21:07:19 +01003666 if (sk->sk_type != SOCK_SEQPACKET)
3667 return;
3668
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003669 if (encrypt == 0x00) {
3670 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
3671 l2cap_sock_clear_timer(sk);
3672 l2cap_sock_set_timer(sk, HZ * 5);
3673 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
3674 __l2cap_sock_close(sk, ECONNREFUSED);
3675 } else {
3676 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
3677 l2cap_sock_clear_timer(sk);
3678 }
3679}
3680
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003681static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003682{
3683 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02003684 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003685 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003686
Marcel Holtmann01394182006-07-03 10:02:46 +02003687 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003688 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02003689
Linus Torvalds1da177e2005-04-16 15:20:36 -07003690 l = &conn->chan_list;
3691
3692 BT_DBG("conn %p", conn);
3693
3694 read_lock(&l->lock);
3695
3696 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
3697 bh_lock_sock(sk);
3698
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003699 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
3700 bh_unlock_sock(sk);
3701 continue;
3702 }
3703
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003704 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003705 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003706 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02003707 bh_unlock_sock(sk);
3708 continue;
3709 }
3710
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003711 if (sk->sk_state == BT_CONNECT) {
3712 if (!status) {
3713 struct l2cap_conn_req req;
3714 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
3715 req.psm = l2cap_pi(sk)->psm;
3716
3717 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
3718
3719 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3720 L2CAP_CONN_REQ, sizeof(req), &req);
3721 } else {
3722 l2cap_sock_clear_timer(sk);
3723 l2cap_sock_set_timer(sk, HZ / 10);
3724 }
3725 } else if (sk->sk_state == BT_CONNECT2) {
3726 struct l2cap_conn_rsp rsp;
3727 __u16 result;
3728
3729 if (!status) {
3730 sk->sk_state = BT_CONFIG;
3731 result = L2CAP_CR_SUCCESS;
3732 } else {
3733 sk->sk_state = BT_DISCONN;
3734 l2cap_sock_set_timer(sk, HZ / 10);
3735 result = L2CAP_CR_SEC_BLOCK;
3736 }
3737
3738 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
3739 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3740 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003741 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003742 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3743 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003744 }
3745
Linus Torvalds1da177e2005-04-16 15:20:36 -07003746 bh_unlock_sock(sk);
3747 }
3748
3749 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003750
Linus Torvalds1da177e2005-04-16 15:20:36 -07003751 return 0;
3752}
3753
3754static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
3755{
3756 struct l2cap_conn *conn = hcon->l2cap_data;
3757
3758 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
3759 goto drop;
3760
3761 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
3762
3763 if (flags & ACL_START) {
3764 struct l2cap_hdr *hdr;
3765 int len;
3766
3767 if (conn->rx_len) {
3768 BT_ERR("Unexpected start frame (len %d)", skb->len);
3769 kfree_skb(conn->rx_skb);
3770 conn->rx_skb = NULL;
3771 conn->rx_len = 0;
3772 l2cap_conn_unreliable(conn, ECOMM);
3773 }
3774
3775 if (skb->len < 2) {
3776 BT_ERR("Frame is too short (len %d)", skb->len);
3777 l2cap_conn_unreliable(conn, ECOMM);
3778 goto drop;
3779 }
3780
3781 hdr = (struct l2cap_hdr *) skb->data;
3782 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
3783
3784 if (len == skb->len) {
3785 /* Complete frame received */
3786 l2cap_recv_frame(conn, skb);
3787 return 0;
3788 }
3789
3790 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
3791
3792 if (skb->len > len) {
3793 BT_ERR("Frame is too long (len %d, expected len %d)",
3794 skb->len, len);
3795 l2cap_conn_unreliable(conn, ECOMM);
3796 goto drop;
3797 }
3798
3799 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003800 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
3801 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003802 goto drop;
3803
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03003804 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003805 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003806 conn->rx_len = len - skb->len;
3807 } else {
3808 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
3809
3810 if (!conn->rx_len) {
3811 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
3812 l2cap_conn_unreliable(conn, ECOMM);
3813 goto drop;
3814 }
3815
3816 if (skb->len > conn->rx_len) {
3817 BT_ERR("Fragment is too long (len %d, expected %d)",
3818 skb->len, conn->rx_len);
3819 kfree_skb(conn->rx_skb);
3820 conn->rx_skb = NULL;
3821 conn->rx_len = 0;
3822 l2cap_conn_unreliable(conn, ECOMM);
3823 goto drop;
3824 }
3825
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03003826 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003827 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003828 conn->rx_len -= skb->len;
3829
3830 if (!conn->rx_len) {
3831 /* Complete frame received */
3832 l2cap_recv_frame(conn, conn->rx_skb);
3833 conn->rx_skb = NULL;
3834 }
3835 }
3836
3837drop:
3838 kfree_skb(skb);
3839 return 0;
3840}
3841
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003842static ssize_t l2cap_sysfs_show(struct class *dev, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003843{
3844 struct sock *sk;
3845 struct hlist_node *node;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003846 char *str = buf;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003847
3848 read_lock_bh(&l2cap_sk_list.lock);
3849
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003850 sk_for_each(sk, node, &l2cap_sk_list.head) {
3851 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003852
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003853 str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003854 batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
Marcel Holtmannb4324b52009-06-07 18:06:51 +02003855 sk->sk_state, __le16_to_cpu(pi->psm), pi->scid,
3856 pi->dcid, pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003857 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003858
Linus Torvalds1da177e2005-04-16 15:20:36 -07003859 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003860
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003861 return str - buf;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003862}
3863
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003864static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003865
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08003866static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003867 .family = PF_BLUETOOTH,
3868 .owner = THIS_MODULE,
3869 .release = l2cap_sock_release,
3870 .bind = l2cap_sock_bind,
3871 .connect = l2cap_sock_connect,
3872 .listen = l2cap_sock_listen,
3873 .accept = l2cap_sock_accept,
3874 .getname = l2cap_sock_getname,
3875 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003876 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003877 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02003878 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003879 .mmap = sock_no_mmap,
3880 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003881 .shutdown = l2cap_sock_shutdown,
3882 .setsockopt = l2cap_sock_setsockopt,
3883 .getsockopt = l2cap_sock_getsockopt
3884};
3885
3886static struct net_proto_family l2cap_sock_family_ops = {
3887 .family = PF_BLUETOOTH,
3888 .owner = THIS_MODULE,
3889 .create = l2cap_sock_create,
3890};
3891
3892static struct hci_proto l2cap_hci_proto = {
3893 .name = "L2CAP",
3894 .id = HCI_PROTO_L2CAP,
3895 .connect_ind = l2cap_connect_ind,
3896 .connect_cfm = l2cap_connect_cfm,
3897 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01003898 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003899 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003900 .recv_acldata = l2cap_recv_acldata
3901};
3902
3903static int __init l2cap_init(void)
3904{
3905 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003906
Linus Torvalds1da177e2005-04-16 15:20:36 -07003907 err = proto_register(&l2cap_proto, 0);
3908 if (err < 0)
3909 return err;
3910
3911 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
3912 if (err < 0) {
3913 BT_ERR("L2CAP socket registration failed");
3914 goto error;
3915 }
3916
3917 err = hci_register_proto(&l2cap_hci_proto);
3918 if (err < 0) {
3919 BT_ERR("L2CAP protocol registration failed");
3920 bt_sock_unregister(BTPROTO_L2CAP);
3921 goto error;
3922 }
3923
Marcel Holtmanndf5c37e2006-10-15 17:30:45 +02003924 if (class_create_file(bt_class, &class_attr_l2cap) < 0)
3925 BT_ERR("Failed to create L2CAP info file");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003926
3927 BT_INFO("L2CAP ver %s", VERSION);
3928 BT_INFO("L2CAP socket layer initialized");
3929
3930 return 0;
3931
3932error:
3933 proto_unregister(&l2cap_proto);
3934 return err;
3935}
3936
3937static void __exit l2cap_exit(void)
3938{
Marcel Holtmanna91f2e32006-07-03 10:02:41 +02003939 class_remove_file(bt_class, &class_attr_l2cap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003940
3941 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
3942 BT_ERR("L2CAP socket unregistration failed");
3943
3944 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
3945 BT_ERR("L2CAP protocol unregistration failed");
3946
3947 proto_unregister(&l2cap_proto);
3948}
3949
3950void l2cap_load(void)
3951{
3952 /* Dummy function to trigger automatic L2CAP module loading by
3953 * other modules that use L2CAP sockets but don't use any other
3954 * symbols from it. */
3955 return;
3956}
3957EXPORT_SYMBOL(l2cap_load);
3958
3959module_init(l2cap_init);
3960module_exit(l2cap_exit);
3961
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003962module_param(enable_ertm, bool, 0644);
3963MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
3964
Marcel Holtmann63fbd242008-08-18 13:23:53 +02003965MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003966MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
3967MODULE_VERSION(VERSION);
3968MODULE_LICENSE("GPL");
3969MODULE_ALIAS("bt-proto-0");