blob: e366be0792cbadcb3e171c2e850cf343f4ef5636 [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) {
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300525 if (l2cap_check_security(sk) &&
526 __l2cap_no_conn_pending(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200527 struct l2cap_conn_req req;
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300528
529 if (!l2cap_mode_supported(l2cap_pi(sk)->mode,
530 conn->feat_mask)
531 && l2cap_pi(sk)->conf_state &
532 L2CAP_CONF_STATE2_DEVICE) {
533 tmp1 = kzalloc(sizeof(struct srej_list),
534 GFP_ATOMIC);
535 tmp1->sk = sk;
536 list_add_tail(&tmp1->list, &del.list);
537 bh_unlock_sock(sk);
538 continue;
539 }
540
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200541 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
542 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200543
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200544 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300545 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200546
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200547 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200548 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200549 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200550 } else if (sk->sk_state == BT_CONNECT2) {
551 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -0300552 char buf[128];
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200553 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
554 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
555
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100556 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100557 if (bt_sk(sk)->defer_setup) {
558 struct sock *parent = bt_sk(sk)->parent;
559 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
560 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
561 parent->sk_data_ready(parent, 0);
562
563 } else {
564 sk->sk_state = BT_CONFIG;
565 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
566 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
567 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200568 } else {
569 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
570 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
571 }
572
573 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
574 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -0300575
576 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT ||
577 rsp.result != L2CAP_CR_SUCCESS) {
578 bh_unlock_sock(sk);
579 continue;
580 }
581
582 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
583 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
584 l2cap_build_conf_req(sk, buf), buf);
585 l2cap_pi(sk)->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200586 }
587
588 bh_unlock_sock(sk);
589 }
590
591 read_unlock(&l->lock);
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300592
593 list_for_each_entry_safe(tmp1, tmp2, &del.list, list) {
594 bh_lock_sock(tmp1->sk);
595 __l2cap_sock_close(tmp1->sk, ECONNRESET);
596 bh_unlock_sock(tmp1->sk);
597 list_del(&tmp1->list);
598 kfree(tmp1);
599 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200600}
601
602static void l2cap_conn_ready(struct l2cap_conn *conn)
603{
604 struct l2cap_chan_list *l = &conn->chan_list;
605 struct sock *sk;
606
607 BT_DBG("conn %p", conn);
608
609 read_lock(&l->lock);
610
611 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
612 bh_lock_sock(sk);
613
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300614 if (sk->sk_type != SOCK_SEQPACKET &&
615 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200616 l2cap_sock_clear_timer(sk);
617 sk->sk_state = BT_CONNECTED;
618 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200619 } else if (sk->sk_state == BT_CONNECT)
620 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200621
622 bh_unlock_sock(sk);
623 }
624
625 read_unlock(&l->lock);
626}
627
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200628/* Notify sockets that we cannot guaranty reliability anymore */
629static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
630{
631 struct l2cap_chan_list *l = &conn->chan_list;
632 struct sock *sk;
633
634 BT_DBG("conn %p", conn);
635
636 read_lock(&l->lock);
637
638 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100639 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200640 sk->sk_err = err;
641 }
642
643 read_unlock(&l->lock);
644}
645
646static void l2cap_info_timeout(unsigned long arg)
647{
648 struct l2cap_conn *conn = (void *) arg;
649
Marcel Holtmann984947d2009-02-06 23:35:19 +0100650 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100651 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100652
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200653 l2cap_conn_start(conn);
654}
655
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
657{
Marcel Holtmann01394182006-07-03 10:02:46 +0200658 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700659
Marcel Holtmann01394182006-07-03 10:02:46 +0200660 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661 return conn;
662
Marcel Holtmann01394182006-07-03 10:02:46 +0200663 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
664 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666
667 hcon->l2cap_data = conn;
668 conn->hcon = hcon;
669
Marcel Holtmann01394182006-07-03 10:02:46 +0200670 BT_DBG("hcon %p conn %p", hcon, conn);
671
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672 conn->mtu = hcon->hdev->acl_mtu;
673 conn->src = &hcon->hdev->bdaddr;
674 conn->dst = &hcon->dst;
675
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200676 conn->feat_mask = 0;
677
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678 spin_lock_init(&conn->lock);
679 rwlock_init(&conn->chan_list.lock);
680
Dave Young45054dc2009-10-18 20:28:30 +0000681 setup_timer(&conn->info_timer, l2cap_info_timeout,
682 (unsigned long) conn);
683
Marcel Holtmann2950f212009-02-12 14:02:50 +0100684 conn->disc_reason = 0x13;
685
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 return conn;
687}
688
Marcel Holtmann01394182006-07-03 10:02:46 +0200689static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690{
Marcel Holtmann01394182006-07-03 10:02:46 +0200691 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692 struct sock *sk;
693
Marcel Holtmann01394182006-07-03 10:02:46 +0200694 if (!conn)
695 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696
697 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
698
Wei Yongjun7585b972009-02-25 18:29:52 +0800699 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700
701 /* Kill channels */
702 while ((sk = conn->chan_list.head)) {
703 bh_lock_sock(sk);
704 l2cap_chan_del(sk, err);
705 bh_unlock_sock(sk);
706 l2cap_sock_kill(sk);
707 }
708
Dave Young8e8440f2008-03-03 12:18:55 -0800709 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
710 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800711
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712 hcon->l2cap_data = NULL;
713 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714}
715
716static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
717{
718 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200719 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200721 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722}
723
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700725static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726{
727 struct sock *sk;
728 struct hlist_node *node;
729 sk_for_each(sk, node, &l2cap_sk_list.head)
730 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
731 goto found;
732 sk = NULL;
733found:
734 return sk;
735}
736
737/* Find socket with psm and source bdaddr.
738 * Returns closest match.
739 */
Al Viro8e036fc2007-07-29 00:16:36 -0700740static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741{
742 struct sock *sk = NULL, *sk1 = NULL;
743 struct hlist_node *node;
744
745 sk_for_each(sk, node, &l2cap_sk_list.head) {
746 if (state && sk->sk_state != state)
747 continue;
748
749 if (l2cap_pi(sk)->psm == psm) {
750 /* Exact match. */
751 if (!bacmp(&bt_sk(sk)->src, src))
752 break;
753
754 /* Closest match */
755 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
756 sk1 = sk;
757 }
758 }
759 return node ? sk : sk1;
760}
761
762/* Find socket with given address (psm, src).
763 * Returns locked socket */
Al Viro8e036fc2007-07-29 00:16:36 -0700764static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765{
766 struct sock *s;
767 read_lock(&l2cap_sk_list.lock);
768 s = __l2cap_get_sock_by_psm(state, psm, src);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300769 if (s)
770 bh_lock_sock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 read_unlock(&l2cap_sk_list.lock);
772 return s;
773}
774
775static void l2cap_sock_destruct(struct sock *sk)
776{
777 BT_DBG("sk %p", sk);
778
779 skb_queue_purge(&sk->sk_receive_queue);
780 skb_queue_purge(&sk->sk_write_queue);
781}
782
783static void l2cap_sock_cleanup_listen(struct sock *parent)
784{
785 struct sock *sk;
786
787 BT_DBG("parent %p", parent);
788
789 /* Close not yet accepted channels */
790 while ((sk = bt_accept_dequeue(parent, NULL)))
791 l2cap_sock_close(sk);
792
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200793 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794 sock_set_flag(parent, SOCK_ZAPPED);
795}
796
797/* Kill socket (only if zapped and orphan)
798 * Must be called on unlocked socket.
799 */
800static void l2cap_sock_kill(struct sock *sk)
801{
802 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
803 return;
804
805 BT_DBG("sk %p state %d", sk, sk->sk_state);
806
807 /* Kill poor orphan */
808 bt_sock_unlink(&l2cap_sk_list, sk);
809 sock_set_flag(sk, SOCK_DEAD);
810 sock_put(sk);
811}
812
813static void __l2cap_sock_close(struct sock *sk, int reason)
814{
815 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
816
817 switch (sk->sk_state) {
818 case BT_LISTEN:
819 l2cap_sock_cleanup_listen(sk);
820 break;
821
822 case BT_CONNECTED:
823 case BT_CONFIG:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300824 if (sk->sk_type == SOCK_SEQPACKET ||
825 sk->sk_type == SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827
Linus Torvalds1da177e2005-04-16 15:20:36 -0700828 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300829 l2cap_send_disconn_req(conn, sk, reason);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200830 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832 break;
833
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100834 case BT_CONNECT2:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300835 if (sk->sk_type == SOCK_SEQPACKET ||
836 sk->sk_type == SOCK_STREAM) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100837 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
838 struct l2cap_conn_rsp rsp;
839 __u16 result;
840
841 if (bt_sk(sk)->defer_setup)
842 result = L2CAP_CR_SEC_BLOCK;
843 else
844 result = L2CAP_CR_BAD_PSM;
845
846 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
847 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
848 rsp.result = cpu_to_le16(result);
849 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
850 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
851 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
852 } else
853 l2cap_chan_del(sk, reason);
854 break;
855
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 case BT_CONNECT:
857 case BT_DISCONN:
858 l2cap_chan_del(sk, reason);
859 break;
860
861 default:
862 sock_set_flag(sk, SOCK_ZAPPED);
863 break;
864 }
865}
866
867/* Must be called on unlocked socket. */
868static void l2cap_sock_close(struct sock *sk)
869{
870 l2cap_sock_clear_timer(sk);
871 lock_sock(sk);
872 __l2cap_sock_close(sk, ECONNRESET);
873 release_sock(sk);
874 l2cap_sock_kill(sk);
875}
876
877static void l2cap_sock_init(struct sock *sk, struct sock *parent)
878{
879 struct l2cap_pinfo *pi = l2cap_pi(sk);
880
881 BT_DBG("sk %p", sk);
882
883 if (parent) {
884 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100885 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
886
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887 pi->imtu = l2cap_pi(parent)->imtu;
888 pi->omtu = l2cap_pi(parent)->omtu;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300889 pi->conf_state = l2cap_pi(parent)->conf_state;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700890 pi->mode = l2cap_pi(parent)->mode;
891 pi->fcs = l2cap_pi(parent)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -0300892 pi->max_tx = l2cap_pi(parent)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -0300893 pi->tx_win = l2cap_pi(parent)->tx_win;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100894 pi->sec_level = l2cap_pi(parent)->sec_level;
895 pi->role_switch = l2cap_pi(parent)->role_switch;
896 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897 } else {
898 pi->imtu = L2CAP_DEFAULT_MTU;
899 pi->omtu = 0;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300900 if (enable_ertm && sk->sk_type == SOCK_STREAM) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300901 pi->mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300902 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
903 } else {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300904 pi->mode = L2CAP_MODE_BASIC;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300905 }
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300906 pi->max_tx = L2CAP_DEFAULT_MAX_TX;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700907 pi->fcs = L2CAP_FCS_CRC16;
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300908 pi->tx_win = L2CAP_DEFAULT_TX_WINDOW;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100909 pi->sec_level = BT_SECURITY_LOW;
910 pi->role_switch = 0;
911 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912 }
913
914 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200915 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Dave Young45054dc2009-10-18 20:28:30 +0000917 skb_queue_head_init(TX_QUEUE(sk));
918 skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300919 skb_queue_head_init(BUSY_QUEUE(sk));
Dave Young45054dc2009-10-18 20:28:30 +0000920 INIT_LIST_HEAD(SREJ_LIST(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921}
922
923static struct proto l2cap_proto = {
924 .name = "L2CAP",
925 .owner = THIS_MODULE,
926 .obj_size = sizeof(struct l2cap_pinfo)
927};
928
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700929static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930{
931 struct sock *sk;
932
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700933 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 if (!sk)
935 return NULL;
936
937 sock_init_data(sock, sk);
938 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
939
940 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200941 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942
943 sock_reset_flag(sk, SOCK_ZAPPED);
944
945 sk->sk_protocol = proto;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200946 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200948 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949
950 bt_sock_link(&l2cap_sk_list, sk);
951 return sk;
952}
953
Eric Paris3f378b62009-11-05 22:18:14 -0800954static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
955 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956{
957 struct sock *sk;
958
959 BT_DBG("sock %p", sock);
960
961 sock->state = SS_UNCONNECTED;
962
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300963 if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700964 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
965 return -ESOCKTNOSUPPORT;
966
Eric Parisc84b3262009-11-05 20:45:52 -0800967 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700968 return -EPERM;
969
970 sock->ops = &l2cap_sock_ops;
971
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700972 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973 if (!sk)
974 return -ENOMEM;
975
976 l2cap_sock_init(sk, NULL);
977 return 0;
978}
979
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100980static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100983 struct sockaddr_l2 la;
984 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100986 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987
988 if (!addr || addr->sa_family != AF_BLUETOOTH)
989 return -EINVAL;
990
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100991 memset(&la, 0, sizeof(la));
992 len = min_t(unsigned int, sizeof(la), alen);
993 memcpy(&la, addr, len);
994
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100995 if (la.l2_cid)
996 return -EINVAL;
997
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998 lock_sock(sk);
999
1000 if (sk->sk_state != BT_OPEN) {
1001 err = -EBADFD;
1002 goto done;
1003 }
1004
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001005 if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
Marcel Holtmann847641d2007-01-22 22:00:45 +01001006 !capable(CAP_NET_BIND_SERVICE)) {
1007 err = -EACCES;
1008 goto done;
1009 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001010
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011 write_lock_bh(&l2cap_sk_list.lock);
1012
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001013 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001014 err = -EADDRINUSE;
1015 } else {
1016 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001017 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
1018 l2cap_pi(sk)->psm = la.l2_psm;
1019 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001021
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001022 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
1023 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001024 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 }
1026
1027 write_unlock_bh(&l2cap_sk_list.lock);
1028
1029done:
1030 release_sock(sk);
1031 return err;
1032}
1033
1034static int l2cap_do_connect(struct sock *sk)
1035{
1036 bdaddr_t *src = &bt_sk(sk)->src;
1037 bdaddr_t *dst = &bt_sk(sk)->dst;
1038 struct l2cap_conn *conn;
1039 struct hci_conn *hcon;
1040 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001041 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001042 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001043
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001044 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
1045 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001047 hdev = hci_get_route(dst, src);
1048 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 return -EHOSTUNREACH;
1050
1051 hci_dev_lock_bh(hdev);
1052
1053 err = -ENOMEM;
1054
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001055 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001056 switch (l2cap_pi(sk)->sec_level) {
1057 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001058 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001059 break;
1060 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001061 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001062 break;
1063 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001064 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001065 break;
1066 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001067 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001068 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001069 auth_type = HCI_AT_NO_BONDING_MITM;
1070 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001071 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +01001072
1073 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
1074 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001075 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001076 switch (l2cap_pi(sk)->sec_level) {
1077 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001078 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001079 break;
1080 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001081 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001082 break;
1083 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001084 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001085 break;
1086 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001087 }
1088
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001089 hcon = hci_connect(hdev, ACL_LINK, dst,
1090 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091 if (!hcon)
1092 goto done;
1093
1094 conn = l2cap_conn_add(hcon, 0);
1095 if (!conn) {
1096 hci_conn_put(hcon);
1097 goto done;
1098 }
1099
1100 err = 0;
1101
1102 /* Update source addr of the socket */
1103 bacpy(src, conn->src);
1104
1105 l2cap_chan_add(conn, sk, NULL);
1106
1107 sk->sk_state = BT_CONNECT;
1108 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
1109
1110 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001111 if (sk->sk_type != SOCK_SEQPACKET &&
1112 sk->sk_type != SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113 l2cap_sock_clear_timer(sk);
1114 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001115 } else
1116 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117 }
1118
1119done:
1120 hci_dev_unlock_bh(hdev);
1121 hci_dev_put(hdev);
1122 return err;
1123}
1124
1125static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
1126{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001128 struct sockaddr_l2 la;
1129 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131 BT_DBG("sk %p", sk);
1132
Changli Gao6503d962010-03-31 22:58:26 +00001133 if (!addr || alen < sizeof(addr->sa_family) ||
1134 addr->sa_family != AF_BLUETOOTH)
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001135 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001137 memset(&la, 0, sizeof(la));
1138 len = min_t(unsigned int, sizeof(la), alen);
1139 memcpy(&la, addr, len);
1140
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001141 if (la.l2_cid)
1142 return -EINVAL;
1143
1144 lock_sock(sk);
1145
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001146 if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
1147 && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148 err = -EINVAL;
1149 goto done;
1150 }
1151
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001152 switch (l2cap_pi(sk)->mode) {
1153 case L2CAP_MODE_BASIC:
1154 break;
1155 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001156 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001157 if (enable_ertm)
1158 break;
1159 /* fall through */
1160 default:
1161 err = -ENOTSUPP;
1162 goto done;
1163 }
1164
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001165 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166 case BT_CONNECT:
1167 case BT_CONNECT2:
1168 case BT_CONFIG:
1169 /* Already connecting */
1170 goto wait;
1171
1172 case BT_CONNECTED:
1173 /* Already connected */
João Paulo Rechi Vita8b0dc6d2010-06-22 13:56:22 -03001174 err = -EISCONN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175 goto done;
1176
1177 case BT_OPEN:
1178 case BT_BOUND:
1179 /* Can connect */
1180 break;
1181
1182 default:
1183 err = -EBADFD;
1184 goto done;
1185 }
1186
1187 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001188 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1189 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001191 err = l2cap_do_connect(sk);
1192 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 goto done;
1194
1195wait:
1196 err = bt_sock_wait_state(sk, BT_CONNECTED,
1197 sock_sndtimeo(sk, flags & O_NONBLOCK));
1198done:
1199 release_sock(sk);
1200 return err;
1201}
1202
1203static int l2cap_sock_listen(struct socket *sock, int backlog)
1204{
1205 struct sock *sk = sock->sk;
1206 int err = 0;
1207
1208 BT_DBG("sk %p backlog %d", sk, backlog);
1209
1210 lock_sock(sk);
1211
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001212 if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
1213 || sk->sk_state != BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214 err = -EBADFD;
1215 goto done;
1216 }
1217
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001218 switch (l2cap_pi(sk)->mode) {
1219 case L2CAP_MODE_BASIC:
1220 break;
1221 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001222 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001223 if (enable_ertm)
1224 break;
1225 /* fall through */
1226 default:
1227 err = -ENOTSUPP;
1228 goto done;
1229 }
1230
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231 if (!l2cap_pi(sk)->psm) {
1232 bdaddr_t *src = &bt_sk(sk)->src;
1233 u16 psm;
1234
1235 err = -EINVAL;
1236
1237 write_lock_bh(&l2cap_sk_list.lock);
1238
1239 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001240 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1241 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1242 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243 err = 0;
1244 break;
1245 }
1246
1247 write_unlock_bh(&l2cap_sk_list.lock);
1248
1249 if (err < 0)
1250 goto done;
1251 }
1252
1253 sk->sk_max_ack_backlog = backlog;
1254 sk->sk_ack_backlog = 0;
1255 sk->sk_state = BT_LISTEN;
1256
1257done:
1258 release_sock(sk);
1259 return err;
1260}
1261
1262static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1263{
1264 DECLARE_WAITQUEUE(wait, current);
1265 struct sock *sk = sock->sk, *nsk;
1266 long timeo;
1267 int err = 0;
1268
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001269 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270
1271 if (sk->sk_state != BT_LISTEN) {
1272 err = -EBADFD;
1273 goto done;
1274 }
1275
1276 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1277
1278 BT_DBG("sk %p timeo %ld", sk, timeo);
1279
1280 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +00001281 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001282 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1283 set_current_state(TASK_INTERRUPTIBLE);
1284 if (!timeo) {
1285 err = -EAGAIN;
1286 break;
1287 }
1288
1289 release_sock(sk);
1290 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001291 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001292
1293 if (sk->sk_state != BT_LISTEN) {
1294 err = -EBADFD;
1295 break;
1296 }
1297
1298 if (signal_pending(current)) {
1299 err = sock_intr_errno(timeo);
1300 break;
1301 }
1302 }
1303 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +00001304 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001305
1306 if (err)
1307 goto done;
1308
1309 newsock->state = SS_CONNECTED;
1310
1311 BT_DBG("new socket %p", nsk);
1312
1313done:
1314 release_sock(sk);
1315 return err;
1316}
1317
1318static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1319{
1320 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1321 struct sock *sk = sock->sk;
1322
1323 BT_DBG("sock %p, sk %p", sock, sk);
1324
1325 addr->sa_family = AF_BLUETOOTH;
1326 *len = sizeof(struct sockaddr_l2);
1327
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001328 if (peer) {
1329 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001331 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001332 } else {
1333 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001335 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001336 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337
Linus Torvalds1da177e2005-04-16 15:20:36 -07001338 return 0;
1339}
1340
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001341static int __l2cap_wait_ack(struct sock *sk)
1342{
1343 DECLARE_WAITQUEUE(wait, current);
1344 int err = 0;
1345 int timeo = HZ/5;
1346
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001347 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001348 while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
1349 set_current_state(TASK_INTERRUPTIBLE);
1350
1351 if (!timeo)
1352 timeo = HZ/5;
1353
1354 if (signal_pending(current)) {
1355 err = sock_intr_errno(timeo);
1356 break;
1357 }
1358
1359 release_sock(sk);
1360 timeo = schedule_timeout(timeo);
1361 lock_sock(sk);
1362
1363 err = sock_error(sk);
1364 if (err)
1365 break;
1366 }
1367 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001368 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001369 return err;
1370}
1371
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001372static void l2cap_monitor_timeout(unsigned long arg)
1373{
1374 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001375
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001376 BT_DBG("sk %p", sk);
1377
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001378 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001379 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001380 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001381 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001382 return;
1383 }
1384
1385 l2cap_pi(sk)->retry_count++;
1386 __mod_monitor_timer();
1387
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001388 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001389 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001390}
1391
1392static void l2cap_retrans_timeout(unsigned long arg)
1393{
1394 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001395
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001396 BT_DBG("sk %p", sk);
1397
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001398 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001399 l2cap_pi(sk)->retry_count = 1;
1400 __mod_monitor_timer();
1401
1402 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1403
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001404 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001405 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001406}
1407
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001408static void l2cap_drop_acked_frames(struct sock *sk)
1409{
1410 struct sk_buff *skb;
1411
Gustavo F. Padovan812e7372010-05-01 16:15:42 -03001412 while ((skb = skb_peek(TX_QUEUE(sk))) &&
1413 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001414 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1415 break;
1416
1417 skb = skb_dequeue(TX_QUEUE(sk));
1418 kfree_skb(skb);
1419
1420 l2cap_pi(sk)->unacked_frames--;
1421 }
1422
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001423 if (!l2cap_pi(sk)->unacked_frames)
1424 del_timer(&l2cap_pi(sk)->retrans_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001425}
1426
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001427static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001428{
1429 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001430
1431 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1432
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001433 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001434}
1435
João Paulo Rechi Vita305682e2010-06-22 13:56:23 -03001436static void l2cap_streaming_send(struct sock *sk)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001437{
1438 struct sk_buff *skb, *tx_skb;
1439 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001440 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001441
1442 while ((skb = sk->sk_send_head)) {
1443 tx_skb = skb_clone(skb, GFP_ATOMIC);
1444
1445 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1446 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1447 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1448
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001449 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001450 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1451 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1452 }
1453
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001454 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001455
1456 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1457
1458 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1459 sk->sk_send_head = NULL;
1460 else
1461 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1462
1463 skb = skb_dequeue(TX_QUEUE(sk));
1464 kfree_skb(skb);
1465 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001466}
1467
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001468static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001469{
1470 struct l2cap_pinfo *pi = l2cap_pi(sk);
1471 struct sk_buff *skb, *tx_skb;
1472 u16 control, fcs;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001473
1474 skb = skb_peek(TX_QUEUE(sk));
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001475 if (!skb)
1476 return;
1477
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001478 do {
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001479 if (bt_cb(skb)->tx_seq == tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001480 break;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001481
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001482 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1483 return;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001484
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001485 } while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001486
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001487 if (pi->remote_max_tx &&
1488 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001489 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001490 return;
1491 }
1492
1493 tx_skb = skb_clone(skb, GFP_ATOMIC);
1494 bt_cb(skb)->retries++;
1495 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001496
1497 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1498 control |= L2CAP_CTRL_FINAL;
1499 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1500 }
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001501
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001502 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1503 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001504
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001505 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1506
1507 if (pi->fcs == L2CAP_FCS_CRC16) {
1508 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1509 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1510 }
1511
1512 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001513}
1514
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001515static int l2cap_ertm_send(struct sock *sk)
1516{
1517 struct sk_buff *skb, *tx_skb;
1518 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001519 u16 control, fcs;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001520 int nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001521
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001522 if (sk->sk_state != BT_CONNECTED)
1523 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001524
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001525 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001526
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001527 if (pi->remote_max_tx &&
1528 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001529 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001530 break;
1531 }
1532
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001533 tx_skb = skb_clone(skb, GFP_ATOMIC);
1534
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001535 bt_cb(skb)->retries++;
1536
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001537 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001538 control &= L2CAP_CTRL_SAR;
1539
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001540 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1541 control |= L2CAP_CTRL_FINAL;
1542 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1543 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001544 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001545 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1546 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1547
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001548
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001549 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001550 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1551 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1552 }
1553
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001554 l2cap_do_send(sk, tx_skb);
1555
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001556 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001557
1558 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1559 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1560
1561 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001562 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001563
1564 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1565 sk->sk_send_head = NULL;
1566 else
1567 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001568
1569 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001570 }
1571
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001572 return nsent;
1573}
1574
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001575static int l2cap_retransmit_frames(struct sock *sk)
1576{
1577 struct l2cap_pinfo *pi = l2cap_pi(sk);
1578 int ret;
1579
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001580 if (!skb_queue_empty(TX_QUEUE(sk)))
1581 sk->sk_send_head = TX_QUEUE(sk)->next;
1582
1583 pi->next_tx_seq = pi->expected_ack_seq;
1584 ret = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001585 return ret;
1586}
1587
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001588static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001589{
1590 struct sock *sk = (struct sock *)pi;
1591 u16 control = 0;
1592
1593 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1594
1595 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1596 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001597 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001598 l2cap_send_sframe(pi, control);
1599 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001600 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001601
Gustavo F. Padovane0f66212010-06-21 18:50:49 -03001602 if (l2cap_ertm_send(sk) > 0)
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001603 return;
1604
1605 control |= L2CAP_SUPER_RCV_READY;
1606 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001607}
1608
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001609static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001610{
1611 struct srej_list *tail;
1612 u16 control;
1613
1614 control = L2CAP_SUPER_SELECT_REJECT;
1615 control |= L2CAP_CTRL_FINAL;
1616
1617 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1618 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1619
1620 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001621}
1622
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001623static 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 -07001624{
1625 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001626 struct sk_buff **frag;
1627 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001628
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001629 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001630 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001631
1632 sent += count;
1633 len -= count;
1634
1635 /* Continuation fragments (no L2CAP header) */
1636 frag = &skb_shinfo(skb)->frag_list;
1637 while (len) {
1638 count = min_t(unsigned int, conn->mtu, len);
1639
1640 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1641 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001642 return -EFAULT;
1643 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1644 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001645
1646 sent += count;
1647 len -= count;
1648
1649 frag = &(*frag)->next;
1650 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651
1652 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001653}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001655static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1656{
1657 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1658 struct sk_buff *skb;
1659 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1660 struct l2cap_hdr *lh;
1661
1662 BT_DBG("sk %p len %d", sk, (int)len);
1663
1664 count = min_t(unsigned int, (conn->mtu - hlen), len);
1665 skb = bt_skb_send_alloc(sk, count + hlen,
1666 msg->msg_flags & MSG_DONTWAIT, &err);
1667 if (!skb)
1668 return ERR_PTR(-ENOMEM);
1669
1670 /* Create L2CAP header */
1671 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1672 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1673 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1674 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1675
1676 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1677 if (unlikely(err < 0)) {
1678 kfree_skb(skb);
1679 return ERR_PTR(err);
1680 }
1681 return skb;
1682}
1683
1684static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1685{
1686 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1687 struct sk_buff *skb;
1688 int err, count, hlen = L2CAP_HDR_SIZE;
1689 struct l2cap_hdr *lh;
1690
1691 BT_DBG("sk %p len %d", sk, (int)len);
1692
1693 count = min_t(unsigned int, (conn->mtu - hlen), len);
1694 skb = bt_skb_send_alloc(sk, count + hlen,
1695 msg->msg_flags & MSG_DONTWAIT, &err);
1696 if (!skb)
1697 return ERR_PTR(-ENOMEM);
1698
1699 /* Create L2CAP header */
1700 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1701 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1702 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1703
1704 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1705 if (unlikely(err < 0)) {
1706 kfree_skb(skb);
1707 return ERR_PTR(err);
1708 }
1709 return skb;
1710}
1711
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001712static 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 -03001713{
1714 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1715 struct sk_buff *skb;
1716 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1717 struct l2cap_hdr *lh;
1718
1719 BT_DBG("sk %p len %d", sk, (int)len);
1720
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001721 if (!conn)
1722 return ERR_PTR(-ENOTCONN);
1723
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001724 if (sdulen)
1725 hlen += 2;
1726
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001727 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1728 hlen += 2;
1729
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001730 count = min_t(unsigned int, (conn->mtu - hlen), len);
1731 skb = bt_skb_send_alloc(sk, count + hlen,
1732 msg->msg_flags & MSG_DONTWAIT, &err);
1733 if (!skb)
1734 return ERR_PTR(-ENOMEM);
1735
1736 /* Create L2CAP header */
1737 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1738 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1739 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1740 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001741 if (sdulen)
1742 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001743
1744 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1745 if (unlikely(err < 0)) {
1746 kfree_skb(skb);
1747 return ERR_PTR(err);
1748 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001749
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001750 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1751 put_unaligned_le16(0, skb_put(skb, 2));
1752
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001753 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001754 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755}
1756
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001757static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1758{
1759 struct l2cap_pinfo *pi = l2cap_pi(sk);
1760 struct sk_buff *skb;
1761 struct sk_buff_head sar_queue;
1762 u16 control;
1763 size_t size = 0;
1764
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001765 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001766 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001767 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001768 if (IS_ERR(skb))
1769 return PTR_ERR(skb);
1770
1771 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001772 len -= pi->remote_mps;
1773 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001774
1775 while (len > 0) {
1776 size_t buflen;
1777
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001778 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001779 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001780 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001781 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001782 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001783 buflen = len;
1784 }
1785
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001786 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001787 if (IS_ERR(skb)) {
1788 skb_queue_purge(&sar_queue);
1789 return PTR_ERR(skb);
1790 }
1791
1792 __skb_queue_tail(&sar_queue, skb);
1793 len -= buflen;
1794 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001795 }
1796 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1797 if (sk->sk_send_head == NULL)
1798 sk->sk_send_head = sar_queue.next;
1799
1800 return size;
1801}
1802
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1804{
1805 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001806 struct l2cap_pinfo *pi = l2cap_pi(sk);
1807 struct sk_buff *skb;
1808 u16 control;
1809 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810
1811 BT_DBG("sock %p, sk %p", sock, sk);
1812
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001813 err = sock_error(sk);
1814 if (err)
1815 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816
1817 if (msg->msg_flags & MSG_OOB)
1818 return -EOPNOTSUPP;
1819
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820 lock_sock(sk);
1821
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001822 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001824 goto done;
1825 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001827 /* Connectionless channel */
1828 if (sk->sk_type == SOCK_DGRAM) {
1829 skb = l2cap_create_connless_pdu(sk, msg, len);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001830 if (IS_ERR(skb)) {
Dan Carpenter477fffb2010-04-21 23:52:01 +00001831 err = PTR_ERR(skb);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001832 } else {
1833 l2cap_do_send(sk, skb);
1834 err = len;
1835 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001836 goto done;
1837 }
1838
1839 switch (pi->mode) {
1840 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001841 /* Check outgoing MTU */
1842 if (len > pi->omtu) {
João Paulo Rechi Vitaf9dd11b2010-06-22 13:56:24 -03001843 err = -EMSGSIZE;
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001844 goto done;
1845 }
1846
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001847 /* Create a basic PDU */
1848 skb = l2cap_create_basic_pdu(sk, msg, len);
1849 if (IS_ERR(skb)) {
1850 err = PTR_ERR(skb);
1851 goto done;
1852 }
1853
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001854 l2cap_do_send(sk, skb);
1855 err = len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001856 break;
1857
1858 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001859 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001860 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001861 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001862 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001863 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001864 if (IS_ERR(skb)) {
1865 err = PTR_ERR(skb);
1866 goto done;
1867 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001868 __skb_queue_tail(TX_QUEUE(sk), skb);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001869
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001870 if (sk->sk_send_head == NULL)
1871 sk->sk_send_head = skb;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001872
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001873 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001874 /* Segment SDU into multiples PDUs */
1875 err = l2cap_sar_segment_sdu(sk, msg, len);
1876 if (err < 0)
1877 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001878 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001879
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001880 if (pi->mode == L2CAP_MODE_STREAMING) {
João Paulo Rechi Vita305682e2010-06-22 13:56:23 -03001881 l2cap_streaming_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001882 } else {
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001883 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY &&
1884 pi->conn_state && L2CAP_CONN_WAIT_F) {
1885 err = len;
1886 break;
1887 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001888 err = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001889 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001890
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001891 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001892 err = len;
1893 break;
1894
1895 default:
1896 BT_DBG("bad state %1.1x", pi->mode);
João Paulo Rechi Vitabc766db22010-06-22 13:56:25 -03001897 err = -EBADFD;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001898 }
1899
1900done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901 release_sock(sk);
1902 return err;
1903}
1904
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001905static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1906{
1907 struct sock *sk = sock->sk;
1908
1909 lock_sock(sk);
1910
1911 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1912 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001913 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1914 u8 buf[128];
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001915
1916 sk->sk_state = BT_CONFIG;
1917
1918 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1919 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1920 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1921 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1922 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1923 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1924
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001925 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) {
1926 release_sock(sk);
1927 return 0;
1928 }
1929
1930 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
1931 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
1932 l2cap_build_conf_req(sk, buf), buf);
1933 l2cap_pi(sk)->num_conf_req++;
1934
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001935 release_sock(sk);
1936 return 0;
1937 }
1938
1939 release_sock(sk);
1940
1941 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1942}
1943
David S. Millerb7058842009-09-30 16:12:20 -07001944static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945{
1946 struct sock *sk = sock->sk;
1947 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001948 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949 u32 opt;
1950
1951 BT_DBG("sk %p", sk);
1952
1953 lock_sock(sk);
1954
1955 switch (optname) {
1956 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001957 opts.imtu = l2cap_pi(sk)->imtu;
1958 opts.omtu = l2cap_pi(sk)->omtu;
1959 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001960 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001961 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001962 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001963 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001964
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965 len = min_t(unsigned int, sizeof(opts), optlen);
1966 if (copy_from_user((char *) &opts, optval, len)) {
1967 err = -EFAULT;
1968 break;
1969 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001970
Gustavo F. Padovan45d65c42010-06-07 19:21:30 -03001971 if (opts.txwin_size > L2CAP_DEFAULT_TX_WINDOW) {
1972 err = -EINVAL;
1973 break;
1974 }
1975
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001976 l2cap_pi(sk)->mode = opts.mode;
1977 switch (l2cap_pi(sk)->mode) {
1978 case L2CAP_MODE_BASIC:
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03001979 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_STATE2_DEVICE;
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001980 break;
1981 case L2CAP_MODE_ERTM:
1982 case L2CAP_MODE_STREAMING:
1983 if (enable_ertm)
1984 break;
1985 /* fall through */
1986 default:
1987 err = -EINVAL;
1988 break;
1989 }
1990
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001991 l2cap_pi(sk)->imtu = opts.imtu;
1992 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001993 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001994 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001995 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001996 break;
1997
1998 case L2CAP_LM:
1999 if (get_user(opt, (u32 __user *) optval)) {
2000 err = -EFAULT;
2001 break;
2002 }
2003
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002004 if (opt & L2CAP_LM_AUTH)
2005 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
2006 if (opt & L2CAP_LM_ENCRYPT)
2007 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
2008 if (opt & L2CAP_LM_SECURE)
2009 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
2010
2011 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
2012 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002013 break;
2014
2015 default:
2016 err = -ENOPROTOOPT;
2017 break;
2018 }
2019
2020 release_sock(sk);
2021 return err;
2022}
2023
David S. Millerb7058842009-09-30 16:12:20 -07002024static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002025{
2026 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002027 struct bt_security sec;
2028 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002029 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002030
2031 BT_DBG("sk %p", sk);
2032
2033 if (level == SOL_L2CAP)
2034 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
2035
Marcel Holtmann0588d942009-01-16 10:06:13 +01002036 if (level != SOL_BLUETOOTH)
2037 return -ENOPROTOOPT;
2038
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002039 lock_sock(sk);
2040
2041 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002042 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002043 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2044 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002045 err = -EINVAL;
2046 break;
2047 }
2048
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002049 sec.level = BT_SECURITY_LOW;
2050
2051 len = min_t(unsigned int, sizeof(sec), optlen);
2052 if (copy_from_user((char *) &sec, optval, len)) {
2053 err = -EFAULT;
2054 break;
2055 }
2056
2057 if (sec.level < BT_SECURITY_LOW ||
2058 sec.level > BT_SECURITY_HIGH) {
2059 err = -EINVAL;
2060 break;
2061 }
2062
2063 l2cap_pi(sk)->sec_level = sec.level;
2064 break;
2065
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002066 case BT_DEFER_SETUP:
2067 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2068 err = -EINVAL;
2069 break;
2070 }
2071
2072 if (get_user(opt, (u32 __user *) optval)) {
2073 err = -EFAULT;
2074 break;
2075 }
2076
2077 bt_sk(sk)->defer_setup = opt;
2078 break;
2079
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002080 default:
2081 err = -ENOPROTOOPT;
2082 break;
2083 }
2084
2085 release_sock(sk);
2086 return err;
2087}
2088
2089static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002090{
2091 struct sock *sk = sock->sk;
2092 struct l2cap_options opts;
2093 struct l2cap_conninfo cinfo;
2094 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002095 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002096
2097 BT_DBG("sk %p", sk);
2098
2099 if (get_user(len, optlen))
2100 return -EFAULT;
2101
2102 lock_sock(sk);
2103
2104 switch (optname) {
2105 case L2CAP_OPTIONS:
2106 opts.imtu = l2cap_pi(sk)->imtu;
2107 opts.omtu = l2cap_pi(sk)->omtu;
2108 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07002109 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002110 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002111 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002112 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002113
2114 len = min_t(unsigned int, len, sizeof(opts));
2115 if (copy_to_user(optval, (char *) &opts, len))
2116 err = -EFAULT;
2117
2118 break;
2119
2120 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002121 switch (l2cap_pi(sk)->sec_level) {
2122 case BT_SECURITY_LOW:
2123 opt = L2CAP_LM_AUTH;
2124 break;
2125 case BT_SECURITY_MEDIUM:
2126 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
2127 break;
2128 case BT_SECURITY_HIGH:
2129 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
2130 L2CAP_LM_SECURE;
2131 break;
2132 default:
2133 opt = 0;
2134 break;
2135 }
2136
2137 if (l2cap_pi(sk)->role_switch)
2138 opt |= L2CAP_LM_MASTER;
2139
2140 if (l2cap_pi(sk)->force_reliable)
2141 opt |= L2CAP_LM_RELIABLE;
2142
2143 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002144 err = -EFAULT;
2145 break;
2146
2147 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002148 if (sk->sk_state != BT_CONNECTED &&
2149 !(sk->sk_state == BT_CONNECT2 &&
2150 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002151 err = -ENOTCONN;
2152 break;
2153 }
2154
2155 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
2156 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
2157
2158 len = min_t(unsigned int, len, sizeof(cinfo));
2159 if (copy_to_user(optval, (char *) &cinfo, len))
2160 err = -EFAULT;
2161
2162 break;
2163
2164 default:
2165 err = -ENOPROTOOPT;
2166 break;
2167 }
2168
2169 release_sock(sk);
2170 return err;
2171}
2172
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002173static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
2174{
2175 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002176 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002177 int len, err = 0;
2178
2179 BT_DBG("sk %p", sk);
2180
2181 if (level == SOL_L2CAP)
2182 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
2183
Marcel Holtmann0588d942009-01-16 10:06:13 +01002184 if (level != SOL_BLUETOOTH)
2185 return -ENOPROTOOPT;
2186
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002187 if (get_user(len, optlen))
2188 return -EFAULT;
2189
2190 lock_sock(sk);
2191
2192 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002193 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002194 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2195 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002196 err = -EINVAL;
2197 break;
2198 }
2199
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002200 sec.level = l2cap_pi(sk)->sec_level;
2201
2202 len = min_t(unsigned int, len, sizeof(sec));
2203 if (copy_to_user(optval, (char *) &sec, len))
2204 err = -EFAULT;
2205
2206 break;
2207
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002208 case BT_DEFER_SETUP:
2209 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2210 err = -EINVAL;
2211 break;
2212 }
2213
2214 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2215 err = -EFAULT;
2216
2217 break;
2218
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002219 default:
2220 err = -ENOPROTOOPT;
2221 break;
2222 }
2223
2224 release_sock(sk);
2225 return err;
2226}
2227
Linus Torvalds1da177e2005-04-16 15:20:36 -07002228static int l2cap_sock_shutdown(struct socket *sock, int how)
2229{
2230 struct sock *sk = sock->sk;
2231 int err = 0;
2232
2233 BT_DBG("sock %p, sk %p", sock, sk);
2234
2235 if (!sk)
2236 return 0;
2237
2238 lock_sock(sk);
2239 if (!sk->sk_shutdown) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03002240 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2241 err = __l2cap_wait_ack(sk);
2242
Linus Torvalds1da177e2005-04-16 15:20:36 -07002243 sk->sk_shutdown = SHUTDOWN_MASK;
2244 l2cap_sock_clear_timer(sk);
2245 __l2cap_sock_close(sk, 0);
2246
2247 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002248 err = bt_sock_wait_state(sk, BT_CLOSED,
2249 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002250 }
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002251
2252 if (!err && sk->sk_err)
2253 err = -sk->sk_err;
2254
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255 release_sock(sk);
2256 return err;
2257}
2258
2259static int l2cap_sock_release(struct socket *sock)
2260{
2261 struct sock *sk = sock->sk;
2262 int err;
2263
2264 BT_DBG("sock %p, sk %p", sock, sk);
2265
2266 if (!sk)
2267 return 0;
2268
2269 err = l2cap_sock_shutdown(sock, 2);
2270
2271 sock_orphan(sk);
2272 l2cap_sock_kill(sk);
2273 return err;
2274}
2275
Linus Torvalds1da177e2005-04-16 15:20:36 -07002276static void l2cap_chan_ready(struct sock *sk)
2277{
2278 struct sock *parent = bt_sk(sk)->parent;
2279
2280 BT_DBG("sk %p, parent %p", sk, parent);
2281
2282 l2cap_pi(sk)->conf_state = 0;
2283 l2cap_sock_clear_timer(sk);
2284
2285 if (!parent) {
2286 /* Outgoing channel.
2287 * Wake up socket sleeping on connect.
2288 */
2289 sk->sk_state = BT_CONNECTED;
2290 sk->sk_state_change(sk);
2291 } else {
2292 /* Incoming channel.
2293 * Wake up socket sleeping on accept.
2294 */
2295 parent->sk_data_ready(parent, 0);
2296 }
2297}
2298
2299/* Copy frame to all raw sockets on that connection */
2300static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2301{
2302 struct l2cap_chan_list *l = &conn->chan_list;
2303 struct sk_buff *nskb;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002304 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002305
2306 BT_DBG("conn %p", conn);
2307
2308 read_lock(&l->lock);
2309 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2310 if (sk->sk_type != SOCK_RAW)
2311 continue;
2312
2313 /* Don't send frame to the socket it came from */
2314 if (skb->sk == sk)
2315 continue;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002316 nskb = skb_clone(skb, GFP_ATOMIC);
2317 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002318 continue;
2319
2320 if (sock_queue_rcv_skb(sk, nskb))
2321 kfree_skb(nskb);
2322 }
2323 read_unlock(&l->lock);
2324}
2325
2326/* ---- L2CAP signalling commands ---- */
2327static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2328 u8 code, u8 ident, u16 dlen, void *data)
2329{
2330 struct sk_buff *skb, **frag;
2331 struct l2cap_cmd_hdr *cmd;
2332 struct l2cap_hdr *lh;
2333 int len, count;
2334
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002335 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2336 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002337
2338 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2339 count = min_t(unsigned int, conn->mtu, len);
2340
2341 skb = bt_skb_alloc(count, GFP_ATOMIC);
2342 if (!skb)
2343 return NULL;
2344
2345 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002346 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002347 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002348
2349 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2350 cmd->code = code;
2351 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002352 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002353
2354 if (dlen) {
2355 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2356 memcpy(skb_put(skb, count), data, count);
2357 data += count;
2358 }
2359
2360 len -= skb->len;
2361
2362 /* Continuation fragments (no L2CAP header) */
2363 frag = &skb_shinfo(skb)->frag_list;
2364 while (len) {
2365 count = min_t(unsigned int, conn->mtu, len);
2366
2367 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2368 if (!*frag)
2369 goto fail;
2370
2371 memcpy(skb_put(*frag, count), data, count);
2372
2373 len -= count;
2374 data += count;
2375
2376 frag = &(*frag)->next;
2377 }
2378
2379 return skb;
2380
2381fail:
2382 kfree_skb(skb);
2383 return NULL;
2384}
2385
2386static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2387{
2388 struct l2cap_conf_opt *opt = *ptr;
2389 int len;
2390
2391 len = L2CAP_CONF_OPT_SIZE + opt->len;
2392 *ptr += len;
2393
2394 *type = opt->type;
2395 *olen = opt->len;
2396
2397 switch (opt->len) {
2398 case 1:
2399 *val = *((u8 *) opt->val);
2400 break;
2401
2402 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002403 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002404 break;
2405
2406 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002407 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002408 break;
2409
2410 default:
2411 *val = (unsigned long) opt->val;
2412 break;
2413 }
2414
2415 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2416 return len;
2417}
2418
Linus Torvalds1da177e2005-04-16 15:20:36 -07002419static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2420{
2421 struct l2cap_conf_opt *opt = *ptr;
2422
2423 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2424
2425 opt->type = type;
2426 opt->len = len;
2427
2428 switch (len) {
2429 case 1:
2430 *((u8 *) opt->val) = val;
2431 break;
2432
2433 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002434 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002435 break;
2436
2437 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002438 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002439 break;
2440
2441 default:
2442 memcpy(opt->val, (void *) val, len);
2443 break;
2444 }
2445
2446 *ptr += L2CAP_CONF_OPT_SIZE + len;
2447}
2448
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002449static void l2cap_ack_timeout(unsigned long arg)
2450{
2451 struct sock *sk = (void *) arg;
2452
2453 bh_lock_sock(sk);
2454 l2cap_send_ack(l2cap_pi(sk));
2455 bh_unlock_sock(sk);
2456}
2457
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002458static inline void l2cap_ertm_init(struct sock *sk)
2459{
2460 l2cap_pi(sk)->expected_ack_seq = 0;
2461 l2cap_pi(sk)->unacked_frames = 0;
2462 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002463 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002464 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002465
2466 setup_timer(&l2cap_pi(sk)->retrans_timer,
2467 l2cap_retrans_timeout, (unsigned long) sk);
2468 setup_timer(&l2cap_pi(sk)->monitor_timer,
2469 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002470 setup_timer(&l2cap_pi(sk)->ack_timer,
2471 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002472
2473 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002474 __skb_queue_head_init(BUSY_QUEUE(sk));
2475
2476 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03002477
2478 sk->sk_backlog_rcv = l2cap_ertm_data_rcv;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002479}
2480
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002481static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2482{
2483 switch (mode) {
2484 case L2CAP_MODE_STREAMING:
2485 case L2CAP_MODE_ERTM:
2486 if (l2cap_mode_supported(mode, remote_feat_mask))
2487 return mode;
2488 /* fall through */
2489 default:
2490 return L2CAP_MODE_BASIC;
2491 }
2492}
2493
Linus Torvalds1da177e2005-04-16 15:20:36 -07002494static int l2cap_build_conf_req(struct sock *sk, void *data)
2495{
2496 struct l2cap_pinfo *pi = l2cap_pi(sk);
2497 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002498 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499 void *ptr = req->data;
2500
2501 BT_DBG("sk %p", sk);
2502
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002503 if (pi->num_conf_req || pi->num_conf_rsp)
2504 goto done;
2505
2506 switch (pi->mode) {
2507 case L2CAP_MODE_STREAMING:
2508 case L2CAP_MODE_ERTM:
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002509 if (pi->conf_state & L2CAP_CONF_STATE2_DEVICE)
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002510 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002511
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002512 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002513 default:
2514 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2515 break;
2516 }
2517
2518done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002519 switch (pi->mode) {
2520 case L2CAP_MODE_BASIC:
2521 if (pi->imtu != L2CAP_DEFAULT_MTU)
2522 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002523
2524 rfc.mode = L2CAP_MODE_BASIC;
2525 rfc.txwin_size = 0;
2526 rfc.max_transmit = 0;
2527 rfc.retrans_timeout = 0;
2528 rfc.monitor_timeout = 0;
2529 rfc.max_pdu_size = 0;
2530
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002531 break;
2532
2533 case L2CAP_MODE_ERTM:
2534 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002535 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002536 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002537 rfc.retrans_timeout = 0;
2538 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002539 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002540 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002541 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002542
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002543 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2544 break;
2545
2546 if (pi->fcs == L2CAP_FCS_NONE ||
2547 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2548 pi->fcs = L2CAP_FCS_NONE;
2549 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2550 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002551 break;
2552
2553 case L2CAP_MODE_STREAMING:
2554 rfc.mode = L2CAP_MODE_STREAMING;
2555 rfc.txwin_size = 0;
2556 rfc.max_transmit = 0;
2557 rfc.retrans_timeout = 0;
2558 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002559 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002560 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002561 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002562
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002563 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2564 break;
2565
2566 if (pi->fcs == L2CAP_FCS_NONE ||
2567 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2568 pi->fcs = L2CAP_FCS_NONE;
2569 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2570 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002571 break;
2572 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002573
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002574 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2575 (unsigned long) &rfc);
2576
Linus Torvalds1da177e2005-04-16 15:20:36 -07002577 /* FIXME: Need actual value of the flush timeout */
2578 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2579 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2580
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002581 req->dcid = cpu_to_le16(pi->dcid);
2582 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002583
2584 return ptr - data;
2585}
2586
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002587static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002588{
2589 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002590 struct l2cap_conf_rsp *rsp = data;
2591 void *ptr = rsp->data;
2592 void *req = pi->conf_req;
2593 int len = pi->conf_len;
2594 int type, hint, olen;
2595 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002596 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002597 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002598 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002599
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002600 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002601
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002602 while (len >= L2CAP_CONF_OPT_SIZE) {
2603 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002605 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002606 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002607
2608 switch (type) {
2609 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002610 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002611 break;
2612
2613 case L2CAP_CONF_FLUSH_TO:
2614 pi->flush_to = val;
2615 break;
2616
2617 case L2CAP_CONF_QOS:
2618 break;
2619
Marcel Holtmann6464f352007-10-20 13:39:51 +02002620 case L2CAP_CONF_RFC:
2621 if (olen == sizeof(rfc))
2622 memcpy(&rfc, (void *) val, olen);
2623 break;
2624
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002625 case L2CAP_CONF_FCS:
2626 if (val == L2CAP_FCS_NONE)
2627 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2628
2629 break;
2630
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002631 default:
2632 if (hint)
2633 break;
2634
2635 result = L2CAP_CONF_UNKNOWN;
2636 *((u8 *) ptr++) = type;
2637 break;
2638 }
2639 }
2640
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002641 if (pi->num_conf_rsp || pi->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002642 goto done;
2643
2644 switch (pi->mode) {
2645 case L2CAP_MODE_STREAMING:
2646 case L2CAP_MODE_ERTM:
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002647 if (!(pi->conf_state & L2CAP_CONF_STATE2_DEVICE)) {
2648 pi->mode = l2cap_select_mode(rfc.mode,
2649 pi->conn->feat_mask);
2650 break;
2651 }
2652
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03002653 if (pi->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002654 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03002655
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002656 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002657 }
2658
2659done:
2660 if (pi->mode != rfc.mode) {
2661 result = L2CAP_CONF_UNACCEPT;
2662 rfc.mode = pi->mode;
2663
2664 if (pi->num_conf_rsp == 1)
2665 return -ECONNREFUSED;
2666
2667 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2668 sizeof(rfc), (unsigned long) &rfc);
2669 }
2670
2671
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002672 if (result == L2CAP_CONF_SUCCESS) {
2673 /* Configure output options and let the other side know
2674 * which ones we don't like. */
2675
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002676 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2677 result = L2CAP_CONF_UNACCEPT;
2678 else {
2679 pi->omtu = mtu;
2680 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2681 }
2682 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002683
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002684 switch (rfc.mode) {
2685 case L2CAP_MODE_BASIC:
2686 pi->fcs = L2CAP_FCS_NONE;
2687 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2688 break;
2689
2690 case L2CAP_MODE_ERTM:
2691 pi->remote_tx_win = rfc.txwin_size;
2692 pi->remote_max_tx = rfc.max_transmit;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002693 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2694 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2695
2696 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002697
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002698 rfc.retrans_timeout =
2699 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2700 rfc.monitor_timeout =
2701 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002702
2703 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002704
2705 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2706 sizeof(rfc), (unsigned long) &rfc);
2707
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002708 break;
2709
2710 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002711 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2712 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2713
2714 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002715
2716 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002717
2718 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2719 sizeof(rfc), (unsigned long) &rfc);
2720
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002721 break;
2722
2723 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002724 result = L2CAP_CONF_UNACCEPT;
2725
2726 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002727 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002728 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002729
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002730 if (result == L2CAP_CONF_SUCCESS)
2731 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2732 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002733 rsp->scid = cpu_to_le16(pi->dcid);
2734 rsp->result = cpu_to_le16(result);
2735 rsp->flags = cpu_to_le16(0x0000);
2736
2737 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002738}
2739
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002740static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2741{
2742 struct l2cap_pinfo *pi = l2cap_pi(sk);
2743 struct l2cap_conf_req *req = data;
2744 void *ptr = req->data;
2745 int type, olen;
2746 unsigned long val;
2747 struct l2cap_conf_rfc rfc;
2748
2749 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2750
2751 while (len >= L2CAP_CONF_OPT_SIZE) {
2752 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2753
2754 switch (type) {
2755 case L2CAP_CONF_MTU:
2756 if (val < L2CAP_DEFAULT_MIN_MTU) {
2757 *result = L2CAP_CONF_UNACCEPT;
2758 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2759 } else
2760 pi->omtu = val;
2761 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2762 break;
2763
2764 case L2CAP_CONF_FLUSH_TO:
2765 pi->flush_to = val;
2766 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2767 2, pi->flush_to);
2768 break;
2769
2770 case L2CAP_CONF_RFC:
2771 if (olen == sizeof(rfc))
2772 memcpy(&rfc, (void *)val, olen);
2773
2774 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2775 rfc.mode != pi->mode)
2776 return -ECONNREFUSED;
2777
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002778 pi->fcs = 0;
2779
2780 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2781 sizeof(rfc), (unsigned long) &rfc);
2782 break;
2783 }
2784 }
2785
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03002786 if (pi->mode == L2CAP_MODE_BASIC && pi->mode != rfc.mode)
2787 return -ECONNREFUSED;
2788
2789 pi->mode = rfc.mode;
2790
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002791 if (*result == L2CAP_CONF_SUCCESS) {
2792 switch (rfc.mode) {
2793 case L2CAP_MODE_ERTM:
2794 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002795 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2796 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002797 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002798 break;
2799 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002800 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002801 }
2802 }
2803
2804 req->dcid = cpu_to_le16(pi->dcid);
2805 req->flags = cpu_to_le16(0x0000);
2806
2807 return ptr - data;
2808}
2809
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002810static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002811{
2812 struct l2cap_conf_rsp *rsp = data;
2813 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002814
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002815 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002816
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002817 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002818 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002819 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002820
2821 return ptr - data;
2822}
2823
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002824static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2825{
2826 struct l2cap_pinfo *pi = l2cap_pi(sk);
2827 int type, olen;
2828 unsigned long val;
2829 struct l2cap_conf_rfc rfc;
2830
2831 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2832
2833 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2834 return;
2835
2836 while (len >= L2CAP_CONF_OPT_SIZE) {
2837 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2838
2839 switch (type) {
2840 case L2CAP_CONF_RFC:
2841 if (olen == sizeof(rfc))
2842 memcpy(&rfc, (void *)val, olen);
2843 goto done;
2844 }
2845 }
2846
2847done:
2848 switch (rfc.mode) {
2849 case L2CAP_MODE_ERTM:
2850 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002851 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2852 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002853 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2854 break;
2855 case L2CAP_MODE_STREAMING:
2856 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2857 }
2858}
2859
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002860static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2861{
2862 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2863
2864 if (rej->reason != 0x0000)
2865 return 0;
2866
2867 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2868 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002869 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002870
2871 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002872 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002873
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002874 l2cap_conn_start(conn);
2875 }
2876
2877 return 0;
2878}
2879
Linus Torvalds1da177e2005-04-16 15:20:36 -07002880static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2881{
2882 struct l2cap_chan_list *list = &conn->chan_list;
2883 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2884 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002885 struct sock *parent, *uninitialized_var(sk);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002886 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002887
2888 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002889 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002890
2891 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2892
2893 /* Check if we have socket listening on psm */
2894 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2895 if (!parent) {
2896 result = L2CAP_CR_BAD_PSM;
2897 goto sendresp;
2898 }
2899
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002900 /* Check if the ACL is secure enough (if not SDP) */
2901 if (psm != cpu_to_le16(0x0001) &&
2902 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002903 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002904 result = L2CAP_CR_SEC_BLOCK;
2905 goto response;
2906 }
2907
Linus Torvalds1da177e2005-04-16 15:20:36 -07002908 result = L2CAP_CR_NO_MEM;
2909
2910 /* Check for backlog size */
2911 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002912 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002913 goto response;
2914 }
2915
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002916 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002917 if (!sk)
2918 goto response;
2919
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002920 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002921
2922 /* Check if we already have channel with that dcid */
2923 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002924 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002925 sock_set_flag(sk, SOCK_ZAPPED);
2926 l2cap_sock_kill(sk);
2927 goto response;
2928 }
2929
2930 hci_conn_hold(conn->hcon);
2931
2932 l2cap_sock_init(sk, parent);
2933 bacpy(&bt_sk(sk)->src, conn->src);
2934 bacpy(&bt_sk(sk)->dst, conn->dst);
2935 l2cap_pi(sk)->psm = psm;
2936 l2cap_pi(sk)->dcid = scid;
2937
2938 __l2cap_chan_add(conn, sk, parent);
2939 dcid = l2cap_pi(sk)->scid;
2940
2941 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2942
Linus Torvalds1da177e2005-04-16 15:20:36 -07002943 l2cap_pi(sk)->ident = cmd->ident;
2944
Marcel Holtmann984947d2009-02-06 23:35:19 +01002945 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002946 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002947 if (bt_sk(sk)->defer_setup) {
2948 sk->sk_state = BT_CONNECT2;
2949 result = L2CAP_CR_PEND;
2950 status = L2CAP_CS_AUTHOR_PEND;
2951 parent->sk_data_ready(parent, 0);
2952 } else {
2953 sk->sk_state = BT_CONFIG;
2954 result = L2CAP_CR_SUCCESS;
2955 status = L2CAP_CS_NO_INFO;
2956 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002957 } else {
2958 sk->sk_state = BT_CONNECT2;
2959 result = L2CAP_CR_PEND;
2960 status = L2CAP_CS_AUTHEN_PEND;
2961 }
2962 } else {
2963 sk->sk_state = BT_CONNECT2;
2964 result = L2CAP_CR_PEND;
2965 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002966 }
2967
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002968 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002969
2970response:
2971 bh_unlock_sock(parent);
2972
2973sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002974 rsp.scid = cpu_to_le16(scid);
2975 rsp.dcid = cpu_to_le16(dcid);
2976 rsp.result = cpu_to_le16(result);
2977 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002978 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002979
2980 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2981 struct l2cap_info_req info;
2982 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2983
2984 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2985 conn->info_ident = l2cap_get_ident(conn);
2986
2987 mod_timer(&conn->info_timer, jiffies +
2988 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2989
2990 l2cap_send_cmd(conn, conn->info_ident,
2991 L2CAP_INFO_REQ, sizeof(info), &info);
2992 }
2993
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002994 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) &&
2995 result == L2CAP_CR_SUCCESS) {
2996 u8 buf[128];
2997 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2998 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2999 l2cap_build_conf_req(sk, buf), buf);
3000 l2cap_pi(sk)->num_conf_req++;
3001 }
3002
Linus Torvalds1da177e2005-04-16 15:20:36 -07003003 return 0;
3004}
3005
3006static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3007{
3008 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3009 u16 scid, dcid, result, status;
3010 struct sock *sk;
3011 u8 req[128];
3012
3013 scid = __le16_to_cpu(rsp->scid);
3014 dcid = __le16_to_cpu(rsp->dcid);
3015 result = __le16_to_cpu(rsp->result);
3016 status = __le16_to_cpu(rsp->status);
3017
3018 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
3019
3020 if (scid) {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003021 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3022 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03003023 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003024 } else {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003025 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
3026 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03003027 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003028 }
3029
3030 switch (result) {
3031 case L2CAP_CR_SUCCESS:
3032 sk->sk_state = BT_CONFIG;
3033 l2cap_pi(sk)->ident = 0;
3034 l2cap_pi(sk)->dcid = dcid;
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003035 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
3036
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003037 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)
3038 break;
3039
3040 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
3041
Linus Torvalds1da177e2005-04-16 15:20:36 -07003042 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3043 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003044 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003045 break;
3046
3047 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003048 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003049 break;
3050
3051 default:
3052 l2cap_chan_del(sk, ECONNREFUSED);
3053 break;
3054 }
3055
3056 bh_unlock_sock(sk);
3057 return 0;
3058}
3059
Al Viro88219a02007-07-29 00:17:25 -07003060static 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 -07003061{
3062 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3063 u16 dcid, flags;
3064 u8 rsp[64];
3065 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003066 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003067
3068 dcid = __le16_to_cpu(req->dcid);
3069 flags = __le16_to_cpu(req->flags);
3070
3071 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3072
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003073 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3074 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003075 return -ENOENT;
3076
Gustavo F. Padovan8cb8e6f2010-06-14 02:26:15 -03003077 if (sk->sk_state != BT_CONFIG) {
3078 struct l2cap_cmd_rej rej;
3079
3080 rej.reason = cpu_to_le16(0x0002);
3081 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
3082 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003083 goto unlock;
Gustavo F. Padovan8cb8e6f2010-06-14 02:26:15 -03003084 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003085
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003086 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003087 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003088 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
3089 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
3090 l2cap_build_conf_rsp(sk, rsp,
3091 L2CAP_CONF_REJECT, flags), rsp);
3092 goto unlock;
3093 }
3094
3095 /* Store config. */
3096 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
3097 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003098
3099 if (flags & 0x0001) {
3100 /* Incomplete config. Send empty response. */
3101 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003102 l2cap_build_conf_rsp(sk, rsp,
3103 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003104 goto unlock;
3105 }
3106
3107 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003108 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003109 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003110 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003111 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003112 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003113
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003114 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003115 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003116
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003117 /* Reset config buffer. */
3118 l2cap_pi(sk)->conf_len = 0;
3119
Marcel Holtmann876d9482007-10-20 13:35:42 +02003120 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
3121 goto unlock;
3122
Linus Torvalds1da177e2005-04-16 15:20:36 -07003123 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003124 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3125 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003126 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3127
Linus Torvalds1da177e2005-04-16 15:20:36 -07003128 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003129
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003130 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003131 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003132 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003133 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3134 l2cap_ertm_init(sk);
3135
Linus Torvalds1da177e2005-04-16 15:20:36 -07003136 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02003137 goto unlock;
3138 }
3139
3140 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003141 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003142 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003143 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003144 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003145 }
3146
3147unlock:
3148 bh_unlock_sock(sk);
3149 return 0;
3150}
3151
3152static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3153{
3154 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3155 u16 scid, flags, result;
3156 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003157 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003158
3159 scid = __le16_to_cpu(rsp->scid);
3160 flags = __le16_to_cpu(rsp->flags);
3161 result = __le16_to_cpu(rsp->result);
3162
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003163 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
3164 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003165
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003166 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3167 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003168 return 0;
3169
3170 switch (result) {
3171 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003172 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003173 break;
3174
3175 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003176 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003177 char req[64];
3178
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003179 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003180 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003181 goto done;
3182 }
3183
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003184 /* throw out any old stored conf requests */
3185 result = L2CAP_CONF_SUCCESS;
3186 len = l2cap_parse_conf_rsp(sk, rsp->data,
3187 len, req, &result);
3188 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003189 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003190 goto done;
3191 }
3192
3193 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3194 L2CAP_CONF_REQ, len, req);
3195 l2cap_pi(sk)->num_conf_req++;
3196 if (result != L2CAP_CONF_SUCCESS)
3197 goto done;
3198 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003199 }
3200
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003201 default:
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003202 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003203 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003204 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003205 goto done;
3206 }
3207
3208 if (flags & 0x01)
3209 goto done;
3210
Linus Torvalds1da177e2005-04-16 15:20:36 -07003211 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3212
3213 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003214 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3215 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003216 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3217
Linus Torvalds1da177e2005-04-16 15:20:36 -07003218 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003219 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003220 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003221 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003222 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3223 l2cap_ertm_init(sk);
3224
Linus Torvalds1da177e2005-04-16 15:20:36 -07003225 l2cap_chan_ready(sk);
3226 }
3227
3228done:
3229 bh_unlock_sock(sk);
3230 return 0;
3231}
3232
3233static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3234{
3235 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3236 struct l2cap_disconn_rsp rsp;
3237 u16 dcid, scid;
3238 struct sock *sk;
3239
3240 scid = __le16_to_cpu(req->scid);
3241 dcid = __le16_to_cpu(req->dcid);
3242
3243 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3244
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003245 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3246 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003247 return 0;
3248
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003249 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3250 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003251 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3252
3253 sk->sk_shutdown = SHUTDOWN_MASK;
3254
3255 l2cap_chan_del(sk, ECONNRESET);
3256 bh_unlock_sock(sk);
3257
3258 l2cap_sock_kill(sk);
3259 return 0;
3260}
3261
3262static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3263{
3264 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3265 u16 dcid, scid;
3266 struct sock *sk;
3267
3268 scid = __le16_to_cpu(rsp->scid);
3269 dcid = __le16_to_cpu(rsp->dcid);
3270
3271 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3272
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003273 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3274 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003275 return 0;
3276
3277 l2cap_chan_del(sk, 0);
3278 bh_unlock_sock(sk);
3279
3280 l2cap_sock_kill(sk);
3281 return 0;
3282}
3283
3284static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3285{
3286 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003287 u16 type;
3288
3289 type = __le16_to_cpu(req->type);
3290
3291 BT_DBG("type 0x%4.4x", type);
3292
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003293 if (type == L2CAP_IT_FEAT_MASK) {
3294 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003295 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003296 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3297 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3298 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003299 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003300 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3301 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003302 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003303 l2cap_send_cmd(conn, cmd->ident,
3304 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003305 } else if (type == L2CAP_IT_FIXED_CHAN) {
3306 u8 buf[12];
3307 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3308 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3309 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3310 memcpy(buf + 4, l2cap_fixed_chan, 8);
3311 l2cap_send_cmd(conn, cmd->ident,
3312 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003313 } else {
3314 struct l2cap_info_rsp rsp;
3315 rsp.type = cpu_to_le16(type);
3316 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3317 l2cap_send_cmd(conn, cmd->ident,
3318 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3319 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003320
3321 return 0;
3322}
3323
3324static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3325{
3326 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3327 u16 type, result;
3328
3329 type = __le16_to_cpu(rsp->type);
3330 result = __le16_to_cpu(rsp->result);
3331
3332 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3333
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003334 del_timer(&conn->info_timer);
3335
Marcel Holtmann984947d2009-02-06 23:35:19 +01003336 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003337 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003338
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003339 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003340 struct l2cap_info_req req;
3341 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3342
3343 conn->info_ident = l2cap_get_ident(conn);
3344
3345 l2cap_send_cmd(conn, conn->info_ident,
3346 L2CAP_INFO_REQ, sizeof(req), &req);
3347 } else {
3348 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3349 conn->info_ident = 0;
3350
3351 l2cap_conn_start(conn);
3352 }
3353 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003354 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003355 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003356
3357 l2cap_conn_start(conn);
3358 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003359
Linus Torvalds1da177e2005-04-16 15:20:36 -07003360 return 0;
3361}
3362
3363static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3364{
3365 u8 *data = skb->data;
3366 int len = skb->len;
3367 struct l2cap_cmd_hdr cmd;
3368 int err = 0;
3369
3370 l2cap_raw_recv(conn, skb);
3371
3372 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003373 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003374 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3375 data += L2CAP_CMD_HDR_SIZE;
3376 len -= L2CAP_CMD_HDR_SIZE;
3377
Al Viro88219a02007-07-29 00:17:25 -07003378 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003379
Al Viro88219a02007-07-29 00:17:25 -07003380 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 -07003381
Al Viro88219a02007-07-29 00:17:25 -07003382 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003383 BT_DBG("corrupted command");
3384 break;
3385 }
3386
3387 switch (cmd.code) {
3388 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003389 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003390 break;
3391
3392 case L2CAP_CONN_REQ:
3393 err = l2cap_connect_req(conn, &cmd, data);
3394 break;
3395
3396 case L2CAP_CONN_RSP:
3397 err = l2cap_connect_rsp(conn, &cmd, data);
3398 break;
3399
3400 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003401 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003402 break;
3403
3404 case L2CAP_CONF_RSP:
3405 err = l2cap_config_rsp(conn, &cmd, data);
3406 break;
3407
3408 case L2CAP_DISCONN_REQ:
3409 err = l2cap_disconnect_req(conn, &cmd, data);
3410 break;
3411
3412 case L2CAP_DISCONN_RSP:
3413 err = l2cap_disconnect_rsp(conn, &cmd, data);
3414 break;
3415
3416 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003417 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003418 break;
3419
3420 case L2CAP_ECHO_RSP:
3421 break;
3422
3423 case L2CAP_INFO_REQ:
3424 err = l2cap_information_req(conn, &cmd, data);
3425 break;
3426
3427 case L2CAP_INFO_RSP:
3428 err = l2cap_information_rsp(conn, &cmd, data);
3429 break;
3430
3431 default:
3432 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3433 err = -EINVAL;
3434 break;
3435 }
3436
3437 if (err) {
3438 struct l2cap_cmd_rej rej;
3439 BT_DBG("error %d", err);
3440
3441 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003442 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003443 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3444 }
3445
Al Viro88219a02007-07-29 00:17:25 -07003446 data += cmd_len;
3447 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003448 }
3449
3450 kfree_skb(skb);
3451}
3452
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003453static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3454{
3455 u16 our_fcs, rcv_fcs;
3456 int hdr_size = L2CAP_HDR_SIZE + 2;
3457
3458 if (pi->fcs == L2CAP_FCS_CRC16) {
3459 skb_trim(skb, skb->len - 2);
3460 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3461 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3462
3463 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03003464 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003465 }
3466 return 0;
3467}
3468
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003469static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3470{
3471 struct l2cap_pinfo *pi = l2cap_pi(sk);
3472 u16 control = 0;
3473
3474 pi->frames_sent = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003475
3476 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3477
3478 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan64988862010-05-10 14:54:14 -03003479 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003480 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003481 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003482 }
3483
Gustavo F. Padovan4ea727e2010-06-03 16:34:20 -03003484 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY)
3485 l2cap_retransmit_frames(sk);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003486
3487 l2cap_ertm_send(sk);
3488
3489 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3490 pi->frames_sent == 0) {
3491 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003492 l2cap_send_sframe(pi, control);
3493 }
3494}
3495
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003496static 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 -03003497{
3498 struct sk_buff *next_skb;
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003499 struct l2cap_pinfo *pi = l2cap_pi(sk);
3500 int tx_seq_offset, next_tx_seq_offset;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003501
3502 bt_cb(skb)->tx_seq = tx_seq;
3503 bt_cb(skb)->sar = sar;
3504
3505 next_skb = skb_peek(SREJ_QUEUE(sk));
3506 if (!next_skb) {
3507 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003508 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003509 }
3510
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003511 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3512 if (tx_seq_offset < 0)
3513 tx_seq_offset += 64;
3514
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003515 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003516 if (bt_cb(next_skb)->tx_seq == tx_seq)
3517 return -EINVAL;
3518
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003519 next_tx_seq_offset = (bt_cb(next_skb)->tx_seq -
3520 pi->buffer_seq) % 64;
3521 if (next_tx_seq_offset < 0)
3522 next_tx_seq_offset += 64;
3523
3524 if (next_tx_seq_offset > tx_seq_offset) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003525 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003526 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003527 }
3528
3529 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3530 break;
3531
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003532 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003533
3534 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003535
3536 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003537}
3538
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003539static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3540{
3541 struct l2cap_pinfo *pi = l2cap_pi(sk);
3542 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003543 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003544
3545 switch (control & L2CAP_CTRL_SAR) {
3546 case L2CAP_SDU_UNSEGMENTED:
3547 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3548 goto drop;
3549
3550 err = sock_queue_rcv_skb(sk, skb);
3551 if (!err)
3552 return err;
3553
3554 break;
3555
3556 case L2CAP_SDU_START:
3557 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3558 goto drop;
3559
3560 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003561
3562 if (pi->sdu_len > pi->imtu)
3563 goto disconnect;
3564
3565 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003566 if (!pi->sdu)
3567 return -ENOMEM;
3568
3569 /* pull sdu_len bytes only after alloc, because of Local Busy
3570 * condition we have to be sure that this will be executed
3571 * only once, i.e., when alloc does not fail */
3572 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003573
3574 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3575
3576 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3577 pi->partial_sdu_len = skb->len;
3578 break;
3579
3580 case L2CAP_SDU_CONTINUE:
3581 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3582 goto disconnect;
3583
3584 if (!pi->sdu)
3585 goto disconnect;
3586
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003587 pi->partial_sdu_len += skb->len;
3588 if (pi->partial_sdu_len > pi->sdu_len)
3589 goto drop;
3590
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003591 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3592
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003593 break;
3594
3595 case L2CAP_SDU_END:
3596 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3597 goto disconnect;
3598
3599 if (!pi->sdu)
3600 goto disconnect;
3601
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003602 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003603 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003604
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003605 if (pi->partial_sdu_len > pi->imtu)
3606 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003607
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003608 if (pi->partial_sdu_len != pi->sdu_len)
3609 goto drop;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003610
3611 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003612 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003613
3614 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003615 if (!_skb) {
3616 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3617 return -ENOMEM;
3618 }
3619
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003620 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003621 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003622 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003623 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3624 return err;
3625 }
3626
3627 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
3628 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003629
3630 kfree_skb(pi->sdu);
3631 break;
3632 }
3633
3634 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003635 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003636
3637drop:
3638 kfree_skb(pi->sdu);
3639 pi->sdu = NULL;
3640
3641disconnect:
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003642 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003643 kfree_skb(skb);
3644 return 0;
3645}
3646
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003647static int l2cap_try_push_rx_skb(struct sock *sk)
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003648{
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003649 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003650 struct sk_buff *skb;
3651 u16 control;
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003652 int err;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003653
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003654 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
3655 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3656 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3657 if (err < 0) {
3658 skb_queue_head(BUSY_QUEUE(sk), skb);
3659 return -EBUSY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003660 }
3661
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003662 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003663 }
3664
3665 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
3666 goto done;
3667
3668 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3669 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
3670 l2cap_send_sframe(pi, control);
3671 l2cap_pi(sk)->retry_count = 1;
3672
3673 del_timer(&pi->retrans_timer);
3674 __mod_monitor_timer();
3675
3676 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
3677
3678done:
3679 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
3680 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
3681
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003682 BT_DBG("sk %p, Exit local busy", sk);
3683
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003684 return 0;
3685}
3686
3687static void l2cap_busy_work(struct work_struct *work)
3688{
3689 DECLARE_WAITQUEUE(wait, current);
3690 struct l2cap_pinfo *pi =
3691 container_of(work, struct l2cap_pinfo, busy_work);
3692 struct sock *sk = (struct sock *)pi;
3693 int n_tries = 0, timeo = HZ/5, err;
3694 struct sk_buff *skb;
3695
3696 lock_sock(sk);
3697
3698 add_wait_queue(sk_sleep(sk), &wait);
3699 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
3700 set_current_state(TASK_INTERRUPTIBLE);
3701
3702 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
3703 err = -EBUSY;
3704 l2cap_send_disconn_req(pi->conn, sk, EBUSY);
3705 break;
3706 }
3707
3708 if (!timeo)
3709 timeo = HZ/5;
3710
3711 if (signal_pending(current)) {
3712 err = sock_intr_errno(timeo);
3713 break;
3714 }
3715
3716 release_sock(sk);
3717 timeo = schedule_timeout(timeo);
3718 lock_sock(sk);
3719
3720 err = sock_error(sk);
3721 if (err)
3722 break;
3723
3724 if (l2cap_try_push_rx_skb(sk) == 0)
3725 break;
3726 }
3727
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003728 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003729 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003730
3731 release_sock(sk);
3732}
3733
3734static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
3735{
3736 struct l2cap_pinfo *pi = l2cap_pi(sk);
3737 int sctrl, err;
3738
3739 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3740 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3741 __skb_queue_tail(BUSY_QUEUE(sk), skb);
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003742 return l2cap_try_push_rx_skb(sk);
3743
3744
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003745 }
3746
3747 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3748 if (err >= 0) {
3749 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3750 return err;
3751 }
3752
3753 /* Busy Condition */
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003754 BT_DBG("sk %p, Enter local busy", sk);
3755
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003756 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
3757 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3758 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3759
3760 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3761 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
3762 l2cap_send_sframe(pi, sctrl);
3763
3764 pi->conn_state |= L2CAP_CONN_RNR_SENT;
3765
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03003766 del_timer(&pi->ack_timer);
3767
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003768 queue_work(_busy_wq, &pi->busy_work);
3769
3770 return err;
3771}
3772
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003773static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003774{
3775 struct l2cap_pinfo *pi = l2cap_pi(sk);
3776 struct sk_buff *_skb;
3777 int err = -EINVAL;
3778
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003779 /*
3780 * TODO: We have to notify the userland if some data is lost with the
3781 * Streaming Mode.
3782 */
3783
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003784 switch (control & L2CAP_CTRL_SAR) {
3785 case L2CAP_SDU_UNSEGMENTED:
3786 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3787 kfree_skb(pi->sdu);
3788 break;
3789 }
3790
3791 err = sock_queue_rcv_skb(sk, skb);
3792 if (!err)
3793 return 0;
3794
3795 break;
3796
3797 case L2CAP_SDU_START:
3798 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3799 kfree_skb(pi->sdu);
3800 break;
3801 }
3802
3803 pi->sdu_len = get_unaligned_le16(skb->data);
3804 skb_pull(skb, 2);
3805
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003806 if (pi->sdu_len > pi->imtu) {
3807 err = -EMSGSIZE;
3808 break;
3809 }
3810
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003811 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3812 if (!pi->sdu) {
3813 err = -ENOMEM;
3814 break;
3815 }
3816
3817 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3818
3819 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3820 pi->partial_sdu_len = skb->len;
3821 err = 0;
3822 break;
3823
3824 case L2CAP_SDU_CONTINUE:
3825 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3826 break;
3827
3828 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3829
3830 pi->partial_sdu_len += skb->len;
3831 if (pi->partial_sdu_len > pi->sdu_len)
3832 kfree_skb(pi->sdu);
3833 else
3834 err = 0;
3835
3836 break;
3837
3838 case L2CAP_SDU_END:
3839 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3840 break;
3841
3842 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3843
3844 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3845 pi->partial_sdu_len += skb->len;
3846
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003847 if (pi->partial_sdu_len > pi->imtu)
3848 goto drop;
3849
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003850 if (pi->partial_sdu_len == pi->sdu_len) {
3851 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3852 err = sock_queue_rcv_skb(sk, _skb);
3853 if (err < 0)
3854 kfree_skb(_skb);
3855 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003856 err = 0;
3857
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003858drop:
3859 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003860 break;
3861 }
3862
3863 kfree_skb(skb);
3864 return err;
3865}
3866
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003867static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3868{
3869 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003870 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003871
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003872 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003873 if (bt_cb(skb)->tx_seq != tx_seq)
3874 break;
3875
3876 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003877 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003878 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003879 l2cap_pi(sk)->buffer_seq_srej =
3880 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003881 tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003882 }
3883}
3884
3885static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3886{
3887 struct l2cap_pinfo *pi = l2cap_pi(sk);
3888 struct srej_list *l, *tmp;
3889 u16 control;
3890
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003891 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003892 if (l->tx_seq == tx_seq) {
3893 list_del(&l->list);
3894 kfree(l);
3895 return;
3896 }
3897 control = L2CAP_SUPER_SELECT_REJECT;
3898 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3899 l2cap_send_sframe(pi, control);
3900 list_del(&l->list);
3901 list_add_tail(&l->list, SREJ_LIST(sk));
3902 }
3903}
3904
3905static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3906{
3907 struct l2cap_pinfo *pi = l2cap_pi(sk);
3908 struct srej_list *new;
3909 u16 control;
3910
3911 while (tx_seq != pi->expected_tx_seq) {
3912 control = L2CAP_SUPER_SELECT_REJECT;
3913 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3914 l2cap_send_sframe(pi, control);
3915
3916 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003917 new->tx_seq = pi->expected_tx_seq;
3918 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003919 list_add_tail(&new->list, SREJ_LIST(sk));
3920 }
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003921 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003922}
3923
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003924static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3925{
3926 struct l2cap_pinfo *pi = l2cap_pi(sk);
3927 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003928 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003929 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03003930 int tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003931 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003932 int err = 0;
3933
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003934 BT_DBG("sk %p len %d tx_seq %d rx_control 0x%4.4x", sk, skb->len, tx_seq,
3935 rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003936
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003937 if (L2CAP_CTRL_FINAL & rx_control &&
3938 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003939 del_timer(&pi->monitor_timer);
3940 if (pi->unacked_frames > 0)
3941 __mod_retrans_timer();
3942 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3943 }
3944
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003945 pi->expected_ack_seq = req_seq;
3946 l2cap_drop_acked_frames(sk);
3947
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003948 if (tx_seq == pi->expected_tx_seq)
3949 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003950
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003951 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3952 if (tx_seq_offset < 0)
3953 tx_seq_offset += 64;
3954
3955 /* invalid tx_seq */
3956 if (tx_seq_offset >= pi->tx_win) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003957 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003958 goto drop;
3959 }
3960
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003961 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
3962 goto drop;
3963
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003964 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3965 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003966
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003967 first = list_first_entry(SREJ_LIST(sk),
3968 struct srej_list, list);
3969 if (tx_seq == first->tx_seq) {
3970 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3971 l2cap_check_srej_gap(sk, tx_seq);
3972
3973 list_del(&first->list);
3974 kfree(first);
3975
3976 if (list_empty(SREJ_LIST(sk))) {
3977 pi->buffer_seq = pi->buffer_seq_srej;
3978 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666c2010-05-01 16:15:40 -03003979 l2cap_send_ack(pi);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003980 BT_DBG("sk %p, Exit SREJ_SENT", sk);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003981 }
3982 } else {
3983 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003984
3985 /* duplicated tx_seq */
3986 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
3987 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003988
3989 list_for_each_entry(l, SREJ_LIST(sk), list) {
3990 if (l->tx_seq == tx_seq) {
3991 l2cap_resend_srejframe(sk, tx_seq);
3992 return 0;
3993 }
3994 }
3995 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003996 }
3997 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003998 expected_tx_seq_offset =
3999 (pi->expected_tx_seq - pi->buffer_seq) % 64;
4000 if (expected_tx_seq_offset < 0)
4001 expected_tx_seq_offset += 64;
4002
4003 /* duplicated tx_seq */
4004 if (tx_seq_offset < expected_tx_seq_offset)
4005 goto drop;
4006
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004007 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004008
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004009 BT_DBG("sk %p, Enter SREJ", sk);
4010
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004011 INIT_LIST_HEAD(SREJ_LIST(sk));
4012 pi->buffer_seq_srej = pi->buffer_seq;
4013
4014 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004015 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004016 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
4017
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03004018 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
4019
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004020 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03004021
4022 del_timer(&pi->ack_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004023 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004024 return 0;
4025
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004026expected:
4027 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4028
4029 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03004030 bt_cb(skb)->tx_seq = tx_seq;
4031 bt_cb(skb)->sar = sar;
4032 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004033 return 0;
4034 }
4035
Gustavo F. Padovan2ece3682010-06-16 17:21:44 -03004036 err = l2cap_push_rx_skb(sk, skb, rx_control);
4037 if (err < 0)
4038 return 0;
4039
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03004040 if (rx_control & L2CAP_CTRL_FINAL) {
4041 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4042 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004043 else
4044 l2cap_retransmit_frames(sk);
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03004045 }
4046
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03004047 __mod_ack_timer();
4048
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03004049 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
4050 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03004051 l2cap_send_ack(pi);
4052
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004053 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03004054
4055drop:
4056 kfree_skb(skb);
4057 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004058}
4059
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004060static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004061{
4062 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03004063
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004064 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control),
4065 rx_control);
4066
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03004067 pi->expected_ack_seq = __get_reqseq(rx_control);
4068 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004069
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004070 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004071 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03004072 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
4073 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
4074 (pi->unacked_frames > 0))
4075 __mod_retrans_timer();
4076
4077 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4078 l2cap_send_srejtail(sk);
4079 } else {
4080 l2cap_send_i_or_rr_or_rnr(sk);
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03004081 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004082
4083 } else if (rx_control & L2CAP_CTRL_FINAL) {
4084 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004085
4086 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4087 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004088 else
4089 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004090
4091 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004092 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
4093 (pi->unacked_frames > 0))
4094 __mod_retrans_timer();
4095
4096 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004097 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004098 l2cap_send_ack(pi);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004099 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004100 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004101 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004102 }
4103}
4104
4105static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
4106{
4107 struct l2cap_pinfo *pi = l2cap_pi(sk);
4108 u8 tx_seq = __get_reqseq(rx_control);
4109
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004110 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4111
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004112 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4113
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03004114 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004115 l2cap_drop_acked_frames(sk);
4116
4117 if (rx_control & L2CAP_CTRL_FINAL) {
4118 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4119 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004120 else
4121 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004122 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004123 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004124
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03004125 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004126 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004127 }
4128}
4129static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
4130{
4131 struct l2cap_pinfo *pi = l2cap_pi(sk);
4132 u8 tx_seq = __get_reqseq(rx_control);
4133
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004134 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4135
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004136 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4137
4138 if (rx_control & L2CAP_CTRL_POLL) {
4139 pi->expected_ack_seq = tx_seq;
4140 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004141
4142 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004143 l2cap_retransmit_one_frame(sk, tx_seq);
4144
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004145 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004146
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004147 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4148 pi->srej_save_reqseq = tx_seq;
4149 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4150 }
4151 } else if (rx_control & L2CAP_CTRL_FINAL) {
4152 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
4153 pi->srej_save_reqseq == tx_seq)
4154 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
4155 else
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004156 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004157 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004158 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004159 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4160 pi->srej_save_reqseq = tx_seq;
4161 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4162 }
4163 }
4164}
4165
4166static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
4167{
4168 struct l2cap_pinfo *pi = l2cap_pi(sk);
4169 u8 tx_seq = __get_reqseq(rx_control);
4170
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004171 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4172
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004173 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
4174 pi->expected_ack_seq = tx_seq;
4175 l2cap_drop_acked_frames(sk);
4176
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004177 if (rx_control & L2CAP_CTRL_POLL)
4178 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
4179
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004180 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
4181 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03004182 if (rx_control & L2CAP_CTRL_POLL)
4183 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004184 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004185 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004186
4187 if (rx_control & L2CAP_CTRL_POLL)
4188 l2cap_send_srejtail(sk);
4189 else
4190 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004191}
4192
4193static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
4194{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004195 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
4196
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03004197 if (L2CAP_CTRL_FINAL & rx_control &&
4198 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004199 del_timer(&l2cap_pi(sk)->monitor_timer);
4200 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004201 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004202 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004203 }
4204
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004205 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
4206 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004207 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004208 break;
4209
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004210 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004211 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004212 break;
4213
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004214 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004215 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004216 break;
4217
4218 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004219 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004220 break;
4221 }
4222
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03004223 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004224 return 0;
4225}
4226
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004227static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
4228{
4229 struct l2cap_pinfo *pi = l2cap_pi(sk);
4230 u16 control;
4231 u8 req_seq;
4232 int len, next_tx_seq_offset, req_seq_offset;
4233
4234 control = get_unaligned_le16(skb->data);
4235 skb_pull(skb, 2);
4236 len = skb->len;
4237
4238 /*
4239 * We can just drop the corrupted I-frame here.
4240 * Receiver will miss it and start proper recovery
4241 * procedures and ask retransmission.
4242 */
4243 if (l2cap_check_fcs(pi, skb))
4244 goto drop;
4245
4246 if (__is_sar_start(control) && __is_iframe(control))
4247 len -= 2;
4248
4249 if (pi->fcs == L2CAP_FCS_CRC16)
4250 len -= 2;
4251
4252 if (len > pi->mps) {
4253 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4254 goto drop;
4255 }
4256
4257 req_seq = __get_reqseq(control);
4258 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
4259 if (req_seq_offset < 0)
4260 req_seq_offset += 64;
4261
4262 next_tx_seq_offset =
4263 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
4264 if (next_tx_seq_offset < 0)
4265 next_tx_seq_offset += 64;
4266
4267 /* check for invalid req-seq */
4268 if (req_seq_offset > next_tx_seq_offset) {
4269 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4270 goto drop;
4271 }
4272
4273 if (__is_iframe(control)) {
4274 if (len < 0) {
4275 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4276 goto drop;
4277 }
4278
4279 l2cap_data_channel_iframe(sk, control, skb);
4280 } else {
4281 if (len != 0) {
4282 BT_ERR("%d", len);
4283 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4284 goto drop;
4285 }
4286
4287 l2cap_data_channel_sframe(sk, control, skb);
4288 }
4289
4290 return 0;
4291
4292drop:
4293 kfree_skb(skb);
4294 return 0;
4295}
4296
Linus Torvalds1da177e2005-04-16 15:20:36 -07004297static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
4298{
4299 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004300 struct l2cap_pinfo *pi;
Nathan Holstein51893f82010-06-09 15:46:25 -04004301 u16 control;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004302 u8 tx_seq;
4303 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004304
4305 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
4306 if (!sk) {
4307 BT_DBG("unknown cid 0x%4.4x", cid);
4308 goto drop;
4309 }
4310
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004311 pi = l2cap_pi(sk);
4312
Linus Torvalds1da177e2005-04-16 15:20:36 -07004313 BT_DBG("sk %p, len %d", sk, skb->len);
4314
4315 if (sk->sk_state != BT_CONNECTED)
4316 goto drop;
4317
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004318 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004319 case L2CAP_MODE_BASIC:
4320 /* If socket recv buffers overflows we drop data here
4321 * which is *bad* because L2CAP has to be reliable.
4322 * But we don't have any other choice. L2CAP doesn't
4323 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004324
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004325 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004326 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004327
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004328 if (!sock_queue_rcv_skb(sk, skb))
4329 goto done;
4330 break;
4331
4332 case L2CAP_MODE_ERTM:
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004333 if (!sock_owned_by_user(sk)) {
4334 l2cap_ertm_data_rcv(sk, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004335 } else {
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004336 if (sk_add_backlog(sk, skb))
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004337 goto drop;
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004338 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004339
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004340 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004341
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004342 case L2CAP_MODE_STREAMING:
4343 control = get_unaligned_le16(skb->data);
4344 skb_pull(skb, 2);
4345 len = skb->len;
4346
Gustavo F. Padovan26000082010-05-11 22:02:00 -03004347 if (l2cap_check_fcs(pi, skb))
4348 goto drop;
4349
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004350 if (__is_sar_start(control))
4351 len -= 2;
4352
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004353 if (pi->fcs == L2CAP_FCS_CRC16)
4354 len -= 2;
4355
Nathan Holstein51893f82010-06-09 15:46:25 -04004356 if (len > pi->mps || len < 0 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004357 goto drop;
4358
4359 tx_seq = __get_txseq(control);
4360
4361 if (pi->expected_tx_seq == tx_seq)
4362 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4363 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03004364 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004365
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004366 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004367
4368 goto done;
4369
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004370 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03004371 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004372 break;
4373 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004374
4375drop:
4376 kfree_skb(skb);
4377
4378done:
Marcel Holtmann01394182006-07-03 10:02:46 +02004379 if (sk)
4380 bh_unlock_sock(sk);
4381
Linus Torvalds1da177e2005-04-16 15:20:36 -07004382 return 0;
4383}
4384
Al Viro8e036fc2007-07-29 00:16:36 -07004385static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004386{
4387 struct sock *sk;
4388
4389 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
4390 if (!sk)
4391 goto drop;
4392
4393 BT_DBG("sk %p, len %d", sk, skb->len);
4394
4395 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
4396 goto drop;
4397
4398 if (l2cap_pi(sk)->imtu < skb->len)
4399 goto drop;
4400
4401 if (!sock_queue_rcv_skb(sk, skb))
4402 goto done;
4403
4404drop:
4405 kfree_skb(skb);
4406
4407done:
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03004408 if (sk)
4409 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004410 return 0;
4411}
4412
4413static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
4414{
4415 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07004416 u16 cid, len;
4417 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004418
4419 skb_pull(skb, L2CAP_HDR_SIZE);
4420 cid = __le16_to_cpu(lh->cid);
4421 len = __le16_to_cpu(lh->len);
4422
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004423 if (len != skb->len) {
4424 kfree_skb(skb);
4425 return;
4426 }
4427
Linus Torvalds1da177e2005-04-16 15:20:36 -07004428 BT_DBG("len %d, cid 0x%4.4x", len, cid);
4429
4430 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004431 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004432 l2cap_sig_channel(conn, skb);
4433 break;
4434
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004435 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004436 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004437 skb_pull(skb, 2);
4438 l2cap_conless_channel(conn, psm, skb);
4439 break;
4440
4441 default:
4442 l2cap_data_channel(conn, cid, skb);
4443 break;
4444 }
4445}
4446
4447/* ---- L2CAP interface with lower layer (HCI) ---- */
4448
4449static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
4450{
4451 int exact = 0, lm1 = 0, lm2 = 0;
4452 register struct sock *sk;
4453 struct hlist_node *node;
4454
4455 if (type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03004456 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004457
4458 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
4459
4460 /* Find listening sockets and check their link_mode */
4461 read_lock(&l2cap_sk_list.lock);
4462 sk_for_each(sk, node, &l2cap_sk_list.head) {
4463 if (sk->sk_state != BT_LISTEN)
4464 continue;
4465
4466 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004467 lm1 |= HCI_LM_ACCEPT;
4468 if (l2cap_pi(sk)->role_switch)
4469 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004470 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004471 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
4472 lm2 |= HCI_LM_ACCEPT;
4473 if (l2cap_pi(sk)->role_switch)
4474 lm2 |= HCI_LM_MASTER;
4475 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004476 }
4477 read_unlock(&l2cap_sk_list.lock);
4478
4479 return exact ? lm1 : lm2;
4480}
4481
4482static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
4483{
Marcel Holtmann01394182006-07-03 10:02:46 +02004484 struct l2cap_conn *conn;
4485
Linus Torvalds1da177e2005-04-16 15:20:36 -07004486 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
4487
4488 if (hcon->type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03004489 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004490
4491 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004492 conn = l2cap_conn_add(hcon, status);
4493 if (conn)
4494 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02004495 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004496 l2cap_conn_del(hcon, bt_err(status));
4497
4498 return 0;
4499}
4500
Marcel Holtmann2950f212009-02-12 14:02:50 +01004501static int l2cap_disconn_ind(struct hci_conn *hcon)
4502{
4503 struct l2cap_conn *conn = hcon->l2cap_data;
4504
4505 BT_DBG("hcon %p", hcon);
4506
4507 if (hcon->type != ACL_LINK || !conn)
4508 return 0x13;
4509
4510 return conn->disc_reason;
4511}
4512
4513static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004514{
4515 BT_DBG("hcon %p reason %d", hcon, reason);
4516
4517 if (hcon->type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03004518 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004519
4520 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004521
Linus Torvalds1da177e2005-04-16 15:20:36 -07004522 return 0;
4523}
4524
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004525static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4526{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004527 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004528 return;
4529
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004530 if (encrypt == 0x00) {
4531 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4532 l2cap_sock_clear_timer(sk);
4533 l2cap_sock_set_timer(sk, HZ * 5);
4534 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4535 __l2cap_sock_close(sk, ECONNREFUSED);
4536 } else {
4537 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4538 l2cap_sock_clear_timer(sk);
4539 }
4540}
4541
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004542static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004543{
4544 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004545 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004546 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004547
Marcel Holtmann01394182006-07-03 10:02:46 +02004548 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004549 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004550
Linus Torvalds1da177e2005-04-16 15:20:36 -07004551 l = &conn->chan_list;
4552
4553 BT_DBG("conn %p", conn);
4554
4555 read_lock(&l->lock);
4556
4557 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4558 bh_lock_sock(sk);
4559
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004560 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4561 bh_unlock_sock(sk);
4562 continue;
4563 }
4564
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004565 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004566 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004567 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004568 bh_unlock_sock(sk);
4569 continue;
4570 }
4571
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004572 if (sk->sk_state == BT_CONNECT) {
4573 if (!status) {
4574 struct l2cap_conn_req req;
4575 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4576 req.psm = l2cap_pi(sk)->psm;
4577
4578 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03004579 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004580
4581 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4582 L2CAP_CONN_REQ, sizeof(req), &req);
4583 } else {
4584 l2cap_sock_clear_timer(sk);
4585 l2cap_sock_set_timer(sk, HZ / 10);
4586 }
4587 } else if (sk->sk_state == BT_CONNECT2) {
4588 struct l2cap_conn_rsp rsp;
4589 __u16 result;
4590
4591 if (!status) {
4592 sk->sk_state = BT_CONFIG;
4593 result = L2CAP_CR_SUCCESS;
4594 } else {
4595 sk->sk_state = BT_DISCONN;
4596 l2cap_sock_set_timer(sk, HZ / 10);
4597 result = L2CAP_CR_SEC_BLOCK;
4598 }
4599
4600 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4601 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4602 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004603 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004604 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4605 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004606 }
4607
Linus Torvalds1da177e2005-04-16 15:20:36 -07004608 bh_unlock_sock(sk);
4609 }
4610
4611 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004612
Linus Torvalds1da177e2005-04-16 15:20:36 -07004613 return 0;
4614}
4615
4616static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4617{
4618 struct l2cap_conn *conn = hcon->l2cap_data;
4619
4620 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4621 goto drop;
4622
4623 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4624
4625 if (flags & ACL_START) {
4626 struct l2cap_hdr *hdr;
4627 int len;
4628
4629 if (conn->rx_len) {
4630 BT_ERR("Unexpected start frame (len %d)", skb->len);
4631 kfree_skb(conn->rx_skb);
4632 conn->rx_skb = NULL;
4633 conn->rx_len = 0;
4634 l2cap_conn_unreliable(conn, ECOMM);
4635 }
4636
4637 if (skb->len < 2) {
4638 BT_ERR("Frame is too short (len %d)", skb->len);
4639 l2cap_conn_unreliable(conn, ECOMM);
4640 goto drop;
4641 }
4642
4643 hdr = (struct l2cap_hdr *) skb->data;
4644 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4645
4646 if (len == skb->len) {
4647 /* Complete frame received */
4648 l2cap_recv_frame(conn, skb);
4649 return 0;
4650 }
4651
4652 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4653
4654 if (skb->len > len) {
4655 BT_ERR("Frame is too long (len %d, expected len %d)",
4656 skb->len, len);
4657 l2cap_conn_unreliable(conn, ECOMM);
4658 goto drop;
4659 }
4660
4661 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03004662 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4663 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004664 goto drop;
4665
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004666 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004667 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004668 conn->rx_len = len - skb->len;
4669 } else {
4670 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4671
4672 if (!conn->rx_len) {
4673 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4674 l2cap_conn_unreliable(conn, ECOMM);
4675 goto drop;
4676 }
4677
4678 if (skb->len > conn->rx_len) {
4679 BT_ERR("Fragment is too long (len %d, expected %d)",
4680 skb->len, conn->rx_len);
4681 kfree_skb(conn->rx_skb);
4682 conn->rx_skb = NULL;
4683 conn->rx_len = 0;
4684 l2cap_conn_unreliable(conn, ECOMM);
4685 goto drop;
4686 }
4687
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004688 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004689 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004690 conn->rx_len -= skb->len;
4691
4692 if (!conn->rx_len) {
4693 /* Complete frame received */
4694 l2cap_recv_frame(conn, conn->rx_skb);
4695 conn->rx_skb = NULL;
4696 }
4697 }
4698
4699drop:
4700 kfree_skb(skb);
4701 return 0;
4702}
4703
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004704static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004705{
4706 struct sock *sk;
4707 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004708
4709 read_lock_bh(&l2cap_sk_list.lock);
4710
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004711 sk_for_each(sk, node, &l2cap_sk_list.head) {
4712 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004713
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004714 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4715 batostr(&bt_sk(sk)->src),
4716 batostr(&bt_sk(sk)->dst),
4717 sk->sk_state, __le16_to_cpu(pi->psm),
4718 pi->scid, pi->dcid,
4719 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004720 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004721
Linus Torvalds1da177e2005-04-16 15:20:36 -07004722 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004723
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004724 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004725}
4726
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004727static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4728{
4729 return single_open(file, l2cap_debugfs_show, inode->i_private);
4730}
4731
4732static const struct file_operations l2cap_debugfs_fops = {
4733 .open = l2cap_debugfs_open,
4734 .read = seq_read,
4735 .llseek = seq_lseek,
4736 .release = single_release,
4737};
4738
4739static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004740
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004741static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004742 .family = PF_BLUETOOTH,
4743 .owner = THIS_MODULE,
4744 .release = l2cap_sock_release,
4745 .bind = l2cap_sock_bind,
4746 .connect = l2cap_sock_connect,
4747 .listen = l2cap_sock_listen,
4748 .accept = l2cap_sock_accept,
4749 .getname = l2cap_sock_getname,
4750 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004751 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004752 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004753 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004754 .mmap = sock_no_mmap,
4755 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004756 .shutdown = l2cap_sock_shutdown,
4757 .setsockopt = l2cap_sock_setsockopt,
4758 .getsockopt = l2cap_sock_getsockopt
4759};
4760
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004761static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004762 .family = PF_BLUETOOTH,
4763 .owner = THIS_MODULE,
4764 .create = l2cap_sock_create,
4765};
4766
4767static struct hci_proto l2cap_hci_proto = {
4768 .name = "L2CAP",
4769 .id = HCI_PROTO_L2CAP,
4770 .connect_ind = l2cap_connect_ind,
4771 .connect_cfm = l2cap_connect_cfm,
4772 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004773 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004774 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004775 .recv_acldata = l2cap_recv_acldata
4776};
4777
4778static int __init l2cap_init(void)
4779{
4780 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004781
Linus Torvalds1da177e2005-04-16 15:20:36 -07004782 err = proto_register(&l2cap_proto, 0);
4783 if (err < 0)
4784 return err;
4785
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004786 _busy_wq = create_singlethread_workqueue("l2cap");
4787 if (!_busy_wq)
4788 goto error;
4789
Linus Torvalds1da177e2005-04-16 15:20:36 -07004790 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4791 if (err < 0) {
4792 BT_ERR("L2CAP socket registration failed");
4793 goto error;
4794 }
4795
4796 err = hci_register_proto(&l2cap_hci_proto);
4797 if (err < 0) {
4798 BT_ERR("L2CAP protocol registration failed");
4799 bt_sock_unregister(BTPROTO_L2CAP);
4800 goto error;
4801 }
4802
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004803 if (bt_debugfs) {
4804 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4805 bt_debugfs, NULL, &l2cap_debugfs_fops);
4806 if (!l2cap_debugfs)
4807 BT_ERR("Failed to create L2CAP debug file");
4808 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004809
4810 BT_INFO("L2CAP ver %s", VERSION);
4811 BT_INFO("L2CAP socket layer initialized");
4812
4813 return 0;
4814
4815error:
4816 proto_unregister(&l2cap_proto);
4817 return err;
4818}
4819
4820static void __exit l2cap_exit(void)
4821{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004822 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004823
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004824 flush_workqueue(_busy_wq);
4825 destroy_workqueue(_busy_wq);
4826
Linus Torvalds1da177e2005-04-16 15:20:36 -07004827 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4828 BT_ERR("L2CAP socket unregistration failed");
4829
4830 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4831 BT_ERR("L2CAP protocol unregistration failed");
4832
4833 proto_unregister(&l2cap_proto);
4834}
4835
4836void l2cap_load(void)
4837{
4838 /* Dummy function to trigger automatic L2CAP module loading by
4839 * other modules that use L2CAP sockets but don't use any other
4840 * symbols from it. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004841}
4842EXPORT_SYMBOL(l2cap_load);
4843
4844module_init(l2cap_init);
4845module_exit(l2cap_exit);
4846
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004847module_param(enable_ertm, bool, 0644);
4848MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4849
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004850MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004851MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4852MODULE_VERSION(VERSION);
4853MODULE_LICENSE("GPL");
4854MODULE_ALIAS("bt-proto-0");