blob: 449cbdd4ddbb4d297fccb31a2ed495b7ea4bfd02 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth L2CAP core and sockets. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
Randy Dunlap4fc268d2006-01-11 12:17:47 -080030#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/errno.h>
32#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/sched.h>
34#include <linux/slab.h>
35#include <linux/poll.h>
36#include <linux/fcntl.h>
37#include <linux/init.h>
38#include <linux/interrupt.h>
39#include <linux/socket.h>
40#include <linux/skbuff.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <linux/list.h>
Marcel Holtmannbe9d1222005-11-08 09:57:38 -080042#include <linux/device.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010043#include <linux/debugfs.h>
44#include <linux/seq_file.h>
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -030045#include <linux/uaccess.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030046#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070047#include <net/sock.h>
48
49#include <asm/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070050#include <asm/unaligned.h>
51
52#include <net/bluetooth/bluetooth.h>
53#include <net/bluetooth/hci_core.h>
54#include <net/bluetooth/l2cap.h>
55
Marcel Holtmann44dd46d2009-05-02 19:09:01 -070056#define VERSION "2.14"
57
58static int enable_ertm = 0;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020059
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070060static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Marcel Holtmanne1027a72009-02-09 09:18:02 +010061static u8 l2cap_fixed_chan[8] = { 0x02, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070062
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080063static const struct proto_ops l2cap_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070064
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030065static struct workqueue_struct *_busy_wq;
66
Linus Torvalds1da177e2005-04-16 15:20:36 -070067static struct bt_sock_list l2cap_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070068 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070069};
70
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030071static void l2cap_busy_work(struct work_struct *work);
72
Linus Torvalds1da177e2005-04-16 15:20:36 -070073static void __l2cap_sock_close(struct sock *sk, int reason);
74static void l2cap_sock_close(struct sock *sk);
75static void l2cap_sock_kill(struct sock *sk);
76
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -030077static int l2cap_build_conf_req(struct sock *sk, void *data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070078static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
79 u8 code, u8 ident, u16 dlen, void *data);
80
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -030081static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
82
Linus Torvalds1da177e2005-04-16 15:20:36 -070083/* ---- L2CAP timers ---- */
84static void l2cap_sock_timeout(unsigned long arg)
85{
86 struct sock *sk = (struct sock *) arg;
Marcel Holtmannb1235d72008-07-14 20:13:54 +020087 int reason;
Linus Torvalds1da177e2005-04-16 15:20:36 -070088
89 BT_DBG("sock %p state %d", sk, sk->sk_state);
90
91 bh_lock_sock(sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +020092
Marcel Holtmannf62e4322009-01-15 21:58:44 +010093 if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
94 reason = ECONNREFUSED;
95 else if (sk->sk_state == BT_CONNECT &&
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +010096 l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
Marcel Holtmannb1235d72008-07-14 20:13:54 +020097 reason = ECONNREFUSED;
98 else
99 reason = ETIMEDOUT;
100
101 __l2cap_sock_close(sk, reason);
102
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103 bh_unlock_sock(sk);
104
105 l2cap_sock_kill(sk);
106 sock_put(sk);
107}
108
109static void l2cap_sock_set_timer(struct sock *sk, long timeout)
110{
111 BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
112 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
113}
114
115static void l2cap_sock_clear_timer(struct sock *sk)
116{
117 BT_DBG("sock %p state %d", sk, sk->sk_state);
118 sk_stop_timer(sk, &sk->sk_timer);
119}
120
Marcel Holtmann01394182006-07-03 10:02:46 +0200121/* ---- L2CAP channels ---- */
122static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
123{
124 struct sock *s;
125 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
126 if (l2cap_pi(s)->dcid == cid)
127 break;
128 }
129 return s;
130}
131
132static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
133{
134 struct sock *s;
135 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
136 if (l2cap_pi(s)->scid == cid)
137 break;
138 }
139 return s;
140}
141
142/* Find channel with given SCID.
143 * Returns locked socket */
144static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
145{
146 struct sock *s;
147 read_lock(&l->lock);
148 s = __l2cap_get_chan_by_scid(l, cid);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300149 if (s)
150 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200151 read_unlock(&l->lock);
152 return s;
153}
154
155static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
156{
157 struct sock *s;
158 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
159 if (l2cap_pi(s)->ident == ident)
160 break;
161 }
162 return s;
163}
164
165static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
166{
167 struct sock *s;
168 read_lock(&l->lock);
169 s = __l2cap_get_chan_by_ident(l, ident);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300170 if (s)
171 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200172 read_unlock(&l->lock);
173 return s;
174}
175
176static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
177{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300178 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200179
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300180 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300181 if (!__l2cap_get_chan_by_scid(l, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200182 return cid;
183 }
184
185 return 0;
186}
187
188static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
189{
190 sock_hold(sk);
191
192 if (l->head)
193 l2cap_pi(l->head)->prev_c = sk;
194
195 l2cap_pi(sk)->next_c = l->head;
196 l2cap_pi(sk)->prev_c = NULL;
197 l->head = sk;
198}
199
200static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
201{
202 struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
203
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200204 write_lock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200205 if (sk == l->head)
206 l->head = next;
207
208 if (next)
209 l2cap_pi(next)->prev_c = prev;
210 if (prev)
211 l2cap_pi(prev)->next_c = next;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200212 write_unlock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200213
214 __sock_put(sk);
215}
216
217static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
218{
219 struct l2cap_chan_list *l = &conn->chan_list;
220
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300221 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
222 l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200223
Marcel Holtmann2950f212009-02-12 14:02:50 +0100224 conn->disc_reason = 0x13;
225
Marcel Holtmann01394182006-07-03 10:02:46 +0200226 l2cap_pi(sk)->conn = conn;
227
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300228 if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200229 /* Alloc CID for connection-oriented socket */
230 l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
231 } else if (sk->sk_type == SOCK_DGRAM) {
232 /* Connectionless socket */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300233 l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
234 l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
Marcel Holtmann01394182006-07-03 10:02:46 +0200235 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
236 } else {
237 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300238 l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
239 l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
Marcel Holtmann01394182006-07-03 10:02:46 +0200240 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
241 }
242
243 __l2cap_chan_link(l, sk);
244
245 if (parent)
246 bt_accept_enqueue(parent, sk);
247}
248
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900249/* Delete channel.
Marcel Holtmann01394182006-07-03 10:02:46 +0200250 * Must be called on the locked socket. */
251static void l2cap_chan_del(struct sock *sk, int err)
252{
253 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
254 struct sock *parent = bt_sk(sk)->parent;
255
256 l2cap_sock_clear_timer(sk);
257
258 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
259
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900260 if (conn) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200261 /* Unlink from channel list */
262 l2cap_chan_unlink(&conn->chan_list, sk);
263 l2cap_pi(sk)->conn = NULL;
264 hci_conn_put(conn->hcon);
265 }
266
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200267 sk->sk_state = BT_CLOSED;
Marcel Holtmann01394182006-07-03 10:02:46 +0200268 sock_set_flag(sk, SOCK_ZAPPED);
269
270 if (err)
271 sk->sk_err = err;
272
273 if (parent) {
274 bt_accept_unlink(sk);
275 parent->sk_data_ready(parent, 0);
276 } else
277 sk->sk_state_change(sk);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300278
279 skb_queue_purge(TX_QUEUE(sk));
280
281 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
282 struct srej_list *l, *tmp;
283
284 del_timer(&l2cap_pi(sk)->retrans_timer);
285 del_timer(&l2cap_pi(sk)->monitor_timer);
286 del_timer(&l2cap_pi(sk)->ack_timer);
287
288 skb_queue_purge(SREJ_QUEUE(sk));
289 skb_queue_purge(BUSY_QUEUE(sk));
290
291 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
292 list_del(&l->list);
293 kfree(l);
294 }
295 }
Marcel Holtmann01394182006-07-03 10:02:46 +0200296}
297
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200298/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100299static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200300{
301 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100302 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200303
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100304 if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
305 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
306 auth_type = HCI_AT_NO_BONDING_MITM;
307 else
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300308 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100309
310 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
311 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
312 } else {
313 switch (l2cap_pi(sk)->sec_level) {
314 case BT_SECURITY_HIGH:
315 auth_type = HCI_AT_GENERAL_BONDING_MITM;
316 break;
317 case BT_SECURITY_MEDIUM:
318 auth_type = HCI_AT_GENERAL_BONDING;
319 break;
320 default:
321 auth_type = HCI_AT_NO_BONDING;
322 break;
323 }
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100324 }
325
326 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
327 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200328}
329
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200330static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
331{
332 u8 id;
333
334 /* Get next available identificator.
335 * 1 - 128 are used by kernel.
336 * 129 - 199 are reserved.
337 * 200 - 254 are used by utilities like l2ping, etc.
338 */
339
340 spin_lock_bh(&conn->lock);
341
342 if (++conn->tx_ident > 128)
343 conn->tx_ident = 1;
344
345 id = conn->tx_ident;
346
347 spin_unlock_bh(&conn->lock);
348
349 return id;
350}
351
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300352static inline void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200353{
354 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
355
356 BT_DBG("code 0x%2.2x", code);
357
358 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300359 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200360
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300361 hci_send_acl(conn->hcon, skb, 0);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200362}
363
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300364static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300365{
366 struct sk_buff *skb;
367 struct l2cap_hdr *lh;
368 struct l2cap_conn *conn = pi->conn;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300369 struct sock *sk = (struct sock *)pi;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300370 int count, hlen = L2CAP_HDR_SIZE + 2;
371
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300372 if (sk->sk_state != BT_CONNECTED)
373 return;
374
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300375 if (pi->fcs == L2CAP_FCS_CRC16)
376 hlen += 2;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300377
378 BT_DBG("pi %p, control 0x%2.2x", pi, control);
379
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300380 count = min_t(unsigned int, conn->mtu, hlen);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300381 control |= L2CAP_CTRL_FRAME_TYPE;
382
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -0300383 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
384 control |= L2CAP_CTRL_FINAL;
385 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
386 }
387
Gustavo F. Padovanf0946cc2010-05-01 16:15:37 -0300388 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
389 control |= L2CAP_CTRL_POLL;
390 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
391 }
392
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300393 skb = bt_skb_alloc(count, GFP_ATOMIC);
394 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300395 return;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300396
397 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300398 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300399 lh->cid = cpu_to_le16(pi->dcid);
400 put_unaligned_le16(control, skb_put(skb, 2));
401
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300402 if (pi->fcs == L2CAP_FCS_CRC16) {
403 u16 fcs = crc16(0, (u8 *)lh, count - 2);
404 put_unaligned_le16(fcs, skb_put(skb, 2));
405 }
406
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300407 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300408}
409
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300410static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300411{
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300412 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300413 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300414 pi->conn_state |= L2CAP_CONN_RNR_SENT;
415 } else
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300416 control |= L2CAP_SUPER_RCV_READY;
417
Gustavo F. Padovan2ab25cd2009-10-03 02:34:40 -0300418 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
419
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300420 l2cap_send_sframe(pi, control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300421}
422
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300423static inline int __l2cap_no_conn_pending(struct sock *sk)
424{
425 return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND);
426}
427
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200428static void l2cap_do_start(struct sock *sk)
429{
430 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
431
432 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100433 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
434 return;
435
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300436 if (l2cap_check_security(sk) && __l2cap_no_conn_pending(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200437 struct l2cap_conn_req req;
438 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
439 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200440
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200441 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300442 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200443
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200444 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200445 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200446 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200447 } else {
448 struct l2cap_info_req req;
449 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
450
451 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
452 conn->info_ident = l2cap_get_ident(conn);
453
454 mod_timer(&conn->info_timer, jiffies +
455 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
456
457 l2cap_send_cmd(conn, conn->info_ident,
458 L2CAP_INFO_REQ, sizeof(req), &req);
459 }
460}
461
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300462static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
463{
464 u32 local_feat_mask = l2cap_feat_mask;
465 if (enable_ertm)
466 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
467
468 switch (mode) {
469 case L2CAP_MODE_ERTM:
470 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
471 case L2CAP_MODE_STREAMING:
472 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
473 default:
474 return 0x00;
475 }
476}
477
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300478static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300479{
480 struct l2cap_disconn_req req;
481
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300482 if (!conn)
483 return;
484
485 skb_queue_purge(TX_QUEUE(sk));
486
487 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
488 del_timer(&l2cap_pi(sk)->retrans_timer);
489 del_timer(&l2cap_pi(sk)->monitor_timer);
490 del_timer(&l2cap_pi(sk)->ack_timer);
491 }
492
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300493 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
494 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
495 l2cap_send_cmd(conn, l2cap_get_ident(conn),
496 L2CAP_DISCONN_REQ, sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300497
498 sk->sk_state = BT_DISCONN;
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300499 sk->sk_err = err;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300500}
501
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200503static void l2cap_conn_start(struct l2cap_conn *conn)
504{
505 struct l2cap_chan_list *l = &conn->chan_list;
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300506 struct sock_del_list del, *tmp1, *tmp2;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200507 struct sock *sk;
508
509 BT_DBG("conn %p", conn);
510
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300511 INIT_LIST_HEAD(&del.list);
512
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200513 read_lock(&l->lock);
514
515 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
516 bh_lock_sock(sk);
517
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300518 if (sk->sk_type != SOCK_SEQPACKET &&
519 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200520 bh_unlock_sock(sk);
521 continue;
522 }
523
524 if (sk->sk_state == BT_CONNECT) {
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300525 struct l2cap_conn_req req;
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300526
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300527 if (!l2cap_check_security(sk) ||
528 !__l2cap_no_conn_pending(sk)) {
529 bh_unlock_sock(sk);
530 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200531 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300532
533 if (!l2cap_mode_supported(l2cap_pi(sk)->mode,
534 conn->feat_mask)
535 && l2cap_pi(sk)->conf_state &
536 L2CAP_CONF_STATE2_DEVICE) {
537 tmp1 = kzalloc(sizeof(struct sock_del_list),
538 GFP_ATOMIC);
539 tmp1->sk = sk;
540 list_add_tail(&tmp1->list, &del.list);
541 bh_unlock_sock(sk);
542 continue;
543 }
544
545 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
546 req.psm = l2cap_pi(sk)->psm;
547
548 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
549 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
550
551 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
552 L2CAP_CONN_REQ, sizeof(req), &req);
553
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200554 } else if (sk->sk_state == BT_CONNECT2) {
555 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -0300556 char buf[128];
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200557 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
558 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
559
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100560 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100561 if (bt_sk(sk)->defer_setup) {
562 struct sock *parent = bt_sk(sk)->parent;
563 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
564 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
565 parent->sk_data_ready(parent, 0);
566
567 } else {
568 sk->sk_state = BT_CONFIG;
569 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
570 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
571 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200572 } else {
573 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
574 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
575 }
576
577 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
578 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -0300579
580 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT ||
581 rsp.result != L2CAP_CR_SUCCESS) {
582 bh_unlock_sock(sk);
583 continue;
584 }
585
586 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
587 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
588 l2cap_build_conf_req(sk, buf), buf);
589 l2cap_pi(sk)->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200590 }
591
592 bh_unlock_sock(sk);
593 }
594
595 read_unlock(&l->lock);
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300596
597 list_for_each_entry_safe(tmp1, tmp2, &del.list, list) {
598 bh_lock_sock(tmp1->sk);
599 __l2cap_sock_close(tmp1->sk, ECONNRESET);
600 bh_unlock_sock(tmp1->sk);
601 list_del(&tmp1->list);
602 kfree(tmp1);
603 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200604}
605
606static void l2cap_conn_ready(struct l2cap_conn *conn)
607{
608 struct l2cap_chan_list *l = &conn->chan_list;
609 struct sock *sk;
610
611 BT_DBG("conn %p", conn);
612
613 read_lock(&l->lock);
614
615 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
616 bh_lock_sock(sk);
617
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300618 if (sk->sk_type != SOCK_SEQPACKET &&
619 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200620 l2cap_sock_clear_timer(sk);
621 sk->sk_state = BT_CONNECTED;
622 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200623 } else if (sk->sk_state == BT_CONNECT)
624 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200625
626 bh_unlock_sock(sk);
627 }
628
629 read_unlock(&l->lock);
630}
631
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200632/* Notify sockets that we cannot guaranty reliability anymore */
633static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
634{
635 struct l2cap_chan_list *l = &conn->chan_list;
636 struct sock *sk;
637
638 BT_DBG("conn %p", conn);
639
640 read_lock(&l->lock);
641
642 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100643 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200644 sk->sk_err = err;
645 }
646
647 read_unlock(&l->lock);
648}
649
650static void l2cap_info_timeout(unsigned long arg)
651{
652 struct l2cap_conn *conn = (void *) arg;
653
Marcel Holtmann984947d2009-02-06 23:35:19 +0100654 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100655 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100656
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200657 l2cap_conn_start(conn);
658}
659
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
661{
Marcel Holtmann01394182006-07-03 10:02:46 +0200662 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700663
Marcel Holtmann01394182006-07-03 10:02:46 +0200664 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665 return conn;
666
Marcel Holtmann01394182006-07-03 10:02:46 +0200667 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
668 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670
671 hcon->l2cap_data = conn;
672 conn->hcon = hcon;
673
Marcel Holtmann01394182006-07-03 10:02:46 +0200674 BT_DBG("hcon %p conn %p", hcon, conn);
675
Linus Torvalds1da177e2005-04-16 15:20:36 -0700676 conn->mtu = hcon->hdev->acl_mtu;
677 conn->src = &hcon->hdev->bdaddr;
678 conn->dst = &hcon->dst;
679
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200680 conn->feat_mask = 0;
681
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682 spin_lock_init(&conn->lock);
683 rwlock_init(&conn->chan_list.lock);
684
Dave Young45054dc2009-10-18 20:28:30 +0000685 setup_timer(&conn->info_timer, l2cap_info_timeout,
686 (unsigned long) conn);
687
Marcel Holtmann2950f212009-02-12 14:02:50 +0100688 conn->disc_reason = 0x13;
689
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690 return conn;
691}
692
Marcel Holtmann01394182006-07-03 10:02:46 +0200693static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694{
Marcel Holtmann01394182006-07-03 10:02:46 +0200695 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696 struct sock *sk;
697
Marcel Holtmann01394182006-07-03 10:02:46 +0200698 if (!conn)
699 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700
701 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
702
Wei Yongjun7585b972009-02-25 18:29:52 +0800703 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704
705 /* Kill channels */
706 while ((sk = conn->chan_list.head)) {
707 bh_lock_sock(sk);
708 l2cap_chan_del(sk, err);
709 bh_unlock_sock(sk);
710 l2cap_sock_kill(sk);
711 }
712
Dave Young8e8440f2008-03-03 12:18:55 -0800713 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
714 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800715
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716 hcon->l2cap_data = NULL;
717 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718}
719
720static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
721{
722 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200723 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200725 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726}
727
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700729static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730{
731 struct sock *sk;
732 struct hlist_node *node;
733 sk_for_each(sk, node, &l2cap_sk_list.head)
734 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
735 goto found;
736 sk = NULL;
737found:
738 return sk;
739}
740
741/* Find socket with psm and source bdaddr.
742 * Returns closest match.
743 */
Al Viro8e036fc2007-07-29 00:16:36 -0700744static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745{
746 struct sock *sk = NULL, *sk1 = NULL;
747 struct hlist_node *node;
748
749 sk_for_each(sk, node, &l2cap_sk_list.head) {
750 if (state && sk->sk_state != state)
751 continue;
752
753 if (l2cap_pi(sk)->psm == psm) {
754 /* Exact match. */
755 if (!bacmp(&bt_sk(sk)->src, src))
756 break;
757
758 /* Closest match */
759 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
760 sk1 = sk;
761 }
762 }
763 return node ? sk : sk1;
764}
765
766/* Find socket with given address (psm, src).
767 * Returns locked socket */
Al Viro8e036fc2007-07-29 00:16:36 -0700768static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769{
770 struct sock *s;
771 read_lock(&l2cap_sk_list.lock);
772 s = __l2cap_get_sock_by_psm(state, psm, src);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300773 if (s)
774 bh_lock_sock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775 read_unlock(&l2cap_sk_list.lock);
776 return s;
777}
778
779static void l2cap_sock_destruct(struct sock *sk)
780{
781 BT_DBG("sk %p", sk);
782
783 skb_queue_purge(&sk->sk_receive_queue);
784 skb_queue_purge(&sk->sk_write_queue);
785}
786
787static void l2cap_sock_cleanup_listen(struct sock *parent)
788{
789 struct sock *sk;
790
791 BT_DBG("parent %p", parent);
792
793 /* Close not yet accepted channels */
794 while ((sk = bt_accept_dequeue(parent, NULL)))
795 l2cap_sock_close(sk);
796
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200797 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798 sock_set_flag(parent, SOCK_ZAPPED);
799}
800
801/* Kill socket (only if zapped and orphan)
802 * Must be called on unlocked socket.
803 */
804static void l2cap_sock_kill(struct sock *sk)
805{
806 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
807 return;
808
809 BT_DBG("sk %p state %d", sk, sk->sk_state);
810
811 /* Kill poor orphan */
812 bt_sock_unlink(&l2cap_sk_list, sk);
813 sock_set_flag(sk, SOCK_DEAD);
814 sock_put(sk);
815}
816
817static void __l2cap_sock_close(struct sock *sk, int reason)
818{
819 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
820
821 switch (sk->sk_state) {
822 case BT_LISTEN:
823 l2cap_sock_cleanup_listen(sk);
824 break;
825
826 case BT_CONNECTED:
827 case BT_CONFIG:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300828 if (sk->sk_type == SOCK_SEQPACKET ||
829 sk->sk_type == SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300833 l2cap_send_disconn_req(conn, sk, reason);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200834 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836 break;
837
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100838 case BT_CONNECT2:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300839 if (sk->sk_type == SOCK_SEQPACKET ||
840 sk->sk_type == SOCK_STREAM) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100841 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
842 struct l2cap_conn_rsp rsp;
843 __u16 result;
844
845 if (bt_sk(sk)->defer_setup)
846 result = L2CAP_CR_SEC_BLOCK;
847 else
848 result = L2CAP_CR_BAD_PSM;
849
850 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
851 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
852 rsp.result = cpu_to_le16(result);
853 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
854 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
855 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
856 } else
857 l2cap_chan_del(sk, reason);
858 break;
859
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860 case BT_CONNECT:
861 case BT_DISCONN:
862 l2cap_chan_del(sk, reason);
863 break;
864
865 default:
866 sock_set_flag(sk, SOCK_ZAPPED);
867 break;
868 }
869}
870
871/* Must be called on unlocked socket. */
872static void l2cap_sock_close(struct sock *sk)
873{
874 l2cap_sock_clear_timer(sk);
875 lock_sock(sk);
876 __l2cap_sock_close(sk, ECONNRESET);
877 release_sock(sk);
878 l2cap_sock_kill(sk);
879}
880
881static void l2cap_sock_init(struct sock *sk, struct sock *parent)
882{
883 struct l2cap_pinfo *pi = l2cap_pi(sk);
884
885 BT_DBG("sk %p", sk);
886
887 if (parent) {
888 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100889 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
890
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891 pi->imtu = l2cap_pi(parent)->imtu;
892 pi->omtu = l2cap_pi(parent)->omtu;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300893 pi->conf_state = l2cap_pi(parent)->conf_state;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700894 pi->mode = l2cap_pi(parent)->mode;
895 pi->fcs = l2cap_pi(parent)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -0300896 pi->max_tx = l2cap_pi(parent)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -0300897 pi->tx_win = l2cap_pi(parent)->tx_win;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100898 pi->sec_level = l2cap_pi(parent)->sec_level;
899 pi->role_switch = l2cap_pi(parent)->role_switch;
900 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901 } else {
902 pi->imtu = L2CAP_DEFAULT_MTU;
903 pi->omtu = 0;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300904 if (enable_ertm && sk->sk_type == SOCK_STREAM) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300905 pi->mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300906 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
907 } else {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300908 pi->mode = L2CAP_MODE_BASIC;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300909 }
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300910 pi->max_tx = L2CAP_DEFAULT_MAX_TX;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700911 pi->fcs = L2CAP_FCS_CRC16;
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300912 pi->tx_win = L2CAP_DEFAULT_TX_WINDOW;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100913 pi->sec_level = BT_SECURITY_LOW;
914 pi->role_switch = 0;
915 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916 }
917
918 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200919 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Dave Young45054dc2009-10-18 20:28:30 +0000921 skb_queue_head_init(TX_QUEUE(sk));
922 skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300923 skb_queue_head_init(BUSY_QUEUE(sk));
Dave Young45054dc2009-10-18 20:28:30 +0000924 INIT_LIST_HEAD(SREJ_LIST(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925}
926
927static struct proto l2cap_proto = {
928 .name = "L2CAP",
929 .owner = THIS_MODULE,
930 .obj_size = sizeof(struct l2cap_pinfo)
931};
932
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700933static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934{
935 struct sock *sk;
936
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700937 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938 if (!sk)
939 return NULL;
940
941 sock_init_data(sock, sk);
942 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
943
944 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200945 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946
947 sock_reset_flag(sk, SOCK_ZAPPED);
948
949 sk->sk_protocol = proto;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200950 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200952 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953
954 bt_sock_link(&l2cap_sk_list, sk);
955 return sk;
956}
957
Eric Paris3f378b62009-11-05 22:18:14 -0800958static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
959 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960{
961 struct sock *sk;
962
963 BT_DBG("sock %p", sock);
964
965 sock->state = SS_UNCONNECTED;
966
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300967 if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700968 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
969 return -ESOCKTNOSUPPORT;
970
Eric Parisc84b3262009-11-05 20:45:52 -0800971 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972 return -EPERM;
973
974 sock->ops = &l2cap_sock_ops;
975
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700976 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977 if (!sk)
978 return -ENOMEM;
979
980 l2cap_sock_init(sk, NULL);
981 return 0;
982}
983
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100984static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100987 struct sockaddr_l2 la;
988 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700989
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100990 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991
992 if (!addr || addr->sa_family != AF_BLUETOOTH)
993 return -EINVAL;
994
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100995 memset(&la, 0, sizeof(la));
996 len = min_t(unsigned int, sizeof(la), alen);
997 memcpy(&la, addr, len);
998
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100999 if (la.l2_cid)
1000 return -EINVAL;
1001
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002 lock_sock(sk);
1003
1004 if (sk->sk_state != BT_OPEN) {
1005 err = -EBADFD;
1006 goto done;
1007 }
1008
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001009 if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
Marcel Holtmann847641d2007-01-22 22:00:45 +01001010 !capable(CAP_NET_BIND_SERVICE)) {
1011 err = -EACCES;
1012 goto done;
1013 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001014
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015 write_lock_bh(&l2cap_sk_list.lock);
1016
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001017 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018 err = -EADDRINUSE;
1019 } else {
1020 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001021 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
1022 l2cap_pi(sk)->psm = la.l2_psm;
1023 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001025
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001026 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
1027 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001028 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029 }
1030
1031 write_unlock_bh(&l2cap_sk_list.lock);
1032
1033done:
1034 release_sock(sk);
1035 return err;
1036}
1037
1038static int l2cap_do_connect(struct sock *sk)
1039{
1040 bdaddr_t *src = &bt_sk(sk)->src;
1041 bdaddr_t *dst = &bt_sk(sk)->dst;
1042 struct l2cap_conn *conn;
1043 struct hci_conn *hcon;
1044 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001045 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001046 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001048 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
1049 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001051 hdev = hci_get_route(dst, src);
1052 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053 return -EHOSTUNREACH;
1054
1055 hci_dev_lock_bh(hdev);
1056
1057 err = -ENOMEM;
1058
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001059 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001060 switch (l2cap_pi(sk)->sec_level) {
1061 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001062 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001063 break;
1064 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001065 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001066 break;
1067 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001068 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001069 break;
1070 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001071 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001072 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001073 auth_type = HCI_AT_NO_BONDING_MITM;
1074 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001075 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +01001076
1077 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
1078 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001079 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001080 switch (l2cap_pi(sk)->sec_level) {
1081 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001082 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001083 break;
1084 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001085 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001086 break;
1087 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001088 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001089 break;
1090 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001091 }
1092
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001093 hcon = hci_connect(hdev, ACL_LINK, dst,
1094 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095 if (!hcon)
1096 goto done;
1097
1098 conn = l2cap_conn_add(hcon, 0);
1099 if (!conn) {
1100 hci_conn_put(hcon);
1101 goto done;
1102 }
1103
1104 err = 0;
1105
1106 /* Update source addr of the socket */
1107 bacpy(src, conn->src);
1108
1109 l2cap_chan_add(conn, sk, NULL);
1110
1111 sk->sk_state = BT_CONNECT;
1112 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
1113
1114 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001115 if (sk->sk_type != SOCK_SEQPACKET &&
1116 sk->sk_type != SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117 l2cap_sock_clear_timer(sk);
1118 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001119 } else
1120 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121 }
1122
1123done:
1124 hci_dev_unlock_bh(hdev);
1125 hci_dev_put(hdev);
1126 return err;
1127}
1128
1129static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
1130{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001132 struct sockaddr_l2 la;
1133 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135 BT_DBG("sk %p", sk);
1136
Changli Gao6503d962010-03-31 22:58:26 +00001137 if (!addr || alen < sizeof(addr->sa_family) ||
1138 addr->sa_family != AF_BLUETOOTH)
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001139 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001141 memset(&la, 0, sizeof(la));
1142 len = min_t(unsigned int, sizeof(la), alen);
1143 memcpy(&la, addr, len);
1144
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001145 if (la.l2_cid)
1146 return -EINVAL;
1147
1148 lock_sock(sk);
1149
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001150 if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
1151 && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152 err = -EINVAL;
1153 goto done;
1154 }
1155
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001156 switch (l2cap_pi(sk)->mode) {
1157 case L2CAP_MODE_BASIC:
1158 break;
1159 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001160 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001161 if (enable_ertm)
1162 break;
1163 /* fall through */
1164 default:
1165 err = -ENOTSUPP;
1166 goto done;
1167 }
1168
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001169 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170 case BT_CONNECT:
1171 case BT_CONNECT2:
1172 case BT_CONFIG:
1173 /* Already connecting */
1174 goto wait;
1175
1176 case BT_CONNECTED:
1177 /* Already connected */
João Paulo Rechi Vita8b0dc6d2010-06-22 13:56:22 -03001178 err = -EISCONN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179 goto done;
1180
1181 case BT_OPEN:
1182 case BT_BOUND:
1183 /* Can connect */
1184 break;
1185
1186 default:
1187 err = -EBADFD;
1188 goto done;
1189 }
1190
1191 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001192 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1193 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001195 err = l2cap_do_connect(sk);
1196 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197 goto done;
1198
1199wait:
1200 err = bt_sock_wait_state(sk, BT_CONNECTED,
1201 sock_sndtimeo(sk, flags & O_NONBLOCK));
1202done:
1203 release_sock(sk);
1204 return err;
1205}
1206
1207static int l2cap_sock_listen(struct socket *sock, int backlog)
1208{
1209 struct sock *sk = sock->sk;
1210 int err = 0;
1211
1212 BT_DBG("sk %p backlog %d", sk, backlog);
1213
1214 lock_sock(sk);
1215
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001216 if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
1217 || sk->sk_state != BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 err = -EBADFD;
1219 goto done;
1220 }
1221
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001222 switch (l2cap_pi(sk)->mode) {
1223 case L2CAP_MODE_BASIC:
1224 break;
1225 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001226 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001227 if (enable_ertm)
1228 break;
1229 /* fall through */
1230 default:
1231 err = -ENOTSUPP;
1232 goto done;
1233 }
1234
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235 if (!l2cap_pi(sk)->psm) {
1236 bdaddr_t *src = &bt_sk(sk)->src;
1237 u16 psm;
1238
1239 err = -EINVAL;
1240
1241 write_lock_bh(&l2cap_sk_list.lock);
1242
1243 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001244 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1245 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1246 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247 err = 0;
1248 break;
1249 }
1250
1251 write_unlock_bh(&l2cap_sk_list.lock);
1252
1253 if (err < 0)
1254 goto done;
1255 }
1256
1257 sk->sk_max_ack_backlog = backlog;
1258 sk->sk_ack_backlog = 0;
1259 sk->sk_state = BT_LISTEN;
1260
1261done:
1262 release_sock(sk);
1263 return err;
1264}
1265
1266static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1267{
1268 DECLARE_WAITQUEUE(wait, current);
1269 struct sock *sk = sock->sk, *nsk;
1270 long timeo;
1271 int err = 0;
1272
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001273 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274
1275 if (sk->sk_state != BT_LISTEN) {
1276 err = -EBADFD;
1277 goto done;
1278 }
1279
1280 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1281
1282 BT_DBG("sk %p timeo %ld", sk, timeo);
1283
1284 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +00001285 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001286 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1287 set_current_state(TASK_INTERRUPTIBLE);
1288 if (!timeo) {
1289 err = -EAGAIN;
1290 break;
1291 }
1292
1293 release_sock(sk);
1294 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001295 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296
1297 if (sk->sk_state != BT_LISTEN) {
1298 err = -EBADFD;
1299 break;
1300 }
1301
1302 if (signal_pending(current)) {
1303 err = sock_intr_errno(timeo);
1304 break;
1305 }
1306 }
1307 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +00001308 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001309
1310 if (err)
1311 goto done;
1312
1313 newsock->state = SS_CONNECTED;
1314
1315 BT_DBG("new socket %p", nsk);
1316
1317done:
1318 release_sock(sk);
1319 return err;
1320}
1321
1322static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1323{
1324 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1325 struct sock *sk = sock->sk;
1326
1327 BT_DBG("sock %p, sk %p", sock, sk);
1328
1329 addr->sa_family = AF_BLUETOOTH;
1330 *len = sizeof(struct sockaddr_l2);
1331
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001332 if (peer) {
1333 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001335 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001336 } else {
1337 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001338 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001339 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001340 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342 return 0;
1343}
1344
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001345static int __l2cap_wait_ack(struct sock *sk)
1346{
1347 DECLARE_WAITQUEUE(wait, current);
1348 int err = 0;
1349 int timeo = HZ/5;
1350
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001351 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001352 while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
1353 set_current_state(TASK_INTERRUPTIBLE);
1354
1355 if (!timeo)
1356 timeo = HZ/5;
1357
1358 if (signal_pending(current)) {
1359 err = sock_intr_errno(timeo);
1360 break;
1361 }
1362
1363 release_sock(sk);
1364 timeo = schedule_timeout(timeo);
1365 lock_sock(sk);
1366
1367 err = sock_error(sk);
1368 if (err)
1369 break;
1370 }
1371 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001372 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001373 return err;
1374}
1375
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001376static void l2cap_monitor_timeout(unsigned long arg)
1377{
1378 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001379
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001380 BT_DBG("sk %p", sk);
1381
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001382 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001383 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001384 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001385 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001386 return;
1387 }
1388
1389 l2cap_pi(sk)->retry_count++;
1390 __mod_monitor_timer();
1391
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001392 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001393 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001394}
1395
1396static void l2cap_retrans_timeout(unsigned long arg)
1397{
1398 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001399
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001400 BT_DBG("sk %p", sk);
1401
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001402 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001403 l2cap_pi(sk)->retry_count = 1;
1404 __mod_monitor_timer();
1405
1406 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1407
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001408 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001409 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001410}
1411
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001412static void l2cap_drop_acked_frames(struct sock *sk)
1413{
1414 struct sk_buff *skb;
1415
Gustavo F. Padovan812e7372010-05-01 16:15:42 -03001416 while ((skb = skb_peek(TX_QUEUE(sk))) &&
1417 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001418 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1419 break;
1420
1421 skb = skb_dequeue(TX_QUEUE(sk));
1422 kfree_skb(skb);
1423
1424 l2cap_pi(sk)->unacked_frames--;
1425 }
1426
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001427 if (!l2cap_pi(sk)->unacked_frames)
1428 del_timer(&l2cap_pi(sk)->retrans_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001429}
1430
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001431static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001432{
1433 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001434
1435 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1436
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001437 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001438}
1439
João Paulo Rechi Vita305682e2010-06-22 13:56:23 -03001440static void l2cap_streaming_send(struct sock *sk)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001441{
1442 struct sk_buff *skb, *tx_skb;
1443 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001444 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001445
1446 while ((skb = sk->sk_send_head)) {
1447 tx_skb = skb_clone(skb, GFP_ATOMIC);
1448
1449 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1450 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1451 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1452
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001453 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001454 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1455 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1456 }
1457
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001458 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001459
1460 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1461
1462 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1463 sk->sk_send_head = NULL;
1464 else
1465 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1466
1467 skb = skb_dequeue(TX_QUEUE(sk));
1468 kfree_skb(skb);
1469 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001470}
1471
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001472static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001473{
1474 struct l2cap_pinfo *pi = l2cap_pi(sk);
1475 struct sk_buff *skb, *tx_skb;
1476 u16 control, fcs;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001477
1478 skb = skb_peek(TX_QUEUE(sk));
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001479 if (!skb)
1480 return;
1481
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001482 do {
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001483 if (bt_cb(skb)->tx_seq == tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001484 break;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001485
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001486 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1487 return;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001488
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001489 } while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001490
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001491 if (pi->remote_max_tx &&
1492 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001493 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001494 return;
1495 }
1496
1497 tx_skb = skb_clone(skb, GFP_ATOMIC);
1498 bt_cb(skb)->retries++;
1499 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001500
1501 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1502 control |= L2CAP_CTRL_FINAL;
1503 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1504 }
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001505
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001506 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1507 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001508
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001509 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1510
1511 if (pi->fcs == L2CAP_FCS_CRC16) {
1512 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1513 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1514 }
1515
1516 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001517}
1518
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001519static int l2cap_ertm_send(struct sock *sk)
1520{
1521 struct sk_buff *skb, *tx_skb;
1522 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001523 u16 control, fcs;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001524 int nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001525
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001526 if (sk->sk_state != BT_CONNECTED)
1527 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001528
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001529 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001530
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001531 if (pi->remote_max_tx &&
1532 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001533 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001534 break;
1535 }
1536
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001537 tx_skb = skb_clone(skb, GFP_ATOMIC);
1538
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001539 bt_cb(skb)->retries++;
1540
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001541 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001542 control &= L2CAP_CTRL_SAR;
1543
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001544 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1545 control |= L2CAP_CTRL_FINAL;
1546 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1547 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001548 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001549 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1550 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1551
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001552
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001553 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001554 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1555 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1556 }
1557
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001558 l2cap_do_send(sk, tx_skb);
1559
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001560 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001561
1562 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1563 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1564
1565 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001566 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001567
1568 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1569 sk->sk_send_head = NULL;
1570 else
1571 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001572
1573 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001574 }
1575
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001576 return nsent;
1577}
1578
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001579static int l2cap_retransmit_frames(struct sock *sk)
1580{
1581 struct l2cap_pinfo *pi = l2cap_pi(sk);
1582 int ret;
1583
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001584 if (!skb_queue_empty(TX_QUEUE(sk)))
1585 sk->sk_send_head = TX_QUEUE(sk)->next;
1586
1587 pi->next_tx_seq = pi->expected_ack_seq;
1588 ret = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001589 return ret;
1590}
1591
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001592static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001593{
1594 struct sock *sk = (struct sock *)pi;
1595 u16 control = 0;
1596
1597 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1598
1599 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1600 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001601 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001602 l2cap_send_sframe(pi, control);
1603 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001604 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001605
Gustavo F. Padovane0f66212010-06-21 18:50:49 -03001606 if (l2cap_ertm_send(sk) > 0)
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001607 return;
1608
1609 control |= L2CAP_SUPER_RCV_READY;
1610 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001611}
1612
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001613static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001614{
1615 struct srej_list *tail;
1616 u16 control;
1617
1618 control = L2CAP_SUPER_SELECT_REJECT;
1619 control |= L2CAP_CTRL_FINAL;
1620
1621 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1622 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1623
1624 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001625}
1626
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001627static 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 -07001628{
1629 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001630 struct sk_buff **frag;
1631 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001632
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001633 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001634 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001635
1636 sent += count;
1637 len -= count;
1638
1639 /* Continuation fragments (no L2CAP header) */
1640 frag = &skb_shinfo(skb)->frag_list;
1641 while (len) {
1642 count = min_t(unsigned int, conn->mtu, len);
1643
1644 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1645 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001646 return -EFAULT;
1647 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1648 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001649
1650 sent += count;
1651 len -= count;
1652
1653 frag = &(*frag)->next;
1654 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001655
1656 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001657}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001659static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1660{
1661 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1662 struct sk_buff *skb;
1663 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1664 struct l2cap_hdr *lh;
1665
1666 BT_DBG("sk %p len %d", sk, (int)len);
1667
1668 count = min_t(unsigned int, (conn->mtu - hlen), len);
1669 skb = bt_skb_send_alloc(sk, count + hlen,
1670 msg->msg_flags & MSG_DONTWAIT, &err);
1671 if (!skb)
1672 return ERR_PTR(-ENOMEM);
1673
1674 /* Create L2CAP header */
1675 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1676 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1677 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1678 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1679
1680 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1681 if (unlikely(err < 0)) {
1682 kfree_skb(skb);
1683 return ERR_PTR(err);
1684 }
1685 return skb;
1686}
1687
1688static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1689{
1690 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1691 struct sk_buff *skb;
1692 int err, count, hlen = L2CAP_HDR_SIZE;
1693 struct l2cap_hdr *lh;
1694
1695 BT_DBG("sk %p len %d", sk, (int)len);
1696
1697 count = min_t(unsigned int, (conn->mtu - hlen), len);
1698 skb = bt_skb_send_alloc(sk, count + hlen,
1699 msg->msg_flags & MSG_DONTWAIT, &err);
1700 if (!skb)
1701 return ERR_PTR(-ENOMEM);
1702
1703 /* Create L2CAP header */
1704 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1705 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1706 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1707
1708 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1709 if (unlikely(err < 0)) {
1710 kfree_skb(skb);
1711 return ERR_PTR(err);
1712 }
1713 return skb;
1714}
1715
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001716static 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 -03001717{
1718 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1719 struct sk_buff *skb;
1720 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1721 struct l2cap_hdr *lh;
1722
1723 BT_DBG("sk %p len %d", sk, (int)len);
1724
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001725 if (!conn)
1726 return ERR_PTR(-ENOTCONN);
1727
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001728 if (sdulen)
1729 hlen += 2;
1730
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001731 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1732 hlen += 2;
1733
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001734 count = min_t(unsigned int, (conn->mtu - hlen), len);
1735 skb = bt_skb_send_alloc(sk, count + hlen,
1736 msg->msg_flags & MSG_DONTWAIT, &err);
1737 if (!skb)
1738 return ERR_PTR(-ENOMEM);
1739
1740 /* Create L2CAP header */
1741 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1742 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1743 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1744 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001745 if (sdulen)
1746 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001747
1748 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1749 if (unlikely(err < 0)) {
1750 kfree_skb(skb);
1751 return ERR_PTR(err);
1752 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001753
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001754 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1755 put_unaligned_le16(0, skb_put(skb, 2));
1756
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001757 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001758 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759}
1760
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001761static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1762{
1763 struct l2cap_pinfo *pi = l2cap_pi(sk);
1764 struct sk_buff *skb;
1765 struct sk_buff_head sar_queue;
1766 u16 control;
1767 size_t size = 0;
1768
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001769 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001770 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001771 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001772 if (IS_ERR(skb))
1773 return PTR_ERR(skb);
1774
1775 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001776 len -= pi->remote_mps;
1777 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001778
1779 while (len > 0) {
1780 size_t buflen;
1781
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001782 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001783 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001784 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001785 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001786 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001787 buflen = len;
1788 }
1789
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001790 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001791 if (IS_ERR(skb)) {
1792 skb_queue_purge(&sar_queue);
1793 return PTR_ERR(skb);
1794 }
1795
1796 __skb_queue_tail(&sar_queue, skb);
1797 len -= buflen;
1798 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001799 }
1800 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1801 if (sk->sk_send_head == NULL)
1802 sk->sk_send_head = sar_queue.next;
1803
1804 return size;
1805}
1806
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1808{
1809 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001810 struct l2cap_pinfo *pi = l2cap_pi(sk);
1811 struct sk_buff *skb;
1812 u16 control;
1813 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814
1815 BT_DBG("sock %p, sk %p", sock, sk);
1816
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001817 err = sock_error(sk);
1818 if (err)
1819 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820
1821 if (msg->msg_flags & MSG_OOB)
1822 return -EOPNOTSUPP;
1823
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824 lock_sock(sk);
1825
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001826 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001827 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001828 goto done;
1829 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001831 /* Connectionless channel */
1832 if (sk->sk_type == SOCK_DGRAM) {
1833 skb = l2cap_create_connless_pdu(sk, msg, len);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001834 if (IS_ERR(skb)) {
Dan Carpenter477fffb2010-04-21 23:52:01 +00001835 err = PTR_ERR(skb);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001836 } else {
1837 l2cap_do_send(sk, skb);
1838 err = len;
1839 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001840 goto done;
1841 }
1842
1843 switch (pi->mode) {
1844 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001845 /* Check outgoing MTU */
1846 if (len > pi->omtu) {
João Paulo Rechi Vitaf9dd11b2010-06-22 13:56:24 -03001847 err = -EMSGSIZE;
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001848 goto done;
1849 }
1850
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001851 /* Create a basic PDU */
1852 skb = l2cap_create_basic_pdu(sk, msg, len);
1853 if (IS_ERR(skb)) {
1854 err = PTR_ERR(skb);
1855 goto done;
1856 }
1857
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001858 l2cap_do_send(sk, skb);
1859 err = len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001860 break;
1861
1862 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001863 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001864 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001865 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001866 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001867 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001868 if (IS_ERR(skb)) {
1869 err = PTR_ERR(skb);
1870 goto done;
1871 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001872 __skb_queue_tail(TX_QUEUE(sk), skb);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001873
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001874 if (sk->sk_send_head == NULL)
1875 sk->sk_send_head = skb;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001876
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001877 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001878 /* Segment SDU into multiples PDUs */
1879 err = l2cap_sar_segment_sdu(sk, msg, len);
1880 if (err < 0)
1881 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001882 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001883
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001884 if (pi->mode == L2CAP_MODE_STREAMING) {
João Paulo Rechi Vita305682e2010-06-22 13:56:23 -03001885 l2cap_streaming_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001886 } else {
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001887 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY &&
1888 pi->conn_state && L2CAP_CONN_WAIT_F) {
1889 err = len;
1890 break;
1891 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001892 err = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001893 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001894
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001895 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001896 err = len;
1897 break;
1898
1899 default:
1900 BT_DBG("bad state %1.1x", pi->mode);
João Paulo Rechi Vitabc766db22010-06-22 13:56:25 -03001901 err = -EBADFD;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001902 }
1903
1904done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905 release_sock(sk);
1906 return err;
1907}
1908
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001909static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1910{
1911 struct sock *sk = sock->sk;
1912
1913 lock_sock(sk);
1914
1915 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1916 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001917 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1918 u8 buf[128];
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001919
1920 sk->sk_state = BT_CONFIG;
1921
1922 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1923 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1924 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1925 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1926 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1927 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1928
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001929 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) {
1930 release_sock(sk);
1931 return 0;
1932 }
1933
1934 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
1935 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
1936 l2cap_build_conf_req(sk, buf), buf);
1937 l2cap_pi(sk)->num_conf_req++;
1938
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001939 release_sock(sk);
1940 return 0;
1941 }
1942
1943 release_sock(sk);
1944
1945 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1946}
1947
David S. Millerb7058842009-09-30 16:12:20 -07001948static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949{
1950 struct sock *sk = sock->sk;
1951 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001952 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001953 u32 opt;
1954
1955 BT_DBG("sk %p", sk);
1956
1957 lock_sock(sk);
1958
1959 switch (optname) {
1960 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001961 opts.imtu = l2cap_pi(sk)->imtu;
1962 opts.omtu = l2cap_pi(sk)->omtu;
1963 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001964 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001965 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001966 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001967 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001968
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969 len = min_t(unsigned int, sizeof(opts), optlen);
1970 if (copy_from_user((char *) &opts, optval, len)) {
1971 err = -EFAULT;
1972 break;
1973 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001974
Gustavo F. Padovan45d65c42010-06-07 19:21:30 -03001975 if (opts.txwin_size > L2CAP_DEFAULT_TX_WINDOW) {
1976 err = -EINVAL;
1977 break;
1978 }
1979
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001980 l2cap_pi(sk)->mode = opts.mode;
1981 switch (l2cap_pi(sk)->mode) {
1982 case L2CAP_MODE_BASIC:
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03001983 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_STATE2_DEVICE;
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001984 break;
1985 case L2CAP_MODE_ERTM:
1986 case L2CAP_MODE_STREAMING:
1987 if (enable_ertm)
1988 break;
1989 /* fall through */
1990 default:
1991 err = -EINVAL;
1992 break;
1993 }
1994
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001995 l2cap_pi(sk)->imtu = opts.imtu;
1996 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001997 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001998 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001999 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002000 break;
2001
2002 case L2CAP_LM:
2003 if (get_user(opt, (u32 __user *) optval)) {
2004 err = -EFAULT;
2005 break;
2006 }
2007
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002008 if (opt & L2CAP_LM_AUTH)
2009 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
2010 if (opt & L2CAP_LM_ENCRYPT)
2011 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
2012 if (opt & L2CAP_LM_SECURE)
2013 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
2014
2015 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
2016 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002017 break;
2018
2019 default:
2020 err = -ENOPROTOOPT;
2021 break;
2022 }
2023
2024 release_sock(sk);
2025 return err;
2026}
2027
David S. Millerb7058842009-09-30 16:12:20 -07002028static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002029{
2030 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002031 struct bt_security sec;
2032 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002033 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002034
2035 BT_DBG("sk %p", sk);
2036
2037 if (level == SOL_L2CAP)
2038 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
2039
Marcel Holtmann0588d942009-01-16 10:06:13 +01002040 if (level != SOL_BLUETOOTH)
2041 return -ENOPROTOOPT;
2042
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002043 lock_sock(sk);
2044
2045 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002046 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002047 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2048 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002049 err = -EINVAL;
2050 break;
2051 }
2052
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002053 sec.level = BT_SECURITY_LOW;
2054
2055 len = min_t(unsigned int, sizeof(sec), optlen);
2056 if (copy_from_user((char *) &sec, optval, len)) {
2057 err = -EFAULT;
2058 break;
2059 }
2060
2061 if (sec.level < BT_SECURITY_LOW ||
2062 sec.level > BT_SECURITY_HIGH) {
2063 err = -EINVAL;
2064 break;
2065 }
2066
2067 l2cap_pi(sk)->sec_level = sec.level;
2068 break;
2069
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002070 case BT_DEFER_SETUP:
2071 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2072 err = -EINVAL;
2073 break;
2074 }
2075
2076 if (get_user(opt, (u32 __user *) optval)) {
2077 err = -EFAULT;
2078 break;
2079 }
2080
2081 bt_sk(sk)->defer_setup = opt;
2082 break;
2083
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002084 default:
2085 err = -ENOPROTOOPT;
2086 break;
2087 }
2088
2089 release_sock(sk);
2090 return err;
2091}
2092
2093static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002094{
2095 struct sock *sk = sock->sk;
2096 struct l2cap_options opts;
2097 struct l2cap_conninfo cinfo;
2098 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002099 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002100
2101 BT_DBG("sk %p", sk);
2102
2103 if (get_user(len, optlen))
2104 return -EFAULT;
2105
2106 lock_sock(sk);
2107
2108 switch (optname) {
2109 case L2CAP_OPTIONS:
2110 opts.imtu = l2cap_pi(sk)->imtu;
2111 opts.omtu = l2cap_pi(sk)->omtu;
2112 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07002113 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002114 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002115 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002116 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002117
2118 len = min_t(unsigned int, len, sizeof(opts));
2119 if (copy_to_user(optval, (char *) &opts, len))
2120 err = -EFAULT;
2121
2122 break;
2123
2124 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002125 switch (l2cap_pi(sk)->sec_level) {
2126 case BT_SECURITY_LOW:
2127 opt = L2CAP_LM_AUTH;
2128 break;
2129 case BT_SECURITY_MEDIUM:
2130 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
2131 break;
2132 case BT_SECURITY_HIGH:
2133 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
2134 L2CAP_LM_SECURE;
2135 break;
2136 default:
2137 opt = 0;
2138 break;
2139 }
2140
2141 if (l2cap_pi(sk)->role_switch)
2142 opt |= L2CAP_LM_MASTER;
2143
2144 if (l2cap_pi(sk)->force_reliable)
2145 opt |= L2CAP_LM_RELIABLE;
2146
2147 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002148 err = -EFAULT;
2149 break;
2150
2151 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002152 if (sk->sk_state != BT_CONNECTED &&
2153 !(sk->sk_state == BT_CONNECT2 &&
2154 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002155 err = -ENOTCONN;
2156 break;
2157 }
2158
2159 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
2160 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
2161
2162 len = min_t(unsigned int, len, sizeof(cinfo));
2163 if (copy_to_user(optval, (char *) &cinfo, len))
2164 err = -EFAULT;
2165
2166 break;
2167
2168 default:
2169 err = -ENOPROTOOPT;
2170 break;
2171 }
2172
2173 release_sock(sk);
2174 return err;
2175}
2176
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002177static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
2178{
2179 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002180 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002181 int len, err = 0;
2182
2183 BT_DBG("sk %p", sk);
2184
2185 if (level == SOL_L2CAP)
2186 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
2187
Marcel Holtmann0588d942009-01-16 10:06:13 +01002188 if (level != SOL_BLUETOOTH)
2189 return -ENOPROTOOPT;
2190
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002191 if (get_user(len, optlen))
2192 return -EFAULT;
2193
2194 lock_sock(sk);
2195
2196 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002197 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002198 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2199 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002200 err = -EINVAL;
2201 break;
2202 }
2203
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002204 sec.level = l2cap_pi(sk)->sec_level;
2205
2206 len = min_t(unsigned int, len, sizeof(sec));
2207 if (copy_to_user(optval, (char *) &sec, len))
2208 err = -EFAULT;
2209
2210 break;
2211
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002212 case BT_DEFER_SETUP:
2213 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2214 err = -EINVAL;
2215 break;
2216 }
2217
2218 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2219 err = -EFAULT;
2220
2221 break;
2222
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002223 default:
2224 err = -ENOPROTOOPT;
2225 break;
2226 }
2227
2228 release_sock(sk);
2229 return err;
2230}
2231
Linus Torvalds1da177e2005-04-16 15:20:36 -07002232static int l2cap_sock_shutdown(struct socket *sock, int how)
2233{
2234 struct sock *sk = sock->sk;
2235 int err = 0;
2236
2237 BT_DBG("sock %p, sk %p", sock, sk);
2238
2239 if (!sk)
2240 return 0;
2241
2242 lock_sock(sk);
2243 if (!sk->sk_shutdown) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03002244 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2245 err = __l2cap_wait_ack(sk);
2246
Linus Torvalds1da177e2005-04-16 15:20:36 -07002247 sk->sk_shutdown = SHUTDOWN_MASK;
2248 l2cap_sock_clear_timer(sk);
2249 __l2cap_sock_close(sk, 0);
2250
2251 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002252 err = bt_sock_wait_state(sk, BT_CLOSED,
2253 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002254 }
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002255
2256 if (!err && sk->sk_err)
2257 err = -sk->sk_err;
2258
Linus Torvalds1da177e2005-04-16 15:20:36 -07002259 release_sock(sk);
2260 return err;
2261}
2262
2263static int l2cap_sock_release(struct socket *sock)
2264{
2265 struct sock *sk = sock->sk;
2266 int err;
2267
2268 BT_DBG("sock %p, sk %p", sock, sk);
2269
2270 if (!sk)
2271 return 0;
2272
2273 err = l2cap_sock_shutdown(sock, 2);
2274
2275 sock_orphan(sk);
2276 l2cap_sock_kill(sk);
2277 return err;
2278}
2279
Linus Torvalds1da177e2005-04-16 15:20:36 -07002280static void l2cap_chan_ready(struct sock *sk)
2281{
2282 struct sock *parent = bt_sk(sk)->parent;
2283
2284 BT_DBG("sk %p, parent %p", sk, parent);
2285
2286 l2cap_pi(sk)->conf_state = 0;
2287 l2cap_sock_clear_timer(sk);
2288
2289 if (!parent) {
2290 /* Outgoing channel.
2291 * Wake up socket sleeping on connect.
2292 */
2293 sk->sk_state = BT_CONNECTED;
2294 sk->sk_state_change(sk);
2295 } else {
2296 /* Incoming channel.
2297 * Wake up socket sleeping on accept.
2298 */
2299 parent->sk_data_ready(parent, 0);
2300 }
2301}
2302
2303/* Copy frame to all raw sockets on that connection */
2304static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2305{
2306 struct l2cap_chan_list *l = &conn->chan_list;
2307 struct sk_buff *nskb;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002308 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002309
2310 BT_DBG("conn %p", conn);
2311
2312 read_lock(&l->lock);
2313 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2314 if (sk->sk_type != SOCK_RAW)
2315 continue;
2316
2317 /* Don't send frame to the socket it came from */
2318 if (skb->sk == sk)
2319 continue;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002320 nskb = skb_clone(skb, GFP_ATOMIC);
2321 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002322 continue;
2323
2324 if (sock_queue_rcv_skb(sk, nskb))
2325 kfree_skb(nskb);
2326 }
2327 read_unlock(&l->lock);
2328}
2329
2330/* ---- L2CAP signalling commands ---- */
2331static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2332 u8 code, u8 ident, u16 dlen, void *data)
2333{
2334 struct sk_buff *skb, **frag;
2335 struct l2cap_cmd_hdr *cmd;
2336 struct l2cap_hdr *lh;
2337 int len, count;
2338
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002339 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2340 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002341
2342 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2343 count = min_t(unsigned int, conn->mtu, len);
2344
2345 skb = bt_skb_alloc(count, GFP_ATOMIC);
2346 if (!skb)
2347 return NULL;
2348
2349 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002350 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002351 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002352
2353 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2354 cmd->code = code;
2355 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002356 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002357
2358 if (dlen) {
2359 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2360 memcpy(skb_put(skb, count), data, count);
2361 data += count;
2362 }
2363
2364 len -= skb->len;
2365
2366 /* Continuation fragments (no L2CAP header) */
2367 frag = &skb_shinfo(skb)->frag_list;
2368 while (len) {
2369 count = min_t(unsigned int, conn->mtu, len);
2370
2371 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2372 if (!*frag)
2373 goto fail;
2374
2375 memcpy(skb_put(*frag, count), data, count);
2376
2377 len -= count;
2378 data += count;
2379
2380 frag = &(*frag)->next;
2381 }
2382
2383 return skb;
2384
2385fail:
2386 kfree_skb(skb);
2387 return NULL;
2388}
2389
2390static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2391{
2392 struct l2cap_conf_opt *opt = *ptr;
2393 int len;
2394
2395 len = L2CAP_CONF_OPT_SIZE + opt->len;
2396 *ptr += len;
2397
2398 *type = opt->type;
2399 *olen = opt->len;
2400
2401 switch (opt->len) {
2402 case 1:
2403 *val = *((u8 *) opt->val);
2404 break;
2405
2406 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002407 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002408 break;
2409
2410 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002411 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002412 break;
2413
2414 default:
2415 *val = (unsigned long) opt->val;
2416 break;
2417 }
2418
2419 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2420 return len;
2421}
2422
Linus Torvalds1da177e2005-04-16 15:20:36 -07002423static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2424{
2425 struct l2cap_conf_opt *opt = *ptr;
2426
2427 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2428
2429 opt->type = type;
2430 opt->len = len;
2431
2432 switch (len) {
2433 case 1:
2434 *((u8 *) opt->val) = val;
2435 break;
2436
2437 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002438 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002439 break;
2440
2441 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002442 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002443 break;
2444
2445 default:
2446 memcpy(opt->val, (void *) val, len);
2447 break;
2448 }
2449
2450 *ptr += L2CAP_CONF_OPT_SIZE + len;
2451}
2452
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002453static void l2cap_ack_timeout(unsigned long arg)
2454{
2455 struct sock *sk = (void *) arg;
2456
2457 bh_lock_sock(sk);
2458 l2cap_send_ack(l2cap_pi(sk));
2459 bh_unlock_sock(sk);
2460}
2461
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002462static inline void l2cap_ertm_init(struct sock *sk)
2463{
2464 l2cap_pi(sk)->expected_ack_seq = 0;
2465 l2cap_pi(sk)->unacked_frames = 0;
2466 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002467 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002468 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002469
2470 setup_timer(&l2cap_pi(sk)->retrans_timer,
2471 l2cap_retrans_timeout, (unsigned long) sk);
2472 setup_timer(&l2cap_pi(sk)->monitor_timer,
2473 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002474 setup_timer(&l2cap_pi(sk)->ack_timer,
2475 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002476
2477 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002478 __skb_queue_head_init(BUSY_QUEUE(sk));
2479
2480 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03002481
2482 sk->sk_backlog_rcv = l2cap_ertm_data_rcv;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002483}
2484
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002485static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2486{
2487 switch (mode) {
2488 case L2CAP_MODE_STREAMING:
2489 case L2CAP_MODE_ERTM:
2490 if (l2cap_mode_supported(mode, remote_feat_mask))
2491 return mode;
2492 /* fall through */
2493 default:
2494 return L2CAP_MODE_BASIC;
2495 }
2496}
2497
Linus Torvalds1da177e2005-04-16 15:20:36 -07002498static int l2cap_build_conf_req(struct sock *sk, void *data)
2499{
2500 struct l2cap_pinfo *pi = l2cap_pi(sk);
2501 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002502 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002503 void *ptr = req->data;
2504
2505 BT_DBG("sk %p", sk);
2506
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002507 if (pi->num_conf_req || pi->num_conf_rsp)
2508 goto done;
2509
2510 switch (pi->mode) {
2511 case L2CAP_MODE_STREAMING:
2512 case L2CAP_MODE_ERTM:
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002513 if (pi->conf_state & L2CAP_CONF_STATE2_DEVICE)
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002514 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002515
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002516 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002517 default:
2518 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2519 break;
2520 }
2521
2522done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002523 switch (pi->mode) {
2524 case L2CAP_MODE_BASIC:
2525 if (pi->imtu != L2CAP_DEFAULT_MTU)
2526 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002527
2528 rfc.mode = L2CAP_MODE_BASIC;
2529 rfc.txwin_size = 0;
2530 rfc.max_transmit = 0;
2531 rfc.retrans_timeout = 0;
2532 rfc.monitor_timeout = 0;
2533 rfc.max_pdu_size = 0;
2534
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002535 break;
2536
2537 case L2CAP_MODE_ERTM:
2538 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002539 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002540 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002541 rfc.retrans_timeout = 0;
2542 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002543 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002544 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002545 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002546
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002547 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2548 break;
2549
2550 if (pi->fcs == L2CAP_FCS_NONE ||
2551 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2552 pi->fcs = L2CAP_FCS_NONE;
2553 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2554 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002555 break;
2556
2557 case L2CAP_MODE_STREAMING:
2558 rfc.mode = L2CAP_MODE_STREAMING;
2559 rfc.txwin_size = 0;
2560 rfc.max_transmit = 0;
2561 rfc.retrans_timeout = 0;
2562 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002563 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002564 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002565 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002566
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002567 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2568 break;
2569
2570 if (pi->fcs == L2CAP_FCS_NONE ||
2571 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2572 pi->fcs = L2CAP_FCS_NONE;
2573 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2574 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002575 break;
2576 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002577
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002578 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2579 (unsigned long) &rfc);
2580
Linus Torvalds1da177e2005-04-16 15:20:36 -07002581 /* FIXME: Need actual value of the flush timeout */
2582 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2583 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2584
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002585 req->dcid = cpu_to_le16(pi->dcid);
2586 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002587
2588 return ptr - data;
2589}
2590
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002591static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002592{
2593 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002594 struct l2cap_conf_rsp *rsp = data;
2595 void *ptr = rsp->data;
2596 void *req = pi->conf_req;
2597 int len = pi->conf_len;
2598 int type, hint, olen;
2599 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002600 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002601 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002602 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002603
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002604 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002605
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002606 while (len >= L2CAP_CONF_OPT_SIZE) {
2607 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002608
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002609 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002610 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002611
2612 switch (type) {
2613 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002614 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002615 break;
2616
2617 case L2CAP_CONF_FLUSH_TO:
2618 pi->flush_to = val;
2619 break;
2620
2621 case L2CAP_CONF_QOS:
2622 break;
2623
Marcel Holtmann6464f352007-10-20 13:39:51 +02002624 case L2CAP_CONF_RFC:
2625 if (olen == sizeof(rfc))
2626 memcpy(&rfc, (void *) val, olen);
2627 break;
2628
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002629 case L2CAP_CONF_FCS:
2630 if (val == L2CAP_FCS_NONE)
2631 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2632
2633 break;
2634
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002635 default:
2636 if (hint)
2637 break;
2638
2639 result = L2CAP_CONF_UNKNOWN;
2640 *((u8 *) ptr++) = type;
2641 break;
2642 }
2643 }
2644
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002645 if (pi->num_conf_rsp || pi->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002646 goto done;
2647
2648 switch (pi->mode) {
2649 case L2CAP_MODE_STREAMING:
2650 case L2CAP_MODE_ERTM:
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002651 if (!(pi->conf_state & L2CAP_CONF_STATE2_DEVICE)) {
2652 pi->mode = l2cap_select_mode(rfc.mode,
2653 pi->conn->feat_mask);
2654 break;
2655 }
2656
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03002657 if (pi->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002658 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03002659
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002660 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002661 }
2662
2663done:
2664 if (pi->mode != rfc.mode) {
2665 result = L2CAP_CONF_UNACCEPT;
2666 rfc.mode = pi->mode;
2667
2668 if (pi->num_conf_rsp == 1)
2669 return -ECONNREFUSED;
2670
2671 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2672 sizeof(rfc), (unsigned long) &rfc);
2673 }
2674
2675
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002676 if (result == L2CAP_CONF_SUCCESS) {
2677 /* Configure output options and let the other side know
2678 * which ones we don't like. */
2679
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002680 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2681 result = L2CAP_CONF_UNACCEPT;
2682 else {
2683 pi->omtu = mtu;
2684 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2685 }
2686 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002687
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002688 switch (rfc.mode) {
2689 case L2CAP_MODE_BASIC:
2690 pi->fcs = L2CAP_FCS_NONE;
2691 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2692 break;
2693
2694 case L2CAP_MODE_ERTM:
2695 pi->remote_tx_win = rfc.txwin_size;
2696 pi->remote_max_tx = rfc.max_transmit;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002697 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2698 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2699
2700 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002701
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002702 rfc.retrans_timeout =
2703 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2704 rfc.monitor_timeout =
2705 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002706
2707 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002708
2709 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2710 sizeof(rfc), (unsigned long) &rfc);
2711
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002712 break;
2713
2714 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002715 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2716 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2717
2718 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002719
2720 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002721
2722 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2723 sizeof(rfc), (unsigned long) &rfc);
2724
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002725 break;
2726
2727 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002728 result = L2CAP_CONF_UNACCEPT;
2729
2730 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002731 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002732 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002733
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002734 if (result == L2CAP_CONF_SUCCESS)
2735 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2736 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002737 rsp->scid = cpu_to_le16(pi->dcid);
2738 rsp->result = cpu_to_le16(result);
2739 rsp->flags = cpu_to_le16(0x0000);
2740
2741 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002742}
2743
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002744static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2745{
2746 struct l2cap_pinfo *pi = l2cap_pi(sk);
2747 struct l2cap_conf_req *req = data;
2748 void *ptr = req->data;
2749 int type, olen;
2750 unsigned long val;
2751 struct l2cap_conf_rfc rfc;
2752
2753 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2754
2755 while (len >= L2CAP_CONF_OPT_SIZE) {
2756 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2757
2758 switch (type) {
2759 case L2CAP_CONF_MTU:
2760 if (val < L2CAP_DEFAULT_MIN_MTU) {
2761 *result = L2CAP_CONF_UNACCEPT;
2762 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2763 } else
2764 pi->omtu = val;
2765 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2766 break;
2767
2768 case L2CAP_CONF_FLUSH_TO:
2769 pi->flush_to = val;
2770 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2771 2, pi->flush_to);
2772 break;
2773
2774 case L2CAP_CONF_RFC:
2775 if (olen == sizeof(rfc))
2776 memcpy(&rfc, (void *)val, olen);
2777
2778 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2779 rfc.mode != pi->mode)
2780 return -ECONNREFUSED;
2781
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002782 pi->fcs = 0;
2783
2784 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2785 sizeof(rfc), (unsigned long) &rfc);
2786 break;
2787 }
2788 }
2789
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03002790 if (pi->mode == L2CAP_MODE_BASIC && pi->mode != rfc.mode)
2791 return -ECONNREFUSED;
2792
2793 pi->mode = rfc.mode;
2794
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002795 if (*result == L2CAP_CONF_SUCCESS) {
2796 switch (rfc.mode) {
2797 case L2CAP_MODE_ERTM:
2798 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002799 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2800 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002801 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002802 break;
2803 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002804 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002805 }
2806 }
2807
2808 req->dcid = cpu_to_le16(pi->dcid);
2809 req->flags = cpu_to_le16(0x0000);
2810
2811 return ptr - data;
2812}
2813
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002814static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002815{
2816 struct l2cap_conf_rsp *rsp = data;
2817 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002818
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002819 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002820
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002821 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002822 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002823 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002824
2825 return ptr - data;
2826}
2827
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002828static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2829{
2830 struct l2cap_pinfo *pi = l2cap_pi(sk);
2831 int type, olen;
2832 unsigned long val;
2833 struct l2cap_conf_rfc rfc;
2834
2835 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2836
2837 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2838 return;
2839
2840 while (len >= L2CAP_CONF_OPT_SIZE) {
2841 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2842
2843 switch (type) {
2844 case L2CAP_CONF_RFC:
2845 if (olen == sizeof(rfc))
2846 memcpy(&rfc, (void *)val, olen);
2847 goto done;
2848 }
2849 }
2850
2851done:
2852 switch (rfc.mode) {
2853 case L2CAP_MODE_ERTM:
2854 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002855 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2856 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002857 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2858 break;
2859 case L2CAP_MODE_STREAMING:
2860 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2861 }
2862}
2863
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002864static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2865{
2866 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2867
2868 if (rej->reason != 0x0000)
2869 return 0;
2870
2871 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2872 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002873 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002874
2875 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002876 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002877
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002878 l2cap_conn_start(conn);
2879 }
2880
2881 return 0;
2882}
2883
Linus Torvalds1da177e2005-04-16 15:20:36 -07002884static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2885{
2886 struct l2cap_chan_list *list = &conn->chan_list;
2887 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2888 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002889 struct sock *parent, *uninitialized_var(sk);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002890 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002891
2892 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002893 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002894
2895 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2896
2897 /* Check if we have socket listening on psm */
2898 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2899 if (!parent) {
2900 result = L2CAP_CR_BAD_PSM;
2901 goto sendresp;
2902 }
2903
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002904 /* Check if the ACL is secure enough (if not SDP) */
2905 if (psm != cpu_to_le16(0x0001) &&
2906 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002907 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002908 result = L2CAP_CR_SEC_BLOCK;
2909 goto response;
2910 }
2911
Linus Torvalds1da177e2005-04-16 15:20:36 -07002912 result = L2CAP_CR_NO_MEM;
2913
2914 /* Check for backlog size */
2915 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002916 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002917 goto response;
2918 }
2919
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002920 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002921 if (!sk)
2922 goto response;
2923
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002924 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002925
2926 /* Check if we already have channel with that dcid */
2927 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002928 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002929 sock_set_flag(sk, SOCK_ZAPPED);
2930 l2cap_sock_kill(sk);
2931 goto response;
2932 }
2933
2934 hci_conn_hold(conn->hcon);
2935
2936 l2cap_sock_init(sk, parent);
2937 bacpy(&bt_sk(sk)->src, conn->src);
2938 bacpy(&bt_sk(sk)->dst, conn->dst);
2939 l2cap_pi(sk)->psm = psm;
2940 l2cap_pi(sk)->dcid = scid;
2941
2942 __l2cap_chan_add(conn, sk, parent);
2943 dcid = l2cap_pi(sk)->scid;
2944
2945 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2946
Linus Torvalds1da177e2005-04-16 15:20:36 -07002947 l2cap_pi(sk)->ident = cmd->ident;
2948
Marcel Holtmann984947d2009-02-06 23:35:19 +01002949 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002950 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002951 if (bt_sk(sk)->defer_setup) {
2952 sk->sk_state = BT_CONNECT2;
2953 result = L2CAP_CR_PEND;
2954 status = L2CAP_CS_AUTHOR_PEND;
2955 parent->sk_data_ready(parent, 0);
2956 } else {
2957 sk->sk_state = BT_CONFIG;
2958 result = L2CAP_CR_SUCCESS;
2959 status = L2CAP_CS_NO_INFO;
2960 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002961 } else {
2962 sk->sk_state = BT_CONNECT2;
2963 result = L2CAP_CR_PEND;
2964 status = L2CAP_CS_AUTHEN_PEND;
2965 }
2966 } else {
2967 sk->sk_state = BT_CONNECT2;
2968 result = L2CAP_CR_PEND;
2969 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002970 }
2971
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002972 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002973
2974response:
2975 bh_unlock_sock(parent);
2976
2977sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002978 rsp.scid = cpu_to_le16(scid);
2979 rsp.dcid = cpu_to_le16(dcid);
2980 rsp.result = cpu_to_le16(result);
2981 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002982 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002983
2984 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2985 struct l2cap_info_req info;
2986 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2987
2988 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2989 conn->info_ident = l2cap_get_ident(conn);
2990
2991 mod_timer(&conn->info_timer, jiffies +
2992 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2993
2994 l2cap_send_cmd(conn, conn->info_ident,
2995 L2CAP_INFO_REQ, sizeof(info), &info);
2996 }
2997
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002998 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) &&
2999 result == L2CAP_CR_SUCCESS) {
3000 u8 buf[128];
3001 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
3002 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3003 l2cap_build_conf_req(sk, buf), buf);
3004 l2cap_pi(sk)->num_conf_req++;
3005 }
3006
Linus Torvalds1da177e2005-04-16 15:20:36 -07003007 return 0;
3008}
3009
3010static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3011{
3012 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3013 u16 scid, dcid, result, status;
3014 struct sock *sk;
3015 u8 req[128];
3016
3017 scid = __le16_to_cpu(rsp->scid);
3018 dcid = __le16_to_cpu(rsp->dcid);
3019 result = __le16_to_cpu(rsp->result);
3020 status = __le16_to_cpu(rsp->status);
3021
3022 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
3023
3024 if (scid) {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003025 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3026 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03003027 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003028 } else {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003029 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
3030 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03003031 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003032 }
3033
3034 switch (result) {
3035 case L2CAP_CR_SUCCESS:
3036 sk->sk_state = BT_CONFIG;
3037 l2cap_pi(sk)->ident = 0;
3038 l2cap_pi(sk)->dcid = dcid;
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003039 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
3040
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003041 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)
3042 break;
3043
3044 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
3045
Linus Torvalds1da177e2005-04-16 15:20:36 -07003046 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3047 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003048 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003049 break;
3050
3051 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003052 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003053 break;
3054
3055 default:
3056 l2cap_chan_del(sk, ECONNREFUSED);
3057 break;
3058 }
3059
3060 bh_unlock_sock(sk);
3061 return 0;
3062}
3063
Al Viro88219a02007-07-29 00:17:25 -07003064static 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 -07003065{
3066 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3067 u16 dcid, flags;
3068 u8 rsp[64];
3069 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003070 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003071
3072 dcid = __le16_to_cpu(req->dcid);
3073 flags = __le16_to_cpu(req->flags);
3074
3075 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3076
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003077 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3078 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003079 return -ENOENT;
3080
Gustavo F. Padovan8cb8e6f2010-06-14 02:26:15 -03003081 if (sk->sk_state != BT_CONFIG) {
3082 struct l2cap_cmd_rej rej;
3083
3084 rej.reason = cpu_to_le16(0x0002);
3085 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
3086 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003087 goto unlock;
Gustavo F. Padovan8cb8e6f2010-06-14 02:26:15 -03003088 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003089
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003090 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003091 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003092 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
3093 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
3094 l2cap_build_conf_rsp(sk, rsp,
3095 L2CAP_CONF_REJECT, flags), rsp);
3096 goto unlock;
3097 }
3098
3099 /* Store config. */
3100 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
3101 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003102
3103 if (flags & 0x0001) {
3104 /* Incomplete config. Send empty response. */
3105 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003106 l2cap_build_conf_rsp(sk, rsp,
3107 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003108 goto unlock;
3109 }
3110
3111 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003112 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003113 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003114 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003115 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003116 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003117
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003118 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003119 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003120
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003121 /* Reset config buffer. */
3122 l2cap_pi(sk)->conf_len = 0;
3123
Marcel Holtmann876d9482007-10-20 13:35:42 +02003124 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
3125 goto unlock;
3126
Linus Torvalds1da177e2005-04-16 15:20:36 -07003127 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003128 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3129 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003130 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3131
Linus Torvalds1da177e2005-04-16 15:20:36 -07003132 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003133
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003134 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003135 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003136 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003137 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3138 l2cap_ertm_init(sk);
3139
Linus Torvalds1da177e2005-04-16 15:20:36 -07003140 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02003141 goto unlock;
3142 }
3143
3144 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003145 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003146 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003147 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003148 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003149 }
3150
3151unlock:
3152 bh_unlock_sock(sk);
3153 return 0;
3154}
3155
3156static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3157{
3158 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3159 u16 scid, flags, result;
3160 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003161 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003162
3163 scid = __le16_to_cpu(rsp->scid);
3164 flags = __le16_to_cpu(rsp->flags);
3165 result = __le16_to_cpu(rsp->result);
3166
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003167 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
3168 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003169
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003170 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3171 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003172 return 0;
3173
3174 switch (result) {
3175 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003176 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003177 break;
3178
3179 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003180 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003181 char req[64];
3182
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003183 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003184 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003185 goto done;
3186 }
3187
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003188 /* throw out any old stored conf requests */
3189 result = L2CAP_CONF_SUCCESS;
3190 len = l2cap_parse_conf_rsp(sk, rsp->data,
3191 len, req, &result);
3192 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003193 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003194 goto done;
3195 }
3196
3197 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3198 L2CAP_CONF_REQ, len, req);
3199 l2cap_pi(sk)->num_conf_req++;
3200 if (result != L2CAP_CONF_SUCCESS)
3201 goto done;
3202 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003203 }
3204
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003205 default:
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003206 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003207 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003208 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003209 goto done;
3210 }
3211
3212 if (flags & 0x01)
3213 goto done;
3214
Linus Torvalds1da177e2005-04-16 15:20:36 -07003215 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3216
3217 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003218 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3219 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003220 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3221
Linus Torvalds1da177e2005-04-16 15:20:36 -07003222 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003223 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003224 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003225 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003226 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3227 l2cap_ertm_init(sk);
3228
Linus Torvalds1da177e2005-04-16 15:20:36 -07003229 l2cap_chan_ready(sk);
3230 }
3231
3232done:
3233 bh_unlock_sock(sk);
3234 return 0;
3235}
3236
3237static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3238{
3239 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3240 struct l2cap_disconn_rsp rsp;
3241 u16 dcid, scid;
3242 struct sock *sk;
3243
3244 scid = __le16_to_cpu(req->scid);
3245 dcid = __le16_to_cpu(req->dcid);
3246
3247 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3248
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003249 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3250 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003251 return 0;
3252
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003253 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3254 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003255 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3256
3257 sk->sk_shutdown = SHUTDOWN_MASK;
3258
3259 l2cap_chan_del(sk, ECONNRESET);
3260 bh_unlock_sock(sk);
3261
3262 l2cap_sock_kill(sk);
3263 return 0;
3264}
3265
3266static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3267{
3268 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3269 u16 dcid, scid;
3270 struct sock *sk;
3271
3272 scid = __le16_to_cpu(rsp->scid);
3273 dcid = __le16_to_cpu(rsp->dcid);
3274
3275 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3276
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003277 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3278 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003279 return 0;
3280
3281 l2cap_chan_del(sk, 0);
3282 bh_unlock_sock(sk);
3283
3284 l2cap_sock_kill(sk);
3285 return 0;
3286}
3287
3288static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3289{
3290 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003291 u16 type;
3292
3293 type = __le16_to_cpu(req->type);
3294
3295 BT_DBG("type 0x%4.4x", type);
3296
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003297 if (type == L2CAP_IT_FEAT_MASK) {
3298 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003299 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003300 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3301 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3302 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003303 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003304 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3305 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003306 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003307 l2cap_send_cmd(conn, cmd->ident,
3308 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003309 } else if (type == L2CAP_IT_FIXED_CHAN) {
3310 u8 buf[12];
3311 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3312 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3313 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3314 memcpy(buf + 4, l2cap_fixed_chan, 8);
3315 l2cap_send_cmd(conn, cmd->ident,
3316 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003317 } else {
3318 struct l2cap_info_rsp rsp;
3319 rsp.type = cpu_to_le16(type);
3320 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3321 l2cap_send_cmd(conn, cmd->ident,
3322 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3323 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003324
3325 return 0;
3326}
3327
3328static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3329{
3330 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3331 u16 type, result;
3332
3333 type = __le16_to_cpu(rsp->type);
3334 result = __le16_to_cpu(rsp->result);
3335
3336 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3337
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003338 del_timer(&conn->info_timer);
3339
Marcel Holtmann984947d2009-02-06 23:35:19 +01003340 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003341 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003342
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003343 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003344 struct l2cap_info_req req;
3345 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3346
3347 conn->info_ident = l2cap_get_ident(conn);
3348
3349 l2cap_send_cmd(conn, conn->info_ident,
3350 L2CAP_INFO_REQ, sizeof(req), &req);
3351 } else {
3352 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3353 conn->info_ident = 0;
3354
3355 l2cap_conn_start(conn);
3356 }
3357 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003358 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003359 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003360
3361 l2cap_conn_start(conn);
3362 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003363
Linus Torvalds1da177e2005-04-16 15:20:36 -07003364 return 0;
3365}
3366
3367static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3368{
3369 u8 *data = skb->data;
3370 int len = skb->len;
3371 struct l2cap_cmd_hdr cmd;
3372 int err = 0;
3373
3374 l2cap_raw_recv(conn, skb);
3375
3376 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003377 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003378 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3379 data += L2CAP_CMD_HDR_SIZE;
3380 len -= L2CAP_CMD_HDR_SIZE;
3381
Al Viro88219a02007-07-29 00:17:25 -07003382 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003383
Al Viro88219a02007-07-29 00:17:25 -07003384 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 -07003385
Al Viro88219a02007-07-29 00:17:25 -07003386 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003387 BT_DBG("corrupted command");
3388 break;
3389 }
3390
3391 switch (cmd.code) {
3392 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003393 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003394 break;
3395
3396 case L2CAP_CONN_REQ:
3397 err = l2cap_connect_req(conn, &cmd, data);
3398 break;
3399
3400 case L2CAP_CONN_RSP:
3401 err = l2cap_connect_rsp(conn, &cmd, data);
3402 break;
3403
3404 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003405 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003406 break;
3407
3408 case L2CAP_CONF_RSP:
3409 err = l2cap_config_rsp(conn, &cmd, data);
3410 break;
3411
3412 case L2CAP_DISCONN_REQ:
3413 err = l2cap_disconnect_req(conn, &cmd, data);
3414 break;
3415
3416 case L2CAP_DISCONN_RSP:
3417 err = l2cap_disconnect_rsp(conn, &cmd, data);
3418 break;
3419
3420 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003421 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003422 break;
3423
3424 case L2CAP_ECHO_RSP:
3425 break;
3426
3427 case L2CAP_INFO_REQ:
3428 err = l2cap_information_req(conn, &cmd, data);
3429 break;
3430
3431 case L2CAP_INFO_RSP:
3432 err = l2cap_information_rsp(conn, &cmd, data);
3433 break;
3434
3435 default:
3436 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3437 err = -EINVAL;
3438 break;
3439 }
3440
3441 if (err) {
3442 struct l2cap_cmd_rej rej;
3443 BT_DBG("error %d", err);
3444
3445 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003446 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003447 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3448 }
3449
Al Viro88219a02007-07-29 00:17:25 -07003450 data += cmd_len;
3451 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003452 }
3453
3454 kfree_skb(skb);
3455}
3456
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003457static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3458{
3459 u16 our_fcs, rcv_fcs;
3460 int hdr_size = L2CAP_HDR_SIZE + 2;
3461
3462 if (pi->fcs == L2CAP_FCS_CRC16) {
3463 skb_trim(skb, skb->len - 2);
3464 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3465 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3466
3467 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03003468 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003469 }
3470 return 0;
3471}
3472
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003473static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3474{
3475 struct l2cap_pinfo *pi = l2cap_pi(sk);
3476 u16 control = 0;
3477
3478 pi->frames_sent = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003479
3480 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3481
3482 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan64988862010-05-10 14:54:14 -03003483 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003484 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003485 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003486 }
3487
Gustavo F. Padovan4ea727e2010-06-03 16:34:20 -03003488 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY)
3489 l2cap_retransmit_frames(sk);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003490
3491 l2cap_ertm_send(sk);
3492
3493 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3494 pi->frames_sent == 0) {
3495 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003496 l2cap_send_sframe(pi, control);
3497 }
3498}
3499
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003500static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003501{
3502 struct sk_buff *next_skb;
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003503 struct l2cap_pinfo *pi = l2cap_pi(sk);
3504 int tx_seq_offset, next_tx_seq_offset;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003505
3506 bt_cb(skb)->tx_seq = tx_seq;
3507 bt_cb(skb)->sar = sar;
3508
3509 next_skb = skb_peek(SREJ_QUEUE(sk));
3510 if (!next_skb) {
3511 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003512 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003513 }
3514
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003515 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3516 if (tx_seq_offset < 0)
3517 tx_seq_offset += 64;
3518
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003519 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003520 if (bt_cb(next_skb)->tx_seq == tx_seq)
3521 return -EINVAL;
3522
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003523 next_tx_seq_offset = (bt_cb(next_skb)->tx_seq -
3524 pi->buffer_seq) % 64;
3525 if (next_tx_seq_offset < 0)
3526 next_tx_seq_offset += 64;
3527
3528 if (next_tx_seq_offset > tx_seq_offset) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003529 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003530 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003531 }
3532
3533 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3534 break;
3535
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003536 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003537
3538 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003539
3540 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003541}
3542
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003543static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3544{
3545 struct l2cap_pinfo *pi = l2cap_pi(sk);
3546 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003547 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003548
3549 switch (control & L2CAP_CTRL_SAR) {
3550 case L2CAP_SDU_UNSEGMENTED:
3551 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3552 goto drop;
3553
3554 err = sock_queue_rcv_skb(sk, skb);
3555 if (!err)
3556 return err;
3557
3558 break;
3559
3560 case L2CAP_SDU_START:
3561 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3562 goto drop;
3563
3564 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003565
3566 if (pi->sdu_len > pi->imtu)
3567 goto disconnect;
3568
3569 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003570 if (!pi->sdu)
3571 return -ENOMEM;
3572
3573 /* pull sdu_len bytes only after alloc, because of Local Busy
3574 * condition we have to be sure that this will be executed
3575 * only once, i.e., when alloc does not fail */
3576 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003577
3578 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3579
3580 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3581 pi->partial_sdu_len = skb->len;
3582 break;
3583
3584 case L2CAP_SDU_CONTINUE:
3585 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3586 goto disconnect;
3587
3588 if (!pi->sdu)
3589 goto disconnect;
3590
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003591 pi->partial_sdu_len += skb->len;
3592 if (pi->partial_sdu_len > pi->sdu_len)
3593 goto drop;
3594
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003595 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3596
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003597 break;
3598
3599 case L2CAP_SDU_END:
3600 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3601 goto disconnect;
3602
3603 if (!pi->sdu)
3604 goto disconnect;
3605
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003606 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003607 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003608
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003609 if (pi->partial_sdu_len > pi->imtu)
3610 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003611
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003612 if (pi->partial_sdu_len != pi->sdu_len)
3613 goto drop;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003614
3615 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003616 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003617
3618 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003619 if (!_skb) {
3620 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3621 return -ENOMEM;
3622 }
3623
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003624 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003625 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003626 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003627 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3628 return err;
3629 }
3630
3631 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
3632 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003633
3634 kfree_skb(pi->sdu);
3635 break;
3636 }
3637
3638 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003639 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003640
3641drop:
3642 kfree_skb(pi->sdu);
3643 pi->sdu = NULL;
3644
3645disconnect:
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003646 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003647 kfree_skb(skb);
3648 return 0;
3649}
3650
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003651static int l2cap_try_push_rx_skb(struct sock *sk)
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003652{
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003653 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003654 struct sk_buff *skb;
3655 u16 control;
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003656 int err;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003657
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003658 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
3659 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3660 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3661 if (err < 0) {
3662 skb_queue_head(BUSY_QUEUE(sk), skb);
3663 return -EBUSY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003664 }
3665
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003666 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003667 }
3668
3669 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
3670 goto done;
3671
3672 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3673 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
3674 l2cap_send_sframe(pi, control);
3675 l2cap_pi(sk)->retry_count = 1;
3676
3677 del_timer(&pi->retrans_timer);
3678 __mod_monitor_timer();
3679
3680 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
3681
3682done:
3683 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
3684 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
3685
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003686 BT_DBG("sk %p, Exit local busy", sk);
3687
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003688 return 0;
3689}
3690
3691static void l2cap_busy_work(struct work_struct *work)
3692{
3693 DECLARE_WAITQUEUE(wait, current);
3694 struct l2cap_pinfo *pi =
3695 container_of(work, struct l2cap_pinfo, busy_work);
3696 struct sock *sk = (struct sock *)pi;
3697 int n_tries = 0, timeo = HZ/5, err;
3698 struct sk_buff *skb;
3699
3700 lock_sock(sk);
3701
3702 add_wait_queue(sk_sleep(sk), &wait);
3703 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
3704 set_current_state(TASK_INTERRUPTIBLE);
3705
3706 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
3707 err = -EBUSY;
3708 l2cap_send_disconn_req(pi->conn, sk, EBUSY);
3709 break;
3710 }
3711
3712 if (!timeo)
3713 timeo = HZ/5;
3714
3715 if (signal_pending(current)) {
3716 err = sock_intr_errno(timeo);
3717 break;
3718 }
3719
3720 release_sock(sk);
3721 timeo = schedule_timeout(timeo);
3722 lock_sock(sk);
3723
3724 err = sock_error(sk);
3725 if (err)
3726 break;
3727
3728 if (l2cap_try_push_rx_skb(sk) == 0)
3729 break;
3730 }
3731
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003732 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003733 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003734
3735 release_sock(sk);
3736}
3737
3738static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
3739{
3740 struct l2cap_pinfo *pi = l2cap_pi(sk);
3741 int sctrl, err;
3742
3743 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3744 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3745 __skb_queue_tail(BUSY_QUEUE(sk), skb);
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003746 return l2cap_try_push_rx_skb(sk);
3747
3748
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003749 }
3750
3751 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3752 if (err >= 0) {
3753 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3754 return err;
3755 }
3756
3757 /* Busy Condition */
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003758 BT_DBG("sk %p, Enter local busy", sk);
3759
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003760 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
3761 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3762 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3763
3764 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3765 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
3766 l2cap_send_sframe(pi, sctrl);
3767
3768 pi->conn_state |= L2CAP_CONN_RNR_SENT;
3769
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03003770 del_timer(&pi->ack_timer);
3771
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003772 queue_work(_busy_wq, &pi->busy_work);
3773
3774 return err;
3775}
3776
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003777static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003778{
3779 struct l2cap_pinfo *pi = l2cap_pi(sk);
3780 struct sk_buff *_skb;
3781 int err = -EINVAL;
3782
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003783 /*
3784 * TODO: We have to notify the userland if some data is lost with the
3785 * Streaming Mode.
3786 */
3787
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003788 switch (control & L2CAP_CTRL_SAR) {
3789 case L2CAP_SDU_UNSEGMENTED:
3790 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3791 kfree_skb(pi->sdu);
3792 break;
3793 }
3794
3795 err = sock_queue_rcv_skb(sk, skb);
3796 if (!err)
3797 return 0;
3798
3799 break;
3800
3801 case L2CAP_SDU_START:
3802 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3803 kfree_skb(pi->sdu);
3804 break;
3805 }
3806
3807 pi->sdu_len = get_unaligned_le16(skb->data);
3808 skb_pull(skb, 2);
3809
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003810 if (pi->sdu_len > pi->imtu) {
3811 err = -EMSGSIZE;
3812 break;
3813 }
3814
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003815 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3816 if (!pi->sdu) {
3817 err = -ENOMEM;
3818 break;
3819 }
3820
3821 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3822
3823 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3824 pi->partial_sdu_len = skb->len;
3825 err = 0;
3826 break;
3827
3828 case L2CAP_SDU_CONTINUE:
3829 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3830 break;
3831
3832 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3833
3834 pi->partial_sdu_len += skb->len;
3835 if (pi->partial_sdu_len > pi->sdu_len)
3836 kfree_skb(pi->sdu);
3837 else
3838 err = 0;
3839
3840 break;
3841
3842 case L2CAP_SDU_END:
3843 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3844 break;
3845
3846 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3847
3848 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3849 pi->partial_sdu_len += skb->len;
3850
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003851 if (pi->partial_sdu_len > pi->imtu)
3852 goto drop;
3853
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003854 if (pi->partial_sdu_len == pi->sdu_len) {
3855 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3856 err = sock_queue_rcv_skb(sk, _skb);
3857 if (err < 0)
3858 kfree_skb(_skb);
3859 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003860 err = 0;
3861
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003862drop:
3863 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003864 break;
3865 }
3866
3867 kfree_skb(skb);
3868 return err;
3869}
3870
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003871static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3872{
3873 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003874 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003875
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003876 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003877 if (bt_cb(skb)->tx_seq != tx_seq)
3878 break;
3879
3880 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003881 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003882 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003883 l2cap_pi(sk)->buffer_seq_srej =
3884 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003885 tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003886 }
3887}
3888
3889static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3890{
3891 struct l2cap_pinfo *pi = l2cap_pi(sk);
3892 struct srej_list *l, *tmp;
3893 u16 control;
3894
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003895 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003896 if (l->tx_seq == tx_seq) {
3897 list_del(&l->list);
3898 kfree(l);
3899 return;
3900 }
3901 control = L2CAP_SUPER_SELECT_REJECT;
3902 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3903 l2cap_send_sframe(pi, control);
3904 list_del(&l->list);
3905 list_add_tail(&l->list, SREJ_LIST(sk));
3906 }
3907}
3908
3909static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3910{
3911 struct l2cap_pinfo *pi = l2cap_pi(sk);
3912 struct srej_list *new;
3913 u16 control;
3914
3915 while (tx_seq != pi->expected_tx_seq) {
3916 control = L2CAP_SUPER_SELECT_REJECT;
3917 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3918 l2cap_send_sframe(pi, control);
3919
3920 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003921 new->tx_seq = pi->expected_tx_seq;
3922 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003923 list_add_tail(&new->list, SREJ_LIST(sk));
3924 }
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003925 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003926}
3927
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003928static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3929{
3930 struct l2cap_pinfo *pi = l2cap_pi(sk);
3931 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003932 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003933 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03003934 int tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003935 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003936 int err = 0;
3937
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003938 BT_DBG("sk %p len %d tx_seq %d rx_control 0x%4.4x", sk, skb->len, tx_seq,
3939 rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003940
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003941 if (L2CAP_CTRL_FINAL & rx_control &&
3942 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003943 del_timer(&pi->monitor_timer);
3944 if (pi->unacked_frames > 0)
3945 __mod_retrans_timer();
3946 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3947 }
3948
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003949 pi->expected_ack_seq = req_seq;
3950 l2cap_drop_acked_frames(sk);
3951
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003952 if (tx_seq == pi->expected_tx_seq)
3953 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003954
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003955 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3956 if (tx_seq_offset < 0)
3957 tx_seq_offset += 64;
3958
3959 /* invalid tx_seq */
3960 if (tx_seq_offset >= pi->tx_win) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003961 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003962 goto drop;
3963 }
3964
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003965 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
3966 goto drop;
3967
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003968 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3969 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003970
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003971 first = list_first_entry(SREJ_LIST(sk),
3972 struct srej_list, list);
3973 if (tx_seq == first->tx_seq) {
3974 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3975 l2cap_check_srej_gap(sk, tx_seq);
3976
3977 list_del(&first->list);
3978 kfree(first);
3979
3980 if (list_empty(SREJ_LIST(sk))) {
3981 pi->buffer_seq = pi->buffer_seq_srej;
3982 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666c2010-05-01 16:15:40 -03003983 l2cap_send_ack(pi);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003984 BT_DBG("sk %p, Exit SREJ_SENT", sk);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003985 }
3986 } else {
3987 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003988
3989 /* duplicated tx_seq */
3990 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
3991 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003992
3993 list_for_each_entry(l, SREJ_LIST(sk), list) {
3994 if (l->tx_seq == tx_seq) {
3995 l2cap_resend_srejframe(sk, tx_seq);
3996 return 0;
3997 }
3998 }
3999 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004000 }
4001 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03004002 expected_tx_seq_offset =
4003 (pi->expected_tx_seq - pi->buffer_seq) % 64;
4004 if (expected_tx_seq_offset < 0)
4005 expected_tx_seq_offset += 64;
4006
4007 /* duplicated tx_seq */
4008 if (tx_seq_offset < expected_tx_seq_offset)
4009 goto drop;
4010
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004011 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004012
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004013 BT_DBG("sk %p, Enter SREJ", sk);
4014
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004015 INIT_LIST_HEAD(SREJ_LIST(sk));
4016 pi->buffer_seq_srej = pi->buffer_seq;
4017
4018 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004019 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004020 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
4021
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03004022 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
4023
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004024 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03004025
4026 del_timer(&pi->ack_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004027 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004028 return 0;
4029
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004030expected:
4031 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4032
4033 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03004034 bt_cb(skb)->tx_seq = tx_seq;
4035 bt_cb(skb)->sar = sar;
4036 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004037 return 0;
4038 }
4039
Gustavo F. Padovan2ece3682010-06-16 17:21:44 -03004040 err = l2cap_push_rx_skb(sk, skb, rx_control);
4041 if (err < 0)
4042 return 0;
4043
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03004044 if (rx_control & L2CAP_CTRL_FINAL) {
4045 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4046 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004047 else
4048 l2cap_retransmit_frames(sk);
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03004049 }
4050
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03004051 __mod_ack_timer();
4052
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03004053 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
4054 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03004055 l2cap_send_ack(pi);
4056
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004057 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03004058
4059drop:
4060 kfree_skb(skb);
4061 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004062}
4063
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004064static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004065{
4066 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03004067
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004068 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control),
4069 rx_control);
4070
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03004071 pi->expected_ack_seq = __get_reqseq(rx_control);
4072 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004073
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004074 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004075 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03004076 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
4077 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
4078 (pi->unacked_frames > 0))
4079 __mod_retrans_timer();
4080
4081 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4082 l2cap_send_srejtail(sk);
4083 } else {
4084 l2cap_send_i_or_rr_or_rnr(sk);
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03004085 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004086
4087 } else if (rx_control & L2CAP_CTRL_FINAL) {
4088 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004089
4090 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4091 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004092 else
4093 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004094
4095 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004096 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
4097 (pi->unacked_frames > 0))
4098 __mod_retrans_timer();
4099
4100 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004101 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004102 l2cap_send_ack(pi);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004103 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004104 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004105 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004106 }
4107}
4108
4109static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
4110{
4111 struct l2cap_pinfo *pi = l2cap_pi(sk);
4112 u8 tx_seq = __get_reqseq(rx_control);
4113
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004114 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4115
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004116 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4117
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03004118 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004119 l2cap_drop_acked_frames(sk);
4120
4121 if (rx_control & L2CAP_CTRL_FINAL) {
4122 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4123 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004124 else
4125 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004126 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004127 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004128
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03004129 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004130 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004131 }
4132}
4133static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
4134{
4135 struct l2cap_pinfo *pi = l2cap_pi(sk);
4136 u8 tx_seq = __get_reqseq(rx_control);
4137
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004138 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4139
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004140 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4141
4142 if (rx_control & L2CAP_CTRL_POLL) {
4143 pi->expected_ack_seq = tx_seq;
4144 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004145
4146 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004147 l2cap_retransmit_one_frame(sk, tx_seq);
4148
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004149 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004150
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004151 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4152 pi->srej_save_reqseq = tx_seq;
4153 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4154 }
4155 } else if (rx_control & L2CAP_CTRL_FINAL) {
4156 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
4157 pi->srej_save_reqseq == tx_seq)
4158 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
4159 else
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004160 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004161 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004162 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004163 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4164 pi->srej_save_reqseq = tx_seq;
4165 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4166 }
4167 }
4168}
4169
4170static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
4171{
4172 struct l2cap_pinfo *pi = l2cap_pi(sk);
4173 u8 tx_seq = __get_reqseq(rx_control);
4174
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004175 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4176
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004177 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
4178 pi->expected_ack_seq = tx_seq;
4179 l2cap_drop_acked_frames(sk);
4180
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004181 if (rx_control & L2CAP_CTRL_POLL)
4182 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
4183
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004184 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
4185 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03004186 if (rx_control & L2CAP_CTRL_POLL)
4187 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004188 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004189 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004190
4191 if (rx_control & L2CAP_CTRL_POLL)
4192 l2cap_send_srejtail(sk);
4193 else
4194 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004195}
4196
4197static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
4198{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004199 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
4200
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03004201 if (L2CAP_CTRL_FINAL & rx_control &&
4202 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004203 del_timer(&l2cap_pi(sk)->monitor_timer);
4204 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004205 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004206 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004207 }
4208
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004209 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
4210 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004211 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004212 break;
4213
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004214 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004215 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004216 break;
4217
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004218 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004219 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004220 break;
4221
4222 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004223 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004224 break;
4225 }
4226
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03004227 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004228 return 0;
4229}
4230
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004231static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
4232{
4233 struct l2cap_pinfo *pi = l2cap_pi(sk);
4234 u16 control;
4235 u8 req_seq;
4236 int len, next_tx_seq_offset, req_seq_offset;
4237
4238 control = get_unaligned_le16(skb->data);
4239 skb_pull(skb, 2);
4240 len = skb->len;
4241
4242 /*
4243 * We can just drop the corrupted I-frame here.
4244 * Receiver will miss it and start proper recovery
4245 * procedures and ask retransmission.
4246 */
4247 if (l2cap_check_fcs(pi, skb))
4248 goto drop;
4249
4250 if (__is_sar_start(control) && __is_iframe(control))
4251 len -= 2;
4252
4253 if (pi->fcs == L2CAP_FCS_CRC16)
4254 len -= 2;
4255
4256 if (len > pi->mps) {
4257 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4258 goto drop;
4259 }
4260
4261 req_seq = __get_reqseq(control);
4262 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
4263 if (req_seq_offset < 0)
4264 req_seq_offset += 64;
4265
4266 next_tx_seq_offset =
4267 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
4268 if (next_tx_seq_offset < 0)
4269 next_tx_seq_offset += 64;
4270
4271 /* check for invalid req-seq */
4272 if (req_seq_offset > next_tx_seq_offset) {
4273 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4274 goto drop;
4275 }
4276
4277 if (__is_iframe(control)) {
4278 if (len < 0) {
4279 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4280 goto drop;
4281 }
4282
4283 l2cap_data_channel_iframe(sk, control, skb);
4284 } else {
4285 if (len != 0) {
4286 BT_ERR("%d", len);
4287 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4288 goto drop;
4289 }
4290
4291 l2cap_data_channel_sframe(sk, control, skb);
4292 }
4293
4294 return 0;
4295
4296drop:
4297 kfree_skb(skb);
4298 return 0;
4299}
4300
Linus Torvalds1da177e2005-04-16 15:20:36 -07004301static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
4302{
4303 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004304 struct l2cap_pinfo *pi;
Nathan Holstein51893f82010-06-09 15:46:25 -04004305 u16 control;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004306 u8 tx_seq;
4307 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004308
4309 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
4310 if (!sk) {
4311 BT_DBG("unknown cid 0x%4.4x", cid);
4312 goto drop;
4313 }
4314
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004315 pi = l2cap_pi(sk);
4316
Linus Torvalds1da177e2005-04-16 15:20:36 -07004317 BT_DBG("sk %p, len %d", sk, skb->len);
4318
4319 if (sk->sk_state != BT_CONNECTED)
4320 goto drop;
4321
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004322 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004323 case L2CAP_MODE_BASIC:
4324 /* If socket recv buffers overflows we drop data here
4325 * which is *bad* because L2CAP has to be reliable.
4326 * But we don't have any other choice. L2CAP doesn't
4327 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004328
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004329 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004330 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004331
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004332 if (!sock_queue_rcv_skb(sk, skb))
4333 goto done;
4334 break;
4335
4336 case L2CAP_MODE_ERTM:
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004337 if (!sock_owned_by_user(sk)) {
4338 l2cap_ertm_data_rcv(sk, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004339 } else {
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004340 if (sk_add_backlog(sk, skb))
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004341 goto drop;
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004342 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004343
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004344 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004345
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004346 case L2CAP_MODE_STREAMING:
4347 control = get_unaligned_le16(skb->data);
4348 skb_pull(skb, 2);
4349 len = skb->len;
4350
Gustavo F. Padovan26000082010-05-11 22:02:00 -03004351 if (l2cap_check_fcs(pi, skb))
4352 goto drop;
4353
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004354 if (__is_sar_start(control))
4355 len -= 2;
4356
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004357 if (pi->fcs == L2CAP_FCS_CRC16)
4358 len -= 2;
4359
Nathan Holstein51893f82010-06-09 15:46:25 -04004360 if (len > pi->mps || len < 0 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004361 goto drop;
4362
4363 tx_seq = __get_txseq(control);
4364
4365 if (pi->expected_tx_seq == tx_seq)
4366 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4367 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03004368 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004369
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004370 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004371
4372 goto done;
4373
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004374 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03004375 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004376 break;
4377 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004378
4379drop:
4380 kfree_skb(skb);
4381
4382done:
Marcel Holtmann01394182006-07-03 10:02:46 +02004383 if (sk)
4384 bh_unlock_sock(sk);
4385
Linus Torvalds1da177e2005-04-16 15:20:36 -07004386 return 0;
4387}
4388
Al Viro8e036fc2007-07-29 00:16:36 -07004389static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004390{
4391 struct sock *sk;
4392
4393 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
4394 if (!sk)
4395 goto drop;
4396
4397 BT_DBG("sk %p, len %d", sk, skb->len);
4398
4399 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
4400 goto drop;
4401
4402 if (l2cap_pi(sk)->imtu < skb->len)
4403 goto drop;
4404
4405 if (!sock_queue_rcv_skb(sk, skb))
4406 goto done;
4407
4408drop:
4409 kfree_skb(skb);
4410
4411done:
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03004412 if (sk)
4413 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004414 return 0;
4415}
4416
4417static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
4418{
4419 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07004420 u16 cid, len;
4421 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004422
4423 skb_pull(skb, L2CAP_HDR_SIZE);
4424 cid = __le16_to_cpu(lh->cid);
4425 len = __le16_to_cpu(lh->len);
4426
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004427 if (len != skb->len) {
4428 kfree_skb(skb);
4429 return;
4430 }
4431
Linus Torvalds1da177e2005-04-16 15:20:36 -07004432 BT_DBG("len %d, cid 0x%4.4x", len, cid);
4433
4434 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004435 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004436 l2cap_sig_channel(conn, skb);
4437 break;
4438
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004439 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004440 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004441 skb_pull(skb, 2);
4442 l2cap_conless_channel(conn, psm, skb);
4443 break;
4444
4445 default:
4446 l2cap_data_channel(conn, cid, skb);
4447 break;
4448 }
4449}
4450
4451/* ---- L2CAP interface with lower layer (HCI) ---- */
4452
4453static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
4454{
4455 int exact = 0, lm1 = 0, lm2 = 0;
4456 register struct sock *sk;
4457 struct hlist_node *node;
4458
4459 if (type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03004460 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004461
4462 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
4463
4464 /* Find listening sockets and check their link_mode */
4465 read_lock(&l2cap_sk_list.lock);
4466 sk_for_each(sk, node, &l2cap_sk_list.head) {
4467 if (sk->sk_state != BT_LISTEN)
4468 continue;
4469
4470 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004471 lm1 |= HCI_LM_ACCEPT;
4472 if (l2cap_pi(sk)->role_switch)
4473 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004474 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004475 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
4476 lm2 |= HCI_LM_ACCEPT;
4477 if (l2cap_pi(sk)->role_switch)
4478 lm2 |= HCI_LM_MASTER;
4479 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004480 }
4481 read_unlock(&l2cap_sk_list.lock);
4482
4483 return exact ? lm1 : lm2;
4484}
4485
4486static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
4487{
Marcel Holtmann01394182006-07-03 10:02:46 +02004488 struct l2cap_conn *conn;
4489
Linus Torvalds1da177e2005-04-16 15:20:36 -07004490 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
4491
4492 if (hcon->type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03004493 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004494
4495 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004496 conn = l2cap_conn_add(hcon, status);
4497 if (conn)
4498 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02004499 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004500 l2cap_conn_del(hcon, bt_err(status));
4501
4502 return 0;
4503}
4504
Marcel Holtmann2950f212009-02-12 14:02:50 +01004505static int l2cap_disconn_ind(struct hci_conn *hcon)
4506{
4507 struct l2cap_conn *conn = hcon->l2cap_data;
4508
4509 BT_DBG("hcon %p", hcon);
4510
4511 if (hcon->type != ACL_LINK || !conn)
4512 return 0x13;
4513
4514 return conn->disc_reason;
4515}
4516
4517static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004518{
4519 BT_DBG("hcon %p reason %d", hcon, reason);
4520
4521 if (hcon->type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03004522 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004523
4524 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004525
Linus Torvalds1da177e2005-04-16 15:20:36 -07004526 return 0;
4527}
4528
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004529static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4530{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004531 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004532 return;
4533
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004534 if (encrypt == 0x00) {
4535 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4536 l2cap_sock_clear_timer(sk);
4537 l2cap_sock_set_timer(sk, HZ * 5);
4538 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4539 __l2cap_sock_close(sk, ECONNREFUSED);
4540 } else {
4541 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4542 l2cap_sock_clear_timer(sk);
4543 }
4544}
4545
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004546static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004547{
4548 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004549 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004550 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004551
Marcel Holtmann01394182006-07-03 10:02:46 +02004552 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004553 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004554
Linus Torvalds1da177e2005-04-16 15:20:36 -07004555 l = &conn->chan_list;
4556
4557 BT_DBG("conn %p", conn);
4558
4559 read_lock(&l->lock);
4560
4561 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4562 bh_lock_sock(sk);
4563
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004564 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4565 bh_unlock_sock(sk);
4566 continue;
4567 }
4568
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004569 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004570 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004571 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004572 bh_unlock_sock(sk);
4573 continue;
4574 }
4575
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004576 if (sk->sk_state == BT_CONNECT) {
4577 if (!status) {
4578 struct l2cap_conn_req req;
4579 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4580 req.psm = l2cap_pi(sk)->psm;
4581
4582 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03004583 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004584
4585 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4586 L2CAP_CONN_REQ, sizeof(req), &req);
4587 } else {
4588 l2cap_sock_clear_timer(sk);
4589 l2cap_sock_set_timer(sk, HZ / 10);
4590 }
4591 } else if (sk->sk_state == BT_CONNECT2) {
4592 struct l2cap_conn_rsp rsp;
4593 __u16 result;
4594
4595 if (!status) {
4596 sk->sk_state = BT_CONFIG;
4597 result = L2CAP_CR_SUCCESS;
4598 } else {
4599 sk->sk_state = BT_DISCONN;
4600 l2cap_sock_set_timer(sk, HZ / 10);
4601 result = L2CAP_CR_SEC_BLOCK;
4602 }
4603
4604 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4605 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4606 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004607 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004608 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4609 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004610 }
4611
Linus Torvalds1da177e2005-04-16 15:20:36 -07004612 bh_unlock_sock(sk);
4613 }
4614
4615 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004616
Linus Torvalds1da177e2005-04-16 15:20:36 -07004617 return 0;
4618}
4619
4620static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4621{
4622 struct l2cap_conn *conn = hcon->l2cap_data;
4623
4624 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4625 goto drop;
4626
4627 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4628
4629 if (flags & ACL_START) {
4630 struct l2cap_hdr *hdr;
4631 int len;
4632
4633 if (conn->rx_len) {
4634 BT_ERR("Unexpected start frame (len %d)", skb->len);
4635 kfree_skb(conn->rx_skb);
4636 conn->rx_skb = NULL;
4637 conn->rx_len = 0;
4638 l2cap_conn_unreliable(conn, ECOMM);
4639 }
4640
4641 if (skb->len < 2) {
4642 BT_ERR("Frame is too short (len %d)", skb->len);
4643 l2cap_conn_unreliable(conn, ECOMM);
4644 goto drop;
4645 }
4646
4647 hdr = (struct l2cap_hdr *) skb->data;
4648 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4649
4650 if (len == skb->len) {
4651 /* Complete frame received */
4652 l2cap_recv_frame(conn, skb);
4653 return 0;
4654 }
4655
4656 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4657
4658 if (skb->len > len) {
4659 BT_ERR("Frame is too long (len %d, expected len %d)",
4660 skb->len, len);
4661 l2cap_conn_unreliable(conn, ECOMM);
4662 goto drop;
4663 }
4664
4665 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03004666 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4667 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004668 goto drop;
4669
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004670 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004671 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004672 conn->rx_len = len - skb->len;
4673 } else {
4674 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4675
4676 if (!conn->rx_len) {
4677 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4678 l2cap_conn_unreliable(conn, ECOMM);
4679 goto drop;
4680 }
4681
4682 if (skb->len > conn->rx_len) {
4683 BT_ERR("Fragment is too long (len %d, expected %d)",
4684 skb->len, conn->rx_len);
4685 kfree_skb(conn->rx_skb);
4686 conn->rx_skb = NULL;
4687 conn->rx_len = 0;
4688 l2cap_conn_unreliable(conn, ECOMM);
4689 goto drop;
4690 }
4691
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004692 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004693 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004694 conn->rx_len -= skb->len;
4695
4696 if (!conn->rx_len) {
4697 /* Complete frame received */
4698 l2cap_recv_frame(conn, conn->rx_skb);
4699 conn->rx_skb = NULL;
4700 }
4701 }
4702
4703drop:
4704 kfree_skb(skb);
4705 return 0;
4706}
4707
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004708static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004709{
4710 struct sock *sk;
4711 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004712
4713 read_lock_bh(&l2cap_sk_list.lock);
4714
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004715 sk_for_each(sk, node, &l2cap_sk_list.head) {
4716 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004717
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004718 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4719 batostr(&bt_sk(sk)->src),
4720 batostr(&bt_sk(sk)->dst),
4721 sk->sk_state, __le16_to_cpu(pi->psm),
4722 pi->scid, pi->dcid,
4723 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004724 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004725
Linus Torvalds1da177e2005-04-16 15:20:36 -07004726 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004727
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004728 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004729}
4730
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004731static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4732{
4733 return single_open(file, l2cap_debugfs_show, inode->i_private);
4734}
4735
4736static const struct file_operations l2cap_debugfs_fops = {
4737 .open = l2cap_debugfs_open,
4738 .read = seq_read,
4739 .llseek = seq_lseek,
4740 .release = single_release,
4741};
4742
4743static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004744
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004745static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004746 .family = PF_BLUETOOTH,
4747 .owner = THIS_MODULE,
4748 .release = l2cap_sock_release,
4749 .bind = l2cap_sock_bind,
4750 .connect = l2cap_sock_connect,
4751 .listen = l2cap_sock_listen,
4752 .accept = l2cap_sock_accept,
4753 .getname = l2cap_sock_getname,
4754 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004755 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004756 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004757 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004758 .mmap = sock_no_mmap,
4759 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004760 .shutdown = l2cap_sock_shutdown,
4761 .setsockopt = l2cap_sock_setsockopt,
4762 .getsockopt = l2cap_sock_getsockopt
4763};
4764
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004765static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004766 .family = PF_BLUETOOTH,
4767 .owner = THIS_MODULE,
4768 .create = l2cap_sock_create,
4769};
4770
4771static struct hci_proto l2cap_hci_proto = {
4772 .name = "L2CAP",
4773 .id = HCI_PROTO_L2CAP,
4774 .connect_ind = l2cap_connect_ind,
4775 .connect_cfm = l2cap_connect_cfm,
4776 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004777 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004778 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004779 .recv_acldata = l2cap_recv_acldata
4780};
4781
4782static int __init l2cap_init(void)
4783{
4784 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004785
Linus Torvalds1da177e2005-04-16 15:20:36 -07004786 err = proto_register(&l2cap_proto, 0);
4787 if (err < 0)
4788 return err;
4789
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004790 _busy_wq = create_singlethread_workqueue("l2cap");
4791 if (!_busy_wq)
4792 goto error;
4793
Linus Torvalds1da177e2005-04-16 15:20:36 -07004794 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4795 if (err < 0) {
4796 BT_ERR("L2CAP socket registration failed");
4797 goto error;
4798 }
4799
4800 err = hci_register_proto(&l2cap_hci_proto);
4801 if (err < 0) {
4802 BT_ERR("L2CAP protocol registration failed");
4803 bt_sock_unregister(BTPROTO_L2CAP);
4804 goto error;
4805 }
4806
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004807 if (bt_debugfs) {
4808 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4809 bt_debugfs, NULL, &l2cap_debugfs_fops);
4810 if (!l2cap_debugfs)
4811 BT_ERR("Failed to create L2CAP debug file");
4812 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004813
4814 BT_INFO("L2CAP ver %s", VERSION);
4815 BT_INFO("L2CAP socket layer initialized");
4816
4817 return 0;
4818
4819error:
4820 proto_unregister(&l2cap_proto);
4821 return err;
4822}
4823
4824static void __exit l2cap_exit(void)
4825{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004826 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004827
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004828 flush_workqueue(_busy_wq);
4829 destroy_workqueue(_busy_wq);
4830
Linus Torvalds1da177e2005-04-16 15:20:36 -07004831 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4832 BT_ERR("L2CAP socket unregistration failed");
4833
4834 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4835 BT_ERR("L2CAP protocol unregistration failed");
4836
4837 proto_unregister(&l2cap_proto);
4838}
4839
4840void l2cap_load(void)
4841{
4842 /* Dummy function to trigger automatic L2CAP module loading by
4843 * other modules that use L2CAP sockets but don't use any other
4844 * symbols from it. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004845}
4846EXPORT_SYMBOL(l2cap_load);
4847
4848module_init(l2cap_init);
4849module_exit(l2cap_exit);
4850
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004851module_param(enable_ertm, bool, 0644);
4852MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4853
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004854MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004855MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4856MODULE_VERSION(VERSION);
4857MODULE_LICENSE("GPL");
4858MODULE_ALIAS("bt-proto-0");