1*0a708f8fSGustavo F. Padovan /* 2*0a708f8fSGustavo F. Padovan BlueZ - Bluetooth protocol stack for Linux 3*0a708f8fSGustavo F. Padovan Copyright (C) 2000-2001 Qualcomm Incorporated 4*0a708f8fSGustavo F. Padovan Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org> 5*0a708f8fSGustavo F. Padovan Copyright (C) 2010 Google Inc. 6*0a708f8fSGustavo F. Padovan 7*0a708f8fSGustavo F. Padovan Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> 8*0a708f8fSGustavo F. Padovan 9*0a708f8fSGustavo F. Padovan This program is free software; you can redistribute it and/or modify 10*0a708f8fSGustavo F. Padovan it under the terms of the GNU General Public License version 2 as 11*0a708f8fSGustavo F. Padovan published by the Free Software Foundation; 12*0a708f8fSGustavo F. Padovan 13*0a708f8fSGustavo F. Padovan THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 14*0a708f8fSGustavo F. Padovan OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15*0a708f8fSGustavo F. Padovan FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 16*0a708f8fSGustavo F. Padovan IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY 17*0a708f8fSGustavo F. Padovan CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 18*0a708f8fSGustavo F. Padovan WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 19*0a708f8fSGustavo F. Padovan ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 20*0a708f8fSGustavo F. Padovan OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21*0a708f8fSGustavo F. Padovan 22*0a708f8fSGustavo F. Padovan ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 23*0a708f8fSGustavo F. Padovan COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 24*0a708f8fSGustavo F. Padovan SOFTWARE IS DISCLAIMED. 25*0a708f8fSGustavo F. Padovan */ 26*0a708f8fSGustavo F. Padovan 27*0a708f8fSGustavo F. Padovan /* Bluetooth L2CAP core and sockets. */ 28*0a708f8fSGustavo F. Padovan 29*0a708f8fSGustavo F. Padovan #include <linux/module.h> 30*0a708f8fSGustavo F. Padovan 31*0a708f8fSGustavo F. Padovan #include <linux/types.h> 32*0a708f8fSGustavo F. Padovan #include <linux/capability.h> 33*0a708f8fSGustavo F. Padovan #include <linux/errno.h> 34*0a708f8fSGustavo F. Padovan #include <linux/kernel.h> 35*0a708f8fSGustavo F. Padovan #include <linux/sched.h> 36*0a708f8fSGustavo F. Padovan #include <linux/slab.h> 37*0a708f8fSGustavo F. Padovan #include <linux/poll.h> 38*0a708f8fSGustavo F. Padovan #include <linux/fcntl.h> 39*0a708f8fSGustavo F. Padovan #include <linux/init.h> 40*0a708f8fSGustavo F. Padovan #include <linux/interrupt.h> 41*0a708f8fSGustavo F. Padovan #include <linux/socket.h> 42*0a708f8fSGustavo F. Padovan #include <linux/skbuff.h> 43*0a708f8fSGustavo F. Padovan #include <linux/list.h> 44*0a708f8fSGustavo F. Padovan #include <linux/device.h> 45*0a708f8fSGustavo F. Padovan #include <linux/debugfs.h> 46*0a708f8fSGustavo F. Padovan #include <linux/seq_file.h> 47*0a708f8fSGustavo F. Padovan #include <linux/uaccess.h> 48*0a708f8fSGustavo F. Padovan #include <linux/crc16.h> 49*0a708f8fSGustavo F. Padovan #include <net/sock.h> 50*0a708f8fSGustavo F. Padovan 51*0a708f8fSGustavo F. Padovan #include <asm/system.h> 52*0a708f8fSGustavo F. Padovan #include <asm/unaligned.h> 53*0a708f8fSGustavo F. Padovan 54*0a708f8fSGustavo F. Padovan #include <net/bluetooth/bluetooth.h> 55*0a708f8fSGustavo F. Padovan #include <net/bluetooth/hci_core.h> 56*0a708f8fSGustavo F. Padovan #include <net/bluetooth/l2cap.h> 57*0a708f8fSGustavo F. Padovan 58*0a708f8fSGustavo F. Padovan #define VERSION "2.15" 59*0a708f8fSGustavo F. Padovan 60*0a708f8fSGustavo F. Padovan static int disable_ertm; 61*0a708f8fSGustavo F. Padovan 62*0a708f8fSGustavo F. Padovan static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; 63*0a708f8fSGustavo F. Padovan static u8 l2cap_fixed_chan[8] = { 0x02, }; 64*0a708f8fSGustavo F. Padovan 65*0a708f8fSGustavo F. Padovan static const struct proto_ops l2cap_sock_ops; 66*0a708f8fSGustavo F. Padovan 67*0a708f8fSGustavo F. Padovan static struct workqueue_struct *_busy_wq; 68*0a708f8fSGustavo F. Padovan 69*0a708f8fSGustavo F. Padovan static struct bt_sock_list l2cap_sk_list = { 70*0a708f8fSGustavo F. Padovan .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock) 71*0a708f8fSGustavo F. Padovan }; 72*0a708f8fSGustavo F. Padovan 73*0a708f8fSGustavo F. Padovan static void l2cap_busy_work(struct work_struct *work); 74*0a708f8fSGustavo F. Padovan 75*0a708f8fSGustavo F. Padovan static void __l2cap_sock_close(struct sock *sk, int reason); 76*0a708f8fSGustavo F. Padovan static void l2cap_sock_close(struct sock *sk); 77*0a708f8fSGustavo F. Padovan static void l2cap_sock_kill(struct sock *sk); 78*0a708f8fSGustavo F. Padovan 79*0a708f8fSGustavo F. Padovan static int l2cap_build_conf_req(struct sock *sk, void *data); 80*0a708f8fSGustavo F. Padovan static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, 81*0a708f8fSGustavo F. Padovan u8 code, u8 ident, u16 dlen, void *data); 82*0a708f8fSGustavo F. Padovan 83*0a708f8fSGustavo F. Padovan static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb); 84*0a708f8fSGustavo F. Padovan 85*0a708f8fSGustavo F. Padovan /* ---- L2CAP timers ---- */ 86*0a708f8fSGustavo F. Padovan static void l2cap_sock_set_timer(struct sock *sk, long timeout) 87*0a708f8fSGustavo F. Padovan { 88*0a708f8fSGustavo F. Padovan BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout); 89*0a708f8fSGustavo F. Padovan sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout); 90*0a708f8fSGustavo F. Padovan } 91*0a708f8fSGustavo F. Padovan 92*0a708f8fSGustavo F. Padovan static void l2cap_sock_clear_timer(struct sock *sk) 93*0a708f8fSGustavo F. Padovan { 94*0a708f8fSGustavo F. Padovan BT_DBG("sock %p state %d", sk, sk->sk_state); 95*0a708f8fSGustavo F. Padovan sk_stop_timer(sk, &sk->sk_timer); 96*0a708f8fSGustavo F. Padovan } 97*0a708f8fSGustavo F. Padovan 98*0a708f8fSGustavo F. Padovan static void l2cap_sock_timeout(unsigned long arg) 99*0a708f8fSGustavo F. Padovan { 100*0a708f8fSGustavo F. Padovan struct sock *sk = (struct sock *) arg; 101*0a708f8fSGustavo F. Padovan int reason; 102*0a708f8fSGustavo F. Padovan 103*0a708f8fSGustavo F. Padovan BT_DBG("sock %p state %d", sk, sk->sk_state); 104*0a708f8fSGustavo F. Padovan 105*0a708f8fSGustavo F. Padovan bh_lock_sock(sk); 106*0a708f8fSGustavo F. Padovan 107*0a708f8fSGustavo F. Padovan if (sock_owned_by_user(sk)) { 108*0a708f8fSGustavo F. Padovan /* sk is owned by user. Try again later */ 109*0a708f8fSGustavo F. Padovan l2cap_sock_set_timer(sk, HZ / 5); 110*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 111*0a708f8fSGustavo F. Padovan sock_put(sk); 112*0a708f8fSGustavo F. Padovan return; 113*0a708f8fSGustavo F. Padovan } 114*0a708f8fSGustavo F. Padovan 115*0a708f8fSGustavo F. Padovan if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG) 116*0a708f8fSGustavo F. Padovan reason = ECONNREFUSED; 117*0a708f8fSGustavo F. Padovan else if (sk->sk_state == BT_CONNECT && 118*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->sec_level != BT_SECURITY_SDP) 119*0a708f8fSGustavo F. Padovan reason = ECONNREFUSED; 120*0a708f8fSGustavo F. Padovan else 121*0a708f8fSGustavo F. Padovan reason = ETIMEDOUT; 122*0a708f8fSGustavo F. Padovan 123*0a708f8fSGustavo F. Padovan __l2cap_sock_close(sk, reason); 124*0a708f8fSGustavo F. Padovan 125*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 126*0a708f8fSGustavo F. Padovan 127*0a708f8fSGustavo F. Padovan l2cap_sock_kill(sk); 128*0a708f8fSGustavo F. Padovan sock_put(sk); 129*0a708f8fSGustavo F. Padovan } 130*0a708f8fSGustavo F. Padovan 131*0a708f8fSGustavo F. Padovan /* ---- L2CAP channels ---- */ 132*0a708f8fSGustavo F. Padovan static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid) 133*0a708f8fSGustavo F. Padovan { 134*0a708f8fSGustavo F. Padovan struct sock *s; 135*0a708f8fSGustavo F. Padovan for (s = l->head; s; s = l2cap_pi(s)->next_c) { 136*0a708f8fSGustavo F. Padovan if (l2cap_pi(s)->dcid == cid) 137*0a708f8fSGustavo F. Padovan break; 138*0a708f8fSGustavo F. Padovan } 139*0a708f8fSGustavo F. Padovan return s; 140*0a708f8fSGustavo F. Padovan } 141*0a708f8fSGustavo F. Padovan 142*0a708f8fSGustavo F. Padovan static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid) 143*0a708f8fSGustavo F. Padovan { 144*0a708f8fSGustavo F. Padovan struct sock *s; 145*0a708f8fSGustavo F. Padovan for (s = l->head; s; s = l2cap_pi(s)->next_c) { 146*0a708f8fSGustavo F. Padovan if (l2cap_pi(s)->scid == cid) 147*0a708f8fSGustavo F. Padovan break; 148*0a708f8fSGustavo F. Padovan } 149*0a708f8fSGustavo F. Padovan return s; 150*0a708f8fSGustavo F. Padovan } 151*0a708f8fSGustavo F. Padovan 152*0a708f8fSGustavo F. Padovan /* Find channel with given SCID. 153*0a708f8fSGustavo F. Padovan * Returns locked socket */ 154*0a708f8fSGustavo F. Padovan static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid) 155*0a708f8fSGustavo F. Padovan { 156*0a708f8fSGustavo F. Padovan struct sock *s; 157*0a708f8fSGustavo F. Padovan read_lock(&l->lock); 158*0a708f8fSGustavo F. Padovan s = __l2cap_get_chan_by_scid(l, cid); 159*0a708f8fSGustavo F. Padovan if (s) 160*0a708f8fSGustavo F. Padovan bh_lock_sock(s); 161*0a708f8fSGustavo F. Padovan read_unlock(&l->lock); 162*0a708f8fSGustavo F. Padovan return s; 163*0a708f8fSGustavo F. Padovan } 164*0a708f8fSGustavo F. Padovan 165*0a708f8fSGustavo F. Padovan static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident) 166*0a708f8fSGustavo F. Padovan { 167*0a708f8fSGustavo F. Padovan struct sock *s; 168*0a708f8fSGustavo F. Padovan for (s = l->head; s; s = l2cap_pi(s)->next_c) { 169*0a708f8fSGustavo F. Padovan if (l2cap_pi(s)->ident == ident) 170*0a708f8fSGustavo F. Padovan break; 171*0a708f8fSGustavo F. Padovan } 172*0a708f8fSGustavo F. Padovan return s; 173*0a708f8fSGustavo F. Padovan } 174*0a708f8fSGustavo F. Padovan 175*0a708f8fSGustavo F. Padovan static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident) 176*0a708f8fSGustavo F. Padovan { 177*0a708f8fSGustavo F. Padovan struct sock *s; 178*0a708f8fSGustavo F. Padovan read_lock(&l->lock); 179*0a708f8fSGustavo F. Padovan s = __l2cap_get_chan_by_ident(l, ident); 180*0a708f8fSGustavo F. Padovan if (s) 181*0a708f8fSGustavo F. Padovan bh_lock_sock(s); 182*0a708f8fSGustavo F. Padovan read_unlock(&l->lock); 183*0a708f8fSGustavo F. Padovan return s; 184*0a708f8fSGustavo F. Padovan } 185*0a708f8fSGustavo F. Padovan 186*0a708f8fSGustavo F. Padovan static u16 l2cap_alloc_cid(struct l2cap_chan_list *l) 187*0a708f8fSGustavo F. Padovan { 188*0a708f8fSGustavo F. Padovan u16 cid = L2CAP_CID_DYN_START; 189*0a708f8fSGustavo F. Padovan 190*0a708f8fSGustavo F. Padovan for (; cid < L2CAP_CID_DYN_END; cid++) { 191*0a708f8fSGustavo F. Padovan if (!__l2cap_get_chan_by_scid(l, cid)) 192*0a708f8fSGustavo F. Padovan return cid; 193*0a708f8fSGustavo F. Padovan } 194*0a708f8fSGustavo F. Padovan 195*0a708f8fSGustavo F. Padovan return 0; 196*0a708f8fSGustavo F. Padovan } 197*0a708f8fSGustavo F. Padovan 198*0a708f8fSGustavo F. Padovan static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk) 199*0a708f8fSGustavo F. Padovan { 200*0a708f8fSGustavo F. Padovan sock_hold(sk); 201*0a708f8fSGustavo F. Padovan 202*0a708f8fSGustavo F. Padovan if (l->head) 203*0a708f8fSGustavo F. Padovan l2cap_pi(l->head)->prev_c = sk; 204*0a708f8fSGustavo F. Padovan 205*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->next_c = l->head; 206*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->prev_c = NULL; 207*0a708f8fSGustavo F. Padovan l->head = sk; 208*0a708f8fSGustavo F. Padovan } 209*0a708f8fSGustavo F. Padovan 210*0a708f8fSGustavo F. Padovan static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk) 211*0a708f8fSGustavo F. Padovan { 212*0a708f8fSGustavo F. Padovan struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c; 213*0a708f8fSGustavo F. Padovan 214*0a708f8fSGustavo F. Padovan write_lock_bh(&l->lock); 215*0a708f8fSGustavo F. Padovan if (sk == l->head) 216*0a708f8fSGustavo F. Padovan l->head = next; 217*0a708f8fSGustavo F. Padovan 218*0a708f8fSGustavo F. Padovan if (next) 219*0a708f8fSGustavo F. Padovan l2cap_pi(next)->prev_c = prev; 220*0a708f8fSGustavo F. Padovan if (prev) 221*0a708f8fSGustavo F. Padovan l2cap_pi(prev)->next_c = next; 222*0a708f8fSGustavo F. Padovan write_unlock_bh(&l->lock); 223*0a708f8fSGustavo F. Padovan 224*0a708f8fSGustavo F. Padovan __sock_put(sk); 225*0a708f8fSGustavo F. Padovan } 226*0a708f8fSGustavo F. Padovan 227*0a708f8fSGustavo F. Padovan static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent) 228*0a708f8fSGustavo F. Padovan { 229*0a708f8fSGustavo F. Padovan struct l2cap_chan_list *l = &conn->chan_list; 230*0a708f8fSGustavo F. Padovan 231*0a708f8fSGustavo F. Padovan BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, 232*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid); 233*0a708f8fSGustavo F. Padovan 234*0a708f8fSGustavo F. Padovan conn->disc_reason = 0x13; 235*0a708f8fSGustavo F. Padovan 236*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conn = conn; 237*0a708f8fSGustavo F. Padovan 238*0a708f8fSGustavo F. Padovan if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) { 239*0a708f8fSGustavo F. Padovan /* Alloc CID for connection-oriented socket */ 240*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->scid = l2cap_alloc_cid(l); 241*0a708f8fSGustavo F. Padovan } else if (sk->sk_type == SOCK_DGRAM) { 242*0a708f8fSGustavo F. Padovan /* Connectionless socket */ 243*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS; 244*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS; 245*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU; 246*0a708f8fSGustavo F. Padovan } else { 247*0a708f8fSGustavo F. Padovan /* Raw socket can send/recv signalling messages only */ 248*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING; 249*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING; 250*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU; 251*0a708f8fSGustavo F. Padovan } 252*0a708f8fSGustavo F. Padovan 253*0a708f8fSGustavo F. Padovan __l2cap_chan_link(l, sk); 254*0a708f8fSGustavo F. Padovan 255*0a708f8fSGustavo F. Padovan if (parent) 256*0a708f8fSGustavo F. Padovan bt_accept_enqueue(parent, sk); 257*0a708f8fSGustavo F. Padovan } 258*0a708f8fSGustavo F. Padovan 259*0a708f8fSGustavo F. Padovan /* Delete channel. 260*0a708f8fSGustavo F. Padovan * Must be called on the locked socket. */ 261*0a708f8fSGustavo F. Padovan static void l2cap_chan_del(struct sock *sk, int err) 262*0a708f8fSGustavo F. Padovan { 263*0a708f8fSGustavo F. Padovan struct l2cap_conn *conn = l2cap_pi(sk)->conn; 264*0a708f8fSGustavo F. Padovan struct sock *parent = bt_sk(sk)->parent; 265*0a708f8fSGustavo F. Padovan 266*0a708f8fSGustavo F. Padovan l2cap_sock_clear_timer(sk); 267*0a708f8fSGustavo F. Padovan 268*0a708f8fSGustavo F. Padovan BT_DBG("sk %p, conn %p, err %d", sk, conn, err); 269*0a708f8fSGustavo F. Padovan 270*0a708f8fSGustavo F. Padovan if (conn) { 271*0a708f8fSGustavo F. Padovan /* Unlink from channel list */ 272*0a708f8fSGustavo F. Padovan l2cap_chan_unlink(&conn->chan_list, sk); 273*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conn = NULL; 274*0a708f8fSGustavo F. Padovan hci_conn_put(conn->hcon); 275*0a708f8fSGustavo F. Padovan } 276*0a708f8fSGustavo F. Padovan 277*0a708f8fSGustavo F. Padovan sk->sk_state = BT_CLOSED; 278*0a708f8fSGustavo F. Padovan sock_set_flag(sk, SOCK_ZAPPED); 279*0a708f8fSGustavo F. Padovan 280*0a708f8fSGustavo F. Padovan if (err) 281*0a708f8fSGustavo F. Padovan sk->sk_err = err; 282*0a708f8fSGustavo F. Padovan 283*0a708f8fSGustavo F. Padovan if (parent) { 284*0a708f8fSGustavo F. Padovan bt_accept_unlink(sk); 285*0a708f8fSGustavo F. Padovan parent->sk_data_ready(parent, 0); 286*0a708f8fSGustavo F. Padovan } else 287*0a708f8fSGustavo F. Padovan sk->sk_state_change(sk); 288*0a708f8fSGustavo F. Padovan 289*0a708f8fSGustavo F. Padovan skb_queue_purge(TX_QUEUE(sk)); 290*0a708f8fSGustavo F. Padovan 291*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { 292*0a708f8fSGustavo F. Padovan struct srej_list *l, *tmp; 293*0a708f8fSGustavo F. Padovan 294*0a708f8fSGustavo F. Padovan del_timer(&l2cap_pi(sk)->retrans_timer); 295*0a708f8fSGustavo F. Padovan del_timer(&l2cap_pi(sk)->monitor_timer); 296*0a708f8fSGustavo F. Padovan del_timer(&l2cap_pi(sk)->ack_timer); 297*0a708f8fSGustavo F. Padovan 298*0a708f8fSGustavo F. Padovan skb_queue_purge(SREJ_QUEUE(sk)); 299*0a708f8fSGustavo F. Padovan skb_queue_purge(BUSY_QUEUE(sk)); 300*0a708f8fSGustavo F. Padovan 301*0a708f8fSGustavo F. Padovan list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) { 302*0a708f8fSGustavo F. Padovan list_del(&l->list); 303*0a708f8fSGustavo F. Padovan kfree(l); 304*0a708f8fSGustavo F. Padovan } 305*0a708f8fSGustavo F. Padovan } 306*0a708f8fSGustavo F. Padovan } 307*0a708f8fSGustavo F. Padovan 308*0a708f8fSGustavo F. Padovan static inline u8 l2cap_get_auth_type(struct sock *sk) 309*0a708f8fSGustavo F. Padovan { 310*0a708f8fSGustavo F. Padovan if (sk->sk_type == SOCK_RAW) { 311*0a708f8fSGustavo F. Padovan switch (l2cap_pi(sk)->sec_level) { 312*0a708f8fSGustavo F. Padovan case BT_SECURITY_HIGH: 313*0a708f8fSGustavo F. Padovan return HCI_AT_DEDICATED_BONDING_MITM; 314*0a708f8fSGustavo F. Padovan case BT_SECURITY_MEDIUM: 315*0a708f8fSGustavo F. Padovan return HCI_AT_DEDICATED_BONDING; 316*0a708f8fSGustavo F. Padovan default: 317*0a708f8fSGustavo F. Padovan return HCI_AT_NO_BONDING; 318*0a708f8fSGustavo F. Padovan } 319*0a708f8fSGustavo F. Padovan } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) { 320*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW) 321*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; 322*0a708f8fSGustavo F. Padovan 323*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH) 324*0a708f8fSGustavo F. Padovan return HCI_AT_NO_BONDING_MITM; 325*0a708f8fSGustavo F. Padovan else 326*0a708f8fSGustavo F. Padovan return HCI_AT_NO_BONDING; 327*0a708f8fSGustavo F. Padovan } else { 328*0a708f8fSGustavo F. Padovan switch (l2cap_pi(sk)->sec_level) { 329*0a708f8fSGustavo F. Padovan case BT_SECURITY_HIGH: 330*0a708f8fSGustavo F. Padovan return HCI_AT_GENERAL_BONDING_MITM; 331*0a708f8fSGustavo F. Padovan case BT_SECURITY_MEDIUM: 332*0a708f8fSGustavo F. Padovan return HCI_AT_GENERAL_BONDING; 333*0a708f8fSGustavo F. Padovan default: 334*0a708f8fSGustavo F. Padovan return HCI_AT_NO_BONDING; 335*0a708f8fSGustavo F. Padovan } 336*0a708f8fSGustavo F. Padovan } 337*0a708f8fSGustavo F. Padovan } 338*0a708f8fSGustavo F. Padovan 339*0a708f8fSGustavo F. Padovan /* Service level security */ 340*0a708f8fSGustavo F. Padovan static inline int l2cap_check_security(struct sock *sk) 341*0a708f8fSGustavo F. Padovan { 342*0a708f8fSGustavo F. Padovan struct l2cap_conn *conn = l2cap_pi(sk)->conn; 343*0a708f8fSGustavo F. Padovan __u8 auth_type; 344*0a708f8fSGustavo F. Padovan 345*0a708f8fSGustavo F. Padovan auth_type = l2cap_get_auth_type(sk); 346*0a708f8fSGustavo F. Padovan 347*0a708f8fSGustavo F. Padovan return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level, 348*0a708f8fSGustavo F. Padovan auth_type); 349*0a708f8fSGustavo F. Padovan } 350*0a708f8fSGustavo F. Padovan 351*0a708f8fSGustavo F. Padovan static inline u8 l2cap_get_ident(struct l2cap_conn *conn) 352*0a708f8fSGustavo F. Padovan { 353*0a708f8fSGustavo F. Padovan u8 id; 354*0a708f8fSGustavo F. Padovan 355*0a708f8fSGustavo F. Padovan /* Get next available identificator. 356*0a708f8fSGustavo F. Padovan * 1 - 128 are used by kernel. 357*0a708f8fSGustavo F. Padovan * 129 - 199 are reserved. 358*0a708f8fSGustavo F. Padovan * 200 - 254 are used by utilities like l2ping, etc. 359*0a708f8fSGustavo F. Padovan */ 360*0a708f8fSGustavo F. Padovan 361*0a708f8fSGustavo F. Padovan spin_lock_bh(&conn->lock); 362*0a708f8fSGustavo F. Padovan 363*0a708f8fSGustavo F. Padovan if (++conn->tx_ident > 128) 364*0a708f8fSGustavo F. Padovan conn->tx_ident = 1; 365*0a708f8fSGustavo F. Padovan 366*0a708f8fSGustavo F. Padovan id = conn->tx_ident; 367*0a708f8fSGustavo F. Padovan 368*0a708f8fSGustavo F. Padovan spin_unlock_bh(&conn->lock); 369*0a708f8fSGustavo F. Padovan 370*0a708f8fSGustavo F. Padovan return id; 371*0a708f8fSGustavo F. Padovan } 372*0a708f8fSGustavo F. Padovan 373*0a708f8fSGustavo F. Padovan static inline void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data) 374*0a708f8fSGustavo F. Padovan { 375*0a708f8fSGustavo F. Padovan struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data); 376*0a708f8fSGustavo F. Padovan u8 flags; 377*0a708f8fSGustavo F. Padovan 378*0a708f8fSGustavo F. Padovan BT_DBG("code 0x%2.2x", code); 379*0a708f8fSGustavo F. Padovan 380*0a708f8fSGustavo F. Padovan if (!skb) 381*0a708f8fSGustavo F. Padovan return; 382*0a708f8fSGustavo F. Padovan 383*0a708f8fSGustavo F. Padovan if (lmp_no_flush_capable(conn->hcon->hdev)) 384*0a708f8fSGustavo F. Padovan flags = ACL_START_NO_FLUSH; 385*0a708f8fSGustavo F. Padovan else 386*0a708f8fSGustavo F. Padovan flags = ACL_START; 387*0a708f8fSGustavo F. Padovan 388*0a708f8fSGustavo F. Padovan hci_send_acl(conn->hcon, skb, flags); 389*0a708f8fSGustavo F. Padovan } 390*0a708f8fSGustavo F. Padovan 391*0a708f8fSGustavo F. Padovan static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control) 392*0a708f8fSGustavo F. Padovan { 393*0a708f8fSGustavo F. Padovan struct sk_buff *skb; 394*0a708f8fSGustavo F. Padovan struct l2cap_hdr *lh; 395*0a708f8fSGustavo F. Padovan struct l2cap_conn *conn = pi->conn; 396*0a708f8fSGustavo F. Padovan struct sock *sk = (struct sock *)pi; 397*0a708f8fSGustavo F. Padovan int count, hlen = L2CAP_HDR_SIZE + 2; 398*0a708f8fSGustavo F. Padovan u8 flags; 399*0a708f8fSGustavo F. Padovan 400*0a708f8fSGustavo F. Padovan if (sk->sk_state != BT_CONNECTED) 401*0a708f8fSGustavo F. Padovan return; 402*0a708f8fSGustavo F. Padovan 403*0a708f8fSGustavo F. Padovan if (pi->fcs == L2CAP_FCS_CRC16) 404*0a708f8fSGustavo F. Padovan hlen += 2; 405*0a708f8fSGustavo F. Padovan 406*0a708f8fSGustavo F. Padovan BT_DBG("pi %p, control 0x%2.2x", pi, control); 407*0a708f8fSGustavo F. Padovan 408*0a708f8fSGustavo F. Padovan count = min_t(unsigned int, conn->mtu, hlen); 409*0a708f8fSGustavo F. Padovan control |= L2CAP_CTRL_FRAME_TYPE; 410*0a708f8fSGustavo F. Padovan 411*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_SEND_FBIT) { 412*0a708f8fSGustavo F. Padovan control |= L2CAP_CTRL_FINAL; 413*0a708f8fSGustavo F. Padovan pi->conn_state &= ~L2CAP_CONN_SEND_FBIT; 414*0a708f8fSGustavo F. Padovan } 415*0a708f8fSGustavo F. Padovan 416*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_SEND_PBIT) { 417*0a708f8fSGustavo F. Padovan control |= L2CAP_CTRL_POLL; 418*0a708f8fSGustavo F. Padovan pi->conn_state &= ~L2CAP_CONN_SEND_PBIT; 419*0a708f8fSGustavo F. Padovan } 420*0a708f8fSGustavo F. Padovan 421*0a708f8fSGustavo F. Padovan skb = bt_skb_alloc(count, GFP_ATOMIC); 422*0a708f8fSGustavo F. Padovan if (!skb) 423*0a708f8fSGustavo F. Padovan return; 424*0a708f8fSGustavo F. Padovan 425*0a708f8fSGustavo F. Padovan lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); 426*0a708f8fSGustavo F. Padovan lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE); 427*0a708f8fSGustavo F. Padovan lh->cid = cpu_to_le16(pi->dcid); 428*0a708f8fSGustavo F. Padovan put_unaligned_le16(control, skb_put(skb, 2)); 429*0a708f8fSGustavo F. Padovan 430*0a708f8fSGustavo F. Padovan if (pi->fcs == L2CAP_FCS_CRC16) { 431*0a708f8fSGustavo F. Padovan u16 fcs = crc16(0, (u8 *)lh, count - 2); 432*0a708f8fSGustavo F. Padovan put_unaligned_le16(fcs, skb_put(skb, 2)); 433*0a708f8fSGustavo F. Padovan } 434*0a708f8fSGustavo F. Padovan 435*0a708f8fSGustavo F. Padovan if (lmp_no_flush_capable(conn->hcon->hdev)) 436*0a708f8fSGustavo F. Padovan flags = ACL_START_NO_FLUSH; 437*0a708f8fSGustavo F. Padovan else 438*0a708f8fSGustavo F. Padovan flags = ACL_START; 439*0a708f8fSGustavo F. Padovan 440*0a708f8fSGustavo F. Padovan hci_send_acl(pi->conn->hcon, skb, flags); 441*0a708f8fSGustavo F. Padovan } 442*0a708f8fSGustavo F. Padovan 443*0a708f8fSGustavo F. Padovan static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control) 444*0a708f8fSGustavo F. Padovan { 445*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) { 446*0a708f8fSGustavo F. Padovan control |= L2CAP_SUPER_RCV_NOT_READY; 447*0a708f8fSGustavo F. Padovan pi->conn_state |= L2CAP_CONN_RNR_SENT; 448*0a708f8fSGustavo F. Padovan } else 449*0a708f8fSGustavo F. Padovan control |= L2CAP_SUPER_RCV_READY; 450*0a708f8fSGustavo F. Padovan 451*0a708f8fSGustavo F. Padovan control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; 452*0a708f8fSGustavo F. Padovan 453*0a708f8fSGustavo F. Padovan l2cap_send_sframe(pi, control); 454*0a708f8fSGustavo F. Padovan } 455*0a708f8fSGustavo F. Padovan 456*0a708f8fSGustavo F. Padovan static inline int __l2cap_no_conn_pending(struct sock *sk) 457*0a708f8fSGustavo F. Padovan { 458*0a708f8fSGustavo F. Padovan return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND); 459*0a708f8fSGustavo F. Padovan } 460*0a708f8fSGustavo F. Padovan 461*0a708f8fSGustavo F. Padovan static void l2cap_do_start(struct sock *sk) 462*0a708f8fSGustavo F. Padovan { 463*0a708f8fSGustavo F. Padovan struct l2cap_conn *conn = l2cap_pi(sk)->conn; 464*0a708f8fSGustavo F. Padovan 465*0a708f8fSGustavo F. Padovan if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) { 466*0a708f8fSGustavo F. Padovan if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)) 467*0a708f8fSGustavo F. Padovan return; 468*0a708f8fSGustavo F. Padovan 469*0a708f8fSGustavo F. Padovan if (l2cap_check_security(sk) && __l2cap_no_conn_pending(sk)) { 470*0a708f8fSGustavo F. Padovan struct l2cap_conn_req req; 471*0a708f8fSGustavo F. Padovan req.scid = cpu_to_le16(l2cap_pi(sk)->scid); 472*0a708f8fSGustavo F. Padovan req.psm = l2cap_pi(sk)->psm; 473*0a708f8fSGustavo F. Padovan 474*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->ident = l2cap_get_ident(conn); 475*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND; 476*0a708f8fSGustavo F. Padovan 477*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, l2cap_pi(sk)->ident, 478*0a708f8fSGustavo F. Padovan L2CAP_CONN_REQ, sizeof(req), &req); 479*0a708f8fSGustavo F. Padovan } 480*0a708f8fSGustavo F. Padovan } else { 481*0a708f8fSGustavo F. Padovan struct l2cap_info_req req; 482*0a708f8fSGustavo F. Padovan req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); 483*0a708f8fSGustavo F. Padovan 484*0a708f8fSGustavo F. Padovan conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; 485*0a708f8fSGustavo F. Padovan conn->info_ident = l2cap_get_ident(conn); 486*0a708f8fSGustavo F. Padovan 487*0a708f8fSGustavo F. Padovan mod_timer(&conn->info_timer, jiffies + 488*0a708f8fSGustavo F. Padovan msecs_to_jiffies(L2CAP_INFO_TIMEOUT)); 489*0a708f8fSGustavo F. Padovan 490*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, conn->info_ident, 491*0a708f8fSGustavo F. Padovan L2CAP_INFO_REQ, sizeof(req), &req); 492*0a708f8fSGustavo F. Padovan } 493*0a708f8fSGustavo F. Padovan } 494*0a708f8fSGustavo F. Padovan 495*0a708f8fSGustavo F. Padovan static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask) 496*0a708f8fSGustavo F. Padovan { 497*0a708f8fSGustavo F. Padovan u32 local_feat_mask = l2cap_feat_mask; 498*0a708f8fSGustavo F. Padovan if (!disable_ertm) 499*0a708f8fSGustavo F. Padovan local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING; 500*0a708f8fSGustavo F. Padovan 501*0a708f8fSGustavo F. Padovan switch (mode) { 502*0a708f8fSGustavo F. Padovan case L2CAP_MODE_ERTM: 503*0a708f8fSGustavo F. Padovan return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask; 504*0a708f8fSGustavo F. Padovan case L2CAP_MODE_STREAMING: 505*0a708f8fSGustavo F. Padovan return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask; 506*0a708f8fSGustavo F. Padovan default: 507*0a708f8fSGustavo F. Padovan return 0x00; 508*0a708f8fSGustavo F. Padovan } 509*0a708f8fSGustavo F. Padovan } 510*0a708f8fSGustavo F. Padovan 511*0a708f8fSGustavo F. Padovan static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err) 512*0a708f8fSGustavo F. Padovan { 513*0a708f8fSGustavo F. Padovan struct l2cap_disconn_req req; 514*0a708f8fSGustavo F. Padovan 515*0a708f8fSGustavo F. Padovan if (!conn) 516*0a708f8fSGustavo F. Padovan return; 517*0a708f8fSGustavo F. Padovan 518*0a708f8fSGustavo F. Padovan skb_queue_purge(TX_QUEUE(sk)); 519*0a708f8fSGustavo F. Padovan 520*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { 521*0a708f8fSGustavo F. Padovan del_timer(&l2cap_pi(sk)->retrans_timer); 522*0a708f8fSGustavo F. Padovan del_timer(&l2cap_pi(sk)->monitor_timer); 523*0a708f8fSGustavo F. Padovan del_timer(&l2cap_pi(sk)->ack_timer); 524*0a708f8fSGustavo F. Padovan } 525*0a708f8fSGustavo F. Padovan 526*0a708f8fSGustavo F. Padovan req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid); 527*0a708f8fSGustavo F. Padovan req.scid = cpu_to_le16(l2cap_pi(sk)->scid); 528*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, l2cap_get_ident(conn), 529*0a708f8fSGustavo F. Padovan L2CAP_DISCONN_REQ, sizeof(req), &req); 530*0a708f8fSGustavo F. Padovan 531*0a708f8fSGustavo F. Padovan sk->sk_state = BT_DISCONN; 532*0a708f8fSGustavo F. Padovan sk->sk_err = err; 533*0a708f8fSGustavo F. Padovan } 534*0a708f8fSGustavo F. Padovan 535*0a708f8fSGustavo F. Padovan /* ---- L2CAP connections ---- */ 536*0a708f8fSGustavo F. Padovan static void l2cap_conn_start(struct l2cap_conn *conn) 537*0a708f8fSGustavo F. Padovan { 538*0a708f8fSGustavo F. Padovan struct l2cap_chan_list *l = &conn->chan_list; 539*0a708f8fSGustavo F. Padovan struct sock_del_list del, *tmp1, *tmp2; 540*0a708f8fSGustavo F. Padovan struct sock *sk; 541*0a708f8fSGustavo F. Padovan 542*0a708f8fSGustavo F. Padovan BT_DBG("conn %p", conn); 543*0a708f8fSGustavo F. Padovan 544*0a708f8fSGustavo F. Padovan INIT_LIST_HEAD(&del.list); 545*0a708f8fSGustavo F. Padovan 546*0a708f8fSGustavo F. Padovan read_lock(&l->lock); 547*0a708f8fSGustavo F. Padovan 548*0a708f8fSGustavo F. Padovan for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { 549*0a708f8fSGustavo F. Padovan bh_lock_sock(sk); 550*0a708f8fSGustavo F. Padovan 551*0a708f8fSGustavo F. Padovan if (sk->sk_type != SOCK_SEQPACKET && 552*0a708f8fSGustavo F. Padovan sk->sk_type != SOCK_STREAM) { 553*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 554*0a708f8fSGustavo F. Padovan continue; 555*0a708f8fSGustavo F. Padovan } 556*0a708f8fSGustavo F. Padovan 557*0a708f8fSGustavo F. Padovan if (sk->sk_state == BT_CONNECT) { 558*0a708f8fSGustavo F. Padovan struct l2cap_conn_req req; 559*0a708f8fSGustavo F. Padovan 560*0a708f8fSGustavo F. Padovan if (!l2cap_check_security(sk) || 561*0a708f8fSGustavo F. Padovan !__l2cap_no_conn_pending(sk)) { 562*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 563*0a708f8fSGustavo F. Padovan continue; 564*0a708f8fSGustavo F. Padovan } 565*0a708f8fSGustavo F. Padovan 566*0a708f8fSGustavo F. Padovan if (!l2cap_mode_supported(l2cap_pi(sk)->mode, 567*0a708f8fSGustavo F. Padovan conn->feat_mask) 568*0a708f8fSGustavo F. Padovan && l2cap_pi(sk)->conf_state & 569*0a708f8fSGustavo F. Padovan L2CAP_CONF_STATE2_DEVICE) { 570*0a708f8fSGustavo F. Padovan tmp1 = kzalloc(sizeof(struct sock_del_list), 571*0a708f8fSGustavo F. Padovan GFP_ATOMIC); 572*0a708f8fSGustavo F. Padovan tmp1->sk = sk; 573*0a708f8fSGustavo F. Padovan list_add_tail(&tmp1->list, &del.list); 574*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 575*0a708f8fSGustavo F. Padovan continue; 576*0a708f8fSGustavo F. Padovan } 577*0a708f8fSGustavo F. Padovan 578*0a708f8fSGustavo F. Padovan req.scid = cpu_to_le16(l2cap_pi(sk)->scid); 579*0a708f8fSGustavo F. Padovan req.psm = l2cap_pi(sk)->psm; 580*0a708f8fSGustavo F. Padovan 581*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->ident = l2cap_get_ident(conn); 582*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND; 583*0a708f8fSGustavo F. Padovan 584*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, l2cap_pi(sk)->ident, 585*0a708f8fSGustavo F. Padovan L2CAP_CONN_REQ, sizeof(req), &req); 586*0a708f8fSGustavo F. Padovan 587*0a708f8fSGustavo F. Padovan } else if (sk->sk_state == BT_CONNECT2) { 588*0a708f8fSGustavo F. Padovan struct l2cap_conn_rsp rsp; 589*0a708f8fSGustavo F. Padovan char buf[128]; 590*0a708f8fSGustavo F. Padovan rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); 591*0a708f8fSGustavo F. Padovan rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); 592*0a708f8fSGustavo F. Padovan 593*0a708f8fSGustavo F. Padovan if (l2cap_check_security(sk)) { 594*0a708f8fSGustavo F. Padovan if (bt_sk(sk)->defer_setup) { 595*0a708f8fSGustavo F. Padovan struct sock *parent = bt_sk(sk)->parent; 596*0a708f8fSGustavo F. Padovan rsp.result = cpu_to_le16(L2CAP_CR_PEND); 597*0a708f8fSGustavo F. Padovan rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND); 598*0a708f8fSGustavo F. Padovan parent->sk_data_ready(parent, 0); 599*0a708f8fSGustavo F. Padovan 600*0a708f8fSGustavo F. Padovan } else { 601*0a708f8fSGustavo F. Padovan sk->sk_state = BT_CONFIG; 602*0a708f8fSGustavo F. Padovan rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); 603*0a708f8fSGustavo F. Padovan rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); 604*0a708f8fSGustavo F. Padovan } 605*0a708f8fSGustavo F. Padovan } else { 606*0a708f8fSGustavo F. Padovan rsp.result = cpu_to_le16(L2CAP_CR_PEND); 607*0a708f8fSGustavo F. Padovan rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND); 608*0a708f8fSGustavo F. Padovan } 609*0a708f8fSGustavo F. Padovan 610*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, l2cap_pi(sk)->ident, 611*0a708f8fSGustavo F. Padovan L2CAP_CONN_RSP, sizeof(rsp), &rsp); 612*0a708f8fSGustavo F. Padovan 613*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT || 614*0a708f8fSGustavo F. Padovan rsp.result != L2CAP_CR_SUCCESS) { 615*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 616*0a708f8fSGustavo F. Padovan continue; 617*0a708f8fSGustavo F. Padovan } 618*0a708f8fSGustavo F. Padovan 619*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; 620*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, 621*0a708f8fSGustavo F. Padovan l2cap_build_conf_req(sk, buf), buf); 622*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->num_conf_req++; 623*0a708f8fSGustavo F. Padovan } 624*0a708f8fSGustavo F. Padovan 625*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 626*0a708f8fSGustavo F. Padovan } 627*0a708f8fSGustavo F. Padovan 628*0a708f8fSGustavo F. Padovan read_unlock(&l->lock); 629*0a708f8fSGustavo F. Padovan 630*0a708f8fSGustavo F. Padovan list_for_each_entry_safe(tmp1, tmp2, &del.list, list) { 631*0a708f8fSGustavo F. Padovan bh_lock_sock(tmp1->sk); 632*0a708f8fSGustavo F. Padovan __l2cap_sock_close(tmp1->sk, ECONNRESET); 633*0a708f8fSGustavo F. Padovan bh_unlock_sock(tmp1->sk); 634*0a708f8fSGustavo F. Padovan list_del(&tmp1->list); 635*0a708f8fSGustavo F. Padovan kfree(tmp1); 636*0a708f8fSGustavo F. Padovan } 637*0a708f8fSGustavo F. Padovan } 638*0a708f8fSGustavo F. Padovan 639*0a708f8fSGustavo F. Padovan static void l2cap_conn_ready(struct l2cap_conn *conn) 640*0a708f8fSGustavo F. Padovan { 641*0a708f8fSGustavo F. Padovan struct l2cap_chan_list *l = &conn->chan_list; 642*0a708f8fSGustavo F. Padovan struct sock *sk; 643*0a708f8fSGustavo F. Padovan 644*0a708f8fSGustavo F. Padovan BT_DBG("conn %p", conn); 645*0a708f8fSGustavo F. Padovan 646*0a708f8fSGustavo F. Padovan read_lock(&l->lock); 647*0a708f8fSGustavo F. Padovan 648*0a708f8fSGustavo F. Padovan for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { 649*0a708f8fSGustavo F. Padovan bh_lock_sock(sk); 650*0a708f8fSGustavo F. Padovan 651*0a708f8fSGustavo F. Padovan if (sk->sk_type != SOCK_SEQPACKET && 652*0a708f8fSGustavo F. Padovan sk->sk_type != SOCK_STREAM) { 653*0a708f8fSGustavo F. Padovan l2cap_sock_clear_timer(sk); 654*0a708f8fSGustavo F. Padovan sk->sk_state = BT_CONNECTED; 655*0a708f8fSGustavo F. Padovan sk->sk_state_change(sk); 656*0a708f8fSGustavo F. Padovan } else if (sk->sk_state == BT_CONNECT) 657*0a708f8fSGustavo F. Padovan l2cap_do_start(sk); 658*0a708f8fSGustavo F. Padovan 659*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 660*0a708f8fSGustavo F. Padovan } 661*0a708f8fSGustavo F. Padovan 662*0a708f8fSGustavo F. Padovan read_unlock(&l->lock); 663*0a708f8fSGustavo F. Padovan } 664*0a708f8fSGustavo F. Padovan 665*0a708f8fSGustavo F. Padovan /* Notify sockets that we cannot guaranty reliability anymore */ 666*0a708f8fSGustavo F. Padovan static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err) 667*0a708f8fSGustavo F. Padovan { 668*0a708f8fSGustavo F. Padovan struct l2cap_chan_list *l = &conn->chan_list; 669*0a708f8fSGustavo F. Padovan struct sock *sk; 670*0a708f8fSGustavo F. Padovan 671*0a708f8fSGustavo F. Padovan BT_DBG("conn %p", conn); 672*0a708f8fSGustavo F. Padovan 673*0a708f8fSGustavo F. Padovan read_lock(&l->lock); 674*0a708f8fSGustavo F. Padovan 675*0a708f8fSGustavo F. Padovan for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { 676*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->force_reliable) 677*0a708f8fSGustavo F. Padovan sk->sk_err = err; 678*0a708f8fSGustavo F. Padovan } 679*0a708f8fSGustavo F. Padovan 680*0a708f8fSGustavo F. Padovan read_unlock(&l->lock); 681*0a708f8fSGustavo F. Padovan } 682*0a708f8fSGustavo F. Padovan 683*0a708f8fSGustavo F. Padovan static void l2cap_info_timeout(unsigned long arg) 684*0a708f8fSGustavo F. Padovan { 685*0a708f8fSGustavo F. Padovan struct l2cap_conn *conn = (void *) arg; 686*0a708f8fSGustavo F. Padovan 687*0a708f8fSGustavo F. Padovan conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; 688*0a708f8fSGustavo F. Padovan conn->info_ident = 0; 689*0a708f8fSGustavo F. Padovan 690*0a708f8fSGustavo F. Padovan l2cap_conn_start(conn); 691*0a708f8fSGustavo F. Padovan } 692*0a708f8fSGustavo F. Padovan 693*0a708f8fSGustavo F. Padovan static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) 694*0a708f8fSGustavo F. Padovan { 695*0a708f8fSGustavo F. Padovan struct l2cap_conn *conn = hcon->l2cap_data; 696*0a708f8fSGustavo F. Padovan 697*0a708f8fSGustavo F. Padovan if (conn || status) 698*0a708f8fSGustavo F. Padovan return conn; 699*0a708f8fSGustavo F. Padovan 700*0a708f8fSGustavo F. Padovan conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC); 701*0a708f8fSGustavo F. Padovan if (!conn) 702*0a708f8fSGustavo F. Padovan return NULL; 703*0a708f8fSGustavo F. Padovan 704*0a708f8fSGustavo F. Padovan hcon->l2cap_data = conn; 705*0a708f8fSGustavo F. Padovan conn->hcon = hcon; 706*0a708f8fSGustavo F. Padovan 707*0a708f8fSGustavo F. Padovan BT_DBG("hcon %p conn %p", hcon, conn); 708*0a708f8fSGustavo F. Padovan 709*0a708f8fSGustavo F. Padovan conn->mtu = hcon->hdev->acl_mtu; 710*0a708f8fSGustavo F. Padovan conn->src = &hcon->hdev->bdaddr; 711*0a708f8fSGustavo F. Padovan conn->dst = &hcon->dst; 712*0a708f8fSGustavo F. Padovan 713*0a708f8fSGustavo F. Padovan conn->feat_mask = 0; 714*0a708f8fSGustavo F. Padovan 715*0a708f8fSGustavo F. Padovan spin_lock_init(&conn->lock); 716*0a708f8fSGustavo F. Padovan rwlock_init(&conn->chan_list.lock); 717*0a708f8fSGustavo F. Padovan 718*0a708f8fSGustavo F. Padovan setup_timer(&conn->info_timer, l2cap_info_timeout, 719*0a708f8fSGustavo F. Padovan (unsigned long) conn); 720*0a708f8fSGustavo F. Padovan 721*0a708f8fSGustavo F. Padovan conn->disc_reason = 0x13; 722*0a708f8fSGustavo F. Padovan 723*0a708f8fSGustavo F. Padovan return conn; 724*0a708f8fSGustavo F. Padovan } 725*0a708f8fSGustavo F. Padovan 726*0a708f8fSGustavo F. Padovan static void l2cap_conn_del(struct hci_conn *hcon, int err) 727*0a708f8fSGustavo F. Padovan { 728*0a708f8fSGustavo F. Padovan struct l2cap_conn *conn = hcon->l2cap_data; 729*0a708f8fSGustavo F. Padovan struct sock *sk; 730*0a708f8fSGustavo F. Padovan 731*0a708f8fSGustavo F. Padovan if (!conn) 732*0a708f8fSGustavo F. Padovan return; 733*0a708f8fSGustavo F. Padovan 734*0a708f8fSGustavo F. Padovan BT_DBG("hcon %p conn %p, err %d", hcon, conn, err); 735*0a708f8fSGustavo F. Padovan 736*0a708f8fSGustavo F. Padovan kfree_skb(conn->rx_skb); 737*0a708f8fSGustavo F. Padovan 738*0a708f8fSGustavo F. Padovan /* Kill channels */ 739*0a708f8fSGustavo F. Padovan while ((sk = conn->chan_list.head)) { 740*0a708f8fSGustavo F. Padovan bh_lock_sock(sk); 741*0a708f8fSGustavo F. Padovan l2cap_chan_del(sk, err); 742*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 743*0a708f8fSGustavo F. Padovan l2cap_sock_kill(sk); 744*0a708f8fSGustavo F. Padovan } 745*0a708f8fSGustavo F. Padovan 746*0a708f8fSGustavo F. Padovan if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) 747*0a708f8fSGustavo F. Padovan del_timer_sync(&conn->info_timer); 748*0a708f8fSGustavo F. Padovan 749*0a708f8fSGustavo F. Padovan hcon->l2cap_data = NULL; 750*0a708f8fSGustavo F. Padovan kfree(conn); 751*0a708f8fSGustavo F. Padovan } 752*0a708f8fSGustavo F. Padovan 753*0a708f8fSGustavo F. Padovan static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent) 754*0a708f8fSGustavo F. Padovan { 755*0a708f8fSGustavo F. Padovan struct l2cap_chan_list *l = &conn->chan_list; 756*0a708f8fSGustavo F. Padovan write_lock_bh(&l->lock); 757*0a708f8fSGustavo F. Padovan __l2cap_chan_add(conn, sk, parent); 758*0a708f8fSGustavo F. Padovan write_unlock_bh(&l->lock); 759*0a708f8fSGustavo F. Padovan } 760*0a708f8fSGustavo F. Padovan 761*0a708f8fSGustavo F. Padovan /* ---- Socket interface ---- */ 762*0a708f8fSGustavo F. Padovan static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src) 763*0a708f8fSGustavo F. Padovan { 764*0a708f8fSGustavo F. Padovan struct sock *sk; 765*0a708f8fSGustavo F. Padovan struct hlist_node *node; 766*0a708f8fSGustavo F. Padovan sk_for_each(sk, node, &l2cap_sk_list.head) 767*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src)) 768*0a708f8fSGustavo F. Padovan goto found; 769*0a708f8fSGustavo F. Padovan sk = NULL; 770*0a708f8fSGustavo F. Padovan found: 771*0a708f8fSGustavo F. Padovan return sk; 772*0a708f8fSGustavo F. Padovan } 773*0a708f8fSGustavo F. Padovan 774*0a708f8fSGustavo F. Padovan /* Find socket with psm and source bdaddr. 775*0a708f8fSGustavo F. Padovan * Returns closest match. 776*0a708f8fSGustavo F. Padovan */ 777*0a708f8fSGustavo F. Padovan static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src) 778*0a708f8fSGustavo F. Padovan { 779*0a708f8fSGustavo F. Padovan struct sock *sk = NULL, *sk1 = NULL; 780*0a708f8fSGustavo F. Padovan struct hlist_node *node; 781*0a708f8fSGustavo F. Padovan 782*0a708f8fSGustavo F. Padovan read_lock(&l2cap_sk_list.lock); 783*0a708f8fSGustavo F. Padovan 784*0a708f8fSGustavo F. Padovan sk_for_each(sk, node, &l2cap_sk_list.head) { 785*0a708f8fSGustavo F. Padovan if (state && sk->sk_state != state) 786*0a708f8fSGustavo F. Padovan continue; 787*0a708f8fSGustavo F. Padovan 788*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->psm == psm) { 789*0a708f8fSGustavo F. Padovan /* Exact match. */ 790*0a708f8fSGustavo F. Padovan if (!bacmp(&bt_sk(sk)->src, src)) 791*0a708f8fSGustavo F. Padovan break; 792*0a708f8fSGustavo F. Padovan 793*0a708f8fSGustavo F. Padovan /* Closest match */ 794*0a708f8fSGustavo F. Padovan if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) 795*0a708f8fSGustavo F. Padovan sk1 = sk; 796*0a708f8fSGustavo F. Padovan } 797*0a708f8fSGustavo F. Padovan } 798*0a708f8fSGustavo F. Padovan 799*0a708f8fSGustavo F. Padovan read_unlock(&l2cap_sk_list.lock); 800*0a708f8fSGustavo F. Padovan 801*0a708f8fSGustavo F. Padovan return node ? sk : sk1; 802*0a708f8fSGustavo F. Padovan } 803*0a708f8fSGustavo F. Padovan 804*0a708f8fSGustavo F. Padovan static void l2cap_sock_destruct(struct sock *sk) 805*0a708f8fSGustavo F. Padovan { 806*0a708f8fSGustavo F. Padovan BT_DBG("sk %p", sk); 807*0a708f8fSGustavo F. Padovan 808*0a708f8fSGustavo F. Padovan skb_queue_purge(&sk->sk_receive_queue); 809*0a708f8fSGustavo F. Padovan skb_queue_purge(&sk->sk_write_queue); 810*0a708f8fSGustavo F. Padovan } 811*0a708f8fSGustavo F. Padovan 812*0a708f8fSGustavo F. Padovan static void l2cap_sock_cleanup_listen(struct sock *parent) 813*0a708f8fSGustavo F. Padovan { 814*0a708f8fSGustavo F. Padovan struct sock *sk; 815*0a708f8fSGustavo F. Padovan 816*0a708f8fSGustavo F. Padovan BT_DBG("parent %p", parent); 817*0a708f8fSGustavo F. Padovan 818*0a708f8fSGustavo F. Padovan /* Close not yet accepted channels */ 819*0a708f8fSGustavo F. Padovan while ((sk = bt_accept_dequeue(parent, NULL))) 820*0a708f8fSGustavo F. Padovan l2cap_sock_close(sk); 821*0a708f8fSGustavo F. Padovan 822*0a708f8fSGustavo F. Padovan parent->sk_state = BT_CLOSED; 823*0a708f8fSGustavo F. Padovan sock_set_flag(parent, SOCK_ZAPPED); 824*0a708f8fSGustavo F. Padovan } 825*0a708f8fSGustavo F. Padovan 826*0a708f8fSGustavo F. Padovan /* Kill socket (only if zapped and orphan) 827*0a708f8fSGustavo F. Padovan * Must be called on unlocked socket. 828*0a708f8fSGustavo F. Padovan */ 829*0a708f8fSGustavo F. Padovan static void l2cap_sock_kill(struct sock *sk) 830*0a708f8fSGustavo F. Padovan { 831*0a708f8fSGustavo F. Padovan if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) 832*0a708f8fSGustavo F. Padovan return; 833*0a708f8fSGustavo F. Padovan 834*0a708f8fSGustavo F. Padovan BT_DBG("sk %p state %d", sk, sk->sk_state); 835*0a708f8fSGustavo F. Padovan 836*0a708f8fSGustavo F. Padovan /* Kill poor orphan */ 837*0a708f8fSGustavo F. Padovan bt_sock_unlink(&l2cap_sk_list, sk); 838*0a708f8fSGustavo F. Padovan sock_set_flag(sk, SOCK_DEAD); 839*0a708f8fSGustavo F. Padovan sock_put(sk); 840*0a708f8fSGustavo F. Padovan } 841*0a708f8fSGustavo F. Padovan 842*0a708f8fSGustavo F. Padovan static void __l2cap_sock_close(struct sock *sk, int reason) 843*0a708f8fSGustavo F. Padovan { 844*0a708f8fSGustavo F. Padovan BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); 845*0a708f8fSGustavo F. Padovan 846*0a708f8fSGustavo F. Padovan switch (sk->sk_state) { 847*0a708f8fSGustavo F. Padovan case BT_LISTEN: 848*0a708f8fSGustavo F. Padovan l2cap_sock_cleanup_listen(sk); 849*0a708f8fSGustavo F. Padovan break; 850*0a708f8fSGustavo F. Padovan 851*0a708f8fSGustavo F. Padovan case BT_CONNECTED: 852*0a708f8fSGustavo F. Padovan case BT_CONFIG: 853*0a708f8fSGustavo F. Padovan if (sk->sk_type == SOCK_SEQPACKET || 854*0a708f8fSGustavo F. Padovan sk->sk_type == SOCK_STREAM) { 855*0a708f8fSGustavo F. Padovan struct l2cap_conn *conn = l2cap_pi(sk)->conn; 856*0a708f8fSGustavo F. Padovan 857*0a708f8fSGustavo F. Padovan l2cap_sock_set_timer(sk, sk->sk_sndtimeo); 858*0a708f8fSGustavo F. Padovan l2cap_send_disconn_req(conn, sk, reason); 859*0a708f8fSGustavo F. Padovan } else 860*0a708f8fSGustavo F. Padovan l2cap_chan_del(sk, reason); 861*0a708f8fSGustavo F. Padovan break; 862*0a708f8fSGustavo F. Padovan 863*0a708f8fSGustavo F. Padovan case BT_CONNECT2: 864*0a708f8fSGustavo F. Padovan if (sk->sk_type == SOCK_SEQPACKET || 865*0a708f8fSGustavo F. Padovan sk->sk_type == SOCK_STREAM) { 866*0a708f8fSGustavo F. Padovan struct l2cap_conn *conn = l2cap_pi(sk)->conn; 867*0a708f8fSGustavo F. Padovan struct l2cap_conn_rsp rsp; 868*0a708f8fSGustavo F. Padovan __u16 result; 869*0a708f8fSGustavo F. Padovan 870*0a708f8fSGustavo F. Padovan if (bt_sk(sk)->defer_setup) 871*0a708f8fSGustavo F. Padovan result = L2CAP_CR_SEC_BLOCK; 872*0a708f8fSGustavo F. Padovan else 873*0a708f8fSGustavo F. Padovan result = L2CAP_CR_BAD_PSM; 874*0a708f8fSGustavo F. Padovan sk->sk_state = BT_DISCONN; 875*0a708f8fSGustavo F. Padovan 876*0a708f8fSGustavo F. Padovan rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); 877*0a708f8fSGustavo F. Padovan rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); 878*0a708f8fSGustavo F. Padovan rsp.result = cpu_to_le16(result); 879*0a708f8fSGustavo F. Padovan rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); 880*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, l2cap_pi(sk)->ident, 881*0a708f8fSGustavo F. Padovan L2CAP_CONN_RSP, sizeof(rsp), &rsp); 882*0a708f8fSGustavo F. Padovan } else 883*0a708f8fSGustavo F. Padovan l2cap_chan_del(sk, reason); 884*0a708f8fSGustavo F. Padovan break; 885*0a708f8fSGustavo F. Padovan 886*0a708f8fSGustavo F. Padovan case BT_CONNECT: 887*0a708f8fSGustavo F. Padovan case BT_DISCONN: 888*0a708f8fSGustavo F. Padovan l2cap_chan_del(sk, reason); 889*0a708f8fSGustavo F. Padovan break; 890*0a708f8fSGustavo F. Padovan 891*0a708f8fSGustavo F. Padovan default: 892*0a708f8fSGustavo F. Padovan sock_set_flag(sk, SOCK_ZAPPED); 893*0a708f8fSGustavo F. Padovan break; 894*0a708f8fSGustavo F. Padovan } 895*0a708f8fSGustavo F. Padovan } 896*0a708f8fSGustavo F. Padovan 897*0a708f8fSGustavo F. Padovan /* Must be called on unlocked socket. */ 898*0a708f8fSGustavo F. Padovan static void l2cap_sock_close(struct sock *sk) 899*0a708f8fSGustavo F. Padovan { 900*0a708f8fSGustavo F. Padovan l2cap_sock_clear_timer(sk); 901*0a708f8fSGustavo F. Padovan lock_sock(sk); 902*0a708f8fSGustavo F. Padovan __l2cap_sock_close(sk, ECONNRESET); 903*0a708f8fSGustavo F. Padovan release_sock(sk); 904*0a708f8fSGustavo F. Padovan l2cap_sock_kill(sk); 905*0a708f8fSGustavo F. Padovan } 906*0a708f8fSGustavo F. Padovan 907*0a708f8fSGustavo F. Padovan static void l2cap_sock_init(struct sock *sk, struct sock *parent) 908*0a708f8fSGustavo F. Padovan { 909*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 910*0a708f8fSGustavo F. Padovan 911*0a708f8fSGustavo F. Padovan BT_DBG("sk %p", sk); 912*0a708f8fSGustavo F. Padovan 913*0a708f8fSGustavo F. Padovan if (parent) { 914*0a708f8fSGustavo F. Padovan sk->sk_type = parent->sk_type; 915*0a708f8fSGustavo F. Padovan bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup; 916*0a708f8fSGustavo F. Padovan 917*0a708f8fSGustavo F. Padovan pi->imtu = l2cap_pi(parent)->imtu; 918*0a708f8fSGustavo F. Padovan pi->omtu = l2cap_pi(parent)->omtu; 919*0a708f8fSGustavo F. Padovan pi->conf_state = l2cap_pi(parent)->conf_state; 920*0a708f8fSGustavo F. Padovan pi->mode = l2cap_pi(parent)->mode; 921*0a708f8fSGustavo F. Padovan pi->fcs = l2cap_pi(parent)->fcs; 922*0a708f8fSGustavo F. Padovan pi->max_tx = l2cap_pi(parent)->max_tx; 923*0a708f8fSGustavo F. Padovan pi->tx_win = l2cap_pi(parent)->tx_win; 924*0a708f8fSGustavo F. Padovan pi->sec_level = l2cap_pi(parent)->sec_level; 925*0a708f8fSGustavo F. Padovan pi->role_switch = l2cap_pi(parent)->role_switch; 926*0a708f8fSGustavo F. Padovan pi->force_reliable = l2cap_pi(parent)->force_reliable; 927*0a708f8fSGustavo F. Padovan pi->flushable = l2cap_pi(parent)->flushable; 928*0a708f8fSGustavo F. Padovan } else { 929*0a708f8fSGustavo F. Padovan pi->imtu = L2CAP_DEFAULT_MTU; 930*0a708f8fSGustavo F. Padovan pi->omtu = 0; 931*0a708f8fSGustavo F. Padovan if (!disable_ertm && sk->sk_type == SOCK_STREAM) { 932*0a708f8fSGustavo F. Padovan pi->mode = L2CAP_MODE_ERTM; 933*0a708f8fSGustavo F. Padovan pi->conf_state |= L2CAP_CONF_STATE2_DEVICE; 934*0a708f8fSGustavo F. Padovan } else { 935*0a708f8fSGustavo F. Padovan pi->mode = L2CAP_MODE_BASIC; 936*0a708f8fSGustavo F. Padovan } 937*0a708f8fSGustavo F. Padovan pi->max_tx = L2CAP_DEFAULT_MAX_TX; 938*0a708f8fSGustavo F. Padovan pi->fcs = L2CAP_FCS_CRC16; 939*0a708f8fSGustavo F. Padovan pi->tx_win = L2CAP_DEFAULT_TX_WINDOW; 940*0a708f8fSGustavo F. Padovan pi->sec_level = BT_SECURITY_LOW; 941*0a708f8fSGustavo F. Padovan pi->role_switch = 0; 942*0a708f8fSGustavo F. Padovan pi->force_reliable = 0; 943*0a708f8fSGustavo F. Padovan pi->flushable = BT_FLUSHABLE_OFF; 944*0a708f8fSGustavo F. Padovan } 945*0a708f8fSGustavo F. Padovan 946*0a708f8fSGustavo F. Padovan /* Default config options */ 947*0a708f8fSGustavo F. Padovan pi->conf_len = 0; 948*0a708f8fSGustavo F. Padovan pi->flush_to = L2CAP_DEFAULT_FLUSH_TO; 949*0a708f8fSGustavo F. Padovan skb_queue_head_init(TX_QUEUE(sk)); 950*0a708f8fSGustavo F. Padovan skb_queue_head_init(SREJ_QUEUE(sk)); 951*0a708f8fSGustavo F. Padovan skb_queue_head_init(BUSY_QUEUE(sk)); 952*0a708f8fSGustavo F. Padovan INIT_LIST_HEAD(SREJ_LIST(sk)); 953*0a708f8fSGustavo F. Padovan } 954*0a708f8fSGustavo F. Padovan 955*0a708f8fSGustavo F. Padovan static struct proto l2cap_proto = { 956*0a708f8fSGustavo F. Padovan .name = "L2CAP", 957*0a708f8fSGustavo F. Padovan .owner = THIS_MODULE, 958*0a708f8fSGustavo F. Padovan .obj_size = sizeof(struct l2cap_pinfo) 959*0a708f8fSGustavo F. Padovan }; 960*0a708f8fSGustavo F. Padovan 961*0a708f8fSGustavo F. Padovan static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio) 962*0a708f8fSGustavo F. Padovan { 963*0a708f8fSGustavo F. Padovan struct sock *sk; 964*0a708f8fSGustavo F. Padovan 965*0a708f8fSGustavo F. Padovan sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto); 966*0a708f8fSGustavo F. Padovan if (!sk) 967*0a708f8fSGustavo F. Padovan return NULL; 968*0a708f8fSGustavo F. Padovan 969*0a708f8fSGustavo F. Padovan sock_init_data(sock, sk); 970*0a708f8fSGustavo F. Padovan INIT_LIST_HEAD(&bt_sk(sk)->accept_q); 971*0a708f8fSGustavo F. Padovan 972*0a708f8fSGustavo F. Padovan sk->sk_destruct = l2cap_sock_destruct; 973*0a708f8fSGustavo F. Padovan sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT); 974*0a708f8fSGustavo F. Padovan 975*0a708f8fSGustavo F. Padovan sock_reset_flag(sk, SOCK_ZAPPED); 976*0a708f8fSGustavo F. Padovan 977*0a708f8fSGustavo F. Padovan sk->sk_protocol = proto; 978*0a708f8fSGustavo F. Padovan sk->sk_state = BT_OPEN; 979*0a708f8fSGustavo F. Padovan 980*0a708f8fSGustavo F. Padovan setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk); 981*0a708f8fSGustavo F. Padovan 982*0a708f8fSGustavo F. Padovan bt_sock_link(&l2cap_sk_list, sk); 983*0a708f8fSGustavo F. Padovan return sk; 984*0a708f8fSGustavo F. Padovan } 985*0a708f8fSGustavo F. Padovan 986*0a708f8fSGustavo F. Padovan static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol, 987*0a708f8fSGustavo F. Padovan int kern) 988*0a708f8fSGustavo F. Padovan { 989*0a708f8fSGustavo F. Padovan struct sock *sk; 990*0a708f8fSGustavo F. Padovan 991*0a708f8fSGustavo F. Padovan BT_DBG("sock %p", sock); 992*0a708f8fSGustavo F. Padovan 993*0a708f8fSGustavo F. Padovan sock->state = SS_UNCONNECTED; 994*0a708f8fSGustavo F. Padovan 995*0a708f8fSGustavo F. Padovan if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM && 996*0a708f8fSGustavo F. Padovan sock->type != SOCK_DGRAM && sock->type != SOCK_RAW) 997*0a708f8fSGustavo F. Padovan return -ESOCKTNOSUPPORT; 998*0a708f8fSGustavo F. Padovan 999*0a708f8fSGustavo F. Padovan if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW)) 1000*0a708f8fSGustavo F. Padovan return -EPERM; 1001*0a708f8fSGustavo F. Padovan 1002*0a708f8fSGustavo F. Padovan sock->ops = &l2cap_sock_ops; 1003*0a708f8fSGustavo F. Padovan 1004*0a708f8fSGustavo F. Padovan sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC); 1005*0a708f8fSGustavo F. Padovan if (!sk) 1006*0a708f8fSGustavo F. Padovan return -ENOMEM; 1007*0a708f8fSGustavo F. Padovan 1008*0a708f8fSGustavo F. Padovan l2cap_sock_init(sk, NULL); 1009*0a708f8fSGustavo F. Padovan return 0; 1010*0a708f8fSGustavo F. Padovan } 1011*0a708f8fSGustavo F. Padovan 1012*0a708f8fSGustavo F. Padovan static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) 1013*0a708f8fSGustavo F. Padovan { 1014*0a708f8fSGustavo F. Padovan struct sock *sk = sock->sk; 1015*0a708f8fSGustavo F. Padovan struct sockaddr_l2 la; 1016*0a708f8fSGustavo F. Padovan int len, err = 0; 1017*0a708f8fSGustavo F. Padovan 1018*0a708f8fSGustavo F. Padovan BT_DBG("sk %p", sk); 1019*0a708f8fSGustavo F. Padovan 1020*0a708f8fSGustavo F. Padovan if (!addr || addr->sa_family != AF_BLUETOOTH) 1021*0a708f8fSGustavo F. Padovan return -EINVAL; 1022*0a708f8fSGustavo F. Padovan 1023*0a708f8fSGustavo F. Padovan memset(&la, 0, sizeof(la)); 1024*0a708f8fSGustavo F. Padovan len = min_t(unsigned int, sizeof(la), alen); 1025*0a708f8fSGustavo F. Padovan memcpy(&la, addr, len); 1026*0a708f8fSGustavo F. Padovan 1027*0a708f8fSGustavo F. Padovan if (la.l2_cid) 1028*0a708f8fSGustavo F. Padovan return -EINVAL; 1029*0a708f8fSGustavo F. Padovan 1030*0a708f8fSGustavo F. Padovan lock_sock(sk); 1031*0a708f8fSGustavo F. Padovan 1032*0a708f8fSGustavo F. Padovan if (sk->sk_state != BT_OPEN) { 1033*0a708f8fSGustavo F. Padovan err = -EBADFD; 1034*0a708f8fSGustavo F. Padovan goto done; 1035*0a708f8fSGustavo F. Padovan } 1036*0a708f8fSGustavo F. Padovan 1037*0a708f8fSGustavo F. Padovan if (la.l2_psm) { 1038*0a708f8fSGustavo F. Padovan __u16 psm = __le16_to_cpu(la.l2_psm); 1039*0a708f8fSGustavo F. Padovan 1040*0a708f8fSGustavo F. Padovan /* PSM must be odd and lsb of upper byte must be 0 */ 1041*0a708f8fSGustavo F. Padovan if ((psm & 0x0101) != 0x0001) { 1042*0a708f8fSGustavo F. Padovan err = -EINVAL; 1043*0a708f8fSGustavo F. Padovan goto done; 1044*0a708f8fSGustavo F. Padovan } 1045*0a708f8fSGustavo F. Padovan 1046*0a708f8fSGustavo F. Padovan /* Restrict usage of well-known PSMs */ 1047*0a708f8fSGustavo F. Padovan if (psm < 0x1001 && !capable(CAP_NET_BIND_SERVICE)) { 1048*0a708f8fSGustavo F. Padovan err = -EACCES; 1049*0a708f8fSGustavo F. Padovan goto done; 1050*0a708f8fSGustavo F. Padovan } 1051*0a708f8fSGustavo F. Padovan } 1052*0a708f8fSGustavo F. Padovan 1053*0a708f8fSGustavo F. Padovan write_lock_bh(&l2cap_sk_list.lock); 1054*0a708f8fSGustavo F. Padovan 1055*0a708f8fSGustavo F. Padovan if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) { 1056*0a708f8fSGustavo F. Padovan err = -EADDRINUSE; 1057*0a708f8fSGustavo F. Padovan } else { 1058*0a708f8fSGustavo F. Padovan /* Save source address */ 1059*0a708f8fSGustavo F. Padovan bacpy(&bt_sk(sk)->src, &la.l2_bdaddr); 1060*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->psm = la.l2_psm; 1061*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->sport = la.l2_psm; 1062*0a708f8fSGustavo F. Padovan sk->sk_state = BT_BOUND; 1063*0a708f8fSGustavo F. Padovan 1064*0a708f8fSGustavo F. Padovan if (__le16_to_cpu(la.l2_psm) == 0x0001 || 1065*0a708f8fSGustavo F. Padovan __le16_to_cpu(la.l2_psm) == 0x0003) 1066*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; 1067*0a708f8fSGustavo F. Padovan } 1068*0a708f8fSGustavo F. Padovan 1069*0a708f8fSGustavo F. Padovan write_unlock_bh(&l2cap_sk_list.lock); 1070*0a708f8fSGustavo F. Padovan 1071*0a708f8fSGustavo F. Padovan done: 1072*0a708f8fSGustavo F. Padovan release_sock(sk); 1073*0a708f8fSGustavo F. Padovan return err; 1074*0a708f8fSGustavo F. Padovan } 1075*0a708f8fSGustavo F. Padovan 1076*0a708f8fSGustavo F. Padovan static int l2cap_do_connect(struct sock *sk) 1077*0a708f8fSGustavo F. Padovan { 1078*0a708f8fSGustavo F. Padovan bdaddr_t *src = &bt_sk(sk)->src; 1079*0a708f8fSGustavo F. Padovan bdaddr_t *dst = &bt_sk(sk)->dst; 1080*0a708f8fSGustavo F. Padovan struct l2cap_conn *conn; 1081*0a708f8fSGustavo F. Padovan struct hci_conn *hcon; 1082*0a708f8fSGustavo F. Padovan struct hci_dev *hdev; 1083*0a708f8fSGustavo F. Padovan __u8 auth_type; 1084*0a708f8fSGustavo F. Padovan int err; 1085*0a708f8fSGustavo F. Padovan 1086*0a708f8fSGustavo F. Padovan BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), 1087*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->psm); 1088*0a708f8fSGustavo F. Padovan 1089*0a708f8fSGustavo F. Padovan hdev = hci_get_route(dst, src); 1090*0a708f8fSGustavo F. Padovan if (!hdev) 1091*0a708f8fSGustavo F. Padovan return -EHOSTUNREACH; 1092*0a708f8fSGustavo F. Padovan 1093*0a708f8fSGustavo F. Padovan hci_dev_lock_bh(hdev); 1094*0a708f8fSGustavo F. Padovan 1095*0a708f8fSGustavo F. Padovan err = -ENOMEM; 1096*0a708f8fSGustavo F. Padovan 1097*0a708f8fSGustavo F. Padovan auth_type = l2cap_get_auth_type(sk); 1098*0a708f8fSGustavo F. Padovan 1099*0a708f8fSGustavo F. Padovan hcon = hci_connect(hdev, ACL_LINK, dst, 1100*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->sec_level, auth_type); 1101*0a708f8fSGustavo F. Padovan if (!hcon) 1102*0a708f8fSGustavo F. Padovan goto done; 1103*0a708f8fSGustavo F. Padovan 1104*0a708f8fSGustavo F. Padovan conn = l2cap_conn_add(hcon, 0); 1105*0a708f8fSGustavo F. Padovan if (!conn) { 1106*0a708f8fSGustavo F. Padovan hci_conn_put(hcon); 1107*0a708f8fSGustavo F. Padovan goto done; 1108*0a708f8fSGustavo F. Padovan } 1109*0a708f8fSGustavo F. Padovan 1110*0a708f8fSGustavo F. Padovan err = 0; 1111*0a708f8fSGustavo F. Padovan 1112*0a708f8fSGustavo F. Padovan /* Update source addr of the socket */ 1113*0a708f8fSGustavo F. Padovan bacpy(src, conn->src); 1114*0a708f8fSGustavo F. Padovan 1115*0a708f8fSGustavo F. Padovan l2cap_chan_add(conn, sk, NULL); 1116*0a708f8fSGustavo F. Padovan 1117*0a708f8fSGustavo F. Padovan sk->sk_state = BT_CONNECT; 1118*0a708f8fSGustavo F. Padovan l2cap_sock_set_timer(sk, sk->sk_sndtimeo); 1119*0a708f8fSGustavo F. Padovan 1120*0a708f8fSGustavo F. Padovan if (hcon->state == BT_CONNECTED) { 1121*0a708f8fSGustavo F. Padovan if (sk->sk_type != SOCK_SEQPACKET && 1122*0a708f8fSGustavo F. Padovan sk->sk_type != SOCK_STREAM) { 1123*0a708f8fSGustavo F. Padovan l2cap_sock_clear_timer(sk); 1124*0a708f8fSGustavo F. Padovan if (l2cap_check_security(sk)) 1125*0a708f8fSGustavo F. Padovan sk->sk_state = BT_CONNECTED; 1126*0a708f8fSGustavo F. Padovan } else 1127*0a708f8fSGustavo F. Padovan l2cap_do_start(sk); 1128*0a708f8fSGustavo F. Padovan } 1129*0a708f8fSGustavo F. Padovan 1130*0a708f8fSGustavo F. Padovan done: 1131*0a708f8fSGustavo F. Padovan hci_dev_unlock_bh(hdev); 1132*0a708f8fSGustavo F. Padovan hci_dev_put(hdev); 1133*0a708f8fSGustavo F. Padovan return err; 1134*0a708f8fSGustavo F. Padovan } 1135*0a708f8fSGustavo F. Padovan 1136*0a708f8fSGustavo F. Padovan static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags) 1137*0a708f8fSGustavo F. Padovan { 1138*0a708f8fSGustavo F. Padovan struct sock *sk = sock->sk; 1139*0a708f8fSGustavo F. Padovan struct sockaddr_l2 la; 1140*0a708f8fSGustavo F. Padovan int len, err = 0; 1141*0a708f8fSGustavo F. Padovan 1142*0a708f8fSGustavo F. Padovan BT_DBG("sk %p", sk); 1143*0a708f8fSGustavo F. Padovan 1144*0a708f8fSGustavo F. Padovan if (!addr || alen < sizeof(addr->sa_family) || 1145*0a708f8fSGustavo F. Padovan addr->sa_family != AF_BLUETOOTH) 1146*0a708f8fSGustavo F. Padovan return -EINVAL; 1147*0a708f8fSGustavo F. Padovan 1148*0a708f8fSGustavo F. Padovan memset(&la, 0, sizeof(la)); 1149*0a708f8fSGustavo F. Padovan len = min_t(unsigned int, sizeof(la), alen); 1150*0a708f8fSGustavo F. Padovan memcpy(&la, addr, len); 1151*0a708f8fSGustavo F. Padovan 1152*0a708f8fSGustavo F. Padovan if (la.l2_cid) 1153*0a708f8fSGustavo F. Padovan return -EINVAL; 1154*0a708f8fSGustavo F. Padovan 1155*0a708f8fSGustavo F. Padovan lock_sock(sk); 1156*0a708f8fSGustavo F. Padovan 1157*0a708f8fSGustavo F. Padovan if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) 1158*0a708f8fSGustavo F. Padovan && !la.l2_psm) { 1159*0a708f8fSGustavo F. Padovan err = -EINVAL; 1160*0a708f8fSGustavo F. Padovan goto done; 1161*0a708f8fSGustavo F. Padovan } 1162*0a708f8fSGustavo F. Padovan 1163*0a708f8fSGustavo F. Padovan switch (l2cap_pi(sk)->mode) { 1164*0a708f8fSGustavo F. Padovan case L2CAP_MODE_BASIC: 1165*0a708f8fSGustavo F. Padovan break; 1166*0a708f8fSGustavo F. Padovan case L2CAP_MODE_ERTM: 1167*0a708f8fSGustavo F. Padovan case L2CAP_MODE_STREAMING: 1168*0a708f8fSGustavo F. Padovan if (!disable_ertm) 1169*0a708f8fSGustavo F. Padovan break; 1170*0a708f8fSGustavo F. Padovan /* fall through */ 1171*0a708f8fSGustavo F. Padovan default: 1172*0a708f8fSGustavo F. Padovan err = -ENOTSUPP; 1173*0a708f8fSGustavo F. Padovan goto done; 1174*0a708f8fSGustavo F. Padovan } 1175*0a708f8fSGustavo F. Padovan 1176*0a708f8fSGustavo F. Padovan switch (sk->sk_state) { 1177*0a708f8fSGustavo F. Padovan case BT_CONNECT: 1178*0a708f8fSGustavo F. Padovan case BT_CONNECT2: 1179*0a708f8fSGustavo F. Padovan case BT_CONFIG: 1180*0a708f8fSGustavo F. Padovan /* Already connecting */ 1181*0a708f8fSGustavo F. Padovan goto wait; 1182*0a708f8fSGustavo F. Padovan 1183*0a708f8fSGustavo F. Padovan case BT_CONNECTED: 1184*0a708f8fSGustavo F. Padovan /* Already connected */ 1185*0a708f8fSGustavo F. Padovan err = -EISCONN; 1186*0a708f8fSGustavo F. Padovan goto done; 1187*0a708f8fSGustavo F. Padovan 1188*0a708f8fSGustavo F. Padovan case BT_OPEN: 1189*0a708f8fSGustavo F. Padovan case BT_BOUND: 1190*0a708f8fSGustavo F. Padovan /* Can connect */ 1191*0a708f8fSGustavo F. Padovan break; 1192*0a708f8fSGustavo F. Padovan 1193*0a708f8fSGustavo F. Padovan default: 1194*0a708f8fSGustavo F. Padovan err = -EBADFD; 1195*0a708f8fSGustavo F. Padovan goto done; 1196*0a708f8fSGustavo F. Padovan } 1197*0a708f8fSGustavo F. Padovan 1198*0a708f8fSGustavo F. Padovan /* PSM must be odd and lsb of upper byte must be 0 */ 1199*0a708f8fSGustavo F. Padovan if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 && 1200*0a708f8fSGustavo F. Padovan sk->sk_type != SOCK_RAW) { 1201*0a708f8fSGustavo F. Padovan err = -EINVAL; 1202*0a708f8fSGustavo F. Padovan goto done; 1203*0a708f8fSGustavo F. Padovan } 1204*0a708f8fSGustavo F. Padovan 1205*0a708f8fSGustavo F. Padovan /* Set destination address and psm */ 1206*0a708f8fSGustavo F. Padovan bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr); 1207*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->psm = la.l2_psm; 1208*0a708f8fSGustavo F. Padovan 1209*0a708f8fSGustavo F. Padovan err = l2cap_do_connect(sk); 1210*0a708f8fSGustavo F. Padovan if (err) 1211*0a708f8fSGustavo F. Padovan goto done; 1212*0a708f8fSGustavo F. Padovan 1213*0a708f8fSGustavo F. Padovan wait: 1214*0a708f8fSGustavo F. Padovan err = bt_sock_wait_state(sk, BT_CONNECTED, 1215*0a708f8fSGustavo F. Padovan sock_sndtimeo(sk, flags & O_NONBLOCK)); 1216*0a708f8fSGustavo F. Padovan done: 1217*0a708f8fSGustavo F. Padovan release_sock(sk); 1218*0a708f8fSGustavo F. Padovan return err; 1219*0a708f8fSGustavo F. Padovan } 1220*0a708f8fSGustavo F. Padovan 1221*0a708f8fSGustavo F. Padovan static int l2cap_sock_listen(struct socket *sock, int backlog) 1222*0a708f8fSGustavo F. Padovan { 1223*0a708f8fSGustavo F. Padovan struct sock *sk = sock->sk; 1224*0a708f8fSGustavo F. Padovan int err = 0; 1225*0a708f8fSGustavo F. Padovan 1226*0a708f8fSGustavo F. Padovan BT_DBG("sk %p backlog %d", sk, backlog); 1227*0a708f8fSGustavo F. Padovan 1228*0a708f8fSGustavo F. Padovan lock_sock(sk); 1229*0a708f8fSGustavo F. Padovan 1230*0a708f8fSGustavo F. Padovan if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM) 1231*0a708f8fSGustavo F. Padovan || sk->sk_state != BT_BOUND) { 1232*0a708f8fSGustavo F. Padovan err = -EBADFD; 1233*0a708f8fSGustavo F. Padovan goto done; 1234*0a708f8fSGustavo F. Padovan } 1235*0a708f8fSGustavo F. Padovan 1236*0a708f8fSGustavo F. Padovan switch (l2cap_pi(sk)->mode) { 1237*0a708f8fSGustavo F. Padovan case L2CAP_MODE_BASIC: 1238*0a708f8fSGustavo F. Padovan break; 1239*0a708f8fSGustavo F. Padovan case L2CAP_MODE_ERTM: 1240*0a708f8fSGustavo F. Padovan case L2CAP_MODE_STREAMING: 1241*0a708f8fSGustavo F. Padovan if (!disable_ertm) 1242*0a708f8fSGustavo F. Padovan break; 1243*0a708f8fSGustavo F. Padovan /* fall through */ 1244*0a708f8fSGustavo F. Padovan default: 1245*0a708f8fSGustavo F. Padovan err = -ENOTSUPP; 1246*0a708f8fSGustavo F. Padovan goto done; 1247*0a708f8fSGustavo F. Padovan } 1248*0a708f8fSGustavo F. Padovan 1249*0a708f8fSGustavo F. Padovan if (!l2cap_pi(sk)->psm) { 1250*0a708f8fSGustavo F. Padovan bdaddr_t *src = &bt_sk(sk)->src; 1251*0a708f8fSGustavo F. Padovan u16 psm; 1252*0a708f8fSGustavo F. Padovan 1253*0a708f8fSGustavo F. Padovan err = -EINVAL; 1254*0a708f8fSGustavo F. Padovan 1255*0a708f8fSGustavo F. Padovan write_lock_bh(&l2cap_sk_list.lock); 1256*0a708f8fSGustavo F. Padovan 1257*0a708f8fSGustavo F. Padovan for (psm = 0x1001; psm < 0x1100; psm += 2) 1258*0a708f8fSGustavo F. Padovan if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) { 1259*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->psm = cpu_to_le16(psm); 1260*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->sport = cpu_to_le16(psm); 1261*0a708f8fSGustavo F. Padovan err = 0; 1262*0a708f8fSGustavo F. Padovan break; 1263*0a708f8fSGustavo F. Padovan } 1264*0a708f8fSGustavo F. Padovan 1265*0a708f8fSGustavo F. Padovan write_unlock_bh(&l2cap_sk_list.lock); 1266*0a708f8fSGustavo F. Padovan 1267*0a708f8fSGustavo F. Padovan if (err < 0) 1268*0a708f8fSGustavo F. Padovan goto done; 1269*0a708f8fSGustavo F. Padovan } 1270*0a708f8fSGustavo F. Padovan 1271*0a708f8fSGustavo F. Padovan sk->sk_max_ack_backlog = backlog; 1272*0a708f8fSGustavo F. Padovan sk->sk_ack_backlog = 0; 1273*0a708f8fSGustavo F. Padovan sk->sk_state = BT_LISTEN; 1274*0a708f8fSGustavo F. Padovan 1275*0a708f8fSGustavo F. Padovan done: 1276*0a708f8fSGustavo F. Padovan release_sock(sk); 1277*0a708f8fSGustavo F. Padovan return err; 1278*0a708f8fSGustavo F. Padovan } 1279*0a708f8fSGustavo F. Padovan 1280*0a708f8fSGustavo F. Padovan static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags) 1281*0a708f8fSGustavo F. Padovan { 1282*0a708f8fSGustavo F. Padovan DECLARE_WAITQUEUE(wait, current); 1283*0a708f8fSGustavo F. Padovan struct sock *sk = sock->sk, *nsk; 1284*0a708f8fSGustavo F. Padovan long timeo; 1285*0a708f8fSGustavo F. Padovan int err = 0; 1286*0a708f8fSGustavo F. Padovan 1287*0a708f8fSGustavo F. Padovan lock_sock_nested(sk, SINGLE_DEPTH_NESTING); 1288*0a708f8fSGustavo F. Padovan 1289*0a708f8fSGustavo F. Padovan if (sk->sk_state != BT_LISTEN) { 1290*0a708f8fSGustavo F. Padovan err = -EBADFD; 1291*0a708f8fSGustavo F. Padovan goto done; 1292*0a708f8fSGustavo F. Padovan } 1293*0a708f8fSGustavo F. Padovan 1294*0a708f8fSGustavo F. Padovan timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); 1295*0a708f8fSGustavo F. Padovan 1296*0a708f8fSGustavo F. Padovan BT_DBG("sk %p timeo %ld", sk, timeo); 1297*0a708f8fSGustavo F. Padovan 1298*0a708f8fSGustavo F. Padovan /* Wait for an incoming connection. (wake-one). */ 1299*0a708f8fSGustavo F. Padovan add_wait_queue_exclusive(sk_sleep(sk), &wait); 1300*0a708f8fSGustavo F. Padovan while (!(nsk = bt_accept_dequeue(sk, newsock))) { 1301*0a708f8fSGustavo F. Padovan set_current_state(TASK_INTERRUPTIBLE); 1302*0a708f8fSGustavo F. Padovan if (!timeo) { 1303*0a708f8fSGustavo F. Padovan err = -EAGAIN; 1304*0a708f8fSGustavo F. Padovan break; 1305*0a708f8fSGustavo F. Padovan } 1306*0a708f8fSGustavo F. Padovan 1307*0a708f8fSGustavo F. Padovan release_sock(sk); 1308*0a708f8fSGustavo F. Padovan timeo = schedule_timeout(timeo); 1309*0a708f8fSGustavo F. Padovan lock_sock_nested(sk, SINGLE_DEPTH_NESTING); 1310*0a708f8fSGustavo F. Padovan 1311*0a708f8fSGustavo F. Padovan if (sk->sk_state != BT_LISTEN) { 1312*0a708f8fSGustavo F. Padovan err = -EBADFD; 1313*0a708f8fSGustavo F. Padovan break; 1314*0a708f8fSGustavo F. Padovan } 1315*0a708f8fSGustavo F. Padovan 1316*0a708f8fSGustavo F. Padovan if (signal_pending(current)) { 1317*0a708f8fSGustavo F. Padovan err = sock_intr_errno(timeo); 1318*0a708f8fSGustavo F. Padovan break; 1319*0a708f8fSGustavo F. Padovan } 1320*0a708f8fSGustavo F. Padovan } 1321*0a708f8fSGustavo F. Padovan set_current_state(TASK_RUNNING); 1322*0a708f8fSGustavo F. Padovan remove_wait_queue(sk_sleep(sk), &wait); 1323*0a708f8fSGustavo F. Padovan 1324*0a708f8fSGustavo F. Padovan if (err) 1325*0a708f8fSGustavo F. Padovan goto done; 1326*0a708f8fSGustavo F. Padovan 1327*0a708f8fSGustavo F. Padovan newsock->state = SS_CONNECTED; 1328*0a708f8fSGustavo F. Padovan 1329*0a708f8fSGustavo F. Padovan BT_DBG("new socket %p", nsk); 1330*0a708f8fSGustavo F. Padovan 1331*0a708f8fSGustavo F. Padovan done: 1332*0a708f8fSGustavo F. Padovan release_sock(sk); 1333*0a708f8fSGustavo F. Padovan return err; 1334*0a708f8fSGustavo F. Padovan } 1335*0a708f8fSGustavo F. Padovan 1336*0a708f8fSGustavo F. Padovan static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer) 1337*0a708f8fSGustavo F. Padovan { 1338*0a708f8fSGustavo F. Padovan struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr; 1339*0a708f8fSGustavo F. Padovan struct sock *sk = sock->sk; 1340*0a708f8fSGustavo F. Padovan 1341*0a708f8fSGustavo F. Padovan BT_DBG("sock %p, sk %p", sock, sk); 1342*0a708f8fSGustavo F. Padovan 1343*0a708f8fSGustavo F. Padovan addr->sa_family = AF_BLUETOOTH; 1344*0a708f8fSGustavo F. Padovan *len = sizeof(struct sockaddr_l2); 1345*0a708f8fSGustavo F. Padovan 1346*0a708f8fSGustavo F. Padovan if (peer) { 1347*0a708f8fSGustavo F. Padovan la->l2_psm = l2cap_pi(sk)->psm; 1348*0a708f8fSGustavo F. Padovan bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst); 1349*0a708f8fSGustavo F. Padovan la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid); 1350*0a708f8fSGustavo F. Padovan } else { 1351*0a708f8fSGustavo F. Padovan la->l2_psm = l2cap_pi(sk)->sport; 1352*0a708f8fSGustavo F. Padovan bacpy(&la->l2_bdaddr, &bt_sk(sk)->src); 1353*0a708f8fSGustavo F. Padovan la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid); 1354*0a708f8fSGustavo F. Padovan } 1355*0a708f8fSGustavo F. Padovan 1356*0a708f8fSGustavo F. Padovan return 0; 1357*0a708f8fSGustavo F. Padovan } 1358*0a708f8fSGustavo F. Padovan 1359*0a708f8fSGustavo F. Padovan static int __l2cap_wait_ack(struct sock *sk) 1360*0a708f8fSGustavo F. Padovan { 1361*0a708f8fSGustavo F. Padovan DECLARE_WAITQUEUE(wait, current); 1362*0a708f8fSGustavo F. Padovan int err = 0; 1363*0a708f8fSGustavo F. Padovan int timeo = HZ/5; 1364*0a708f8fSGustavo F. Padovan 1365*0a708f8fSGustavo F. Padovan add_wait_queue(sk_sleep(sk), &wait); 1366*0a708f8fSGustavo F. Padovan while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) { 1367*0a708f8fSGustavo F. Padovan set_current_state(TASK_INTERRUPTIBLE); 1368*0a708f8fSGustavo F. Padovan 1369*0a708f8fSGustavo F. Padovan if (!timeo) 1370*0a708f8fSGustavo F. Padovan timeo = HZ/5; 1371*0a708f8fSGustavo F. Padovan 1372*0a708f8fSGustavo F. Padovan if (signal_pending(current)) { 1373*0a708f8fSGustavo F. Padovan err = sock_intr_errno(timeo); 1374*0a708f8fSGustavo F. Padovan break; 1375*0a708f8fSGustavo F. Padovan } 1376*0a708f8fSGustavo F. Padovan 1377*0a708f8fSGustavo F. Padovan release_sock(sk); 1378*0a708f8fSGustavo F. Padovan timeo = schedule_timeout(timeo); 1379*0a708f8fSGustavo F. Padovan lock_sock(sk); 1380*0a708f8fSGustavo F. Padovan 1381*0a708f8fSGustavo F. Padovan err = sock_error(sk); 1382*0a708f8fSGustavo F. Padovan if (err) 1383*0a708f8fSGustavo F. Padovan break; 1384*0a708f8fSGustavo F. Padovan } 1385*0a708f8fSGustavo F. Padovan set_current_state(TASK_RUNNING); 1386*0a708f8fSGustavo F. Padovan remove_wait_queue(sk_sleep(sk), &wait); 1387*0a708f8fSGustavo F. Padovan return err; 1388*0a708f8fSGustavo F. Padovan } 1389*0a708f8fSGustavo F. Padovan 1390*0a708f8fSGustavo F. Padovan static void l2cap_monitor_timeout(unsigned long arg) 1391*0a708f8fSGustavo F. Padovan { 1392*0a708f8fSGustavo F. Padovan struct sock *sk = (void *) arg; 1393*0a708f8fSGustavo F. Padovan 1394*0a708f8fSGustavo F. Padovan BT_DBG("sk %p", sk); 1395*0a708f8fSGustavo F. Padovan 1396*0a708f8fSGustavo F. Padovan bh_lock_sock(sk); 1397*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) { 1398*0a708f8fSGustavo F. Padovan l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED); 1399*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 1400*0a708f8fSGustavo F. Padovan return; 1401*0a708f8fSGustavo F. Padovan } 1402*0a708f8fSGustavo F. Padovan 1403*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->retry_count++; 1404*0a708f8fSGustavo F. Padovan __mod_monitor_timer(); 1405*0a708f8fSGustavo F. Padovan 1406*0a708f8fSGustavo F. Padovan l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL); 1407*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 1408*0a708f8fSGustavo F. Padovan } 1409*0a708f8fSGustavo F. Padovan 1410*0a708f8fSGustavo F. Padovan static void l2cap_retrans_timeout(unsigned long arg) 1411*0a708f8fSGustavo F. Padovan { 1412*0a708f8fSGustavo F. Padovan struct sock *sk = (void *) arg; 1413*0a708f8fSGustavo F. Padovan 1414*0a708f8fSGustavo F. Padovan BT_DBG("sk %p", sk); 1415*0a708f8fSGustavo F. Padovan 1416*0a708f8fSGustavo F. Padovan bh_lock_sock(sk); 1417*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->retry_count = 1; 1418*0a708f8fSGustavo F. Padovan __mod_monitor_timer(); 1419*0a708f8fSGustavo F. Padovan 1420*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F; 1421*0a708f8fSGustavo F. Padovan 1422*0a708f8fSGustavo F. Padovan l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL); 1423*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 1424*0a708f8fSGustavo F. Padovan } 1425*0a708f8fSGustavo F. Padovan 1426*0a708f8fSGustavo F. Padovan static void l2cap_drop_acked_frames(struct sock *sk) 1427*0a708f8fSGustavo F. Padovan { 1428*0a708f8fSGustavo F. Padovan struct sk_buff *skb; 1429*0a708f8fSGustavo F. Padovan 1430*0a708f8fSGustavo F. Padovan while ((skb = skb_peek(TX_QUEUE(sk))) && 1431*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->unacked_frames) { 1432*0a708f8fSGustavo F. Padovan if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq) 1433*0a708f8fSGustavo F. Padovan break; 1434*0a708f8fSGustavo F. Padovan 1435*0a708f8fSGustavo F. Padovan skb = skb_dequeue(TX_QUEUE(sk)); 1436*0a708f8fSGustavo F. Padovan kfree_skb(skb); 1437*0a708f8fSGustavo F. Padovan 1438*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->unacked_frames--; 1439*0a708f8fSGustavo F. Padovan } 1440*0a708f8fSGustavo F. Padovan 1441*0a708f8fSGustavo F. Padovan if (!l2cap_pi(sk)->unacked_frames) 1442*0a708f8fSGustavo F. Padovan del_timer(&l2cap_pi(sk)->retrans_timer); 1443*0a708f8fSGustavo F. Padovan } 1444*0a708f8fSGustavo F. Padovan 1445*0a708f8fSGustavo F. Padovan static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb) 1446*0a708f8fSGustavo F. Padovan { 1447*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 1448*0a708f8fSGustavo F. Padovan struct hci_conn *hcon = pi->conn->hcon; 1449*0a708f8fSGustavo F. Padovan u16 flags; 1450*0a708f8fSGustavo F. Padovan 1451*0a708f8fSGustavo F. Padovan BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len); 1452*0a708f8fSGustavo F. Padovan 1453*0a708f8fSGustavo F. Padovan if (!pi->flushable && lmp_no_flush_capable(hcon->hdev)) 1454*0a708f8fSGustavo F. Padovan flags = ACL_START_NO_FLUSH; 1455*0a708f8fSGustavo F. Padovan else 1456*0a708f8fSGustavo F. Padovan flags = ACL_START; 1457*0a708f8fSGustavo F. Padovan 1458*0a708f8fSGustavo F. Padovan hci_send_acl(hcon, skb, flags); 1459*0a708f8fSGustavo F. Padovan } 1460*0a708f8fSGustavo F. Padovan 1461*0a708f8fSGustavo F. Padovan static void l2cap_streaming_send(struct sock *sk) 1462*0a708f8fSGustavo F. Padovan { 1463*0a708f8fSGustavo F. Padovan struct sk_buff *skb; 1464*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 1465*0a708f8fSGustavo F. Padovan u16 control, fcs; 1466*0a708f8fSGustavo F. Padovan 1467*0a708f8fSGustavo F. Padovan while ((skb = skb_dequeue(TX_QUEUE(sk)))) { 1468*0a708f8fSGustavo F. Padovan control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE); 1469*0a708f8fSGustavo F. Padovan control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; 1470*0a708f8fSGustavo F. Padovan put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE); 1471*0a708f8fSGustavo F. Padovan 1472*0a708f8fSGustavo F. Padovan if (pi->fcs == L2CAP_FCS_CRC16) { 1473*0a708f8fSGustavo F. Padovan fcs = crc16(0, (u8 *)skb->data, skb->len - 2); 1474*0a708f8fSGustavo F. Padovan put_unaligned_le16(fcs, skb->data + skb->len - 2); 1475*0a708f8fSGustavo F. Padovan } 1476*0a708f8fSGustavo F. Padovan 1477*0a708f8fSGustavo F. Padovan l2cap_do_send(sk, skb); 1478*0a708f8fSGustavo F. Padovan 1479*0a708f8fSGustavo F. Padovan pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; 1480*0a708f8fSGustavo F. Padovan } 1481*0a708f8fSGustavo F. Padovan } 1482*0a708f8fSGustavo F. Padovan 1483*0a708f8fSGustavo F. Padovan static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq) 1484*0a708f8fSGustavo F. Padovan { 1485*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 1486*0a708f8fSGustavo F. Padovan struct sk_buff *skb, *tx_skb; 1487*0a708f8fSGustavo F. Padovan u16 control, fcs; 1488*0a708f8fSGustavo F. Padovan 1489*0a708f8fSGustavo F. Padovan skb = skb_peek(TX_QUEUE(sk)); 1490*0a708f8fSGustavo F. Padovan if (!skb) 1491*0a708f8fSGustavo F. Padovan return; 1492*0a708f8fSGustavo F. Padovan 1493*0a708f8fSGustavo F. Padovan do { 1494*0a708f8fSGustavo F. Padovan if (bt_cb(skb)->tx_seq == tx_seq) 1495*0a708f8fSGustavo F. Padovan break; 1496*0a708f8fSGustavo F. Padovan 1497*0a708f8fSGustavo F. Padovan if (skb_queue_is_last(TX_QUEUE(sk), skb)) 1498*0a708f8fSGustavo F. Padovan return; 1499*0a708f8fSGustavo F. Padovan 1500*0a708f8fSGustavo F. Padovan } while ((skb = skb_queue_next(TX_QUEUE(sk), skb))); 1501*0a708f8fSGustavo F. Padovan 1502*0a708f8fSGustavo F. Padovan if (pi->remote_max_tx && 1503*0a708f8fSGustavo F. Padovan bt_cb(skb)->retries == pi->remote_max_tx) { 1504*0a708f8fSGustavo F. Padovan l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED); 1505*0a708f8fSGustavo F. Padovan return; 1506*0a708f8fSGustavo F. Padovan } 1507*0a708f8fSGustavo F. Padovan 1508*0a708f8fSGustavo F. Padovan tx_skb = skb_clone(skb, GFP_ATOMIC); 1509*0a708f8fSGustavo F. Padovan bt_cb(skb)->retries++; 1510*0a708f8fSGustavo F. Padovan control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); 1511*0a708f8fSGustavo F. Padovan 1512*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_SEND_FBIT) { 1513*0a708f8fSGustavo F. Padovan control |= L2CAP_CTRL_FINAL; 1514*0a708f8fSGustavo F. Padovan pi->conn_state &= ~L2CAP_CONN_SEND_FBIT; 1515*0a708f8fSGustavo F. Padovan } 1516*0a708f8fSGustavo F. Padovan 1517*0a708f8fSGustavo F. Padovan control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) 1518*0a708f8fSGustavo F. Padovan | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); 1519*0a708f8fSGustavo F. Padovan 1520*0a708f8fSGustavo F. Padovan put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); 1521*0a708f8fSGustavo F. Padovan 1522*0a708f8fSGustavo F. Padovan if (pi->fcs == L2CAP_FCS_CRC16) { 1523*0a708f8fSGustavo F. Padovan fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2); 1524*0a708f8fSGustavo F. Padovan put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2); 1525*0a708f8fSGustavo F. Padovan } 1526*0a708f8fSGustavo F. Padovan 1527*0a708f8fSGustavo F. Padovan l2cap_do_send(sk, tx_skb); 1528*0a708f8fSGustavo F. Padovan } 1529*0a708f8fSGustavo F. Padovan 1530*0a708f8fSGustavo F. Padovan static int l2cap_ertm_send(struct sock *sk) 1531*0a708f8fSGustavo F. Padovan { 1532*0a708f8fSGustavo F. Padovan struct sk_buff *skb, *tx_skb; 1533*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 1534*0a708f8fSGustavo F. Padovan u16 control, fcs; 1535*0a708f8fSGustavo F. Padovan int nsent = 0; 1536*0a708f8fSGustavo F. Padovan 1537*0a708f8fSGustavo F. Padovan if (sk->sk_state != BT_CONNECTED) 1538*0a708f8fSGustavo F. Padovan return -ENOTCONN; 1539*0a708f8fSGustavo F. Padovan 1540*0a708f8fSGustavo F. Padovan while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) { 1541*0a708f8fSGustavo F. Padovan 1542*0a708f8fSGustavo F. Padovan if (pi->remote_max_tx && 1543*0a708f8fSGustavo F. Padovan bt_cb(skb)->retries == pi->remote_max_tx) { 1544*0a708f8fSGustavo F. Padovan l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED); 1545*0a708f8fSGustavo F. Padovan break; 1546*0a708f8fSGustavo F. Padovan } 1547*0a708f8fSGustavo F. Padovan 1548*0a708f8fSGustavo F. Padovan tx_skb = skb_clone(skb, GFP_ATOMIC); 1549*0a708f8fSGustavo F. Padovan 1550*0a708f8fSGustavo F. Padovan bt_cb(skb)->retries++; 1551*0a708f8fSGustavo F. Padovan 1552*0a708f8fSGustavo F. Padovan control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); 1553*0a708f8fSGustavo F. Padovan control &= L2CAP_CTRL_SAR; 1554*0a708f8fSGustavo F. Padovan 1555*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_SEND_FBIT) { 1556*0a708f8fSGustavo F. Padovan control |= L2CAP_CTRL_FINAL; 1557*0a708f8fSGustavo F. Padovan pi->conn_state &= ~L2CAP_CONN_SEND_FBIT; 1558*0a708f8fSGustavo F. Padovan } 1559*0a708f8fSGustavo F. Padovan control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) 1560*0a708f8fSGustavo F. Padovan | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); 1561*0a708f8fSGustavo F. Padovan put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); 1562*0a708f8fSGustavo F. Padovan 1563*0a708f8fSGustavo F. Padovan 1564*0a708f8fSGustavo F. Padovan if (pi->fcs == L2CAP_FCS_CRC16) { 1565*0a708f8fSGustavo F. Padovan fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2); 1566*0a708f8fSGustavo F. Padovan put_unaligned_le16(fcs, skb->data + tx_skb->len - 2); 1567*0a708f8fSGustavo F. Padovan } 1568*0a708f8fSGustavo F. Padovan 1569*0a708f8fSGustavo F. Padovan l2cap_do_send(sk, tx_skb); 1570*0a708f8fSGustavo F. Padovan 1571*0a708f8fSGustavo F. Padovan __mod_retrans_timer(); 1572*0a708f8fSGustavo F. Padovan 1573*0a708f8fSGustavo F. Padovan bt_cb(skb)->tx_seq = pi->next_tx_seq; 1574*0a708f8fSGustavo F. Padovan pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; 1575*0a708f8fSGustavo F. Padovan 1576*0a708f8fSGustavo F. Padovan pi->unacked_frames++; 1577*0a708f8fSGustavo F. Padovan pi->frames_sent++; 1578*0a708f8fSGustavo F. Padovan 1579*0a708f8fSGustavo F. Padovan if (skb_queue_is_last(TX_QUEUE(sk), skb)) 1580*0a708f8fSGustavo F. Padovan sk->sk_send_head = NULL; 1581*0a708f8fSGustavo F. Padovan else 1582*0a708f8fSGustavo F. Padovan sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb); 1583*0a708f8fSGustavo F. Padovan 1584*0a708f8fSGustavo F. Padovan nsent++; 1585*0a708f8fSGustavo F. Padovan } 1586*0a708f8fSGustavo F. Padovan 1587*0a708f8fSGustavo F. Padovan return nsent; 1588*0a708f8fSGustavo F. Padovan } 1589*0a708f8fSGustavo F. Padovan 1590*0a708f8fSGustavo F. Padovan static int l2cap_retransmit_frames(struct sock *sk) 1591*0a708f8fSGustavo F. Padovan { 1592*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 1593*0a708f8fSGustavo F. Padovan int ret; 1594*0a708f8fSGustavo F. Padovan 1595*0a708f8fSGustavo F. Padovan if (!skb_queue_empty(TX_QUEUE(sk))) 1596*0a708f8fSGustavo F. Padovan sk->sk_send_head = TX_QUEUE(sk)->next; 1597*0a708f8fSGustavo F. Padovan 1598*0a708f8fSGustavo F. Padovan pi->next_tx_seq = pi->expected_ack_seq; 1599*0a708f8fSGustavo F. Padovan ret = l2cap_ertm_send(sk); 1600*0a708f8fSGustavo F. Padovan return ret; 1601*0a708f8fSGustavo F. Padovan } 1602*0a708f8fSGustavo F. Padovan 1603*0a708f8fSGustavo F. Padovan static void l2cap_send_ack(struct l2cap_pinfo *pi) 1604*0a708f8fSGustavo F. Padovan { 1605*0a708f8fSGustavo F. Padovan struct sock *sk = (struct sock *)pi; 1606*0a708f8fSGustavo F. Padovan u16 control = 0; 1607*0a708f8fSGustavo F. Padovan 1608*0a708f8fSGustavo F. Padovan control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; 1609*0a708f8fSGustavo F. Padovan 1610*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) { 1611*0a708f8fSGustavo F. Padovan control |= L2CAP_SUPER_RCV_NOT_READY; 1612*0a708f8fSGustavo F. Padovan pi->conn_state |= L2CAP_CONN_RNR_SENT; 1613*0a708f8fSGustavo F. Padovan l2cap_send_sframe(pi, control); 1614*0a708f8fSGustavo F. Padovan return; 1615*0a708f8fSGustavo F. Padovan } 1616*0a708f8fSGustavo F. Padovan 1617*0a708f8fSGustavo F. Padovan if (l2cap_ertm_send(sk) > 0) 1618*0a708f8fSGustavo F. Padovan return; 1619*0a708f8fSGustavo F. Padovan 1620*0a708f8fSGustavo F. Padovan control |= L2CAP_SUPER_RCV_READY; 1621*0a708f8fSGustavo F. Padovan l2cap_send_sframe(pi, control); 1622*0a708f8fSGustavo F. Padovan } 1623*0a708f8fSGustavo F. Padovan 1624*0a708f8fSGustavo F. Padovan static void l2cap_send_srejtail(struct sock *sk) 1625*0a708f8fSGustavo F. Padovan { 1626*0a708f8fSGustavo F. Padovan struct srej_list *tail; 1627*0a708f8fSGustavo F. Padovan u16 control; 1628*0a708f8fSGustavo F. Padovan 1629*0a708f8fSGustavo F. Padovan control = L2CAP_SUPER_SELECT_REJECT; 1630*0a708f8fSGustavo F. Padovan control |= L2CAP_CTRL_FINAL; 1631*0a708f8fSGustavo F. Padovan 1632*0a708f8fSGustavo F. Padovan tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list); 1633*0a708f8fSGustavo F. Padovan control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; 1634*0a708f8fSGustavo F. Padovan 1635*0a708f8fSGustavo F. Padovan l2cap_send_sframe(l2cap_pi(sk), control); 1636*0a708f8fSGustavo F. Padovan } 1637*0a708f8fSGustavo F. Padovan 1638*0a708f8fSGustavo F. Padovan static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, int len, int count, struct sk_buff *skb) 1639*0a708f8fSGustavo F. Padovan { 1640*0a708f8fSGustavo F. Padovan struct l2cap_conn *conn = l2cap_pi(sk)->conn; 1641*0a708f8fSGustavo F. Padovan struct sk_buff **frag; 1642*0a708f8fSGustavo F. Padovan int err, sent = 0; 1643*0a708f8fSGustavo F. Padovan 1644*0a708f8fSGustavo F. Padovan if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) 1645*0a708f8fSGustavo F. Padovan return -EFAULT; 1646*0a708f8fSGustavo F. Padovan 1647*0a708f8fSGustavo F. Padovan sent += count; 1648*0a708f8fSGustavo F. Padovan len -= count; 1649*0a708f8fSGustavo F. Padovan 1650*0a708f8fSGustavo F. Padovan /* Continuation fragments (no L2CAP header) */ 1651*0a708f8fSGustavo F. Padovan frag = &skb_shinfo(skb)->frag_list; 1652*0a708f8fSGustavo F. Padovan while (len) { 1653*0a708f8fSGustavo F. Padovan count = min_t(unsigned int, conn->mtu, len); 1654*0a708f8fSGustavo F. Padovan 1655*0a708f8fSGustavo F. Padovan *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err); 1656*0a708f8fSGustavo F. Padovan if (!*frag) 1657*0a708f8fSGustavo F. Padovan return err; 1658*0a708f8fSGustavo F. Padovan if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) 1659*0a708f8fSGustavo F. Padovan return -EFAULT; 1660*0a708f8fSGustavo F. Padovan 1661*0a708f8fSGustavo F. Padovan sent += count; 1662*0a708f8fSGustavo F. Padovan len -= count; 1663*0a708f8fSGustavo F. Padovan 1664*0a708f8fSGustavo F. Padovan frag = &(*frag)->next; 1665*0a708f8fSGustavo F. Padovan } 1666*0a708f8fSGustavo F. Padovan 1667*0a708f8fSGustavo F. Padovan return sent; 1668*0a708f8fSGustavo F. Padovan } 1669*0a708f8fSGustavo F. Padovan 1670*0a708f8fSGustavo F. Padovan static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len) 1671*0a708f8fSGustavo F. Padovan { 1672*0a708f8fSGustavo F. Padovan struct l2cap_conn *conn = l2cap_pi(sk)->conn; 1673*0a708f8fSGustavo F. Padovan struct sk_buff *skb; 1674*0a708f8fSGustavo F. Padovan int err, count, hlen = L2CAP_HDR_SIZE + 2; 1675*0a708f8fSGustavo F. Padovan struct l2cap_hdr *lh; 1676*0a708f8fSGustavo F. Padovan 1677*0a708f8fSGustavo F. Padovan BT_DBG("sk %p len %d", sk, (int)len); 1678*0a708f8fSGustavo F. Padovan 1679*0a708f8fSGustavo F. Padovan count = min_t(unsigned int, (conn->mtu - hlen), len); 1680*0a708f8fSGustavo F. Padovan skb = bt_skb_send_alloc(sk, count + hlen, 1681*0a708f8fSGustavo F. Padovan msg->msg_flags & MSG_DONTWAIT, &err); 1682*0a708f8fSGustavo F. Padovan if (!skb) 1683*0a708f8fSGustavo F. Padovan return ERR_PTR(err); 1684*0a708f8fSGustavo F. Padovan 1685*0a708f8fSGustavo F. Padovan /* Create L2CAP header */ 1686*0a708f8fSGustavo F. Padovan lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); 1687*0a708f8fSGustavo F. Padovan lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid); 1688*0a708f8fSGustavo F. Padovan lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE)); 1689*0a708f8fSGustavo F. Padovan put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2)); 1690*0a708f8fSGustavo F. Padovan 1691*0a708f8fSGustavo F. Padovan err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb); 1692*0a708f8fSGustavo F. Padovan if (unlikely(err < 0)) { 1693*0a708f8fSGustavo F. Padovan kfree_skb(skb); 1694*0a708f8fSGustavo F. Padovan return ERR_PTR(err); 1695*0a708f8fSGustavo F. Padovan } 1696*0a708f8fSGustavo F. Padovan return skb; 1697*0a708f8fSGustavo F. Padovan } 1698*0a708f8fSGustavo F. Padovan 1699*0a708f8fSGustavo F. Padovan static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len) 1700*0a708f8fSGustavo F. Padovan { 1701*0a708f8fSGustavo F. Padovan struct l2cap_conn *conn = l2cap_pi(sk)->conn; 1702*0a708f8fSGustavo F. Padovan struct sk_buff *skb; 1703*0a708f8fSGustavo F. Padovan int err, count, hlen = L2CAP_HDR_SIZE; 1704*0a708f8fSGustavo F. Padovan struct l2cap_hdr *lh; 1705*0a708f8fSGustavo F. Padovan 1706*0a708f8fSGustavo F. Padovan BT_DBG("sk %p len %d", sk, (int)len); 1707*0a708f8fSGustavo F. Padovan 1708*0a708f8fSGustavo F. Padovan count = min_t(unsigned int, (conn->mtu - hlen), len); 1709*0a708f8fSGustavo F. Padovan skb = bt_skb_send_alloc(sk, count + hlen, 1710*0a708f8fSGustavo F. Padovan msg->msg_flags & MSG_DONTWAIT, &err); 1711*0a708f8fSGustavo F. Padovan if (!skb) 1712*0a708f8fSGustavo F. Padovan return ERR_PTR(err); 1713*0a708f8fSGustavo F. Padovan 1714*0a708f8fSGustavo F. Padovan /* Create L2CAP header */ 1715*0a708f8fSGustavo F. Padovan lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); 1716*0a708f8fSGustavo F. Padovan lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid); 1717*0a708f8fSGustavo F. Padovan lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE)); 1718*0a708f8fSGustavo F. Padovan 1719*0a708f8fSGustavo F. Padovan err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb); 1720*0a708f8fSGustavo F. Padovan if (unlikely(err < 0)) { 1721*0a708f8fSGustavo F. Padovan kfree_skb(skb); 1722*0a708f8fSGustavo F. Padovan return ERR_PTR(err); 1723*0a708f8fSGustavo F. Padovan } 1724*0a708f8fSGustavo F. Padovan return skb; 1725*0a708f8fSGustavo F. Padovan } 1726*0a708f8fSGustavo F. Padovan 1727*0a708f8fSGustavo F. Padovan static struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen) 1728*0a708f8fSGustavo F. Padovan { 1729*0a708f8fSGustavo F. Padovan struct l2cap_conn *conn = l2cap_pi(sk)->conn; 1730*0a708f8fSGustavo F. Padovan struct sk_buff *skb; 1731*0a708f8fSGustavo F. Padovan int err, count, hlen = L2CAP_HDR_SIZE + 2; 1732*0a708f8fSGustavo F. Padovan struct l2cap_hdr *lh; 1733*0a708f8fSGustavo F. Padovan 1734*0a708f8fSGustavo F. Padovan BT_DBG("sk %p len %d", sk, (int)len); 1735*0a708f8fSGustavo F. Padovan 1736*0a708f8fSGustavo F. Padovan if (!conn) 1737*0a708f8fSGustavo F. Padovan return ERR_PTR(-ENOTCONN); 1738*0a708f8fSGustavo F. Padovan 1739*0a708f8fSGustavo F. Padovan if (sdulen) 1740*0a708f8fSGustavo F. Padovan hlen += 2; 1741*0a708f8fSGustavo F. Padovan 1742*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) 1743*0a708f8fSGustavo F. Padovan hlen += 2; 1744*0a708f8fSGustavo F. Padovan 1745*0a708f8fSGustavo F. Padovan count = min_t(unsigned int, (conn->mtu - hlen), len); 1746*0a708f8fSGustavo F. Padovan skb = bt_skb_send_alloc(sk, count + hlen, 1747*0a708f8fSGustavo F. Padovan msg->msg_flags & MSG_DONTWAIT, &err); 1748*0a708f8fSGustavo F. Padovan if (!skb) 1749*0a708f8fSGustavo F. Padovan return ERR_PTR(err); 1750*0a708f8fSGustavo F. Padovan 1751*0a708f8fSGustavo F. Padovan /* Create L2CAP header */ 1752*0a708f8fSGustavo F. Padovan lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); 1753*0a708f8fSGustavo F. Padovan lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid); 1754*0a708f8fSGustavo F. Padovan lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE)); 1755*0a708f8fSGustavo F. Padovan put_unaligned_le16(control, skb_put(skb, 2)); 1756*0a708f8fSGustavo F. Padovan if (sdulen) 1757*0a708f8fSGustavo F. Padovan put_unaligned_le16(sdulen, skb_put(skb, 2)); 1758*0a708f8fSGustavo F. Padovan 1759*0a708f8fSGustavo F. Padovan err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb); 1760*0a708f8fSGustavo F. Padovan if (unlikely(err < 0)) { 1761*0a708f8fSGustavo F. Padovan kfree_skb(skb); 1762*0a708f8fSGustavo F. Padovan return ERR_PTR(err); 1763*0a708f8fSGustavo F. Padovan } 1764*0a708f8fSGustavo F. Padovan 1765*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) 1766*0a708f8fSGustavo F. Padovan put_unaligned_le16(0, skb_put(skb, 2)); 1767*0a708f8fSGustavo F. Padovan 1768*0a708f8fSGustavo F. Padovan bt_cb(skb)->retries = 0; 1769*0a708f8fSGustavo F. Padovan return skb; 1770*0a708f8fSGustavo F. Padovan } 1771*0a708f8fSGustavo F. Padovan 1772*0a708f8fSGustavo F. Padovan static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len) 1773*0a708f8fSGustavo F. Padovan { 1774*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 1775*0a708f8fSGustavo F. Padovan struct sk_buff *skb; 1776*0a708f8fSGustavo F. Padovan struct sk_buff_head sar_queue; 1777*0a708f8fSGustavo F. Padovan u16 control; 1778*0a708f8fSGustavo F. Padovan size_t size = 0; 1779*0a708f8fSGustavo F. Padovan 1780*0a708f8fSGustavo F. Padovan skb_queue_head_init(&sar_queue); 1781*0a708f8fSGustavo F. Padovan control = L2CAP_SDU_START; 1782*0a708f8fSGustavo F. Padovan skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len); 1783*0a708f8fSGustavo F. Padovan if (IS_ERR(skb)) 1784*0a708f8fSGustavo F. Padovan return PTR_ERR(skb); 1785*0a708f8fSGustavo F. Padovan 1786*0a708f8fSGustavo F. Padovan __skb_queue_tail(&sar_queue, skb); 1787*0a708f8fSGustavo F. Padovan len -= pi->remote_mps; 1788*0a708f8fSGustavo F. Padovan size += pi->remote_mps; 1789*0a708f8fSGustavo F. Padovan 1790*0a708f8fSGustavo F. Padovan while (len > 0) { 1791*0a708f8fSGustavo F. Padovan size_t buflen; 1792*0a708f8fSGustavo F. Padovan 1793*0a708f8fSGustavo F. Padovan if (len > pi->remote_mps) { 1794*0a708f8fSGustavo F. Padovan control = L2CAP_SDU_CONTINUE; 1795*0a708f8fSGustavo F. Padovan buflen = pi->remote_mps; 1796*0a708f8fSGustavo F. Padovan } else { 1797*0a708f8fSGustavo F. Padovan control = L2CAP_SDU_END; 1798*0a708f8fSGustavo F. Padovan buflen = len; 1799*0a708f8fSGustavo F. Padovan } 1800*0a708f8fSGustavo F. Padovan 1801*0a708f8fSGustavo F. Padovan skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0); 1802*0a708f8fSGustavo F. Padovan if (IS_ERR(skb)) { 1803*0a708f8fSGustavo F. Padovan skb_queue_purge(&sar_queue); 1804*0a708f8fSGustavo F. Padovan return PTR_ERR(skb); 1805*0a708f8fSGustavo F. Padovan } 1806*0a708f8fSGustavo F. Padovan 1807*0a708f8fSGustavo F. Padovan __skb_queue_tail(&sar_queue, skb); 1808*0a708f8fSGustavo F. Padovan len -= buflen; 1809*0a708f8fSGustavo F. Padovan size += buflen; 1810*0a708f8fSGustavo F. Padovan } 1811*0a708f8fSGustavo F. Padovan skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk)); 1812*0a708f8fSGustavo F. Padovan if (sk->sk_send_head == NULL) 1813*0a708f8fSGustavo F. Padovan sk->sk_send_head = sar_queue.next; 1814*0a708f8fSGustavo F. Padovan 1815*0a708f8fSGustavo F. Padovan return size; 1816*0a708f8fSGustavo F. Padovan } 1817*0a708f8fSGustavo F. Padovan 1818*0a708f8fSGustavo F. Padovan static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len) 1819*0a708f8fSGustavo F. Padovan { 1820*0a708f8fSGustavo F. Padovan struct sock *sk = sock->sk; 1821*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 1822*0a708f8fSGustavo F. Padovan struct sk_buff *skb; 1823*0a708f8fSGustavo F. Padovan u16 control; 1824*0a708f8fSGustavo F. Padovan int err; 1825*0a708f8fSGustavo F. Padovan 1826*0a708f8fSGustavo F. Padovan BT_DBG("sock %p, sk %p", sock, sk); 1827*0a708f8fSGustavo F. Padovan 1828*0a708f8fSGustavo F. Padovan err = sock_error(sk); 1829*0a708f8fSGustavo F. Padovan if (err) 1830*0a708f8fSGustavo F. Padovan return err; 1831*0a708f8fSGustavo F. Padovan 1832*0a708f8fSGustavo F. Padovan if (msg->msg_flags & MSG_OOB) 1833*0a708f8fSGustavo F. Padovan return -EOPNOTSUPP; 1834*0a708f8fSGustavo F. Padovan 1835*0a708f8fSGustavo F. Padovan lock_sock(sk); 1836*0a708f8fSGustavo F. Padovan 1837*0a708f8fSGustavo F. Padovan if (sk->sk_state != BT_CONNECTED) { 1838*0a708f8fSGustavo F. Padovan err = -ENOTCONN; 1839*0a708f8fSGustavo F. Padovan goto done; 1840*0a708f8fSGustavo F. Padovan } 1841*0a708f8fSGustavo F. Padovan 1842*0a708f8fSGustavo F. Padovan /* Connectionless channel */ 1843*0a708f8fSGustavo F. Padovan if (sk->sk_type == SOCK_DGRAM) { 1844*0a708f8fSGustavo F. Padovan skb = l2cap_create_connless_pdu(sk, msg, len); 1845*0a708f8fSGustavo F. Padovan if (IS_ERR(skb)) { 1846*0a708f8fSGustavo F. Padovan err = PTR_ERR(skb); 1847*0a708f8fSGustavo F. Padovan } else { 1848*0a708f8fSGustavo F. Padovan l2cap_do_send(sk, skb); 1849*0a708f8fSGustavo F. Padovan err = len; 1850*0a708f8fSGustavo F. Padovan } 1851*0a708f8fSGustavo F. Padovan goto done; 1852*0a708f8fSGustavo F. Padovan } 1853*0a708f8fSGustavo F. Padovan 1854*0a708f8fSGustavo F. Padovan switch (pi->mode) { 1855*0a708f8fSGustavo F. Padovan case L2CAP_MODE_BASIC: 1856*0a708f8fSGustavo F. Padovan /* Check outgoing MTU */ 1857*0a708f8fSGustavo F. Padovan if (len > pi->omtu) { 1858*0a708f8fSGustavo F. Padovan err = -EMSGSIZE; 1859*0a708f8fSGustavo F. Padovan goto done; 1860*0a708f8fSGustavo F. Padovan } 1861*0a708f8fSGustavo F. Padovan 1862*0a708f8fSGustavo F. Padovan /* Create a basic PDU */ 1863*0a708f8fSGustavo F. Padovan skb = l2cap_create_basic_pdu(sk, msg, len); 1864*0a708f8fSGustavo F. Padovan if (IS_ERR(skb)) { 1865*0a708f8fSGustavo F. Padovan err = PTR_ERR(skb); 1866*0a708f8fSGustavo F. Padovan goto done; 1867*0a708f8fSGustavo F. Padovan } 1868*0a708f8fSGustavo F. Padovan 1869*0a708f8fSGustavo F. Padovan l2cap_do_send(sk, skb); 1870*0a708f8fSGustavo F. Padovan err = len; 1871*0a708f8fSGustavo F. Padovan break; 1872*0a708f8fSGustavo F. Padovan 1873*0a708f8fSGustavo F. Padovan case L2CAP_MODE_ERTM: 1874*0a708f8fSGustavo F. Padovan case L2CAP_MODE_STREAMING: 1875*0a708f8fSGustavo F. Padovan /* Entire SDU fits into one PDU */ 1876*0a708f8fSGustavo F. Padovan if (len <= pi->remote_mps) { 1877*0a708f8fSGustavo F. Padovan control = L2CAP_SDU_UNSEGMENTED; 1878*0a708f8fSGustavo F. Padovan skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0); 1879*0a708f8fSGustavo F. Padovan if (IS_ERR(skb)) { 1880*0a708f8fSGustavo F. Padovan err = PTR_ERR(skb); 1881*0a708f8fSGustavo F. Padovan goto done; 1882*0a708f8fSGustavo F. Padovan } 1883*0a708f8fSGustavo F. Padovan __skb_queue_tail(TX_QUEUE(sk), skb); 1884*0a708f8fSGustavo F. Padovan 1885*0a708f8fSGustavo F. Padovan if (sk->sk_send_head == NULL) 1886*0a708f8fSGustavo F. Padovan sk->sk_send_head = skb; 1887*0a708f8fSGustavo F. Padovan 1888*0a708f8fSGustavo F. Padovan } else { 1889*0a708f8fSGustavo F. Padovan /* Segment SDU into multiples PDUs */ 1890*0a708f8fSGustavo F. Padovan err = l2cap_sar_segment_sdu(sk, msg, len); 1891*0a708f8fSGustavo F. Padovan if (err < 0) 1892*0a708f8fSGustavo F. Padovan goto done; 1893*0a708f8fSGustavo F. Padovan } 1894*0a708f8fSGustavo F. Padovan 1895*0a708f8fSGustavo F. Padovan if (pi->mode == L2CAP_MODE_STREAMING) { 1896*0a708f8fSGustavo F. Padovan l2cap_streaming_send(sk); 1897*0a708f8fSGustavo F. Padovan } else { 1898*0a708f8fSGustavo F. Padovan if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) && 1899*0a708f8fSGustavo F. Padovan (pi->conn_state & L2CAP_CONN_WAIT_F)) { 1900*0a708f8fSGustavo F. Padovan err = len; 1901*0a708f8fSGustavo F. Padovan break; 1902*0a708f8fSGustavo F. Padovan } 1903*0a708f8fSGustavo F. Padovan err = l2cap_ertm_send(sk); 1904*0a708f8fSGustavo F. Padovan } 1905*0a708f8fSGustavo F. Padovan 1906*0a708f8fSGustavo F. Padovan if (err >= 0) 1907*0a708f8fSGustavo F. Padovan err = len; 1908*0a708f8fSGustavo F. Padovan break; 1909*0a708f8fSGustavo F. Padovan 1910*0a708f8fSGustavo F. Padovan default: 1911*0a708f8fSGustavo F. Padovan BT_DBG("bad state %1.1x", pi->mode); 1912*0a708f8fSGustavo F. Padovan err = -EBADFD; 1913*0a708f8fSGustavo F. Padovan } 1914*0a708f8fSGustavo F. Padovan 1915*0a708f8fSGustavo F. Padovan done: 1916*0a708f8fSGustavo F. Padovan release_sock(sk); 1917*0a708f8fSGustavo F. Padovan return err; 1918*0a708f8fSGustavo F. Padovan } 1919*0a708f8fSGustavo F. Padovan 1920*0a708f8fSGustavo F. Padovan static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags) 1921*0a708f8fSGustavo F. Padovan { 1922*0a708f8fSGustavo F. Padovan struct sock *sk = sock->sk; 1923*0a708f8fSGustavo F. Padovan 1924*0a708f8fSGustavo F. Padovan lock_sock(sk); 1925*0a708f8fSGustavo F. Padovan 1926*0a708f8fSGustavo F. Padovan if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) { 1927*0a708f8fSGustavo F. Padovan struct l2cap_conn_rsp rsp; 1928*0a708f8fSGustavo F. Padovan struct l2cap_conn *conn = l2cap_pi(sk)->conn; 1929*0a708f8fSGustavo F. Padovan u8 buf[128]; 1930*0a708f8fSGustavo F. Padovan 1931*0a708f8fSGustavo F. Padovan sk->sk_state = BT_CONFIG; 1932*0a708f8fSGustavo F. Padovan 1933*0a708f8fSGustavo F. Padovan rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); 1934*0a708f8fSGustavo F. Padovan rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); 1935*0a708f8fSGustavo F. Padovan rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); 1936*0a708f8fSGustavo F. Padovan rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); 1937*0a708f8fSGustavo F. Padovan l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident, 1938*0a708f8fSGustavo F. Padovan L2CAP_CONN_RSP, sizeof(rsp), &rsp); 1939*0a708f8fSGustavo F. Padovan 1940*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) { 1941*0a708f8fSGustavo F. Padovan release_sock(sk); 1942*0a708f8fSGustavo F. Padovan return 0; 1943*0a708f8fSGustavo F. Padovan } 1944*0a708f8fSGustavo F. Padovan 1945*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; 1946*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, 1947*0a708f8fSGustavo F. Padovan l2cap_build_conf_req(sk, buf), buf); 1948*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->num_conf_req++; 1949*0a708f8fSGustavo F. Padovan 1950*0a708f8fSGustavo F. Padovan release_sock(sk); 1951*0a708f8fSGustavo F. Padovan return 0; 1952*0a708f8fSGustavo F. Padovan } 1953*0a708f8fSGustavo F. Padovan 1954*0a708f8fSGustavo F. Padovan release_sock(sk); 1955*0a708f8fSGustavo F. Padovan 1956*0a708f8fSGustavo F. Padovan if (sock->type == SOCK_STREAM) 1957*0a708f8fSGustavo F. Padovan return bt_sock_stream_recvmsg(iocb, sock, msg, len, flags); 1958*0a708f8fSGustavo F. Padovan 1959*0a708f8fSGustavo F. Padovan return bt_sock_recvmsg(iocb, sock, msg, len, flags); 1960*0a708f8fSGustavo F. Padovan } 1961*0a708f8fSGustavo F. Padovan 1962*0a708f8fSGustavo F. Padovan static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen) 1963*0a708f8fSGustavo F. Padovan { 1964*0a708f8fSGustavo F. Padovan struct sock *sk = sock->sk; 1965*0a708f8fSGustavo F. Padovan struct l2cap_options opts; 1966*0a708f8fSGustavo F. Padovan int len, err = 0; 1967*0a708f8fSGustavo F. Padovan u32 opt; 1968*0a708f8fSGustavo F. Padovan 1969*0a708f8fSGustavo F. Padovan BT_DBG("sk %p", sk); 1970*0a708f8fSGustavo F. Padovan 1971*0a708f8fSGustavo F. Padovan lock_sock(sk); 1972*0a708f8fSGustavo F. Padovan 1973*0a708f8fSGustavo F. Padovan switch (optname) { 1974*0a708f8fSGustavo F. Padovan case L2CAP_OPTIONS: 1975*0a708f8fSGustavo F. Padovan if (sk->sk_state == BT_CONNECTED) { 1976*0a708f8fSGustavo F. Padovan err = -EINVAL; 1977*0a708f8fSGustavo F. Padovan break; 1978*0a708f8fSGustavo F. Padovan } 1979*0a708f8fSGustavo F. Padovan 1980*0a708f8fSGustavo F. Padovan opts.imtu = l2cap_pi(sk)->imtu; 1981*0a708f8fSGustavo F. Padovan opts.omtu = l2cap_pi(sk)->omtu; 1982*0a708f8fSGustavo F. Padovan opts.flush_to = l2cap_pi(sk)->flush_to; 1983*0a708f8fSGustavo F. Padovan opts.mode = l2cap_pi(sk)->mode; 1984*0a708f8fSGustavo F. Padovan opts.fcs = l2cap_pi(sk)->fcs; 1985*0a708f8fSGustavo F. Padovan opts.max_tx = l2cap_pi(sk)->max_tx; 1986*0a708f8fSGustavo F. Padovan opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win; 1987*0a708f8fSGustavo F. Padovan 1988*0a708f8fSGustavo F. Padovan len = min_t(unsigned int, sizeof(opts), optlen); 1989*0a708f8fSGustavo F. Padovan if (copy_from_user((char *) &opts, optval, len)) { 1990*0a708f8fSGustavo F. Padovan err = -EFAULT; 1991*0a708f8fSGustavo F. Padovan break; 1992*0a708f8fSGustavo F. Padovan } 1993*0a708f8fSGustavo F. Padovan 1994*0a708f8fSGustavo F. Padovan if (opts.txwin_size > L2CAP_DEFAULT_TX_WINDOW) { 1995*0a708f8fSGustavo F. Padovan err = -EINVAL; 1996*0a708f8fSGustavo F. Padovan break; 1997*0a708f8fSGustavo F. Padovan } 1998*0a708f8fSGustavo F. Padovan 1999*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->mode = opts.mode; 2000*0a708f8fSGustavo F. Padovan switch (l2cap_pi(sk)->mode) { 2001*0a708f8fSGustavo F. Padovan case L2CAP_MODE_BASIC: 2002*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_STATE2_DEVICE; 2003*0a708f8fSGustavo F. Padovan break; 2004*0a708f8fSGustavo F. Padovan case L2CAP_MODE_ERTM: 2005*0a708f8fSGustavo F. Padovan case L2CAP_MODE_STREAMING: 2006*0a708f8fSGustavo F. Padovan if (!disable_ertm) 2007*0a708f8fSGustavo F. Padovan break; 2008*0a708f8fSGustavo F. Padovan /* fall through */ 2009*0a708f8fSGustavo F. Padovan default: 2010*0a708f8fSGustavo F. Padovan err = -EINVAL; 2011*0a708f8fSGustavo F. Padovan break; 2012*0a708f8fSGustavo F. Padovan } 2013*0a708f8fSGustavo F. Padovan 2014*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->imtu = opts.imtu; 2015*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->omtu = opts.omtu; 2016*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->fcs = opts.fcs; 2017*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->max_tx = opts.max_tx; 2018*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size; 2019*0a708f8fSGustavo F. Padovan break; 2020*0a708f8fSGustavo F. Padovan 2021*0a708f8fSGustavo F. Padovan case L2CAP_LM: 2022*0a708f8fSGustavo F. Padovan if (get_user(opt, (u32 __user *) optval)) { 2023*0a708f8fSGustavo F. Padovan err = -EFAULT; 2024*0a708f8fSGustavo F. Padovan break; 2025*0a708f8fSGustavo F. Padovan } 2026*0a708f8fSGustavo F. Padovan 2027*0a708f8fSGustavo F. Padovan if (opt & L2CAP_LM_AUTH) 2028*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->sec_level = BT_SECURITY_LOW; 2029*0a708f8fSGustavo F. Padovan if (opt & L2CAP_LM_ENCRYPT) 2030*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM; 2031*0a708f8fSGustavo F. Padovan if (opt & L2CAP_LM_SECURE) 2032*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH; 2033*0a708f8fSGustavo F. Padovan 2034*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER); 2035*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE); 2036*0a708f8fSGustavo F. Padovan break; 2037*0a708f8fSGustavo F. Padovan 2038*0a708f8fSGustavo F. Padovan default: 2039*0a708f8fSGustavo F. Padovan err = -ENOPROTOOPT; 2040*0a708f8fSGustavo F. Padovan break; 2041*0a708f8fSGustavo F. Padovan } 2042*0a708f8fSGustavo F. Padovan 2043*0a708f8fSGustavo F. Padovan release_sock(sk); 2044*0a708f8fSGustavo F. Padovan return err; 2045*0a708f8fSGustavo F. Padovan } 2046*0a708f8fSGustavo F. Padovan 2047*0a708f8fSGustavo F. Padovan static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) 2048*0a708f8fSGustavo F. Padovan { 2049*0a708f8fSGustavo F. Padovan struct sock *sk = sock->sk; 2050*0a708f8fSGustavo F. Padovan struct bt_security sec; 2051*0a708f8fSGustavo F. Padovan int len, err = 0; 2052*0a708f8fSGustavo F. Padovan u32 opt; 2053*0a708f8fSGustavo F. Padovan 2054*0a708f8fSGustavo F. Padovan BT_DBG("sk %p", sk); 2055*0a708f8fSGustavo F. Padovan 2056*0a708f8fSGustavo F. Padovan if (level == SOL_L2CAP) 2057*0a708f8fSGustavo F. Padovan return l2cap_sock_setsockopt_old(sock, optname, optval, optlen); 2058*0a708f8fSGustavo F. Padovan 2059*0a708f8fSGustavo F. Padovan if (level != SOL_BLUETOOTH) 2060*0a708f8fSGustavo F. Padovan return -ENOPROTOOPT; 2061*0a708f8fSGustavo F. Padovan 2062*0a708f8fSGustavo F. Padovan lock_sock(sk); 2063*0a708f8fSGustavo F. Padovan 2064*0a708f8fSGustavo F. Padovan switch (optname) { 2065*0a708f8fSGustavo F. Padovan case BT_SECURITY: 2066*0a708f8fSGustavo F. Padovan if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM 2067*0a708f8fSGustavo F. Padovan && sk->sk_type != SOCK_RAW) { 2068*0a708f8fSGustavo F. Padovan err = -EINVAL; 2069*0a708f8fSGustavo F. Padovan break; 2070*0a708f8fSGustavo F. Padovan } 2071*0a708f8fSGustavo F. Padovan 2072*0a708f8fSGustavo F. Padovan sec.level = BT_SECURITY_LOW; 2073*0a708f8fSGustavo F. Padovan 2074*0a708f8fSGustavo F. Padovan len = min_t(unsigned int, sizeof(sec), optlen); 2075*0a708f8fSGustavo F. Padovan if (copy_from_user((char *) &sec, optval, len)) { 2076*0a708f8fSGustavo F. Padovan err = -EFAULT; 2077*0a708f8fSGustavo F. Padovan break; 2078*0a708f8fSGustavo F. Padovan } 2079*0a708f8fSGustavo F. Padovan 2080*0a708f8fSGustavo F. Padovan if (sec.level < BT_SECURITY_LOW || 2081*0a708f8fSGustavo F. Padovan sec.level > BT_SECURITY_HIGH) { 2082*0a708f8fSGustavo F. Padovan err = -EINVAL; 2083*0a708f8fSGustavo F. Padovan break; 2084*0a708f8fSGustavo F. Padovan } 2085*0a708f8fSGustavo F. Padovan 2086*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->sec_level = sec.level; 2087*0a708f8fSGustavo F. Padovan break; 2088*0a708f8fSGustavo F. Padovan 2089*0a708f8fSGustavo F. Padovan case BT_DEFER_SETUP: 2090*0a708f8fSGustavo F. Padovan if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) { 2091*0a708f8fSGustavo F. Padovan err = -EINVAL; 2092*0a708f8fSGustavo F. Padovan break; 2093*0a708f8fSGustavo F. Padovan } 2094*0a708f8fSGustavo F. Padovan 2095*0a708f8fSGustavo F. Padovan if (get_user(opt, (u32 __user *) optval)) { 2096*0a708f8fSGustavo F. Padovan err = -EFAULT; 2097*0a708f8fSGustavo F. Padovan break; 2098*0a708f8fSGustavo F. Padovan } 2099*0a708f8fSGustavo F. Padovan 2100*0a708f8fSGustavo F. Padovan bt_sk(sk)->defer_setup = opt; 2101*0a708f8fSGustavo F. Padovan break; 2102*0a708f8fSGustavo F. Padovan 2103*0a708f8fSGustavo F. Padovan case BT_FLUSHABLE: 2104*0a708f8fSGustavo F. Padovan if (get_user(opt, (u32 __user *) optval)) { 2105*0a708f8fSGustavo F. Padovan err = -EFAULT; 2106*0a708f8fSGustavo F. Padovan break; 2107*0a708f8fSGustavo F. Padovan } 2108*0a708f8fSGustavo F. Padovan 2109*0a708f8fSGustavo F. Padovan if (opt > BT_FLUSHABLE_ON) { 2110*0a708f8fSGustavo F. Padovan err = -EINVAL; 2111*0a708f8fSGustavo F. Padovan break; 2112*0a708f8fSGustavo F. Padovan } 2113*0a708f8fSGustavo F. Padovan 2114*0a708f8fSGustavo F. Padovan if (opt == BT_FLUSHABLE_OFF) { 2115*0a708f8fSGustavo F. Padovan struct l2cap_conn *conn = l2cap_pi(sk)->conn; 2116*0a708f8fSGustavo F. Padovan /* proceed futher only when we have l2cap_conn and 2117*0a708f8fSGustavo F. Padovan No Flush support in the LM */ 2118*0a708f8fSGustavo F. Padovan if (!conn || !lmp_no_flush_capable(conn->hcon->hdev)) { 2119*0a708f8fSGustavo F. Padovan err = -EINVAL; 2120*0a708f8fSGustavo F. Padovan break; 2121*0a708f8fSGustavo F. Padovan } 2122*0a708f8fSGustavo F. Padovan } 2123*0a708f8fSGustavo F. Padovan 2124*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->flushable = opt; 2125*0a708f8fSGustavo F. Padovan break; 2126*0a708f8fSGustavo F. Padovan 2127*0a708f8fSGustavo F. Padovan default: 2128*0a708f8fSGustavo F. Padovan err = -ENOPROTOOPT; 2129*0a708f8fSGustavo F. Padovan break; 2130*0a708f8fSGustavo F. Padovan } 2131*0a708f8fSGustavo F. Padovan 2132*0a708f8fSGustavo F. Padovan release_sock(sk); 2133*0a708f8fSGustavo F. Padovan return err; 2134*0a708f8fSGustavo F. Padovan } 2135*0a708f8fSGustavo F. Padovan 2136*0a708f8fSGustavo F. Padovan static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen) 2137*0a708f8fSGustavo F. Padovan { 2138*0a708f8fSGustavo F. Padovan struct sock *sk = sock->sk; 2139*0a708f8fSGustavo F. Padovan struct l2cap_options opts; 2140*0a708f8fSGustavo F. Padovan struct l2cap_conninfo cinfo; 2141*0a708f8fSGustavo F. Padovan int len, err = 0; 2142*0a708f8fSGustavo F. Padovan u32 opt; 2143*0a708f8fSGustavo F. Padovan 2144*0a708f8fSGustavo F. Padovan BT_DBG("sk %p", sk); 2145*0a708f8fSGustavo F. Padovan 2146*0a708f8fSGustavo F. Padovan if (get_user(len, optlen)) 2147*0a708f8fSGustavo F. Padovan return -EFAULT; 2148*0a708f8fSGustavo F. Padovan 2149*0a708f8fSGustavo F. Padovan lock_sock(sk); 2150*0a708f8fSGustavo F. Padovan 2151*0a708f8fSGustavo F. Padovan switch (optname) { 2152*0a708f8fSGustavo F. Padovan case L2CAP_OPTIONS: 2153*0a708f8fSGustavo F. Padovan opts.imtu = l2cap_pi(sk)->imtu; 2154*0a708f8fSGustavo F. Padovan opts.omtu = l2cap_pi(sk)->omtu; 2155*0a708f8fSGustavo F. Padovan opts.flush_to = l2cap_pi(sk)->flush_to; 2156*0a708f8fSGustavo F. Padovan opts.mode = l2cap_pi(sk)->mode; 2157*0a708f8fSGustavo F. Padovan opts.fcs = l2cap_pi(sk)->fcs; 2158*0a708f8fSGustavo F. Padovan opts.max_tx = l2cap_pi(sk)->max_tx; 2159*0a708f8fSGustavo F. Padovan opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win; 2160*0a708f8fSGustavo F. Padovan 2161*0a708f8fSGustavo F. Padovan len = min_t(unsigned int, len, sizeof(opts)); 2162*0a708f8fSGustavo F. Padovan if (copy_to_user(optval, (char *) &opts, len)) 2163*0a708f8fSGustavo F. Padovan err = -EFAULT; 2164*0a708f8fSGustavo F. Padovan 2165*0a708f8fSGustavo F. Padovan break; 2166*0a708f8fSGustavo F. Padovan 2167*0a708f8fSGustavo F. Padovan case L2CAP_LM: 2168*0a708f8fSGustavo F. Padovan switch (l2cap_pi(sk)->sec_level) { 2169*0a708f8fSGustavo F. Padovan case BT_SECURITY_LOW: 2170*0a708f8fSGustavo F. Padovan opt = L2CAP_LM_AUTH; 2171*0a708f8fSGustavo F. Padovan break; 2172*0a708f8fSGustavo F. Padovan case BT_SECURITY_MEDIUM: 2173*0a708f8fSGustavo F. Padovan opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT; 2174*0a708f8fSGustavo F. Padovan break; 2175*0a708f8fSGustavo F. Padovan case BT_SECURITY_HIGH: 2176*0a708f8fSGustavo F. Padovan opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT | 2177*0a708f8fSGustavo F. Padovan L2CAP_LM_SECURE; 2178*0a708f8fSGustavo F. Padovan break; 2179*0a708f8fSGustavo F. Padovan default: 2180*0a708f8fSGustavo F. Padovan opt = 0; 2181*0a708f8fSGustavo F. Padovan break; 2182*0a708f8fSGustavo F. Padovan } 2183*0a708f8fSGustavo F. Padovan 2184*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->role_switch) 2185*0a708f8fSGustavo F. Padovan opt |= L2CAP_LM_MASTER; 2186*0a708f8fSGustavo F. Padovan 2187*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->force_reliable) 2188*0a708f8fSGustavo F. Padovan opt |= L2CAP_LM_RELIABLE; 2189*0a708f8fSGustavo F. Padovan 2190*0a708f8fSGustavo F. Padovan if (put_user(opt, (u32 __user *) optval)) 2191*0a708f8fSGustavo F. Padovan err = -EFAULT; 2192*0a708f8fSGustavo F. Padovan break; 2193*0a708f8fSGustavo F. Padovan 2194*0a708f8fSGustavo F. Padovan case L2CAP_CONNINFO: 2195*0a708f8fSGustavo F. Padovan if (sk->sk_state != BT_CONNECTED && 2196*0a708f8fSGustavo F. Padovan !(sk->sk_state == BT_CONNECT2 && 2197*0a708f8fSGustavo F. Padovan bt_sk(sk)->defer_setup)) { 2198*0a708f8fSGustavo F. Padovan err = -ENOTCONN; 2199*0a708f8fSGustavo F. Padovan break; 2200*0a708f8fSGustavo F. Padovan } 2201*0a708f8fSGustavo F. Padovan 2202*0a708f8fSGustavo F. Padovan cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle; 2203*0a708f8fSGustavo F. Padovan memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3); 2204*0a708f8fSGustavo F. Padovan 2205*0a708f8fSGustavo F. Padovan len = min_t(unsigned int, len, sizeof(cinfo)); 2206*0a708f8fSGustavo F. Padovan if (copy_to_user(optval, (char *) &cinfo, len)) 2207*0a708f8fSGustavo F. Padovan err = -EFAULT; 2208*0a708f8fSGustavo F. Padovan 2209*0a708f8fSGustavo F. Padovan break; 2210*0a708f8fSGustavo F. Padovan 2211*0a708f8fSGustavo F. Padovan default: 2212*0a708f8fSGustavo F. Padovan err = -ENOPROTOOPT; 2213*0a708f8fSGustavo F. Padovan break; 2214*0a708f8fSGustavo F. Padovan } 2215*0a708f8fSGustavo F. Padovan 2216*0a708f8fSGustavo F. Padovan release_sock(sk); 2217*0a708f8fSGustavo F. Padovan return err; 2218*0a708f8fSGustavo F. Padovan } 2219*0a708f8fSGustavo F. Padovan 2220*0a708f8fSGustavo F. Padovan static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) 2221*0a708f8fSGustavo F. Padovan { 2222*0a708f8fSGustavo F. Padovan struct sock *sk = sock->sk; 2223*0a708f8fSGustavo F. Padovan struct bt_security sec; 2224*0a708f8fSGustavo F. Padovan int len, err = 0; 2225*0a708f8fSGustavo F. Padovan 2226*0a708f8fSGustavo F. Padovan BT_DBG("sk %p", sk); 2227*0a708f8fSGustavo F. Padovan 2228*0a708f8fSGustavo F. Padovan if (level == SOL_L2CAP) 2229*0a708f8fSGustavo F. Padovan return l2cap_sock_getsockopt_old(sock, optname, optval, optlen); 2230*0a708f8fSGustavo F. Padovan 2231*0a708f8fSGustavo F. Padovan if (level != SOL_BLUETOOTH) 2232*0a708f8fSGustavo F. Padovan return -ENOPROTOOPT; 2233*0a708f8fSGustavo F. Padovan 2234*0a708f8fSGustavo F. Padovan if (get_user(len, optlen)) 2235*0a708f8fSGustavo F. Padovan return -EFAULT; 2236*0a708f8fSGustavo F. Padovan 2237*0a708f8fSGustavo F. Padovan lock_sock(sk); 2238*0a708f8fSGustavo F. Padovan 2239*0a708f8fSGustavo F. Padovan switch (optname) { 2240*0a708f8fSGustavo F. Padovan case BT_SECURITY: 2241*0a708f8fSGustavo F. Padovan if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM 2242*0a708f8fSGustavo F. Padovan && sk->sk_type != SOCK_RAW) { 2243*0a708f8fSGustavo F. Padovan err = -EINVAL; 2244*0a708f8fSGustavo F. Padovan break; 2245*0a708f8fSGustavo F. Padovan } 2246*0a708f8fSGustavo F. Padovan 2247*0a708f8fSGustavo F. Padovan sec.level = l2cap_pi(sk)->sec_level; 2248*0a708f8fSGustavo F. Padovan 2249*0a708f8fSGustavo F. Padovan len = min_t(unsigned int, len, sizeof(sec)); 2250*0a708f8fSGustavo F. Padovan if (copy_to_user(optval, (char *) &sec, len)) 2251*0a708f8fSGustavo F. Padovan err = -EFAULT; 2252*0a708f8fSGustavo F. Padovan 2253*0a708f8fSGustavo F. Padovan break; 2254*0a708f8fSGustavo F. Padovan 2255*0a708f8fSGustavo F. Padovan case BT_DEFER_SETUP: 2256*0a708f8fSGustavo F. Padovan if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) { 2257*0a708f8fSGustavo F. Padovan err = -EINVAL; 2258*0a708f8fSGustavo F. Padovan break; 2259*0a708f8fSGustavo F. Padovan } 2260*0a708f8fSGustavo F. Padovan 2261*0a708f8fSGustavo F. Padovan if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval)) 2262*0a708f8fSGustavo F. Padovan err = -EFAULT; 2263*0a708f8fSGustavo F. Padovan 2264*0a708f8fSGustavo F. Padovan break; 2265*0a708f8fSGustavo F. Padovan 2266*0a708f8fSGustavo F. Padovan case BT_FLUSHABLE: 2267*0a708f8fSGustavo F. Padovan if (put_user(l2cap_pi(sk)->flushable, (u32 __user *) optval)) 2268*0a708f8fSGustavo F. Padovan err = -EFAULT; 2269*0a708f8fSGustavo F. Padovan 2270*0a708f8fSGustavo F. Padovan break; 2271*0a708f8fSGustavo F. Padovan 2272*0a708f8fSGustavo F. Padovan default: 2273*0a708f8fSGustavo F. Padovan err = -ENOPROTOOPT; 2274*0a708f8fSGustavo F. Padovan break; 2275*0a708f8fSGustavo F. Padovan } 2276*0a708f8fSGustavo F. Padovan 2277*0a708f8fSGustavo F. Padovan release_sock(sk); 2278*0a708f8fSGustavo F. Padovan return err; 2279*0a708f8fSGustavo F. Padovan } 2280*0a708f8fSGustavo F. Padovan 2281*0a708f8fSGustavo F. Padovan static int l2cap_sock_shutdown(struct socket *sock, int how) 2282*0a708f8fSGustavo F. Padovan { 2283*0a708f8fSGustavo F. Padovan struct sock *sk = sock->sk; 2284*0a708f8fSGustavo F. Padovan int err = 0; 2285*0a708f8fSGustavo F. Padovan 2286*0a708f8fSGustavo F. Padovan BT_DBG("sock %p, sk %p", sock, sk); 2287*0a708f8fSGustavo F. Padovan 2288*0a708f8fSGustavo F. Padovan if (!sk) 2289*0a708f8fSGustavo F. Padovan return 0; 2290*0a708f8fSGustavo F. Padovan 2291*0a708f8fSGustavo F. Padovan lock_sock(sk); 2292*0a708f8fSGustavo F. Padovan if (!sk->sk_shutdown) { 2293*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) 2294*0a708f8fSGustavo F. Padovan err = __l2cap_wait_ack(sk); 2295*0a708f8fSGustavo F. Padovan 2296*0a708f8fSGustavo F. Padovan sk->sk_shutdown = SHUTDOWN_MASK; 2297*0a708f8fSGustavo F. Padovan l2cap_sock_clear_timer(sk); 2298*0a708f8fSGustavo F. Padovan __l2cap_sock_close(sk, 0); 2299*0a708f8fSGustavo F. Padovan 2300*0a708f8fSGustavo F. Padovan if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) 2301*0a708f8fSGustavo F. Padovan err = bt_sock_wait_state(sk, BT_CLOSED, 2302*0a708f8fSGustavo F. Padovan sk->sk_lingertime); 2303*0a708f8fSGustavo F. Padovan } 2304*0a708f8fSGustavo F. Padovan 2305*0a708f8fSGustavo F. Padovan if (!err && sk->sk_err) 2306*0a708f8fSGustavo F. Padovan err = -sk->sk_err; 2307*0a708f8fSGustavo F. Padovan 2308*0a708f8fSGustavo F. Padovan release_sock(sk); 2309*0a708f8fSGustavo F. Padovan return err; 2310*0a708f8fSGustavo F. Padovan } 2311*0a708f8fSGustavo F. Padovan 2312*0a708f8fSGustavo F. Padovan static int l2cap_sock_release(struct socket *sock) 2313*0a708f8fSGustavo F. Padovan { 2314*0a708f8fSGustavo F. Padovan struct sock *sk = sock->sk; 2315*0a708f8fSGustavo F. Padovan int err; 2316*0a708f8fSGustavo F. Padovan 2317*0a708f8fSGustavo F. Padovan BT_DBG("sock %p, sk %p", sock, sk); 2318*0a708f8fSGustavo F. Padovan 2319*0a708f8fSGustavo F. Padovan if (!sk) 2320*0a708f8fSGustavo F. Padovan return 0; 2321*0a708f8fSGustavo F. Padovan 2322*0a708f8fSGustavo F. Padovan err = l2cap_sock_shutdown(sock, 2); 2323*0a708f8fSGustavo F. Padovan 2324*0a708f8fSGustavo F. Padovan sock_orphan(sk); 2325*0a708f8fSGustavo F. Padovan l2cap_sock_kill(sk); 2326*0a708f8fSGustavo F. Padovan return err; 2327*0a708f8fSGustavo F. Padovan } 2328*0a708f8fSGustavo F. Padovan 2329*0a708f8fSGustavo F. Padovan static void l2cap_chan_ready(struct sock *sk) 2330*0a708f8fSGustavo F. Padovan { 2331*0a708f8fSGustavo F. Padovan struct sock *parent = bt_sk(sk)->parent; 2332*0a708f8fSGustavo F. Padovan 2333*0a708f8fSGustavo F. Padovan BT_DBG("sk %p, parent %p", sk, parent); 2334*0a708f8fSGustavo F. Padovan 2335*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conf_state = 0; 2336*0a708f8fSGustavo F. Padovan l2cap_sock_clear_timer(sk); 2337*0a708f8fSGustavo F. Padovan 2338*0a708f8fSGustavo F. Padovan if (!parent) { 2339*0a708f8fSGustavo F. Padovan /* Outgoing channel. 2340*0a708f8fSGustavo F. Padovan * Wake up socket sleeping on connect. 2341*0a708f8fSGustavo F. Padovan */ 2342*0a708f8fSGustavo F. Padovan sk->sk_state = BT_CONNECTED; 2343*0a708f8fSGustavo F. Padovan sk->sk_state_change(sk); 2344*0a708f8fSGustavo F. Padovan } else { 2345*0a708f8fSGustavo F. Padovan /* Incoming channel. 2346*0a708f8fSGustavo F. Padovan * Wake up socket sleeping on accept. 2347*0a708f8fSGustavo F. Padovan */ 2348*0a708f8fSGustavo F. Padovan parent->sk_data_ready(parent, 0); 2349*0a708f8fSGustavo F. Padovan } 2350*0a708f8fSGustavo F. Padovan } 2351*0a708f8fSGustavo F. Padovan 2352*0a708f8fSGustavo F. Padovan /* Copy frame to all raw sockets on that connection */ 2353*0a708f8fSGustavo F. Padovan static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) 2354*0a708f8fSGustavo F. Padovan { 2355*0a708f8fSGustavo F. Padovan struct l2cap_chan_list *l = &conn->chan_list; 2356*0a708f8fSGustavo F. Padovan struct sk_buff *nskb; 2357*0a708f8fSGustavo F. Padovan struct sock *sk; 2358*0a708f8fSGustavo F. Padovan 2359*0a708f8fSGustavo F. Padovan BT_DBG("conn %p", conn); 2360*0a708f8fSGustavo F. Padovan 2361*0a708f8fSGustavo F. Padovan read_lock(&l->lock); 2362*0a708f8fSGustavo F. Padovan for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { 2363*0a708f8fSGustavo F. Padovan if (sk->sk_type != SOCK_RAW) 2364*0a708f8fSGustavo F. Padovan continue; 2365*0a708f8fSGustavo F. Padovan 2366*0a708f8fSGustavo F. Padovan /* Don't send frame to the socket it came from */ 2367*0a708f8fSGustavo F. Padovan if (skb->sk == sk) 2368*0a708f8fSGustavo F. Padovan continue; 2369*0a708f8fSGustavo F. Padovan nskb = skb_clone(skb, GFP_ATOMIC); 2370*0a708f8fSGustavo F. Padovan if (!nskb) 2371*0a708f8fSGustavo F. Padovan continue; 2372*0a708f8fSGustavo F. Padovan 2373*0a708f8fSGustavo F. Padovan if (sock_queue_rcv_skb(sk, nskb)) 2374*0a708f8fSGustavo F. Padovan kfree_skb(nskb); 2375*0a708f8fSGustavo F. Padovan } 2376*0a708f8fSGustavo F. Padovan read_unlock(&l->lock); 2377*0a708f8fSGustavo F. Padovan } 2378*0a708f8fSGustavo F. Padovan 2379*0a708f8fSGustavo F. Padovan /* ---- L2CAP signalling commands ---- */ 2380*0a708f8fSGustavo F. Padovan static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, 2381*0a708f8fSGustavo F. Padovan u8 code, u8 ident, u16 dlen, void *data) 2382*0a708f8fSGustavo F. Padovan { 2383*0a708f8fSGustavo F. Padovan struct sk_buff *skb, **frag; 2384*0a708f8fSGustavo F. Padovan struct l2cap_cmd_hdr *cmd; 2385*0a708f8fSGustavo F. Padovan struct l2cap_hdr *lh; 2386*0a708f8fSGustavo F. Padovan int len, count; 2387*0a708f8fSGustavo F. Padovan 2388*0a708f8fSGustavo F. Padovan BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d", 2389*0a708f8fSGustavo F. Padovan conn, code, ident, dlen); 2390*0a708f8fSGustavo F. Padovan 2391*0a708f8fSGustavo F. Padovan len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen; 2392*0a708f8fSGustavo F. Padovan count = min_t(unsigned int, conn->mtu, len); 2393*0a708f8fSGustavo F. Padovan 2394*0a708f8fSGustavo F. Padovan skb = bt_skb_alloc(count, GFP_ATOMIC); 2395*0a708f8fSGustavo F. Padovan if (!skb) 2396*0a708f8fSGustavo F. Padovan return NULL; 2397*0a708f8fSGustavo F. Padovan 2398*0a708f8fSGustavo F. Padovan lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); 2399*0a708f8fSGustavo F. Padovan lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen); 2400*0a708f8fSGustavo F. Padovan lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING); 2401*0a708f8fSGustavo F. Padovan 2402*0a708f8fSGustavo F. Padovan cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE); 2403*0a708f8fSGustavo F. Padovan cmd->code = code; 2404*0a708f8fSGustavo F. Padovan cmd->ident = ident; 2405*0a708f8fSGustavo F. Padovan cmd->len = cpu_to_le16(dlen); 2406*0a708f8fSGustavo F. Padovan 2407*0a708f8fSGustavo F. Padovan if (dlen) { 2408*0a708f8fSGustavo F. Padovan count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE; 2409*0a708f8fSGustavo F. Padovan memcpy(skb_put(skb, count), data, count); 2410*0a708f8fSGustavo F. Padovan data += count; 2411*0a708f8fSGustavo F. Padovan } 2412*0a708f8fSGustavo F. Padovan 2413*0a708f8fSGustavo F. Padovan len -= skb->len; 2414*0a708f8fSGustavo F. Padovan 2415*0a708f8fSGustavo F. Padovan /* Continuation fragments (no L2CAP header) */ 2416*0a708f8fSGustavo F. Padovan frag = &skb_shinfo(skb)->frag_list; 2417*0a708f8fSGustavo F. Padovan while (len) { 2418*0a708f8fSGustavo F. Padovan count = min_t(unsigned int, conn->mtu, len); 2419*0a708f8fSGustavo F. Padovan 2420*0a708f8fSGustavo F. Padovan *frag = bt_skb_alloc(count, GFP_ATOMIC); 2421*0a708f8fSGustavo F. Padovan if (!*frag) 2422*0a708f8fSGustavo F. Padovan goto fail; 2423*0a708f8fSGustavo F. Padovan 2424*0a708f8fSGustavo F. Padovan memcpy(skb_put(*frag, count), data, count); 2425*0a708f8fSGustavo F. Padovan 2426*0a708f8fSGustavo F. Padovan len -= count; 2427*0a708f8fSGustavo F. Padovan data += count; 2428*0a708f8fSGustavo F. Padovan 2429*0a708f8fSGustavo F. Padovan frag = &(*frag)->next; 2430*0a708f8fSGustavo F. Padovan } 2431*0a708f8fSGustavo F. Padovan 2432*0a708f8fSGustavo F. Padovan return skb; 2433*0a708f8fSGustavo F. Padovan 2434*0a708f8fSGustavo F. Padovan fail: 2435*0a708f8fSGustavo F. Padovan kfree_skb(skb); 2436*0a708f8fSGustavo F. Padovan return NULL; 2437*0a708f8fSGustavo F. Padovan } 2438*0a708f8fSGustavo F. Padovan 2439*0a708f8fSGustavo F. Padovan static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val) 2440*0a708f8fSGustavo F. Padovan { 2441*0a708f8fSGustavo F. Padovan struct l2cap_conf_opt *opt = *ptr; 2442*0a708f8fSGustavo F. Padovan int len; 2443*0a708f8fSGustavo F. Padovan 2444*0a708f8fSGustavo F. Padovan len = L2CAP_CONF_OPT_SIZE + opt->len; 2445*0a708f8fSGustavo F. Padovan *ptr += len; 2446*0a708f8fSGustavo F. Padovan 2447*0a708f8fSGustavo F. Padovan *type = opt->type; 2448*0a708f8fSGustavo F. Padovan *olen = opt->len; 2449*0a708f8fSGustavo F. Padovan 2450*0a708f8fSGustavo F. Padovan switch (opt->len) { 2451*0a708f8fSGustavo F. Padovan case 1: 2452*0a708f8fSGustavo F. Padovan *val = *((u8 *) opt->val); 2453*0a708f8fSGustavo F. Padovan break; 2454*0a708f8fSGustavo F. Padovan 2455*0a708f8fSGustavo F. Padovan case 2: 2456*0a708f8fSGustavo F. Padovan *val = get_unaligned_le16(opt->val); 2457*0a708f8fSGustavo F. Padovan break; 2458*0a708f8fSGustavo F. Padovan 2459*0a708f8fSGustavo F. Padovan case 4: 2460*0a708f8fSGustavo F. Padovan *val = get_unaligned_le32(opt->val); 2461*0a708f8fSGustavo F. Padovan break; 2462*0a708f8fSGustavo F. Padovan 2463*0a708f8fSGustavo F. Padovan default: 2464*0a708f8fSGustavo F. Padovan *val = (unsigned long) opt->val; 2465*0a708f8fSGustavo F. Padovan break; 2466*0a708f8fSGustavo F. Padovan } 2467*0a708f8fSGustavo F. Padovan 2468*0a708f8fSGustavo F. Padovan BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val); 2469*0a708f8fSGustavo F. Padovan return len; 2470*0a708f8fSGustavo F. Padovan } 2471*0a708f8fSGustavo F. Padovan 2472*0a708f8fSGustavo F. Padovan static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val) 2473*0a708f8fSGustavo F. Padovan { 2474*0a708f8fSGustavo F. Padovan struct l2cap_conf_opt *opt = *ptr; 2475*0a708f8fSGustavo F. Padovan 2476*0a708f8fSGustavo F. Padovan BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val); 2477*0a708f8fSGustavo F. Padovan 2478*0a708f8fSGustavo F. Padovan opt->type = type; 2479*0a708f8fSGustavo F. Padovan opt->len = len; 2480*0a708f8fSGustavo F. Padovan 2481*0a708f8fSGustavo F. Padovan switch (len) { 2482*0a708f8fSGustavo F. Padovan case 1: 2483*0a708f8fSGustavo F. Padovan *((u8 *) opt->val) = val; 2484*0a708f8fSGustavo F. Padovan break; 2485*0a708f8fSGustavo F. Padovan 2486*0a708f8fSGustavo F. Padovan case 2: 2487*0a708f8fSGustavo F. Padovan put_unaligned_le16(val, opt->val); 2488*0a708f8fSGustavo F. Padovan break; 2489*0a708f8fSGustavo F. Padovan 2490*0a708f8fSGustavo F. Padovan case 4: 2491*0a708f8fSGustavo F. Padovan put_unaligned_le32(val, opt->val); 2492*0a708f8fSGustavo F. Padovan break; 2493*0a708f8fSGustavo F. Padovan 2494*0a708f8fSGustavo F. Padovan default: 2495*0a708f8fSGustavo F. Padovan memcpy(opt->val, (void *) val, len); 2496*0a708f8fSGustavo F. Padovan break; 2497*0a708f8fSGustavo F. Padovan } 2498*0a708f8fSGustavo F. Padovan 2499*0a708f8fSGustavo F. Padovan *ptr += L2CAP_CONF_OPT_SIZE + len; 2500*0a708f8fSGustavo F. Padovan } 2501*0a708f8fSGustavo F. Padovan 2502*0a708f8fSGustavo F. Padovan static void l2cap_ack_timeout(unsigned long arg) 2503*0a708f8fSGustavo F. Padovan { 2504*0a708f8fSGustavo F. Padovan struct sock *sk = (void *) arg; 2505*0a708f8fSGustavo F. Padovan 2506*0a708f8fSGustavo F. Padovan bh_lock_sock(sk); 2507*0a708f8fSGustavo F. Padovan l2cap_send_ack(l2cap_pi(sk)); 2508*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 2509*0a708f8fSGustavo F. Padovan } 2510*0a708f8fSGustavo F. Padovan 2511*0a708f8fSGustavo F. Padovan static inline void l2cap_ertm_init(struct sock *sk) 2512*0a708f8fSGustavo F. Padovan { 2513*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->expected_ack_seq = 0; 2514*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->unacked_frames = 0; 2515*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->buffer_seq = 0; 2516*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->num_acked = 0; 2517*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->frames_sent = 0; 2518*0a708f8fSGustavo F. Padovan 2519*0a708f8fSGustavo F. Padovan setup_timer(&l2cap_pi(sk)->retrans_timer, 2520*0a708f8fSGustavo F. Padovan l2cap_retrans_timeout, (unsigned long) sk); 2521*0a708f8fSGustavo F. Padovan setup_timer(&l2cap_pi(sk)->monitor_timer, 2522*0a708f8fSGustavo F. Padovan l2cap_monitor_timeout, (unsigned long) sk); 2523*0a708f8fSGustavo F. Padovan setup_timer(&l2cap_pi(sk)->ack_timer, 2524*0a708f8fSGustavo F. Padovan l2cap_ack_timeout, (unsigned long) sk); 2525*0a708f8fSGustavo F. Padovan 2526*0a708f8fSGustavo F. Padovan __skb_queue_head_init(SREJ_QUEUE(sk)); 2527*0a708f8fSGustavo F. Padovan __skb_queue_head_init(BUSY_QUEUE(sk)); 2528*0a708f8fSGustavo F. Padovan 2529*0a708f8fSGustavo F. Padovan INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work); 2530*0a708f8fSGustavo F. Padovan 2531*0a708f8fSGustavo F. Padovan sk->sk_backlog_rcv = l2cap_ertm_data_rcv; 2532*0a708f8fSGustavo F. Padovan } 2533*0a708f8fSGustavo F. Padovan 2534*0a708f8fSGustavo F. Padovan static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask) 2535*0a708f8fSGustavo F. Padovan { 2536*0a708f8fSGustavo F. Padovan switch (mode) { 2537*0a708f8fSGustavo F. Padovan case L2CAP_MODE_STREAMING: 2538*0a708f8fSGustavo F. Padovan case L2CAP_MODE_ERTM: 2539*0a708f8fSGustavo F. Padovan if (l2cap_mode_supported(mode, remote_feat_mask)) 2540*0a708f8fSGustavo F. Padovan return mode; 2541*0a708f8fSGustavo F. Padovan /* fall through */ 2542*0a708f8fSGustavo F. Padovan default: 2543*0a708f8fSGustavo F. Padovan return L2CAP_MODE_BASIC; 2544*0a708f8fSGustavo F. Padovan } 2545*0a708f8fSGustavo F. Padovan } 2546*0a708f8fSGustavo F. Padovan 2547*0a708f8fSGustavo F. Padovan static int l2cap_build_conf_req(struct sock *sk, void *data) 2548*0a708f8fSGustavo F. Padovan { 2549*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 2550*0a708f8fSGustavo F. Padovan struct l2cap_conf_req *req = data; 2551*0a708f8fSGustavo F. Padovan struct l2cap_conf_rfc rfc = { .mode = pi->mode }; 2552*0a708f8fSGustavo F. Padovan void *ptr = req->data; 2553*0a708f8fSGustavo F. Padovan 2554*0a708f8fSGustavo F. Padovan BT_DBG("sk %p", sk); 2555*0a708f8fSGustavo F. Padovan 2556*0a708f8fSGustavo F. Padovan if (pi->num_conf_req || pi->num_conf_rsp) 2557*0a708f8fSGustavo F. Padovan goto done; 2558*0a708f8fSGustavo F. Padovan 2559*0a708f8fSGustavo F. Padovan switch (pi->mode) { 2560*0a708f8fSGustavo F. Padovan case L2CAP_MODE_STREAMING: 2561*0a708f8fSGustavo F. Padovan case L2CAP_MODE_ERTM: 2562*0a708f8fSGustavo F. Padovan if (pi->conf_state & L2CAP_CONF_STATE2_DEVICE) 2563*0a708f8fSGustavo F. Padovan break; 2564*0a708f8fSGustavo F. Padovan 2565*0a708f8fSGustavo F. Padovan /* fall through */ 2566*0a708f8fSGustavo F. Padovan default: 2567*0a708f8fSGustavo F. Padovan pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask); 2568*0a708f8fSGustavo F. Padovan break; 2569*0a708f8fSGustavo F. Padovan } 2570*0a708f8fSGustavo F. Padovan 2571*0a708f8fSGustavo F. Padovan done: 2572*0a708f8fSGustavo F. Padovan if (pi->imtu != L2CAP_DEFAULT_MTU) 2573*0a708f8fSGustavo F. Padovan l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu); 2574*0a708f8fSGustavo F. Padovan 2575*0a708f8fSGustavo F. Padovan switch (pi->mode) { 2576*0a708f8fSGustavo F. Padovan case L2CAP_MODE_BASIC: 2577*0a708f8fSGustavo F. Padovan if (!(pi->conn->feat_mask & L2CAP_FEAT_ERTM) && 2578*0a708f8fSGustavo F. Padovan !(pi->conn->feat_mask & L2CAP_FEAT_STREAMING)) 2579*0a708f8fSGustavo F. Padovan break; 2580*0a708f8fSGustavo F. Padovan 2581*0a708f8fSGustavo F. Padovan rfc.mode = L2CAP_MODE_BASIC; 2582*0a708f8fSGustavo F. Padovan rfc.txwin_size = 0; 2583*0a708f8fSGustavo F. Padovan rfc.max_transmit = 0; 2584*0a708f8fSGustavo F. Padovan rfc.retrans_timeout = 0; 2585*0a708f8fSGustavo F. Padovan rfc.monitor_timeout = 0; 2586*0a708f8fSGustavo F. Padovan rfc.max_pdu_size = 0; 2587*0a708f8fSGustavo F. Padovan 2588*0a708f8fSGustavo F. Padovan l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), 2589*0a708f8fSGustavo F. Padovan (unsigned long) &rfc); 2590*0a708f8fSGustavo F. Padovan break; 2591*0a708f8fSGustavo F. Padovan 2592*0a708f8fSGustavo F. Padovan case L2CAP_MODE_ERTM: 2593*0a708f8fSGustavo F. Padovan rfc.mode = L2CAP_MODE_ERTM; 2594*0a708f8fSGustavo F. Padovan rfc.txwin_size = pi->tx_win; 2595*0a708f8fSGustavo F. Padovan rfc.max_transmit = pi->max_tx; 2596*0a708f8fSGustavo F. Padovan rfc.retrans_timeout = 0; 2597*0a708f8fSGustavo F. Padovan rfc.monitor_timeout = 0; 2598*0a708f8fSGustavo F. Padovan rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE); 2599*0a708f8fSGustavo F. Padovan if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10) 2600*0a708f8fSGustavo F. Padovan rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); 2601*0a708f8fSGustavo F. Padovan 2602*0a708f8fSGustavo F. Padovan l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), 2603*0a708f8fSGustavo F. Padovan (unsigned long) &rfc); 2604*0a708f8fSGustavo F. Padovan 2605*0a708f8fSGustavo F. Padovan if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS)) 2606*0a708f8fSGustavo F. Padovan break; 2607*0a708f8fSGustavo F. Padovan 2608*0a708f8fSGustavo F. Padovan if (pi->fcs == L2CAP_FCS_NONE || 2609*0a708f8fSGustavo F. Padovan pi->conf_state & L2CAP_CONF_NO_FCS_RECV) { 2610*0a708f8fSGustavo F. Padovan pi->fcs = L2CAP_FCS_NONE; 2611*0a708f8fSGustavo F. Padovan l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs); 2612*0a708f8fSGustavo F. Padovan } 2613*0a708f8fSGustavo F. Padovan break; 2614*0a708f8fSGustavo F. Padovan 2615*0a708f8fSGustavo F. Padovan case L2CAP_MODE_STREAMING: 2616*0a708f8fSGustavo F. Padovan rfc.mode = L2CAP_MODE_STREAMING; 2617*0a708f8fSGustavo F. Padovan rfc.txwin_size = 0; 2618*0a708f8fSGustavo F. Padovan rfc.max_transmit = 0; 2619*0a708f8fSGustavo F. Padovan rfc.retrans_timeout = 0; 2620*0a708f8fSGustavo F. Padovan rfc.monitor_timeout = 0; 2621*0a708f8fSGustavo F. Padovan rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE); 2622*0a708f8fSGustavo F. Padovan if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10) 2623*0a708f8fSGustavo F. Padovan rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); 2624*0a708f8fSGustavo F. Padovan 2625*0a708f8fSGustavo F. Padovan l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), 2626*0a708f8fSGustavo F. Padovan (unsigned long) &rfc); 2627*0a708f8fSGustavo F. Padovan 2628*0a708f8fSGustavo F. Padovan if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS)) 2629*0a708f8fSGustavo F. Padovan break; 2630*0a708f8fSGustavo F. Padovan 2631*0a708f8fSGustavo F. Padovan if (pi->fcs == L2CAP_FCS_NONE || 2632*0a708f8fSGustavo F. Padovan pi->conf_state & L2CAP_CONF_NO_FCS_RECV) { 2633*0a708f8fSGustavo F. Padovan pi->fcs = L2CAP_FCS_NONE; 2634*0a708f8fSGustavo F. Padovan l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs); 2635*0a708f8fSGustavo F. Padovan } 2636*0a708f8fSGustavo F. Padovan break; 2637*0a708f8fSGustavo F. Padovan } 2638*0a708f8fSGustavo F. Padovan 2639*0a708f8fSGustavo F. Padovan /* FIXME: Need actual value of the flush timeout */ 2640*0a708f8fSGustavo F. Padovan //if (flush_to != L2CAP_DEFAULT_FLUSH_TO) 2641*0a708f8fSGustavo F. Padovan // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to); 2642*0a708f8fSGustavo F. Padovan 2643*0a708f8fSGustavo F. Padovan req->dcid = cpu_to_le16(pi->dcid); 2644*0a708f8fSGustavo F. Padovan req->flags = cpu_to_le16(0); 2645*0a708f8fSGustavo F. Padovan 2646*0a708f8fSGustavo F. Padovan return ptr - data; 2647*0a708f8fSGustavo F. Padovan } 2648*0a708f8fSGustavo F. Padovan 2649*0a708f8fSGustavo F. Padovan static int l2cap_parse_conf_req(struct sock *sk, void *data) 2650*0a708f8fSGustavo F. Padovan { 2651*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 2652*0a708f8fSGustavo F. Padovan struct l2cap_conf_rsp *rsp = data; 2653*0a708f8fSGustavo F. Padovan void *ptr = rsp->data; 2654*0a708f8fSGustavo F. Padovan void *req = pi->conf_req; 2655*0a708f8fSGustavo F. Padovan int len = pi->conf_len; 2656*0a708f8fSGustavo F. Padovan int type, hint, olen; 2657*0a708f8fSGustavo F. Padovan unsigned long val; 2658*0a708f8fSGustavo F. Padovan struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; 2659*0a708f8fSGustavo F. Padovan u16 mtu = L2CAP_DEFAULT_MTU; 2660*0a708f8fSGustavo F. Padovan u16 result = L2CAP_CONF_SUCCESS; 2661*0a708f8fSGustavo F. Padovan 2662*0a708f8fSGustavo F. Padovan BT_DBG("sk %p", sk); 2663*0a708f8fSGustavo F. Padovan 2664*0a708f8fSGustavo F. Padovan while (len >= L2CAP_CONF_OPT_SIZE) { 2665*0a708f8fSGustavo F. Padovan len -= l2cap_get_conf_opt(&req, &type, &olen, &val); 2666*0a708f8fSGustavo F. Padovan 2667*0a708f8fSGustavo F. Padovan hint = type & L2CAP_CONF_HINT; 2668*0a708f8fSGustavo F. Padovan type &= L2CAP_CONF_MASK; 2669*0a708f8fSGustavo F. Padovan 2670*0a708f8fSGustavo F. Padovan switch (type) { 2671*0a708f8fSGustavo F. Padovan case L2CAP_CONF_MTU: 2672*0a708f8fSGustavo F. Padovan mtu = val; 2673*0a708f8fSGustavo F. Padovan break; 2674*0a708f8fSGustavo F. Padovan 2675*0a708f8fSGustavo F. Padovan case L2CAP_CONF_FLUSH_TO: 2676*0a708f8fSGustavo F. Padovan pi->flush_to = val; 2677*0a708f8fSGustavo F. Padovan break; 2678*0a708f8fSGustavo F. Padovan 2679*0a708f8fSGustavo F. Padovan case L2CAP_CONF_QOS: 2680*0a708f8fSGustavo F. Padovan break; 2681*0a708f8fSGustavo F. Padovan 2682*0a708f8fSGustavo F. Padovan case L2CAP_CONF_RFC: 2683*0a708f8fSGustavo F. Padovan if (olen == sizeof(rfc)) 2684*0a708f8fSGustavo F. Padovan memcpy(&rfc, (void *) val, olen); 2685*0a708f8fSGustavo F. Padovan break; 2686*0a708f8fSGustavo F. Padovan 2687*0a708f8fSGustavo F. Padovan case L2CAP_CONF_FCS: 2688*0a708f8fSGustavo F. Padovan if (val == L2CAP_FCS_NONE) 2689*0a708f8fSGustavo F. Padovan pi->conf_state |= L2CAP_CONF_NO_FCS_RECV; 2690*0a708f8fSGustavo F. Padovan 2691*0a708f8fSGustavo F. Padovan break; 2692*0a708f8fSGustavo F. Padovan 2693*0a708f8fSGustavo F. Padovan default: 2694*0a708f8fSGustavo F. Padovan if (hint) 2695*0a708f8fSGustavo F. Padovan break; 2696*0a708f8fSGustavo F. Padovan 2697*0a708f8fSGustavo F. Padovan result = L2CAP_CONF_UNKNOWN; 2698*0a708f8fSGustavo F. Padovan *((u8 *) ptr++) = type; 2699*0a708f8fSGustavo F. Padovan break; 2700*0a708f8fSGustavo F. Padovan } 2701*0a708f8fSGustavo F. Padovan } 2702*0a708f8fSGustavo F. Padovan 2703*0a708f8fSGustavo F. Padovan if (pi->num_conf_rsp || pi->num_conf_req > 1) 2704*0a708f8fSGustavo F. Padovan goto done; 2705*0a708f8fSGustavo F. Padovan 2706*0a708f8fSGustavo F. Padovan switch (pi->mode) { 2707*0a708f8fSGustavo F. Padovan case L2CAP_MODE_STREAMING: 2708*0a708f8fSGustavo F. Padovan case L2CAP_MODE_ERTM: 2709*0a708f8fSGustavo F. Padovan if (!(pi->conf_state & L2CAP_CONF_STATE2_DEVICE)) { 2710*0a708f8fSGustavo F. Padovan pi->mode = l2cap_select_mode(rfc.mode, 2711*0a708f8fSGustavo F. Padovan pi->conn->feat_mask); 2712*0a708f8fSGustavo F. Padovan break; 2713*0a708f8fSGustavo F. Padovan } 2714*0a708f8fSGustavo F. Padovan 2715*0a708f8fSGustavo F. Padovan if (pi->mode != rfc.mode) 2716*0a708f8fSGustavo F. Padovan return -ECONNREFUSED; 2717*0a708f8fSGustavo F. Padovan 2718*0a708f8fSGustavo F. Padovan break; 2719*0a708f8fSGustavo F. Padovan } 2720*0a708f8fSGustavo F. Padovan 2721*0a708f8fSGustavo F. Padovan done: 2722*0a708f8fSGustavo F. Padovan if (pi->mode != rfc.mode) { 2723*0a708f8fSGustavo F. Padovan result = L2CAP_CONF_UNACCEPT; 2724*0a708f8fSGustavo F. Padovan rfc.mode = pi->mode; 2725*0a708f8fSGustavo F. Padovan 2726*0a708f8fSGustavo F. Padovan if (pi->num_conf_rsp == 1) 2727*0a708f8fSGustavo F. Padovan return -ECONNREFUSED; 2728*0a708f8fSGustavo F. Padovan 2729*0a708f8fSGustavo F. Padovan l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, 2730*0a708f8fSGustavo F. Padovan sizeof(rfc), (unsigned long) &rfc); 2731*0a708f8fSGustavo F. Padovan } 2732*0a708f8fSGustavo F. Padovan 2733*0a708f8fSGustavo F. Padovan 2734*0a708f8fSGustavo F. Padovan if (result == L2CAP_CONF_SUCCESS) { 2735*0a708f8fSGustavo F. Padovan /* Configure output options and let the other side know 2736*0a708f8fSGustavo F. Padovan * which ones we don't like. */ 2737*0a708f8fSGustavo F. Padovan 2738*0a708f8fSGustavo F. Padovan if (mtu < L2CAP_DEFAULT_MIN_MTU) 2739*0a708f8fSGustavo F. Padovan result = L2CAP_CONF_UNACCEPT; 2740*0a708f8fSGustavo F. Padovan else { 2741*0a708f8fSGustavo F. Padovan pi->omtu = mtu; 2742*0a708f8fSGustavo F. Padovan pi->conf_state |= L2CAP_CONF_MTU_DONE; 2743*0a708f8fSGustavo F. Padovan } 2744*0a708f8fSGustavo F. Padovan l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu); 2745*0a708f8fSGustavo F. Padovan 2746*0a708f8fSGustavo F. Padovan switch (rfc.mode) { 2747*0a708f8fSGustavo F. Padovan case L2CAP_MODE_BASIC: 2748*0a708f8fSGustavo F. Padovan pi->fcs = L2CAP_FCS_NONE; 2749*0a708f8fSGustavo F. Padovan pi->conf_state |= L2CAP_CONF_MODE_DONE; 2750*0a708f8fSGustavo F. Padovan break; 2751*0a708f8fSGustavo F. Padovan 2752*0a708f8fSGustavo F. Padovan case L2CAP_MODE_ERTM: 2753*0a708f8fSGustavo F. Padovan pi->remote_tx_win = rfc.txwin_size; 2754*0a708f8fSGustavo F. Padovan pi->remote_max_tx = rfc.max_transmit; 2755*0a708f8fSGustavo F. Padovan 2756*0a708f8fSGustavo F. Padovan if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10) 2757*0a708f8fSGustavo F. Padovan rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); 2758*0a708f8fSGustavo F. Padovan 2759*0a708f8fSGustavo F. Padovan pi->remote_mps = le16_to_cpu(rfc.max_pdu_size); 2760*0a708f8fSGustavo F. Padovan 2761*0a708f8fSGustavo F. Padovan rfc.retrans_timeout = 2762*0a708f8fSGustavo F. Padovan le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO); 2763*0a708f8fSGustavo F. Padovan rfc.monitor_timeout = 2764*0a708f8fSGustavo F. Padovan le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO); 2765*0a708f8fSGustavo F. Padovan 2766*0a708f8fSGustavo F. Padovan pi->conf_state |= L2CAP_CONF_MODE_DONE; 2767*0a708f8fSGustavo F. Padovan 2768*0a708f8fSGustavo F. Padovan l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, 2769*0a708f8fSGustavo F. Padovan sizeof(rfc), (unsigned long) &rfc); 2770*0a708f8fSGustavo F. Padovan 2771*0a708f8fSGustavo F. Padovan break; 2772*0a708f8fSGustavo F. Padovan 2773*0a708f8fSGustavo F. Padovan case L2CAP_MODE_STREAMING: 2774*0a708f8fSGustavo F. Padovan if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10) 2775*0a708f8fSGustavo F. Padovan rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); 2776*0a708f8fSGustavo F. Padovan 2777*0a708f8fSGustavo F. Padovan pi->remote_mps = le16_to_cpu(rfc.max_pdu_size); 2778*0a708f8fSGustavo F. Padovan 2779*0a708f8fSGustavo F. Padovan pi->conf_state |= L2CAP_CONF_MODE_DONE; 2780*0a708f8fSGustavo F. Padovan 2781*0a708f8fSGustavo F. Padovan l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, 2782*0a708f8fSGustavo F. Padovan sizeof(rfc), (unsigned long) &rfc); 2783*0a708f8fSGustavo F. Padovan 2784*0a708f8fSGustavo F. Padovan break; 2785*0a708f8fSGustavo F. Padovan 2786*0a708f8fSGustavo F. Padovan default: 2787*0a708f8fSGustavo F. Padovan result = L2CAP_CONF_UNACCEPT; 2788*0a708f8fSGustavo F. Padovan 2789*0a708f8fSGustavo F. Padovan memset(&rfc, 0, sizeof(rfc)); 2790*0a708f8fSGustavo F. Padovan rfc.mode = pi->mode; 2791*0a708f8fSGustavo F. Padovan } 2792*0a708f8fSGustavo F. Padovan 2793*0a708f8fSGustavo F. Padovan if (result == L2CAP_CONF_SUCCESS) 2794*0a708f8fSGustavo F. Padovan pi->conf_state |= L2CAP_CONF_OUTPUT_DONE; 2795*0a708f8fSGustavo F. Padovan } 2796*0a708f8fSGustavo F. Padovan rsp->scid = cpu_to_le16(pi->dcid); 2797*0a708f8fSGustavo F. Padovan rsp->result = cpu_to_le16(result); 2798*0a708f8fSGustavo F. Padovan rsp->flags = cpu_to_le16(0x0000); 2799*0a708f8fSGustavo F. Padovan 2800*0a708f8fSGustavo F. Padovan return ptr - data; 2801*0a708f8fSGustavo F. Padovan } 2802*0a708f8fSGustavo F. Padovan 2803*0a708f8fSGustavo F. Padovan static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result) 2804*0a708f8fSGustavo F. Padovan { 2805*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 2806*0a708f8fSGustavo F. Padovan struct l2cap_conf_req *req = data; 2807*0a708f8fSGustavo F. Padovan void *ptr = req->data; 2808*0a708f8fSGustavo F. Padovan int type, olen; 2809*0a708f8fSGustavo F. Padovan unsigned long val; 2810*0a708f8fSGustavo F. Padovan struct l2cap_conf_rfc rfc; 2811*0a708f8fSGustavo F. Padovan 2812*0a708f8fSGustavo F. Padovan BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data); 2813*0a708f8fSGustavo F. Padovan 2814*0a708f8fSGustavo F. Padovan while (len >= L2CAP_CONF_OPT_SIZE) { 2815*0a708f8fSGustavo F. Padovan len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); 2816*0a708f8fSGustavo F. Padovan 2817*0a708f8fSGustavo F. Padovan switch (type) { 2818*0a708f8fSGustavo F. Padovan case L2CAP_CONF_MTU: 2819*0a708f8fSGustavo F. Padovan if (val < L2CAP_DEFAULT_MIN_MTU) { 2820*0a708f8fSGustavo F. Padovan *result = L2CAP_CONF_UNACCEPT; 2821*0a708f8fSGustavo F. Padovan pi->imtu = L2CAP_DEFAULT_MIN_MTU; 2822*0a708f8fSGustavo F. Padovan } else 2823*0a708f8fSGustavo F. Padovan pi->imtu = val; 2824*0a708f8fSGustavo F. Padovan l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu); 2825*0a708f8fSGustavo F. Padovan break; 2826*0a708f8fSGustavo F. Padovan 2827*0a708f8fSGustavo F. Padovan case L2CAP_CONF_FLUSH_TO: 2828*0a708f8fSGustavo F. Padovan pi->flush_to = val; 2829*0a708f8fSGustavo F. Padovan l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2830*0a708f8fSGustavo F. Padovan 2, pi->flush_to); 2831*0a708f8fSGustavo F. Padovan break; 2832*0a708f8fSGustavo F. Padovan 2833*0a708f8fSGustavo F. Padovan case L2CAP_CONF_RFC: 2834*0a708f8fSGustavo F. Padovan if (olen == sizeof(rfc)) 2835*0a708f8fSGustavo F. Padovan memcpy(&rfc, (void *)val, olen); 2836*0a708f8fSGustavo F. Padovan 2837*0a708f8fSGustavo F. Padovan if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) && 2838*0a708f8fSGustavo F. Padovan rfc.mode != pi->mode) 2839*0a708f8fSGustavo F. Padovan return -ECONNREFUSED; 2840*0a708f8fSGustavo F. Padovan 2841*0a708f8fSGustavo F. Padovan pi->fcs = 0; 2842*0a708f8fSGustavo F. Padovan 2843*0a708f8fSGustavo F. Padovan l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, 2844*0a708f8fSGustavo F. Padovan sizeof(rfc), (unsigned long) &rfc); 2845*0a708f8fSGustavo F. Padovan break; 2846*0a708f8fSGustavo F. Padovan } 2847*0a708f8fSGustavo F. Padovan } 2848*0a708f8fSGustavo F. Padovan 2849*0a708f8fSGustavo F. Padovan if (pi->mode == L2CAP_MODE_BASIC && pi->mode != rfc.mode) 2850*0a708f8fSGustavo F. Padovan return -ECONNREFUSED; 2851*0a708f8fSGustavo F. Padovan 2852*0a708f8fSGustavo F. Padovan pi->mode = rfc.mode; 2853*0a708f8fSGustavo F. Padovan 2854*0a708f8fSGustavo F. Padovan if (*result == L2CAP_CONF_SUCCESS) { 2855*0a708f8fSGustavo F. Padovan switch (rfc.mode) { 2856*0a708f8fSGustavo F. Padovan case L2CAP_MODE_ERTM: 2857*0a708f8fSGustavo F. Padovan pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout); 2858*0a708f8fSGustavo F. Padovan pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout); 2859*0a708f8fSGustavo F. Padovan pi->mps = le16_to_cpu(rfc.max_pdu_size); 2860*0a708f8fSGustavo F. Padovan break; 2861*0a708f8fSGustavo F. Padovan case L2CAP_MODE_STREAMING: 2862*0a708f8fSGustavo F. Padovan pi->mps = le16_to_cpu(rfc.max_pdu_size); 2863*0a708f8fSGustavo F. Padovan } 2864*0a708f8fSGustavo F. Padovan } 2865*0a708f8fSGustavo F. Padovan 2866*0a708f8fSGustavo F. Padovan req->dcid = cpu_to_le16(pi->dcid); 2867*0a708f8fSGustavo F. Padovan req->flags = cpu_to_le16(0x0000); 2868*0a708f8fSGustavo F. Padovan 2869*0a708f8fSGustavo F. Padovan return ptr - data; 2870*0a708f8fSGustavo F. Padovan } 2871*0a708f8fSGustavo F. Padovan 2872*0a708f8fSGustavo F. Padovan static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags) 2873*0a708f8fSGustavo F. Padovan { 2874*0a708f8fSGustavo F. Padovan struct l2cap_conf_rsp *rsp = data; 2875*0a708f8fSGustavo F. Padovan void *ptr = rsp->data; 2876*0a708f8fSGustavo F. Padovan 2877*0a708f8fSGustavo F. Padovan BT_DBG("sk %p", sk); 2878*0a708f8fSGustavo F. Padovan 2879*0a708f8fSGustavo F. Padovan rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid); 2880*0a708f8fSGustavo F. Padovan rsp->result = cpu_to_le16(result); 2881*0a708f8fSGustavo F. Padovan rsp->flags = cpu_to_le16(flags); 2882*0a708f8fSGustavo F. Padovan 2883*0a708f8fSGustavo F. Padovan return ptr - data; 2884*0a708f8fSGustavo F. Padovan } 2885*0a708f8fSGustavo F. Padovan 2886*0a708f8fSGustavo F. Padovan static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len) 2887*0a708f8fSGustavo F. Padovan { 2888*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 2889*0a708f8fSGustavo F. Padovan int type, olen; 2890*0a708f8fSGustavo F. Padovan unsigned long val; 2891*0a708f8fSGustavo F. Padovan struct l2cap_conf_rfc rfc; 2892*0a708f8fSGustavo F. Padovan 2893*0a708f8fSGustavo F. Padovan BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len); 2894*0a708f8fSGustavo F. Padovan 2895*0a708f8fSGustavo F. Padovan if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING)) 2896*0a708f8fSGustavo F. Padovan return; 2897*0a708f8fSGustavo F. Padovan 2898*0a708f8fSGustavo F. Padovan while (len >= L2CAP_CONF_OPT_SIZE) { 2899*0a708f8fSGustavo F. Padovan len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); 2900*0a708f8fSGustavo F. Padovan 2901*0a708f8fSGustavo F. Padovan switch (type) { 2902*0a708f8fSGustavo F. Padovan case L2CAP_CONF_RFC: 2903*0a708f8fSGustavo F. Padovan if (olen == sizeof(rfc)) 2904*0a708f8fSGustavo F. Padovan memcpy(&rfc, (void *)val, olen); 2905*0a708f8fSGustavo F. Padovan goto done; 2906*0a708f8fSGustavo F. Padovan } 2907*0a708f8fSGustavo F. Padovan } 2908*0a708f8fSGustavo F. Padovan 2909*0a708f8fSGustavo F. Padovan done: 2910*0a708f8fSGustavo F. Padovan switch (rfc.mode) { 2911*0a708f8fSGustavo F. Padovan case L2CAP_MODE_ERTM: 2912*0a708f8fSGustavo F. Padovan pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout); 2913*0a708f8fSGustavo F. Padovan pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout); 2914*0a708f8fSGustavo F. Padovan pi->mps = le16_to_cpu(rfc.max_pdu_size); 2915*0a708f8fSGustavo F. Padovan break; 2916*0a708f8fSGustavo F. Padovan case L2CAP_MODE_STREAMING: 2917*0a708f8fSGustavo F. Padovan pi->mps = le16_to_cpu(rfc.max_pdu_size); 2918*0a708f8fSGustavo F. Padovan } 2919*0a708f8fSGustavo F. Padovan } 2920*0a708f8fSGustavo F. Padovan 2921*0a708f8fSGustavo F. Padovan static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) 2922*0a708f8fSGustavo F. Padovan { 2923*0a708f8fSGustavo F. Padovan struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data; 2924*0a708f8fSGustavo F. Padovan 2925*0a708f8fSGustavo F. Padovan if (rej->reason != 0x0000) 2926*0a708f8fSGustavo F. Padovan return 0; 2927*0a708f8fSGustavo F. Padovan 2928*0a708f8fSGustavo F. Padovan if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) && 2929*0a708f8fSGustavo F. Padovan cmd->ident == conn->info_ident) { 2930*0a708f8fSGustavo F. Padovan del_timer(&conn->info_timer); 2931*0a708f8fSGustavo F. Padovan 2932*0a708f8fSGustavo F. Padovan conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; 2933*0a708f8fSGustavo F. Padovan conn->info_ident = 0; 2934*0a708f8fSGustavo F. Padovan 2935*0a708f8fSGustavo F. Padovan l2cap_conn_start(conn); 2936*0a708f8fSGustavo F. Padovan } 2937*0a708f8fSGustavo F. Padovan 2938*0a708f8fSGustavo F. Padovan return 0; 2939*0a708f8fSGustavo F. Padovan } 2940*0a708f8fSGustavo F. Padovan 2941*0a708f8fSGustavo F. Padovan static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) 2942*0a708f8fSGustavo F. Padovan { 2943*0a708f8fSGustavo F. Padovan struct l2cap_chan_list *list = &conn->chan_list; 2944*0a708f8fSGustavo F. Padovan struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; 2945*0a708f8fSGustavo F. Padovan struct l2cap_conn_rsp rsp; 2946*0a708f8fSGustavo F. Padovan struct sock *parent, *sk = NULL; 2947*0a708f8fSGustavo F. Padovan int result, status = L2CAP_CS_NO_INFO; 2948*0a708f8fSGustavo F. Padovan 2949*0a708f8fSGustavo F. Padovan u16 dcid = 0, scid = __le16_to_cpu(req->scid); 2950*0a708f8fSGustavo F. Padovan __le16 psm = req->psm; 2951*0a708f8fSGustavo F. Padovan 2952*0a708f8fSGustavo F. Padovan BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid); 2953*0a708f8fSGustavo F. Padovan 2954*0a708f8fSGustavo F. Padovan /* Check if we have socket listening on psm */ 2955*0a708f8fSGustavo F. Padovan parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src); 2956*0a708f8fSGustavo F. Padovan if (!parent) { 2957*0a708f8fSGustavo F. Padovan result = L2CAP_CR_BAD_PSM; 2958*0a708f8fSGustavo F. Padovan goto sendresp; 2959*0a708f8fSGustavo F. Padovan } 2960*0a708f8fSGustavo F. Padovan 2961*0a708f8fSGustavo F. Padovan bh_lock_sock(parent); 2962*0a708f8fSGustavo F. Padovan 2963*0a708f8fSGustavo F. Padovan /* Check if the ACL is secure enough (if not SDP) */ 2964*0a708f8fSGustavo F. Padovan if (psm != cpu_to_le16(0x0001) && 2965*0a708f8fSGustavo F. Padovan !hci_conn_check_link_mode(conn->hcon)) { 2966*0a708f8fSGustavo F. Padovan conn->disc_reason = 0x05; 2967*0a708f8fSGustavo F. Padovan result = L2CAP_CR_SEC_BLOCK; 2968*0a708f8fSGustavo F. Padovan goto response; 2969*0a708f8fSGustavo F. Padovan } 2970*0a708f8fSGustavo F. Padovan 2971*0a708f8fSGustavo F. Padovan result = L2CAP_CR_NO_MEM; 2972*0a708f8fSGustavo F. Padovan 2973*0a708f8fSGustavo F. Padovan /* Check for backlog size */ 2974*0a708f8fSGustavo F. Padovan if (sk_acceptq_is_full(parent)) { 2975*0a708f8fSGustavo F. Padovan BT_DBG("backlog full %d", parent->sk_ack_backlog); 2976*0a708f8fSGustavo F. Padovan goto response; 2977*0a708f8fSGustavo F. Padovan } 2978*0a708f8fSGustavo F. Padovan 2979*0a708f8fSGustavo F. Padovan sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC); 2980*0a708f8fSGustavo F. Padovan if (!sk) 2981*0a708f8fSGustavo F. Padovan goto response; 2982*0a708f8fSGustavo F. Padovan 2983*0a708f8fSGustavo F. Padovan write_lock_bh(&list->lock); 2984*0a708f8fSGustavo F. Padovan 2985*0a708f8fSGustavo F. Padovan /* Check if we already have channel with that dcid */ 2986*0a708f8fSGustavo F. Padovan if (__l2cap_get_chan_by_dcid(list, scid)) { 2987*0a708f8fSGustavo F. Padovan write_unlock_bh(&list->lock); 2988*0a708f8fSGustavo F. Padovan sock_set_flag(sk, SOCK_ZAPPED); 2989*0a708f8fSGustavo F. Padovan l2cap_sock_kill(sk); 2990*0a708f8fSGustavo F. Padovan goto response; 2991*0a708f8fSGustavo F. Padovan } 2992*0a708f8fSGustavo F. Padovan 2993*0a708f8fSGustavo F. Padovan hci_conn_hold(conn->hcon); 2994*0a708f8fSGustavo F. Padovan 2995*0a708f8fSGustavo F. Padovan l2cap_sock_init(sk, parent); 2996*0a708f8fSGustavo F. Padovan bacpy(&bt_sk(sk)->src, conn->src); 2997*0a708f8fSGustavo F. Padovan bacpy(&bt_sk(sk)->dst, conn->dst); 2998*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->psm = psm; 2999*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->dcid = scid; 3000*0a708f8fSGustavo F. Padovan 3001*0a708f8fSGustavo F. Padovan __l2cap_chan_add(conn, sk, parent); 3002*0a708f8fSGustavo F. Padovan dcid = l2cap_pi(sk)->scid; 3003*0a708f8fSGustavo F. Padovan 3004*0a708f8fSGustavo F. Padovan l2cap_sock_set_timer(sk, sk->sk_sndtimeo); 3005*0a708f8fSGustavo F. Padovan 3006*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->ident = cmd->ident; 3007*0a708f8fSGustavo F. Padovan 3008*0a708f8fSGustavo F. Padovan if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) { 3009*0a708f8fSGustavo F. Padovan if (l2cap_check_security(sk)) { 3010*0a708f8fSGustavo F. Padovan if (bt_sk(sk)->defer_setup) { 3011*0a708f8fSGustavo F. Padovan sk->sk_state = BT_CONNECT2; 3012*0a708f8fSGustavo F. Padovan result = L2CAP_CR_PEND; 3013*0a708f8fSGustavo F. Padovan status = L2CAP_CS_AUTHOR_PEND; 3014*0a708f8fSGustavo F. Padovan parent->sk_data_ready(parent, 0); 3015*0a708f8fSGustavo F. Padovan } else { 3016*0a708f8fSGustavo F. Padovan sk->sk_state = BT_CONFIG; 3017*0a708f8fSGustavo F. Padovan result = L2CAP_CR_SUCCESS; 3018*0a708f8fSGustavo F. Padovan status = L2CAP_CS_NO_INFO; 3019*0a708f8fSGustavo F. Padovan } 3020*0a708f8fSGustavo F. Padovan } else { 3021*0a708f8fSGustavo F. Padovan sk->sk_state = BT_CONNECT2; 3022*0a708f8fSGustavo F. Padovan result = L2CAP_CR_PEND; 3023*0a708f8fSGustavo F. Padovan status = L2CAP_CS_AUTHEN_PEND; 3024*0a708f8fSGustavo F. Padovan } 3025*0a708f8fSGustavo F. Padovan } else { 3026*0a708f8fSGustavo F. Padovan sk->sk_state = BT_CONNECT2; 3027*0a708f8fSGustavo F. Padovan result = L2CAP_CR_PEND; 3028*0a708f8fSGustavo F. Padovan status = L2CAP_CS_NO_INFO; 3029*0a708f8fSGustavo F. Padovan } 3030*0a708f8fSGustavo F. Padovan 3031*0a708f8fSGustavo F. Padovan write_unlock_bh(&list->lock); 3032*0a708f8fSGustavo F. Padovan 3033*0a708f8fSGustavo F. Padovan response: 3034*0a708f8fSGustavo F. Padovan bh_unlock_sock(parent); 3035*0a708f8fSGustavo F. Padovan 3036*0a708f8fSGustavo F. Padovan sendresp: 3037*0a708f8fSGustavo F. Padovan rsp.scid = cpu_to_le16(scid); 3038*0a708f8fSGustavo F. Padovan rsp.dcid = cpu_to_le16(dcid); 3039*0a708f8fSGustavo F. Padovan rsp.result = cpu_to_le16(result); 3040*0a708f8fSGustavo F. Padovan rsp.status = cpu_to_le16(status); 3041*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); 3042*0a708f8fSGustavo F. Padovan 3043*0a708f8fSGustavo F. Padovan if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) { 3044*0a708f8fSGustavo F. Padovan struct l2cap_info_req info; 3045*0a708f8fSGustavo F. Padovan info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); 3046*0a708f8fSGustavo F. Padovan 3047*0a708f8fSGustavo F. Padovan conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; 3048*0a708f8fSGustavo F. Padovan conn->info_ident = l2cap_get_ident(conn); 3049*0a708f8fSGustavo F. Padovan 3050*0a708f8fSGustavo F. Padovan mod_timer(&conn->info_timer, jiffies + 3051*0a708f8fSGustavo F. Padovan msecs_to_jiffies(L2CAP_INFO_TIMEOUT)); 3052*0a708f8fSGustavo F. Padovan 3053*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, conn->info_ident, 3054*0a708f8fSGustavo F. Padovan L2CAP_INFO_REQ, sizeof(info), &info); 3055*0a708f8fSGustavo F. Padovan } 3056*0a708f8fSGustavo F. Padovan 3057*0a708f8fSGustavo F. Padovan if (sk && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) && 3058*0a708f8fSGustavo F. Padovan result == L2CAP_CR_SUCCESS) { 3059*0a708f8fSGustavo F. Padovan u8 buf[128]; 3060*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; 3061*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, 3062*0a708f8fSGustavo F. Padovan l2cap_build_conf_req(sk, buf), buf); 3063*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->num_conf_req++; 3064*0a708f8fSGustavo F. Padovan } 3065*0a708f8fSGustavo F. Padovan 3066*0a708f8fSGustavo F. Padovan return 0; 3067*0a708f8fSGustavo F. Padovan } 3068*0a708f8fSGustavo F. Padovan 3069*0a708f8fSGustavo F. Padovan static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) 3070*0a708f8fSGustavo F. Padovan { 3071*0a708f8fSGustavo F. Padovan struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data; 3072*0a708f8fSGustavo F. Padovan u16 scid, dcid, result, status; 3073*0a708f8fSGustavo F. Padovan struct sock *sk; 3074*0a708f8fSGustavo F. Padovan u8 req[128]; 3075*0a708f8fSGustavo F. Padovan 3076*0a708f8fSGustavo F. Padovan scid = __le16_to_cpu(rsp->scid); 3077*0a708f8fSGustavo F. Padovan dcid = __le16_to_cpu(rsp->dcid); 3078*0a708f8fSGustavo F. Padovan result = __le16_to_cpu(rsp->result); 3079*0a708f8fSGustavo F. Padovan status = __le16_to_cpu(rsp->status); 3080*0a708f8fSGustavo F. Padovan 3081*0a708f8fSGustavo F. Padovan BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status); 3082*0a708f8fSGustavo F. Padovan 3083*0a708f8fSGustavo F. Padovan if (scid) { 3084*0a708f8fSGustavo F. Padovan sk = l2cap_get_chan_by_scid(&conn->chan_list, scid); 3085*0a708f8fSGustavo F. Padovan if (!sk) 3086*0a708f8fSGustavo F. Padovan return -EFAULT; 3087*0a708f8fSGustavo F. Padovan } else { 3088*0a708f8fSGustavo F. Padovan sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident); 3089*0a708f8fSGustavo F. Padovan if (!sk) 3090*0a708f8fSGustavo F. Padovan return -EFAULT; 3091*0a708f8fSGustavo F. Padovan } 3092*0a708f8fSGustavo F. Padovan 3093*0a708f8fSGustavo F. Padovan switch (result) { 3094*0a708f8fSGustavo F. Padovan case L2CAP_CR_SUCCESS: 3095*0a708f8fSGustavo F. Padovan sk->sk_state = BT_CONFIG; 3096*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->ident = 0; 3097*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->dcid = dcid; 3098*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND; 3099*0a708f8fSGustavo F. Padovan 3100*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) 3101*0a708f8fSGustavo F. Padovan break; 3102*0a708f8fSGustavo F. Padovan 3103*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; 3104*0a708f8fSGustavo F. Padovan 3105*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, 3106*0a708f8fSGustavo F. Padovan l2cap_build_conf_req(sk, req), req); 3107*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->num_conf_req++; 3108*0a708f8fSGustavo F. Padovan break; 3109*0a708f8fSGustavo F. Padovan 3110*0a708f8fSGustavo F. Padovan case L2CAP_CR_PEND: 3111*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND; 3112*0a708f8fSGustavo F. Padovan break; 3113*0a708f8fSGustavo F. Padovan 3114*0a708f8fSGustavo F. Padovan default: 3115*0a708f8fSGustavo F. Padovan /* don't delete l2cap channel if sk is owned by user */ 3116*0a708f8fSGustavo F. Padovan if (sock_owned_by_user(sk)) { 3117*0a708f8fSGustavo F. Padovan sk->sk_state = BT_DISCONN; 3118*0a708f8fSGustavo F. Padovan l2cap_sock_clear_timer(sk); 3119*0a708f8fSGustavo F. Padovan l2cap_sock_set_timer(sk, HZ / 5); 3120*0a708f8fSGustavo F. Padovan break; 3121*0a708f8fSGustavo F. Padovan } 3122*0a708f8fSGustavo F. Padovan 3123*0a708f8fSGustavo F. Padovan l2cap_chan_del(sk, ECONNREFUSED); 3124*0a708f8fSGustavo F. Padovan break; 3125*0a708f8fSGustavo F. Padovan } 3126*0a708f8fSGustavo F. Padovan 3127*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 3128*0a708f8fSGustavo F. Padovan return 0; 3129*0a708f8fSGustavo F. Padovan } 3130*0a708f8fSGustavo F. Padovan 3131*0a708f8fSGustavo F. Padovan static inline void set_default_fcs(struct l2cap_pinfo *pi) 3132*0a708f8fSGustavo F. Padovan { 3133*0a708f8fSGustavo F. Padovan /* FCS is enabled only in ERTM or streaming mode, if one or both 3134*0a708f8fSGustavo F. Padovan * sides request it. 3135*0a708f8fSGustavo F. Padovan */ 3136*0a708f8fSGustavo F. Padovan if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING) 3137*0a708f8fSGustavo F. Padovan pi->fcs = L2CAP_FCS_NONE; 3138*0a708f8fSGustavo F. Padovan else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV)) 3139*0a708f8fSGustavo F. Padovan pi->fcs = L2CAP_FCS_CRC16; 3140*0a708f8fSGustavo F. Padovan } 3141*0a708f8fSGustavo F. Padovan 3142*0a708f8fSGustavo F. Padovan static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) 3143*0a708f8fSGustavo F. Padovan { 3144*0a708f8fSGustavo F. Padovan struct l2cap_conf_req *req = (struct l2cap_conf_req *) data; 3145*0a708f8fSGustavo F. Padovan u16 dcid, flags; 3146*0a708f8fSGustavo F. Padovan u8 rsp[64]; 3147*0a708f8fSGustavo F. Padovan struct sock *sk; 3148*0a708f8fSGustavo F. Padovan int len; 3149*0a708f8fSGustavo F. Padovan 3150*0a708f8fSGustavo F. Padovan dcid = __le16_to_cpu(req->dcid); 3151*0a708f8fSGustavo F. Padovan flags = __le16_to_cpu(req->flags); 3152*0a708f8fSGustavo F. Padovan 3153*0a708f8fSGustavo F. Padovan BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags); 3154*0a708f8fSGustavo F. Padovan 3155*0a708f8fSGustavo F. Padovan sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid); 3156*0a708f8fSGustavo F. Padovan if (!sk) 3157*0a708f8fSGustavo F. Padovan return -ENOENT; 3158*0a708f8fSGustavo F. Padovan 3159*0a708f8fSGustavo F. Padovan if (sk->sk_state != BT_CONFIG) { 3160*0a708f8fSGustavo F. Padovan struct l2cap_cmd_rej rej; 3161*0a708f8fSGustavo F. Padovan 3162*0a708f8fSGustavo F. Padovan rej.reason = cpu_to_le16(0x0002); 3163*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, 3164*0a708f8fSGustavo F. Padovan sizeof(rej), &rej); 3165*0a708f8fSGustavo F. Padovan goto unlock; 3166*0a708f8fSGustavo F. Padovan } 3167*0a708f8fSGustavo F. Padovan 3168*0a708f8fSGustavo F. Padovan /* Reject if config buffer is too small. */ 3169*0a708f8fSGustavo F. Padovan len = cmd_len - sizeof(*req); 3170*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) { 3171*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, 3172*0a708f8fSGustavo F. Padovan l2cap_build_conf_rsp(sk, rsp, 3173*0a708f8fSGustavo F. Padovan L2CAP_CONF_REJECT, flags), rsp); 3174*0a708f8fSGustavo F. Padovan goto unlock; 3175*0a708f8fSGustavo F. Padovan } 3176*0a708f8fSGustavo F. Padovan 3177*0a708f8fSGustavo F. Padovan /* Store config. */ 3178*0a708f8fSGustavo F. Padovan memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len); 3179*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conf_len += len; 3180*0a708f8fSGustavo F. Padovan 3181*0a708f8fSGustavo F. Padovan if (flags & 0x0001) { 3182*0a708f8fSGustavo F. Padovan /* Incomplete config. Send empty response. */ 3183*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, 3184*0a708f8fSGustavo F. Padovan l2cap_build_conf_rsp(sk, rsp, 3185*0a708f8fSGustavo F. Padovan L2CAP_CONF_SUCCESS, 0x0001), rsp); 3186*0a708f8fSGustavo F. Padovan goto unlock; 3187*0a708f8fSGustavo F. Padovan } 3188*0a708f8fSGustavo F. Padovan 3189*0a708f8fSGustavo F. Padovan /* Complete config. */ 3190*0a708f8fSGustavo F. Padovan len = l2cap_parse_conf_req(sk, rsp); 3191*0a708f8fSGustavo F. Padovan if (len < 0) { 3192*0a708f8fSGustavo F. Padovan l2cap_send_disconn_req(conn, sk, ECONNRESET); 3193*0a708f8fSGustavo F. Padovan goto unlock; 3194*0a708f8fSGustavo F. Padovan } 3195*0a708f8fSGustavo F. Padovan 3196*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp); 3197*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->num_conf_rsp++; 3198*0a708f8fSGustavo F. Padovan 3199*0a708f8fSGustavo F. Padovan /* Reset config buffer. */ 3200*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conf_len = 0; 3201*0a708f8fSGustavo F. Padovan 3202*0a708f8fSGustavo F. Padovan if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE)) 3203*0a708f8fSGustavo F. Padovan goto unlock; 3204*0a708f8fSGustavo F. Padovan 3205*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) { 3206*0a708f8fSGustavo F. Padovan set_default_fcs(l2cap_pi(sk)); 3207*0a708f8fSGustavo F. Padovan 3208*0a708f8fSGustavo F. Padovan sk->sk_state = BT_CONNECTED; 3209*0a708f8fSGustavo F. Padovan 3210*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->next_tx_seq = 0; 3211*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->expected_tx_seq = 0; 3212*0a708f8fSGustavo F. Padovan __skb_queue_head_init(TX_QUEUE(sk)); 3213*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) 3214*0a708f8fSGustavo F. Padovan l2cap_ertm_init(sk); 3215*0a708f8fSGustavo F. Padovan 3216*0a708f8fSGustavo F. Padovan l2cap_chan_ready(sk); 3217*0a708f8fSGustavo F. Padovan goto unlock; 3218*0a708f8fSGustavo F. Padovan } 3219*0a708f8fSGustavo F. Padovan 3220*0a708f8fSGustavo F. Padovan if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) { 3221*0a708f8fSGustavo F. Padovan u8 buf[64]; 3222*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; 3223*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, 3224*0a708f8fSGustavo F. Padovan l2cap_build_conf_req(sk, buf), buf); 3225*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->num_conf_req++; 3226*0a708f8fSGustavo F. Padovan } 3227*0a708f8fSGustavo F. Padovan 3228*0a708f8fSGustavo F. Padovan unlock: 3229*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 3230*0a708f8fSGustavo F. Padovan return 0; 3231*0a708f8fSGustavo F. Padovan } 3232*0a708f8fSGustavo F. Padovan 3233*0a708f8fSGustavo F. Padovan static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) 3234*0a708f8fSGustavo F. Padovan { 3235*0a708f8fSGustavo F. Padovan struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data; 3236*0a708f8fSGustavo F. Padovan u16 scid, flags, result; 3237*0a708f8fSGustavo F. Padovan struct sock *sk; 3238*0a708f8fSGustavo F. Padovan int len = cmd->len - sizeof(*rsp); 3239*0a708f8fSGustavo F. Padovan 3240*0a708f8fSGustavo F. Padovan scid = __le16_to_cpu(rsp->scid); 3241*0a708f8fSGustavo F. Padovan flags = __le16_to_cpu(rsp->flags); 3242*0a708f8fSGustavo F. Padovan result = __le16_to_cpu(rsp->result); 3243*0a708f8fSGustavo F. Padovan 3244*0a708f8fSGustavo F. Padovan BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", 3245*0a708f8fSGustavo F. Padovan scid, flags, result); 3246*0a708f8fSGustavo F. Padovan 3247*0a708f8fSGustavo F. Padovan sk = l2cap_get_chan_by_scid(&conn->chan_list, scid); 3248*0a708f8fSGustavo F. Padovan if (!sk) 3249*0a708f8fSGustavo F. Padovan return 0; 3250*0a708f8fSGustavo F. Padovan 3251*0a708f8fSGustavo F. Padovan switch (result) { 3252*0a708f8fSGustavo F. Padovan case L2CAP_CONF_SUCCESS: 3253*0a708f8fSGustavo F. Padovan l2cap_conf_rfc_get(sk, rsp->data, len); 3254*0a708f8fSGustavo F. Padovan break; 3255*0a708f8fSGustavo F. Padovan 3256*0a708f8fSGustavo F. Padovan case L2CAP_CONF_UNACCEPT: 3257*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) { 3258*0a708f8fSGustavo F. Padovan char req[64]; 3259*0a708f8fSGustavo F. Padovan 3260*0a708f8fSGustavo F. Padovan if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) { 3261*0a708f8fSGustavo F. Padovan l2cap_send_disconn_req(conn, sk, ECONNRESET); 3262*0a708f8fSGustavo F. Padovan goto done; 3263*0a708f8fSGustavo F. Padovan } 3264*0a708f8fSGustavo F. Padovan 3265*0a708f8fSGustavo F. Padovan /* throw out any old stored conf requests */ 3266*0a708f8fSGustavo F. Padovan result = L2CAP_CONF_SUCCESS; 3267*0a708f8fSGustavo F. Padovan len = l2cap_parse_conf_rsp(sk, rsp->data, 3268*0a708f8fSGustavo F. Padovan len, req, &result); 3269*0a708f8fSGustavo F. Padovan if (len < 0) { 3270*0a708f8fSGustavo F. Padovan l2cap_send_disconn_req(conn, sk, ECONNRESET); 3271*0a708f8fSGustavo F. Padovan goto done; 3272*0a708f8fSGustavo F. Padovan } 3273*0a708f8fSGustavo F. Padovan 3274*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, l2cap_get_ident(conn), 3275*0a708f8fSGustavo F. Padovan L2CAP_CONF_REQ, len, req); 3276*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->num_conf_req++; 3277*0a708f8fSGustavo F. Padovan if (result != L2CAP_CONF_SUCCESS) 3278*0a708f8fSGustavo F. Padovan goto done; 3279*0a708f8fSGustavo F. Padovan break; 3280*0a708f8fSGustavo F. Padovan } 3281*0a708f8fSGustavo F. Padovan 3282*0a708f8fSGustavo F. Padovan default: 3283*0a708f8fSGustavo F. Padovan sk->sk_err = ECONNRESET; 3284*0a708f8fSGustavo F. Padovan l2cap_sock_set_timer(sk, HZ * 5); 3285*0a708f8fSGustavo F. Padovan l2cap_send_disconn_req(conn, sk, ECONNRESET); 3286*0a708f8fSGustavo F. Padovan goto done; 3287*0a708f8fSGustavo F. Padovan } 3288*0a708f8fSGustavo F. Padovan 3289*0a708f8fSGustavo F. Padovan if (flags & 0x01) 3290*0a708f8fSGustavo F. Padovan goto done; 3291*0a708f8fSGustavo F. Padovan 3292*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE; 3293*0a708f8fSGustavo F. Padovan 3294*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) { 3295*0a708f8fSGustavo F. Padovan set_default_fcs(l2cap_pi(sk)); 3296*0a708f8fSGustavo F. Padovan 3297*0a708f8fSGustavo F. Padovan sk->sk_state = BT_CONNECTED; 3298*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->next_tx_seq = 0; 3299*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->expected_tx_seq = 0; 3300*0a708f8fSGustavo F. Padovan __skb_queue_head_init(TX_QUEUE(sk)); 3301*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) 3302*0a708f8fSGustavo F. Padovan l2cap_ertm_init(sk); 3303*0a708f8fSGustavo F. Padovan 3304*0a708f8fSGustavo F. Padovan l2cap_chan_ready(sk); 3305*0a708f8fSGustavo F. Padovan } 3306*0a708f8fSGustavo F. Padovan 3307*0a708f8fSGustavo F. Padovan done: 3308*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 3309*0a708f8fSGustavo F. Padovan return 0; 3310*0a708f8fSGustavo F. Padovan } 3311*0a708f8fSGustavo F. Padovan 3312*0a708f8fSGustavo F. Padovan static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) 3313*0a708f8fSGustavo F. Padovan { 3314*0a708f8fSGustavo F. Padovan struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data; 3315*0a708f8fSGustavo F. Padovan struct l2cap_disconn_rsp rsp; 3316*0a708f8fSGustavo F. Padovan u16 dcid, scid; 3317*0a708f8fSGustavo F. Padovan struct sock *sk; 3318*0a708f8fSGustavo F. Padovan 3319*0a708f8fSGustavo F. Padovan scid = __le16_to_cpu(req->scid); 3320*0a708f8fSGustavo F. Padovan dcid = __le16_to_cpu(req->dcid); 3321*0a708f8fSGustavo F. Padovan 3322*0a708f8fSGustavo F. Padovan BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid); 3323*0a708f8fSGustavo F. Padovan 3324*0a708f8fSGustavo F. Padovan sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid); 3325*0a708f8fSGustavo F. Padovan if (!sk) 3326*0a708f8fSGustavo F. Padovan return 0; 3327*0a708f8fSGustavo F. Padovan 3328*0a708f8fSGustavo F. Padovan rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); 3329*0a708f8fSGustavo F. Padovan rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); 3330*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp); 3331*0a708f8fSGustavo F. Padovan 3332*0a708f8fSGustavo F. Padovan sk->sk_shutdown = SHUTDOWN_MASK; 3333*0a708f8fSGustavo F. Padovan 3334*0a708f8fSGustavo F. Padovan /* don't delete l2cap channel if sk is owned by user */ 3335*0a708f8fSGustavo F. Padovan if (sock_owned_by_user(sk)) { 3336*0a708f8fSGustavo F. Padovan sk->sk_state = BT_DISCONN; 3337*0a708f8fSGustavo F. Padovan l2cap_sock_clear_timer(sk); 3338*0a708f8fSGustavo F. Padovan l2cap_sock_set_timer(sk, HZ / 5); 3339*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 3340*0a708f8fSGustavo F. Padovan return 0; 3341*0a708f8fSGustavo F. Padovan } 3342*0a708f8fSGustavo F. Padovan 3343*0a708f8fSGustavo F. Padovan l2cap_chan_del(sk, ECONNRESET); 3344*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 3345*0a708f8fSGustavo F. Padovan 3346*0a708f8fSGustavo F. Padovan l2cap_sock_kill(sk); 3347*0a708f8fSGustavo F. Padovan return 0; 3348*0a708f8fSGustavo F. Padovan } 3349*0a708f8fSGustavo F. Padovan 3350*0a708f8fSGustavo F. Padovan static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) 3351*0a708f8fSGustavo F. Padovan { 3352*0a708f8fSGustavo F. Padovan struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data; 3353*0a708f8fSGustavo F. Padovan u16 dcid, scid; 3354*0a708f8fSGustavo F. Padovan struct sock *sk; 3355*0a708f8fSGustavo F. Padovan 3356*0a708f8fSGustavo F. Padovan scid = __le16_to_cpu(rsp->scid); 3357*0a708f8fSGustavo F. Padovan dcid = __le16_to_cpu(rsp->dcid); 3358*0a708f8fSGustavo F. Padovan 3359*0a708f8fSGustavo F. Padovan BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid); 3360*0a708f8fSGustavo F. Padovan 3361*0a708f8fSGustavo F. Padovan sk = l2cap_get_chan_by_scid(&conn->chan_list, scid); 3362*0a708f8fSGustavo F. Padovan if (!sk) 3363*0a708f8fSGustavo F. Padovan return 0; 3364*0a708f8fSGustavo F. Padovan 3365*0a708f8fSGustavo F. Padovan /* don't delete l2cap channel if sk is owned by user */ 3366*0a708f8fSGustavo F. Padovan if (sock_owned_by_user(sk)) { 3367*0a708f8fSGustavo F. Padovan sk->sk_state = BT_DISCONN; 3368*0a708f8fSGustavo F. Padovan l2cap_sock_clear_timer(sk); 3369*0a708f8fSGustavo F. Padovan l2cap_sock_set_timer(sk, HZ / 5); 3370*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 3371*0a708f8fSGustavo F. Padovan return 0; 3372*0a708f8fSGustavo F. Padovan } 3373*0a708f8fSGustavo F. Padovan 3374*0a708f8fSGustavo F. Padovan l2cap_chan_del(sk, 0); 3375*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 3376*0a708f8fSGustavo F. Padovan 3377*0a708f8fSGustavo F. Padovan l2cap_sock_kill(sk); 3378*0a708f8fSGustavo F. Padovan return 0; 3379*0a708f8fSGustavo F. Padovan } 3380*0a708f8fSGustavo F. Padovan 3381*0a708f8fSGustavo F. Padovan static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) 3382*0a708f8fSGustavo F. Padovan { 3383*0a708f8fSGustavo F. Padovan struct l2cap_info_req *req = (struct l2cap_info_req *) data; 3384*0a708f8fSGustavo F. Padovan u16 type; 3385*0a708f8fSGustavo F. Padovan 3386*0a708f8fSGustavo F. Padovan type = __le16_to_cpu(req->type); 3387*0a708f8fSGustavo F. Padovan 3388*0a708f8fSGustavo F. Padovan BT_DBG("type 0x%4.4x", type); 3389*0a708f8fSGustavo F. Padovan 3390*0a708f8fSGustavo F. Padovan if (type == L2CAP_IT_FEAT_MASK) { 3391*0a708f8fSGustavo F. Padovan u8 buf[8]; 3392*0a708f8fSGustavo F. Padovan u32 feat_mask = l2cap_feat_mask; 3393*0a708f8fSGustavo F. Padovan struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf; 3394*0a708f8fSGustavo F. Padovan rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK); 3395*0a708f8fSGustavo F. Padovan rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS); 3396*0a708f8fSGustavo F. Padovan if (!disable_ertm) 3397*0a708f8fSGustavo F. Padovan feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING 3398*0a708f8fSGustavo F. Padovan | L2CAP_FEAT_FCS; 3399*0a708f8fSGustavo F. Padovan put_unaligned_le32(feat_mask, rsp->data); 3400*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, cmd->ident, 3401*0a708f8fSGustavo F. Padovan L2CAP_INFO_RSP, sizeof(buf), buf); 3402*0a708f8fSGustavo F. Padovan } else if (type == L2CAP_IT_FIXED_CHAN) { 3403*0a708f8fSGustavo F. Padovan u8 buf[12]; 3404*0a708f8fSGustavo F. Padovan struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf; 3405*0a708f8fSGustavo F. Padovan rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN); 3406*0a708f8fSGustavo F. Padovan rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS); 3407*0a708f8fSGustavo F. Padovan memcpy(buf + 4, l2cap_fixed_chan, 8); 3408*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, cmd->ident, 3409*0a708f8fSGustavo F. Padovan L2CAP_INFO_RSP, sizeof(buf), buf); 3410*0a708f8fSGustavo F. Padovan } else { 3411*0a708f8fSGustavo F. Padovan struct l2cap_info_rsp rsp; 3412*0a708f8fSGustavo F. Padovan rsp.type = cpu_to_le16(type); 3413*0a708f8fSGustavo F. Padovan rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP); 3414*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, cmd->ident, 3415*0a708f8fSGustavo F. Padovan L2CAP_INFO_RSP, sizeof(rsp), &rsp); 3416*0a708f8fSGustavo F. Padovan } 3417*0a708f8fSGustavo F. Padovan 3418*0a708f8fSGustavo F. Padovan return 0; 3419*0a708f8fSGustavo F. Padovan } 3420*0a708f8fSGustavo F. Padovan 3421*0a708f8fSGustavo F. Padovan static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) 3422*0a708f8fSGustavo F. Padovan { 3423*0a708f8fSGustavo F. Padovan struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data; 3424*0a708f8fSGustavo F. Padovan u16 type, result; 3425*0a708f8fSGustavo F. Padovan 3426*0a708f8fSGustavo F. Padovan type = __le16_to_cpu(rsp->type); 3427*0a708f8fSGustavo F. Padovan result = __le16_to_cpu(rsp->result); 3428*0a708f8fSGustavo F. Padovan 3429*0a708f8fSGustavo F. Padovan BT_DBG("type 0x%4.4x result 0x%2.2x", type, result); 3430*0a708f8fSGustavo F. Padovan 3431*0a708f8fSGustavo F. Padovan del_timer(&conn->info_timer); 3432*0a708f8fSGustavo F. Padovan 3433*0a708f8fSGustavo F. Padovan if (result != L2CAP_IR_SUCCESS) { 3434*0a708f8fSGustavo F. Padovan conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; 3435*0a708f8fSGustavo F. Padovan conn->info_ident = 0; 3436*0a708f8fSGustavo F. Padovan 3437*0a708f8fSGustavo F. Padovan l2cap_conn_start(conn); 3438*0a708f8fSGustavo F. Padovan 3439*0a708f8fSGustavo F. Padovan return 0; 3440*0a708f8fSGustavo F. Padovan } 3441*0a708f8fSGustavo F. Padovan 3442*0a708f8fSGustavo F. Padovan if (type == L2CAP_IT_FEAT_MASK) { 3443*0a708f8fSGustavo F. Padovan conn->feat_mask = get_unaligned_le32(rsp->data); 3444*0a708f8fSGustavo F. Padovan 3445*0a708f8fSGustavo F. Padovan if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) { 3446*0a708f8fSGustavo F. Padovan struct l2cap_info_req req; 3447*0a708f8fSGustavo F. Padovan req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN); 3448*0a708f8fSGustavo F. Padovan 3449*0a708f8fSGustavo F. Padovan conn->info_ident = l2cap_get_ident(conn); 3450*0a708f8fSGustavo F. Padovan 3451*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, conn->info_ident, 3452*0a708f8fSGustavo F. Padovan L2CAP_INFO_REQ, sizeof(req), &req); 3453*0a708f8fSGustavo F. Padovan } else { 3454*0a708f8fSGustavo F. Padovan conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; 3455*0a708f8fSGustavo F. Padovan conn->info_ident = 0; 3456*0a708f8fSGustavo F. Padovan 3457*0a708f8fSGustavo F. Padovan l2cap_conn_start(conn); 3458*0a708f8fSGustavo F. Padovan } 3459*0a708f8fSGustavo F. Padovan } else if (type == L2CAP_IT_FIXED_CHAN) { 3460*0a708f8fSGustavo F. Padovan conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; 3461*0a708f8fSGustavo F. Padovan conn->info_ident = 0; 3462*0a708f8fSGustavo F. Padovan 3463*0a708f8fSGustavo F. Padovan l2cap_conn_start(conn); 3464*0a708f8fSGustavo F. Padovan } 3465*0a708f8fSGustavo F. Padovan 3466*0a708f8fSGustavo F. Padovan return 0; 3467*0a708f8fSGustavo F. Padovan } 3468*0a708f8fSGustavo F. Padovan 3469*0a708f8fSGustavo F. Padovan static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) 3470*0a708f8fSGustavo F. Padovan { 3471*0a708f8fSGustavo F. Padovan u8 *data = skb->data; 3472*0a708f8fSGustavo F. Padovan int len = skb->len; 3473*0a708f8fSGustavo F. Padovan struct l2cap_cmd_hdr cmd; 3474*0a708f8fSGustavo F. Padovan int err = 0; 3475*0a708f8fSGustavo F. Padovan 3476*0a708f8fSGustavo F. Padovan l2cap_raw_recv(conn, skb); 3477*0a708f8fSGustavo F. Padovan 3478*0a708f8fSGustavo F. Padovan while (len >= L2CAP_CMD_HDR_SIZE) { 3479*0a708f8fSGustavo F. Padovan u16 cmd_len; 3480*0a708f8fSGustavo F. Padovan memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE); 3481*0a708f8fSGustavo F. Padovan data += L2CAP_CMD_HDR_SIZE; 3482*0a708f8fSGustavo F. Padovan len -= L2CAP_CMD_HDR_SIZE; 3483*0a708f8fSGustavo F. Padovan 3484*0a708f8fSGustavo F. Padovan cmd_len = le16_to_cpu(cmd.len); 3485*0a708f8fSGustavo F. Padovan 3486*0a708f8fSGustavo F. Padovan BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len, cmd.ident); 3487*0a708f8fSGustavo F. Padovan 3488*0a708f8fSGustavo F. Padovan if (cmd_len > len || !cmd.ident) { 3489*0a708f8fSGustavo F. Padovan BT_DBG("corrupted command"); 3490*0a708f8fSGustavo F. Padovan break; 3491*0a708f8fSGustavo F. Padovan } 3492*0a708f8fSGustavo F. Padovan 3493*0a708f8fSGustavo F. Padovan switch (cmd.code) { 3494*0a708f8fSGustavo F. Padovan case L2CAP_COMMAND_REJ: 3495*0a708f8fSGustavo F. Padovan l2cap_command_rej(conn, &cmd, data); 3496*0a708f8fSGustavo F. Padovan break; 3497*0a708f8fSGustavo F. Padovan 3498*0a708f8fSGustavo F. Padovan case L2CAP_CONN_REQ: 3499*0a708f8fSGustavo F. Padovan err = l2cap_connect_req(conn, &cmd, data); 3500*0a708f8fSGustavo F. Padovan break; 3501*0a708f8fSGustavo F. Padovan 3502*0a708f8fSGustavo F. Padovan case L2CAP_CONN_RSP: 3503*0a708f8fSGustavo F. Padovan err = l2cap_connect_rsp(conn, &cmd, data); 3504*0a708f8fSGustavo F. Padovan break; 3505*0a708f8fSGustavo F. Padovan 3506*0a708f8fSGustavo F. Padovan case L2CAP_CONF_REQ: 3507*0a708f8fSGustavo F. Padovan err = l2cap_config_req(conn, &cmd, cmd_len, data); 3508*0a708f8fSGustavo F. Padovan break; 3509*0a708f8fSGustavo F. Padovan 3510*0a708f8fSGustavo F. Padovan case L2CAP_CONF_RSP: 3511*0a708f8fSGustavo F. Padovan err = l2cap_config_rsp(conn, &cmd, data); 3512*0a708f8fSGustavo F. Padovan break; 3513*0a708f8fSGustavo F. Padovan 3514*0a708f8fSGustavo F. Padovan case L2CAP_DISCONN_REQ: 3515*0a708f8fSGustavo F. Padovan err = l2cap_disconnect_req(conn, &cmd, data); 3516*0a708f8fSGustavo F. Padovan break; 3517*0a708f8fSGustavo F. Padovan 3518*0a708f8fSGustavo F. Padovan case L2CAP_DISCONN_RSP: 3519*0a708f8fSGustavo F. Padovan err = l2cap_disconnect_rsp(conn, &cmd, data); 3520*0a708f8fSGustavo F. Padovan break; 3521*0a708f8fSGustavo F. Padovan 3522*0a708f8fSGustavo F. Padovan case L2CAP_ECHO_REQ: 3523*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data); 3524*0a708f8fSGustavo F. Padovan break; 3525*0a708f8fSGustavo F. Padovan 3526*0a708f8fSGustavo F. Padovan case L2CAP_ECHO_RSP: 3527*0a708f8fSGustavo F. Padovan break; 3528*0a708f8fSGustavo F. Padovan 3529*0a708f8fSGustavo F. Padovan case L2CAP_INFO_REQ: 3530*0a708f8fSGustavo F. Padovan err = l2cap_information_req(conn, &cmd, data); 3531*0a708f8fSGustavo F. Padovan break; 3532*0a708f8fSGustavo F. Padovan 3533*0a708f8fSGustavo F. Padovan case L2CAP_INFO_RSP: 3534*0a708f8fSGustavo F. Padovan err = l2cap_information_rsp(conn, &cmd, data); 3535*0a708f8fSGustavo F. Padovan break; 3536*0a708f8fSGustavo F. Padovan 3537*0a708f8fSGustavo F. Padovan default: 3538*0a708f8fSGustavo F. Padovan BT_ERR("Unknown signaling command 0x%2.2x", cmd.code); 3539*0a708f8fSGustavo F. Padovan err = -EINVAL; 3540*0a708f8fSGustavo F. Padovan break; 3541*0a708f8fSGustavo F. Padovan } 3542*0a708f8fSGustavo F. Padovan 3543*0a708f8fSGustavo F. Padovan if (err) { 3544*0a708f8fSGustavo F. Padovan struct l2cap_cmd_rej rej; 3545*0a708f8fSGustavo F. Padovan BT_DBG("error %d", err); 3546*0a708f8fSGustavo F. Padovan 3547*0a708f8fSGustavo F. Padovan /* FIXME: Map err to a valid reason */ 3548*0a708f8fSGustavo F. Padovan rej.reason = cpu_to_le16(0); 3549*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej); 3550*0a708f8fSGustavo F. Padovan } 3551*0a708f8fSGustavo F. Padovan 3552*0a708f8fSGustavo F. Padovan data += cmd_len; 3553*0a708f8fSGustavo F. Padovan len -= cmd_len; 3554*0a708f8fSGustavo F. Padovan } 3555*0a708f8fSGustavo F. Padovan 3556*0a708f8fSGustavo F. Padovan kfree_skb(skb); 3557*0a708f8fSGustavo F. Padovan } 3558*0a708f8fSGustavo F. Padovan 3559*0a708f8fSGustavo F. Padovan static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb) 3560*0a708f8fSGustavo F. Padovan { 3561*0a708f8fSGustavo F. Padovan u16 our_fcs, rcv_fcs; 3562*0a708f8fSGustavo F. Padovan int hdr_size = L2CAP_HDR_SIZE + 2; 3563*0a708f8fSGustavo F. Padovan 3564*0a708f8fSGustavo F. Padovan if (pi->fcs == L2CAP_FCS_CRC16) { 3565*0a708f8fSGustavo F. Padovan skb_trim(skb, skb->len - 2); 3566*0a708f8fSGustavo F. Padovan rcv_fcs = get_unaligned_le16(skb->data + skb->len); 3567*0a708f8fSGustavo F. Padovan our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size); 3568*0a708f8fSGustavo F. Padovan 3569*0a708f8fSGustavo F. Padovan if (our_fcs != rcv_fcs) 3570*0a708f8fSGustavo F. Padovan return -EBADMSG; 3571*0a708f8fSGustavo F. Padovan } 3572*0a708f8fSGustavo F. Padovan return 0; 3573*0a708f8fSGustavo F. Padovan } 3574*0a708f8fSGustavo F. Padovan 3575*0a708f8fSGustavo F. Padovan static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk) 3576*0a708f8fSGustavo F. Padovan { 3577*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 3578*0a708f8fSGustavo F. Padovan u16 control = 0; 3579*0a708f8fSGustavo F. Padovan 3580*0a708f8fSGustavo F. Padovan pi->frames_sent = 0; 3581*0a708f8fSGustavo F. Padovan 3582*0a708f8fSGustavo F. Padovan control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; 3583*0a708f8fSGustavo F. Padovan 3584*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) { 3585*0a708f8fSGustavo F. Padovan control |= L2CAP_SUPER_RCV_NOT_READY; 3586*0a708f8fSGustavo F. Padovan l2cap_send_sframe(pi, control); 3587*0a708f8fSGustavo F. Padovan pi->conn_state |= L2CAP_CONN_RNR_SENT; 3588*0a708f8fSGustavo F. Padovan } 3589*0a708f8fSGustavo F. Padovan 3590*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY) 3591*0a708f8fSGustavo F. Padovan l2cap_retransmit_frames(sk); 3592*0a708f8fSGustavo F. Padovan 3593*0a708f8fSGustavo F. Padovan l2cap_ertm_send(sk); 3594*0a708f8fSGustavo F. Padovan 3595*0a708f8fSGustavo F. Padovan if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) && 3596*0a708f8fSGustavo F. Padovan pi->frames_sent == 0) { 3597*0a708f8fSGustavo F. Padovan control |= L2CAP_SUPER_RCV_READY; 3598*0a708f8fSGustavo F. Padovan l2cap_send_sframe(pi, control); 3599*0a708f8fSGustavo F. Padovan } 3600*0a708f8fSGustavo F. Padovan } 3601*0a708f8fSGustavo F. Padovan 3602*0a708f8fSGustavo F. Padovan static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar) 3603*0a708f8fSGustavo F. Padovan { 3604*0a708f8fSGustavo F. Padovan struct sk_buff *next_skb; 3605*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 3606*0a708f8fSGustavo F. Padovan int tx_seq_offset, next_tx_seq_offset; 3607*0a708f8fSGustavo F. Padovan 3608*0a708f8fSGustavo F. Padovan bt_cb(skb)->tx_seq = tx_seq; 3609*0a708f8fSGustavo F. Padovan bt_cb(skb)->sar = sar; 3610*0a708f8fSGustavo F. Padovan 3611*0a708f8fSGustavo F. Padovan next_skb = skb_peek(SREJ_QUEUE(sk)); 3612*0a708f8fSGustavo F. Padovan if (!next_skb) { 3613*0a708f8fSGustavo F. Padovan __skb_queue_tail(SREJ_QUEUE(sk), skb); 3614*0a708f8fSGustavo F. Padovan return 0; 3615*0a708f8fSGustavo F. Padovan } 3616*0a708f8fSGustavo F. Padovan 3617*0a708f8fSGustavo F. Padovan tx_seq_offset = (tx_seq - pi->buffer_seq) % 64; 3618*0a708f8fSGustavo F. Padovan if (tx_seq_offset < 0) 3619*0a708f8fSGustavo F. Padovan tx_seq_offset += 64; 3620*0a708f8fSGustavo F. Padovan 3621*0a708f8fSGustavo F. Padovan do { 3622*0a708f8fSGustavo F. Padovan if (bt_cb(next_skb)->tx_seq == tx_seq) 3623*0a708f8fSGustavo F. Padovan return -EINVAL; 3624*0a708f8fSGustavo F. Padovan 3625*0a708f8fSGustavo F. Padovan next_tx_seq_offset = (bt_cb(next_skb)->tx_seq - 3626*0a708f8fSGustavo F. Padovan pi->buffer_seq) % 64; 3627*0a708f8fSGustavo F. Padovan if (next_tx_seq_offset < 0) 3628*0a708f8fSGustavo F. Padovan next_tx_seq_offset += 64; 3629*0a708f8fSGustavo F. Padovan 3630*0a708f8fSGustavo F. Padovan if (next_tx_seq_offset > tx_seq_offset) { 3631*0a708f8fSGustavo F. Padovan __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb); 3632*0a708f8fSGustavo F. Padovan return 0; 3633*0a708f8fSGustavo F. Padovan } 3634*0a708f8fSGustavo F. Padovan 3635*0a708f8fSGustavo F. Padovan if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb)) 3636*0a708f8fSGustavo F. Padovan break; 3637*0a708f8fSGustavo F. Padovan 3638*0a708f8fSGustavo F. Padovan } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb))); 3639*0a708f8fSGustavo F. Padovan 3640*0a708f8fSGustavo F. Padovan __skb_queue_tail(SREJ_QUEUE(sk), skb); 3641*0a708f8fSGustavo F. Padovan 3642*0a708f8fSGustavo F. Padovan return 0; 3643*0a708f8fSGustavo F. Padovan } 3644*0a708f8fSGustavo F. Padovan 3645*0a708f8fSGustavo F. Padovan static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control) 3646*0a708f8fSGustavo F. Padovan { 3647*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 3648*0a708f8fSGustavo F. Padovan struct sk_buff *_skb; 3649*0a708f8fSGustavo F. Padovan int err; 3650*0a708f8fSGustavo F. Padovan 3651*0a708f8fSGustavo F. Padovan switch (control & L2CAP_CTRL_SAR) { 3652*0a708f8fSGustavo F. Padovan case L2CAP_SDU_UNSEGMENTED: 3653*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_SAR_SDU) 3654*0a708f8fSGustavo F. Padovan goto drop; 3655*0a708f8fSGustavo F. Padovan 3656*0a708f8fSGustavo F. Padovan err = sock_queue_rcv_skb(sk, skb); 3657*0a708f8fSGustavo F. Padovan if (!err) 3658*0a708f8fSGustavo F. Padovan return err; 3659*0a708f8fSGustavo F. Padovan 3660*0a708f8fSGustavo F. Padovan break; 3661*0a708f8fSGustavo F. Padovan 3662*0a708f8fSGustavo F. Padovan case L2CAP_SDU_START: 3663*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_SAR_SDU) 3664*0a708f8fSGustavo F. Padovan goto drop; 3665*0a708f8fSGustavo F. Padovan 3666*0a708f8fSGustavo F. Padovan pi->sdu_len = get_unaligned_le16(skb->data); 3667*0a708f8fSGustavo F. Padovan 3668*0a708f8fSGustavo F. Padovan if (pi->sdu_len > pi->imtu) 3669*0a708f8fSGustavo F. Padovan goto disconnect; 3670*0a708f8fSGustavo F. Padovan 3671*0a708f8fSGustavo F. Padovan pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC); 3672*0a708f8fSGustavo F. Padovan if (!pi->sdu) 3673*0a708f8fSGustavo F. Padovan return -ENOMEM; 3674*0a708f8fSGustavo F. Padovan 3675*0a708f8fSGustavo F. Padovan /* pull sdu_len bytes only after alloc, because of Local Busy 3676*0a708f8fSGustavo F. Padovan * condition we have to be sure that this will be executed 3677*0a708f8fSGustavo F. Padovan * only once, i.e., when alloc does not fail */ 3678*0a708f8fSGustavo F. Padovan skb_pull(skb, 2); 3679*0a708f8fSGustavo F. Padovan 3680*0a708f8fSGustavo F. Padovan memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); 3681*0a708f8fSGustavo F. Padovan 3682*0a708f8fSGustavo F. Padovan pi->conn_state |= L2CAP_CONN_SAR_SDU; 3683*0a708f8fSGustavo F. Padovan pi->partial_sdu_len = skb->len; 3684*0a708f8fSGustavo F. Padovan break; 3685*0a708f8fSGustavo F. Padovan 3686*0a708f8fSGustavo F. Padovan case L2CAP_SDU_CONTINUE: 3687*0a708f8fSGustavo F. Padovan if (!(pi->conn_state & L2CAP_CONN_SAR_SDU)) 3688*0a708f8fSGustavo F. Padovan goto disconnect; 3689*0a708f8fSGustavo F. Padovan 3690*0a708f8fSGustavo F. Padovan if (!pi->sdu) 3691*0a708f8fSGustavo F. Padovan goto disconnect; 3692*0a708f8fSGustavo F. Padovan 3693*0a708f8fSGustavo F. Padovan pi->partial_sdu_len += skb->len; 3694*0a708f8fSGustavo F. Padovan if (pi->partial_sdu_len > pi->sdu_len) 3695*0a708f8fSGustavo F. Padovan goto drop; 3696*0a708f8fSGustavo F. Padovan 3697*0a708f8fSGustavo F. Padovan memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); 3698*0a708f8fSGustavo F. Padovan 3699*0a708f8fSGustavo F. Padovan break; 3700*0a708f8fSGustavo F. Padovan 3701*0a708f8fSGustavo F. Padovan case L2CAP_SDU_END: 3702*0a708f8fSGustavo F. Padovan if (!(pi->conn_state & L2CAP_CONN_SAR_SDU)) 3703*0a708f8fSGustavo F. Padovan goto disconnect; 3704*0a708f8fSGustavo F. Padovan 3705*0a708f8fSGustavo F. Padovan if (!pi->sdu) 3706*0a708f8fSGustavo F. Padovan goto disconnect; 3707*0a708f8fSGustavo F. Padovan 3708*0a708f8fSGustavo F. Padovan if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) { 3709*0a708f8fSGustavo F. Padovan pi->partial_sdu_len += skb->len; 3710*0a708f8fSGustavo F. Padovan 3711*0a708f8fSGustavo F. Padovan if (pi->partial_sdu_len > pi->imtu) 3712*0a708f8fSGustavo F. Padovan goto drop; 3713*0a708f8fSGustavo F. Padovan 3714*0a708f8fSGustavo F. Padovan if (pi->partial_sdu_len != pi->sdu_len) 3715*0a708f8fSGustavo F. Padovan goto drop; 3716*0a708f8fSGustavo F. Padovan 3717*0a708f8fSGustavo F. Padovan memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); 3718*0a708f8fSGustavo F. Padovan } 3719*0a708f8fSGustavo F. Padovan 3720*0a708f8fSGustavo F. Padovan _skb = skb_clone(pi->sdu, GFP_ATOMIC); 3721*0a708f8fSGustavo F. Padovan if (!_skb) { 3722*0a708f8fSGustavo F. Padovan pi->conn_state |= L2CAP_CONN_SAR_RETRY; 3723*0a708f8fSGustavo F. Padovan return -ENOMEM; 3724*0a708f8fSGustavo F. Padovan } 3725*0a708f8fSGustavo F. Padovan 3726*0a708f8fSGustavo F. Padovan err = sock_queue_rcv_skb(sk, _skb); 3727*0a708f8fSGustavo F. Padovan if (err < 0) { 3728*0a708f8fSGustavo F. Padovan kfree_skb(_skb); 3729*0a708f8fSGustavo F. Padovan pi->conn_state |= L2CAP_CONN_SAR_RETRY; 3730*0a708f8fSGustavo F. Padovan return err; 3731*0a708f8fSGustavo F. Padovan } 3732*0a708f8fSGustavo F. Padovan 3733*0a708f8fSGustavo F. Padovan pi->conn_state &= ~L2CAP_CONN_SAR_RETRY; 3734*0a708f8fSGustavo F. Padovan pi->conn_state &= ~L2CAP_CONN_SAR_SDU; 3735*0a708f8fSGustavo F. Padovan 3736*0a708f8fSGustavo F. Padovan kfree_skb(pi->sdu); 3737*0a708f8fSGustavo F. Padovan break; 3738*0a708f8fSGustavo F. Padovan } 3739*0a708f8fSGustavo F. Padovan 3740*0a708f8fSGustavo F. Padovan kfree_skb(skb); 3741*0a708f8fSGustavo F. Padovan return 0; 3742*0a708f8fSGustavo F. Padovan 3743*0a708f8fSGustavo F. Padovan drop: 3744*0a708f8fSGustavo F. Padovan kfree_skb(pi->sdu); 3745*0a708f8fSGustavo F. Padovan pi->sdu = NULL; 3746*0a708f8fSGustavo F. Padovan 3747*0a708f8fSGustavo F. Padovan disconnect: 3748*0a708f8fSGustavo F. Padovan l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); 3749*0a708f8fSGustavo F. Padovan kfree_skb(skb); 3750*0a708f8fSGustavo F. Padovan return 0; 3751*0a708f8fSGustavo F. Padovan } 3752*0a708f8fSGustavo F. Padovan 3753*0a708f8fSGustavo F. Padovan static int l2cap_try_push_rx_skb(struct sock *sk) 3754*0a708f8fSGustavo F. Padovan { 3755*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 3756*0a708f8fSGustavo F. Padovan struct sk_buff *skb; 3757*0a708f8fSGustavo F. Padovan u16 control; 3758*0a708f8fSGustavo F. Padovan int err; 3759*0a708f8fSGustavo F. Padovan 3760*0a708f8fSGustavo F. Padovan while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) { 3761*0a708f8fSGustavo F. Padovan control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; 3762*0a708f8fSGustavo F. Padovan err = l2cap_ertm_reassembly_sdu(sk, skb, control); 3763*0a708f8fSGustavo F. Padovan if (err < 0) { 3764*0a708f8fSGustavo F. Padovan skb_queue_head(BUSY_QUEUE(sk), skb); 3765*0a708f8fSGustavo F. Padovan return -EBUSY; 3766*0a708f8fSGustavo F. Padovan } 3767*0a708f8fSGustavo F. Padovan 3768*0a708f8fSGustavo F. Padovan pi->buffer_seq = (pi->buffer_seq + 1) % 64; 3769*0a708f8fSGustavo F. Padovan } 3770*0a708f8fSGustavo F. Padovan 3771*0a708f8fSGustavo F. Padovan if (!(pi->conn_state & L2CAP_CONN_RNR_SENT)) 3772*0a708f8fSGustavo F. Padovan goto done; 3773*0a708f8fSGustavo F. Padovan 3774*0a708f8fSGustavo F. Padovan control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; 3775*0a708f8fSGustavo F. Padovan control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL; 3776*0a708f8fSGustavo F. Padovan l2cap_send_sframe(pi, control); 3777*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->retry_count = 1; 3778*0a708f8fSGustavo F. Padovan 3779*0a708f8fSGustavo F. Padovan del_timer(&pi->retrans_timer); 3780*0a708f8fSGustavo F. Padovan __mod_monitor_timer(); 3781*0a708f8fSGustavo F. Padovan 3782*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F; 3783*0a708f8fSGustavo F. Padovan 3784*0a708f8fSGustavo F. Padovan done: 3785*0a708f8fSGustavo F. Padovan pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY; 3786*0a708f8fSGustavo F. Padovan pi->conn_state &= ~L2CAP_CONN_RNR_SENT; 3787*0a708f8fSGustavo F. Padovan 3788*0a708f8fSGustavo F. Padovan BT_DBG("sk %p, Exit local busy", sk); 3789*0a708f8fSGustavo F. Padovan 3790*0a708f8fSGustavo F. Padovan return 0; 3791*0a708f8fSGustavo F. Padovan } 3792*0a708f8fSGustavo F. Padovan 3793*0a708f8fSGustavo F. Padovan static void l2cap_busy_work(struct work_struct *work) 3794*0a708f8fSGustavo F. Padovan { 3795*0a708f8fSGustavo F. Padovan DECLARE_WAITQUEUE(wait, current); 3796*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = 3797*0a708f8fSGustavo F. Padovan container_of(work, struct l2cap_pinfo, busy_work); 3798*0a708f8fSGustavo F. Padovan struct sock *sk = (struct sock *)pi; 3799*0a708f8fSGustavo F. Padovan int n_tries = 0, timeo = HZ/5, err; 3800*0a708f8fSGustavo F. Padovan struct sk_buff *skb; 3801*0a708f8fSGustavo F. Padovan 3802*0a708f8fSGustavo F. Padovan lock_sock(sk); 3803*0a708f8fSGustavo F. Padovan 3804*0a708f8fSGustavo F. Padovan add_wait_queue(sk_sleep(sk), &wait); 3805*0a708f8fSGustavo F. Padovan while ((skb = skb_peek(BUSY_QUEUE(sk)))) { 3806*0a708f8fSGustavo F. Padovan set_current_state(TASK_INTERRUPTIBLE); 3807*0a708f8fSGustavo F. Padovan 3808*0a708f8fSGustavo F. Padovan if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) { 3809*0a708f8fSGustavo F. Padovan err = -EBUSY; 3810*0a708f8fSGustavo F. Padovan l2cap_send_disconn_req(pi->conn, sk, EBUSY); 3811*0a708f8fSGustavo F. Padovan break; 3812*0a708f8fSGustavo F. Padovan } 3813*0a708f8fSGustavo F. Padovan 3814*0a708f8fSGustavo F. Padovan if (!timeo) 3815*0a708f8fSGustavo F. Padovan timeo = HZ/5; 3816*0a708f8fSGustavo F. Padovan 3817*0a708f8fSGustavo F. Padovan if (signal_pending(current)) { 3818*0a708f8fSGustavo F. Padovan err = sock_intr_errno(timeo); 3819*0a708f8fSGustavo F. Padovan break; 3820*0a708f8fSGustavo F. Padovan } 3821*0a708f8fSGustavo F. Padovan 3822*0a708f8fSGustavo F. Padovan release_sock(sk); 3823*0a708f8fSGustavo F. Padovan timeo = schedule_timeout(timeo); 3824*0a708f8fSGustavo F. Padovan lock_sock(sk); 3825*0a708f8fSGustavo F. Padovan 3826*0a708f8fSGustavo F. Padovan err = sock_error(sk); 3827*0a708f8fSGustavo F. Padovan if (err) 3828*0a708f8fSGustavo F. Padovan break; 3829*0a708f8fSGustavo F. Padovan 3830*0a708f8fSGustavo F. Padovan if (l2cap_try_push_rx_skb(sk) == 0) 3831*0a708f8fSGustavo F. Padovan break; 3832*0a708f8fSGustavo F. Padovan } 3833*0a708f8fSGustavo F. Padovan 3834*0a708f8fSGustavo F. Padovan set_current_state(TASK_RUNNING); 3835*0a708f8fSGustavo F. Padovan remove_wait_queue(sk_sleep(sk), &wait); 3836*0a708f8fSGustavo F. Padovan 3837*0a708f8fSGustavo F. Padovan release_sock(sk); 3838*0a708f8fSGustavo F. Padovan } 3839*0a708f8fSGustavo F. Padovan 3840*0a708f8fSGustavo F. Padovan static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control) 3841*0a708f8fSGustavo F. Padovan { 3842*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 3843*0a708f8fSGustavo F. Padovan int sctrl, err; 3844*0a708f8fSGustavo F. Padovan 3845*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) { 3846*0a708f8fSGustavo F. Padovan bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; 3847*0a708f8fSGustavo F. Padovan __skb_queue_tail(BUSY_QUEUE(sk), skb); 3848*0a708f8fSGustavo F. Padovan return l2cap_try_push_rx_skb(sk); 3849*0a708f8fSGustavo F. Padovan 3850*0a708f8fSGustavo F. Padovan 3851*0a708f8fSGustavo F. Padovan } 3852*0a708f8fSGustavo F. Padovan 3853*0a708f8fSGustavo F. Padovan err = l2cap_ertm_reassembly_sdu(sk, skb, control); 3854*0a708f8fSGustavo F. Padovan if (err >= 0) { 3855*0a708f8fSGustavo F. Padovan pi->buffer_seq = (pi->buffer_seq + 1) % 64; 3856*0a708f8fSGustavo F. Padovan return err; 3857*0a708f8fSGustavo F. Padovan } 3858*0a708f8fSGustavo F. Padovan 3859*0a708f8fSGustavo F. Padovan /* Busy Condition */ 3860*0a708f8fSGustavo F. Padovan BT_DBG("sk %p, Enter local busy", sk); 3861*0a708f8fSGustavo F. Padovan 3862*0a708f8fSGustavo F. Padovan pi->conn_state |= L2CAP_CONN_LOCAL_BUSY; 3863*0a708f8fSGustavo F. Padovan bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; 3864*0a708f8fSGustavo F. Padovan __skb_queue_tail(BUSY_QUEUE(sk), skb); 3865*0a708f8fSGustavo F. Padovan 3866*0a708f8fSGustavo F. Padovan sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; 3867*0a708f8fSGustavo F. Padovan sctrl |= L2CAP_SUPER_RCV_NOT_READY; 3868*0a708f8fSGustavo F. Padovan l2cap_send_sframe(pi, sctrl); 3869*0a708f8fSGustavo F. Padovan 3870*0a708f8fSGustavo F. Padovan pi->conn_state |= L2CAP_CONN_RNR_SENT; 3871*0a708f8fSGustavo F. Padovan 3872*0a708f8fSGustavo F. Padovan del_timer(&pi->ack_timer); 3873*0a708f8fSGustavo F. Padovan 3874*0a708f8fSGustavo F. Padovan queue_work(_busy_wq, &pi->busy_work); 3875*0a708f8fSGustavo F. Padovan 3876*0a708f8fSGustavo F. Padovan return err; 3877*0a708f8fSGustavo F. Padovan } 3878*0a708f8fSGustavo F. Padovan 3879*0a708f8fSGustavo F. Padovan static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control) 3880*0a708f8fSGustavo F. Padovan { 3881*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 3882*0a708f8fSGustavo F. Padovan struct sk_buff *_skb; 3883*0a708f8fSGustavo F. Padovan int err = -EINVAL; 3884*0a708f8fSGustavo F. Padovan 3885*0a708f8fSGustavo F. Padovan /* 3886*0a708f8fSGustavo F. Padovan * TODO: We have to notify the userland if some data is lost with the 3887*0a708f8fSGustavo F. Padovan * Streaming Mode. 3888*0a708f8fSGustavo F. Padovan */ 3889*0a708f8fSGustavo F. Padovan 3890*0a708f8fSGustavo F. Padovan switch (control & L2CAP_CTRL_SAR) { 3891*0a708f8fSGustavo F. Padovan case L2CAP_SDU_UNSEGMENTED: 3892*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_SAR_SDU) { 3893*0a708f8fSGustavo F. Padovan kfree_skb(pi->sdu); 3894*0a708f8fSGustavo F. Padovan break; 3895*0a708f8fSGustavo F. Padovan } 3896*0a708f8fSGustavo F. Padovan 3897*0a708f8fSGustavo F. Padovan err = sock_queue_rcv_skb(sk, skb); 3898*0a708f8fSGustavo F. Padovan if (!err) 3899*0a708f8fSGustavo F. Padovan return 0; 3900*0a708f8fSGustavo F. Padovan 3901*0a708f8fSGustavo F. Padovan break; 3902*0a708f8fSGustavo F. Padovan 3903*0a708f8fSGustavo F. Padovan case L2CAP_SDU_START: 3904*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_SAR_SDU) { 3905*0a708f8fSGustavo F. Padovan kfree_skb(pi->sdu); 3906*0a708f8fSGustavo F. Padovan break; 3907*0a708f8fSGustavo F. Padovan } 3908*0a708f8fSGustavo F. Padovan 3909*0a708f8fSGustavo F. Padovan pi->sdu_len = get_unaligned_le16(skb->data); 3910*0a708f8fSGustavo F. Padovan skb_pull(skb, 2); 3911*0a708f8fSGustavo F. Padovan 3912*0a708f8fSGustavo F. Padovan if (pi->sdu_len > pi->imtu) { 3913*0a708f8fSGustavo F. Padovan err = -EMSGSIZE; 3914*0a708f8fSGustavo F. Padovan break; 3915*0a708f8fSGustavo F. Padovan } 3916*0a708f8fSGustavo F. Padovan 3917*0a708f8fSGustavo F. Padovan pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC); 3918*0a708f8fSGustavo F. Padovan if (!pi->sdu) { 3919*0a708f8fSGustavo F. Padovan err = -ENOMEM; 3920*0a708f8fSGustavo F. Padovan break; 3921*0a708f8fSGustavo F. Padovan } 3922*0a708f8fSGustavo F. Padovan 3923*0a708f8fSGustavo F. Padovan memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); 3924*0a708f8fSGustavo F. Padovan 3925*0a708f8fSGustavo F. Padovan pi->conn_state |= L2CAP_CONN_SAR_SDU; 3926*0a708f8fSGustavo F. Padovan pi->partial_sdu_len = skb->len; 3927*0a708f8fSGustavo F. Padovan err = 0; 3928*0a708f8fSGustavo F. Padovan break; 3929*0a708f8fSGustavo F. Padovan 3930*0a708f8fSGustavo F. Padovan case L2CAP_SDU_CONTINUE: 3931*0a708f8fSGustavo F. Padovan if (!(pi->conn_state & L2CAP_CONN_SAR_SDU)) 3932*0a708f8fSGustavo F. Padovan break; 3933*0a708f8fSGustavo F. Padovan 3934*0a708f8fSGustavo F. Padovan memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); 3935*0a708f8fSGustavo F. Padovan 3936*0a708f8fSGustavo F. Padovan pi->partial_sdu_len += skb->len; 3937*0a708f8fSGustavo F. Padovan if (pi->partial_sdu_len > pi->sdu_len) 3938*0a708f8fSGustavo F. Padovan kfree_skb(pi->sdu); 3939*0a708f8fSGustavo F. Padovan else 3940*0a708f8fSGustavo F. Padovan err = 0; 3941*0a708f8fSGustavo F. Padovan 3942*0a708f8fSGustavo F. Padovan break; 3943*0a708f8fSGustavo F. Padovan 3944*0a708f8fSGustavo F. Padovan case L2CAP_SDU_END: 3945*0a708f8fSGustavo F. Padovan if (!(pi->conn_state & L2CAP_CONN_SAR_SDU)) 3946*0a708f8fSGustavo F. Padovan break; 3947*0a708f8fSGustavo F. Padovan 3948*0a708f8fSGustavo F. Padovan memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); 3949*0a708f8fSGustavo F. Padovan 3950*0a708f8fSGustavo F. Padovan pi->conn_state &= ~L2CAP_CONN_SAR_SDU; 3951*0a708f8fSGustavo F. Padovan pi->partial_sdu_len += skb->len; 3952*0a708f8fSGustavo F. Padovan 3953*0a708f8fSGustavo F. Padovan if (pi->partial_sdu_len > pi->imtu) 3954*0a708f8fSGustavo F. Padovan goto drop; 3955*0a708f8fSGustavo F. Padovan 3956*0a708f8fSGustavo F. Padovan if (pi->partial_sdu_len == pi->sdu_len) { 3957*0a708f8fSGustavo F. Padovan _skb = skb_clone(pi->sdu, GFP_ATOMIC); 3958*0a708f8fSGustavo F. Padovan err = sock_queue_rcv_skb(sk, _skb); 3959*0a708f8fSGustavo F. Padovan if (err < 0) 3960*0a708f8fSGustavo F. Padovan kfree_skb(_skb); 3961*0a708f8fSGustavo F. Padovan } 3962*0a708f8fSGustavo F. Padovan err = 0; 3963*0a708f8fSGustavo F. Padovan 3964*0a708f8fSGustavo F. Padovan drop: 3965*0a708f8fSGustavo F. Padovan kfree_skb(pi->sdu); 3966*0a708f8fSGustavo F. Padovan break; 3967*0a708f8fSGustavo F. Padovan } 3968*0a708f8fSGustavo F. Padovan 3969*0a708f8fSGustavo F. Padovan kfree_skb(skb); 3970*0a708f8fSGustavo F. Padovan return err; 3971*0a708f8fSGustavo F. Padovan } 3972*0a708f8fSGustavo F. Padovan 3973*0a708f8fSGustavo F. Padovan static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq) 3974*0a708f8fSGustavo F. Padovan { 3975*0a708f8fSGustavo F. Padovan struct sk_buff *skb; 3976*0a708f8fSGustavo F. Padovan u16 control; 3977*0a708f8fSGustavo F. Padovan 3978*0a708f8fSGustavo F. Padovan while ((skb = skb_peek(SREJ_QUEUE(sk)))) { 3979*0a708f8fSGustavo F. Padovan if (bt_cb(skb)->tx_seq != tx_seq) 3980*0a708f8fSGustavo F. Padovan break; 3981*0a708f8fSGustavo F. Padovan 3982*0a708f8fSGustavo F. Padovan skb = skb_dequeue(SREJ_QUEUE(sk)); 3983*0a708f8fSGustavo F. Padovan control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; 3984*0a708f8fSGustavo F. Padovan l2cap_ertm_reassembly_sdu(sk, skb, control); 3985*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->buffer_seq_srej = 3986*0a708f8fSGustavo F. Padovan (l2cap_pi(sk)->buffer_seq_srej + 1) % 64; 3987*0a708f8fSGustavo F. Padovan tx_seq = (tx_seq + 1) % 64; 3988*0a708f8fSGustavo F. Padovan } 3989*0a708f8fSGustavo F. Padovan } 3990*0a708f8fSGustavo F. Padovan 3991*0a708f8fSGustavo F. Padovan static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq) 3992*0a708f8fSGustavo F. Padovan { 3993*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 3994*0a708f8fSGustavo F. Padovan struct srej_list *l, *tmp; 3995*0a708f8fSGustavo F. Padovan u16 control; 3996*0a708f8fSGustavo F. Padovan 3997*0a708f8fSGustavo F. Padovan list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) { 3998*0a708f8fSGustavo F. Padovan if (l->tx_seq == tx_seq) { 3999*0a708f8fSGustavo F. Padovan list_del(&l->list); 4000*0a708f8fSGustavo F. Padovan kfree(l); 4001*0a708f8fSGustavo F. Padovan return; 4002*0a708f8fSGustavo F. Padovan } 4003*0a708f8fSGustavo F. Padovan control = L2CAP_SUPER_SELECT_REJECT; 4004*0a708f8fSGustavo F. Padovan control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; 4005*0a708f8fSGustavo F. Padovan l2cap_send_sframe(pi, control); 4006*0a708f8fSGustavo F. Padovan list_del(&l->list); 4007*0a708f8fSGustavo F. Padovan list_add_tail(&l->list, SREJ_LIST(sk)); 4008*0a708f8fSGustavo F. Padovan } 4009*0a708f8fSGustavo F. Padovan } 4010*0a708f8fSGustavo F. Padovan 4011*0a708f8fSGustavo F. Padovan static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq) 4012*0a708f8fSGustavo F. Padovan { 4013*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 4014*0a708f8fSGustavo F. Padovan struct srej_list *new; 4015*0a708f8fSGustavo F. Padovan u16 control; 4016*0a708f8fSGustavo F. Padovan 4017*0a708f8fSGustavo F. Padovan while (tx_seq != pi->expected_tx_seq) { 4018*0a708f8fSGustavo F. Padovan control = L2CAP_SUPER_SELECT_REJECT; 4019*0a708f8fSGustavo F. Padovan control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; 4020*0a708f8fSGustavo F. Padovan l2cap_send_sframe(pi, control); 4021*0a708f8fSGustavo F. Padovan 4022*0a708f8fSGustavo F. Padovan new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC); 4023*0a708f8fSGustavo F. Padovan new->tx_seq = pi->expected_tx_seq; 4024*0a708f8fSGustavo F. Padovan pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64; 4025*0a708f8fSGustavo F. Padovan list_add_tail(&new->list, SREJ_LIST(sk)); 4026*0a708f8fSGustavo F. Padovan } 4027*0a708f8fSGustavo F. Padovan pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64; 4028*0a708f8fSGustavo F. Padovan } 4029*0a708f8fSGustavo F. Padovan 4030*0a708f8fSGustavo F. Padovan static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb) 4031*0a708f8fSGustavo F. Padovan { 4032*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 4033*0a708f8fSGustavo F. Padovan u8 tx_seq = __get_txseq(rx_control); 4034*0a708f8fSGustavo F. Padovan u8 req_seq = __get_reqseq(rx_control); 4035*0a708f8fSGustavo F. Padovan u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT; 4036*0a708f8fSGustavo F. Padovan int tx_seq_offset, expected_tx_seq_offset; 4037*0a708f8fSGustavo F. Padovan int num_to_ack = (pi->tx_win/6) + 1; 4038*0a708f8fSGustavo F. Padovan int err = 0; 4039*0a708f8fSGustavo F. Padovan 4040*0a708f8fSGustavo F. Padovan BT_DBG("sk %p len %d tx_seq %d rx_control 0x%4.4x", sk, skb->len, tx_seq, 4041*0a708f8fSGustavo F. Padovan rx_control); 4042*0a708f8fSGustavo F. Padovan 4043*0a708f8fSGustavo F. Padovan if (L2CAP_CTRL_FINAL & rx_control && 4044*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) { 4045*0a708f8fSGustavo F. Padovan del_timer(&pi->monitor_timer); 4046*0a708f8fSGustavo F. Padovan if (pi->unacked_frames > 0) 4047*0a708f8fSGustavo F. Padovan __mod_retrans_timer(); 4048*0a708f8fSGustavo F. Padovan pi->conn_state &= ~L2CAP_CONN_WAIT_F; 4049*0a708f8fSGustavo F. Padovan } 4050*0a708f8fSGustavo F. Padovan 4051*0a708f8fSGustavo F. Padovan pi->expected_ack_seq = req_seq; 4052*0a708f8fSGustavo F. Padovan l2cap_drop_acked_frames(sk); 4053*0a708f8fSGustavo F. Padovan 4054*0a708f8fSGustavo F. Padovan if (tx_seq == pi->expected_tx_seq) 4055*0a708f8fSGustavo F. Padovan goto expected; 4056*0a708f8fSGustavo F. Padovan 4057*0a708f8fSGustavo F. Padovan tx_seq_offset = (tx_seq - pi->buffer_seq) % 64; 4058*0a708f8fSGustavo F. Padovan if (tx_seq_offset < 0) 4059*0a708f8fSGustavo F. Padovan tx_seq_offset += 64; 4060*0a708f8fSGustavo F. Padovan 4061*0a708f8fSGustavo F. Padovan /* invalid tx_seq */ 4062*0a708f8fSGustavo F. Padovan if (tx_seq_offset >= pi->tx_win) { 4063*0a708f8fSGustavo F. Padovan l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); 4064*0a708f8fSGustavo F. Padovan goto drop; 4065*0a708f8fSGustavo F. Padovan } 4066*0a708f8fSGustavo F. Padovan 4067*0a708f8fSGustavo F. Padovan if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY) 4068*0a708f8fSGustavo F. Padovan goto drop; 4069*0a708f8fSGustavo F. Padovan 4070*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_SREJ_SENT) { 4071*0a708f8fSGustavo F. Padovan struct srej_list *first; 4072*0a708f8fSGustavo F. Padovan 4073*0a708f8fSGustavo F. Padovan first = list_first_entry(SREJ_LIST(sk), 4074*0a708f8fSGustavo F. Padovan struct srej_list, list); 4075*0a708f8fSGustavo F. Padovan if (tx_seq == first->tx_seq) { 4076*0a708f8fSGustavo F. Padovan l2cap_add_to_srej_queue(sk, skb, tx_seq, sar); 4077*0a708f8fSGustavo F. Padovan l2cap_check_srej_gap(sk, tx_seq); 4078*0a708f8fSGustavo F. Padovan 4079*0a708f8fSGustavo F. Padovan list_del(&first->list); 4080*0a708f8fSGustavo F. Padovan kfree(first); 4081*0a708f8fSGustavo F. Padovan 4082*0a708f8fSGustavo F. Padovan if (list_empty(SREJ_LIST(sk))) { 4083*0a708f8fSGustavo F. Padovan pi->buffer_seq = pi->buffer_seq_srej; 4084*0a708f8fSGustavo F. Padovan pi->conn_state &= ~L2CAP_CONN_SREJ_SENT; 4085*0a708f8fSGustavo F. Padovan l2cap_send_ack(pi); 4086*0a708f8fSGustavo F. Padovan BT_DBG("sk %p, Exit SREJ_SENT", sk); 4087*0a708f8fSGustavo F. Padovan } 4088*0a708f8fSGustavo F. Padovan } else { 4089*0a708f8fSGustavo F. Padovan struct srej_list *l; 4090*0a708f8fSGustavo F. Padovan 4091*0a708f8fSGustavo F. Padovan /* duplicated tx_seq */ 4092*0a708f8fSGustavo F. Padovan if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0) 4093*0a708f8fSGustavo F. Padovan goto drop; 4094*0a708f8fSGustavo F. Padovan 4095*0a708f8fSGustavo F. Padovan list_for_each_entry(l, SREJ_LIST(sk), list) { 4096*0a708f8fSGustavo F. Padovan if (l->tx_seq == tx_seq) { 4097*0a708f8fSGustavo F. Padovan l2cap_resend_srejframe(sk, tx_seq); 4098*0a708f8fSGustavo F. Padovan return 0; 4099*0a708f8fSGustavo F. Padovan } 4100*0a708f8fSGustavo F. Padovan } 4101*0a708f8fSGustavo F. Padovan l2cap_send_srejframe(sk, tx_seq); 4102*0a708f8fSGustavo F. Padovan } 4103*0a708f8fSGustavo F. Padovan } else { 4104*0a708f8fSGustavo F. Padovan expected_tx_seq_offset = 4105*0a708f8fSGustavo F. Padovan (pi->expected_tx_seq - pi->buffer_seq) % 64; 4106*0a708f8fSGustavo F. Padovan if (expected_tx_seq_offset < 0) 4107*0a708f8fSGustavo F. Padovan expected_tx_seq_offset += 64; 4108*0a708f8fSGustavo F. Padovan 4109*0a708f8fSGustavo F. Padovan /* duplicated tx_seq */ 4110*0a708f8fSGustavo F. Padovan if (tx_seq_offset < expected_tx_seq_offset) 4111*0a708f8fSGustavo F. Padovan goto drop; 4112*0a708f8fSGustavo F. Padovan 4113*0a708f8fSGustavo F. Padovan pi->conn_state |= L2CAP_CONN_SREJ_SENT; 4114*0a708f8fSGustavo F. Padovan 4115*0a708f8fSGustavo F. Padovan BT_DBG("sk %p, Enter SREJ", sk); 4116*0a708f8fSGustavo F. Padovan 4117*0a708f8fSGustavo F. Padovan INIT_LIST_HEAD(SREJ_LIST(sk)); 4118*0a708f8fSGustavo F. Padovan pi->buffer_seq_srej = pi->buffer_seq; 4119*0a708f8fSGustavo F. Padovan 4120*0a708f8fSGustavo F. Padovan __skb_queue_head_init(SREJ_QUEUE(sk)); 4121*0a708f8fSGustavo F. Padovan __skb_queue_head_init(BUSY_QUEUE(sk)); 4122*0a708f8fSGustavo F. Padovan l2cap_add_to_srej_queue(sk, skb, tx_seq, sar); 4123*0a708f8fSGustavo F. Padovan 4124*0a708f8fSGustavo F. Padovan pi->conn_state |= L2CAP_CONN_SEND_PBIT; 4125*0a708f8fSGustavo F. Padovan 4126*0a708f8fSGustavo F. Padovan l2cap_send_srejframe(sk, tx_seq); 4127*0a708f8fSGustavo F. Padovan 4128*0a708f8fSGustavo F. Padovan del_timer(&pi->ack_timer); 4129*0a708f8fSGustavo F. Padovan } 4130*0a708f8fSGustavo F. Padovan return 0; 4131*0a708f8fSGustavo F. Padovan 4132*0a708f8fSGustavo F. Padovan expected: 4133*0a708f8fSGustavo F. Padovan pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64; 4134*0a708f8fSGustavo F. Padovan 4135*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_SREJ_SENT) { 4136*0a708f8fSGustavo F. Padovan bt_cb(skb)->tx_seq = tx_seq; 4137*0a708f8fSGustavo F. Padovan bt_cb(skb)->sar = sar; 4138*0a708f8fSGustavo F. Padovan __skb_queue_tail(SREJ_QUEUE(sk), skb); 4139*0a708f8fSGustavo F. Padovan return 0; 4140*0a708f8fSGustavo F. Padovan } 4141*0a708f8fSGustavo F. Padovan 4142*0a708f8fSGustavo F. Padovan err = l2cap_push_rx_skb(sk, skb, rx_control); 4143*0a708f8fSGustavo F. Padovan if (err < 0) 4144*0a708f8fSGustavo F. Padovan return 0; 4145*0a708f8fSGustavo F. Padovan 4146*0a708f8fSGustavo F. Padovan if (rx_control & L2CAP_CTRL_FINAL) { 4147*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_REJ_ACT) 4148*0a708f8fSGustavo F. Padovan pi->conn_state &= ~L2CAP_CONN_REJ_ACT; 4149*0a708f8fSGustavo F. Padovan else 4150*0a708f8fSGustavo F. Padovan l2cap_retransmit_frames(sk); 4151*0a708f8fSGustavo F. Padovan } 4152*0a708f8fSGustavo F. Padovan 4153*0a708f8fSGustavo F. Padovan __mod_ack_timer(); 4154*0a708f8fSGustavo F. Padovan 4155*0a708f8fSGustavo F. Padovan pi->num_acked = (pi->num_acked + 1) % num_to_ack; 4156*0a708f8fSGustavo F. Padovan if (pi->num_acked == num_to_ack - 1) 4157*0a708f8fSGustavo F. Padovan l2cap_send_ack(pi); 4158*0a708f8fSGustavo F. Padovan 4159*0a708f8fSGustavo F. Padovan return 0; 4160*0a708f8fSGustavo F. Padovan 4161*0a708f8fSGustavo F. Padovan drop: 4162*0a708f8fSGustavo F. Padovan kfree_skb(skb); 4163*0a708f8fSGustavo F. Padovan return 0; 4164*0a708f8fSGustavo F. Padovan } 4165*0a708f8fSGustavo F. Padovan 4166*0a708f8fSGustavo F. Padovan static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control) 4167*0a708f8fSGustavo F. Padovan { 4168*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 4169*0a708f8fSGustavo F. Padovan 4170*0a708f8fSGustavo F. Padovan BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control), 4171*0a708f8fSGustavo F. Padovan rx_control); 4172*0a708f8fSGustavo F. Padovan 4173*0a708f8fSGustavo F. Padovan pi->expected_ack_seq = __get_reqseq(rx_control); 4174*0a708f8fSGustavo F. Padovan l2cap_drop_acked_frames(sk); 4175*0a708f8fSGustavo F. Padovan 4176*0a708f8fSGustavo F. Padovan if (rx_control & L2CAP_CTRL_POLL) { 4177*0a708f8fSGustavo F. Padovan pi->conn_state |= L2CAP_CONN_SEND_FBIT; 4178*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_SREJ_SENT) { 4179*0a708f8fSGustavo F. Padovan if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) && 4180*0a708f8fSGustavo F. Padovan (pi->unacked_frames > 0)) 4181*0a708f8fSGustavo F. Padovan __mod_retrans_timer(); 4182*0a708f8fSGustavo F. Padovan 4183*0a708f8fSGustavo F. Padovan pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; 4184*0a708f8fSGustavo F. Padovan l2cap_send_srejtail(sk); 4185*0a708f8fSGustavo F. Padovan } else { 4186*0a708f8fSGustavo F. Padovan l2cap_send_i_or_rr_or_rnr(sk); 4187*0a708f8fSGustavo F. Padovan } 4188*0a708f8fSGustavo F. Padovan 4189*0a708f8fSGustavo F. Padovan } else if (rx_control & L2CAP_CTRL_FINAL) { 4190*0a708f8fSGustavo F. Padovan pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; 4191*0a708f8fSGustavo F. Padovan 4192*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_REJ_ACT) 4193*0a708f8fSGustavo F. Padovan pi->conn_state &= ~L2CAP_CONN_REJ_ACT; 4194*0a708f8fSGustavo F. Padovan else 4195*0a708f8fSGustavo F. Padovan l2cap_retransmit_frames(sk); 4196*0a708f8fSGustavo F. Padovan 4197*0a708f8fSGustavo F. Padovan } else { 4198*0a708f8fSGustavo F. Padovan if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) && 4199*0a708f8fSGustavo F. Padovan (pi->unacked_frames > 0)) 4200*0a708f8fSGustavo F. Padovan __mod_retrans_timer(); 4201*0a708f8fSGustavo F. Padovan 4202*0a708f8fSGustavo F. Padovan pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; 4203*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_SREJ_SENT) 4204*0a708f8fSGustavo F. Padovan l2cap_send_ack(pi); 4205*0a708f8fSGustavo F. Padovan else 4206*0a708f8fSGustavo F. Padovan l2cap_ertm_send(sk); 4207*0a708f8fSGustavo F. Padovan } 4208*0a708f8fSGustavo F. Padovan } 4209*0a708f8fSGustavo F. Padovan 4210*0a708f8fSGustavo F. Padovan static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control) 4211*0a708f8fSGustavo F. Padovan { 4212*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 4213*0a708f8fSGustavo F. Padovan u8 tx_seq = __get_reqseq(rx_control); 4214*0a708f8fSGustavo F. Padovan 4215*0a708f8fSGustavo F. Padovan BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control); 4216*0a708f8fSGustavo F. Padovan 4217*0a708f8fSGustavo F. Padovan pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; 4218*0a708f8fSGustavo F. Padovan 4219*0a708f8fSGustavo F. Padovan pi->expected_ack_seq = tx_seq; 4220*0a708f8fSGustavo F. Padovan l2cap_drop_acked_frames(sk); 4221*0a708f8fSGustavo F. Padovan 4222*0a708f8fSGustavo F. Padovan if (rx_control & L2CAP_CTRL_FINAL) { 4223*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_REJ_ACT) 4224*0a708f8fSGustavo F. Padovan pi->conn_state &= ~L2CAP_CONN_REJ_ACT; 4225*0a708f8fSGustavo F. Padovan else 4226*0a708f8fSGustavo F. Padovan l2cap_retransmit_frames(sk); 4227*0a708f8fSGustavo F. Padovan } else { 4228*0a708f8fSGustavo F. Padovan l2cap_retransmit_frames(sk); 4229*0a708f8fSGustavo F. Padovan 4230*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_WAIT_F) 4231*0a708f8fSGustavo F. Padovan pi->conn_state |= L2CAP_CONN_REJ_ACT; 4232*0a708f8fSGustavo F. Padovan } 4233*0a708f8fSGustavo F. Padovan } 4234*0a708f8fSGustavo F. Padovan static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control) 4235*0a708f8fSGustavo F. Padovan { 4236*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 4237*0a708f8fSGustavo F. Padovan u8 tx_seq = __get_reqseq(rx_control); 4238*0a708f8fSGustavo F. Padovan 4239*0a708f8fSGustavo F. Padovan BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control); 4240*0a708f8fSGustavo F. Padovan 4241*0a708f8fSGustavo F. Padovan pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; 4242*0a708f8fSGustavo F. Padovan 4243*0a708f8fSGustavo F. Padovan if (rx_control & L2CAP_CTRL_POLL) { 4244*0a708f8fSGustavo F. Padovan pi->expected_ack_seq = tx_seq; 4245*0a708f8fSGustavo F. Padovan l2cap_drop_acked_frames(sk); 4246*0a708f8fSGustavo F. Padovan 4247*0a708f8fSGustavo F. Padovan pi->conn_state |= L2CAP_CONN_SEND_FBIT; 4248*0a708f8fSGustavo F. Padovan l2cap_retransmit_one_frame(sk, tx_seq); 4249*0a708f8fSGustavo F. Padovan 4250*0a708f8fSGustavo F. Padovan l2cap_ertm_send(sk); 4251*0a708f8fSGustavo F. Padovan 4252*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_WAIT_F) { 4253*0a708f8fSGustavo F. Padovan pi->srej_save_reqseq = tx_seq; 4254*0a708f8fSGustavo F. Padovan pi->conn_state |= L2CAP_CONN_SREJ_ACT; 4255*0a708f8fSGustavo F. Padovan } 4256*0a708f8fSGustavo F. Padovan } else if (rx_control & L2CAP_CTRL_FINAL) { 4257*0a708f8fSGustavo F. Padovan if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) && 4258*0a708f8fSGustavo F. Padovan pi->srej_save_reqseq == tx_seq) 4259*0a708f8fSGustavo F. Padovan pi->conn_state &= ~L2CAP_CONN_SREJ_ACT; 4260*0a708f8fSGustavo F. Padovan else 4261*0a708f8fSGustavo F. Padovan l2cap_retransmit_one_frame(sk, tx_seq); 4262*0a708f8fSGustavo F. Padovan } else { 4263*0a708f8fSGustavo F. Padovan l2cap_retransmit_one_frame(sk, tx_seq); 4264*0a708f8fSGustavo F. Padovan if (pi->conn_state & L2CAP_CONN_WAIT_F) { 4265*0a708f8fSGustavo F. Padovan pi->srej_save_reqseq = tx_seq; 4266*0a708f8fSGustavo F. Padovan pi->conn_state |= L2CAP_CONN_SREJ_ACT; 4267*0a708f8fSGustavo F. Padovan } 4268*0a708f8fSGustavo F. Padovan } 4269*0a708f8fSGustavo F. Padovan } 4270*0a708f8fSGustavo F. Padovan 4271*0a708f8fSGustavo F. Padovan static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control) 4272*0a708f8fSGustavo F. Padovan { 4273*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 4274*0a708f8fSGustavo F. Padovan u8 tx_seq = __get_reqseq(rx_control); 4275*0a708f8fSGustavo F. Padovan 4276*0a708f8fSGustavo F. Padovan BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control); 4277*0a708f8fSGustavo F. Padovan 4278*0a708f8fSGustavo F. Padovan pi->conn_state |= L2CAP_CONN_REMOTE_BUSY; 4279*0a708f8fSGustavo F. Padovan pi->expected_ack_seq = tx_seq; 4280*0a708f8fSGustavo F. Padovan l2cap_drop_acked_frames(sk); 4281*0a708f8fSGustavo F. Padovan 4282*0a708f8fSGustavo F. Padovan if (rx_control & L2CAP_CTRL_POLL) 4283*0a708f8fSGustavo F. Padovan pi->conn_state |= L2CAP_CONN_SEND_FBIT; 4284*0a708f8fSGustavo F. Padovan 4285*0a708f8fSGustavo F. Padovan if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) { 4286*0a708f8fSGustavo F. Padovan del_timer(&pi->retrans_timer); 4287*0a708f8fSGustavo F. Padovan if (rx_control & L2CAP_CTRL_POLL) 4288*0a708f8fSGustavo F. Padovan l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL); 4289*0a708f8fSGustavo F. Padovan return; 4290*0a708f8fSGustavo F. Padovan } 4291*0a708f8fSGustavo F. Padovan 4292*0a708f8fSGustavo F. Padovan if (rx_control & L2CAP_CTRL_POLL) 4293*0a708f8fSGustavo F. Padovan l2cap_send_srejtail(sk); 4294*0a708f8fSGustavo F. Padovan else 4295*0a708f8fSGustavo F. Padovan l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY); 4296*0a708f8fSGustavo F. Padovan } 4297*0a708f8fSGustavo F. Padovan 4298*0a708f8fSGustavo F. Padovan static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb) 4299*0a708f8fSGustavo F. Padovan { 4300*0a708f8fSGustavo F. Padovan BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len); 4301*0a708f8fSGustavo F. Padovan 4302*0a708f8fSGustavo F. Padovan if (L2CAP_CTRL_FINAL & rx_control && 4303*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) { 4304*0a708f8fSGustavo F. Padovan del_timer(&l2cap_pi(sk)->monitor_timer); 4305*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->unacked_frames > 0) 4306*0a708f8fSGustavo F. Padovan __mod_retrans_timer(); 4307*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F; 4308*0a708f8fSGustavo F. Padovan } 4309*0a708f8fSGustavo F. Padovan 4310*0a708f8fSGustavo F. Padovan switch (rx_control & L2CAP_CTRL_SUPERVISE) { 4311*0a708f8fSGustavo F. Padovan case L2CAP_SUPER_RCV_READY: 4312*0a708f8fSGustavo F. Padovan l2cap_data_channel_rrframe(sk, rx_control); 4313*0a708f8fSGustavo F. Padovan break; 4314*0a708f8fSGustavo F. Padovan 4315*0a708f8fSGustavo F. Padovan case L2CAP_SUPER_REJECT: 4316*0a708f8fSGustavo F. Padovan l2cap_data_channel_rejframe(sk, rx_control); 4317*0a708f8fSGustavo F. Padovan break; 4318*0a708f8fSGustavo F. Padovan 4319*0a708f8fSGustavo F. Padovan case L2CAP_SUPER_SELECT_REJECT: 4320*0a708f8fSGustavo F. Padovan l2cap_data_channel_srejframe(sk, rx_control); 4321*0a708f8fSGustavo F. Padovan break; 4322*0a708f8fSGustavo F. Padovan 4323*0a708f8fSGustavo F. Padovan case L2CAP_SUPER_RCV_NOT_READY: 4324*0a708f8fSGustavo F. Padovan l2cap_data_channel_rnrframe(sk, rx_control); 4325*0a708f8fSGustavo F. Padovan break; 4326*0a708f8fSGustavo F. Padovan } 4327*0a708f8fSGustavo F. Padovan 4328*0a708f8fSGustavo F. Padovan kfree_skb(skb); 4329*0a708f8fSGustavo F. Padovan return 0; 4330*0a708f8fSGustavo F. Padovan } 4331*0a708f8fSGustavo F. Padovan 4332*0a708f8fSGustavo F. Padovan static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) 4333*0a708f8fSGustavo F. Padovan { 4334*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 4335*0a708f8fSGustavo F. Padovan u16 control; 4336*0a708f8fSGustavo F. Padovan u8 req_seq; 4337*0a708f8fSGustavo F. Padovan int len, next_tx_seq_offset, req_seq_offset; 4338*0a708f8fSGustavo F. Padovan 4339*0a708f8fSGustavo F. Padovan control = get_unaligned_le16(skb->data); 4340*0a708f8fSGustavo F. Padovan skb_pull(skb, 2); 4341*0a708f8fSGustavo F. Padovan len = skb->len; 4342*0a708f8fSGustavo F. Padovan 4343*0a708f8fSGustavo F. Padovan /* 4344*0a708f8fSGustavo F. Padovan * We can just drop the corrupted I-frame here. 4345*0a708f8fSGustavo F. Padovan * Receiver will miss it and start proper recovery 4346*0a708f8fSGustavo F. Padovan * procedures and ask retransmission. 4347*0a708f8fSGustavo F. Padovan */ 4348*0a708f8fSGustavo F. Padovan if (l2cap_check_fcs(pi, skb)) 4349*0a708f8fSGustavo F. Padovan goto drop; 4350*0a708f8fSGustavo F. Padovan 4351*0a708f8fSGustavo F. Padovan if (__is_sar_start(control) && __is_iframe(control)) 4352*0a708f8fSGustavo F. Padovan len -= 2; 4353*0a708f8fSGustavo F. Padovan 4354*0a708f8fSGustavo F. Padovan if (pi->fcs == L2CAP_FCS_CRC16) 4355*0a708f8fSGustavo F. Padovan len -= 2; 4356*0a708f8fSGustavo F. Padovan 4357*0a708f8fSGustavo F. Padovan if (len > pi->mps) { 4358*0a708f8fSGustavo F. Padovan l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); 4359*0a708f8fSGustavo F. Padovan goto drop; 4360*0a708f8fSGustavo F. Padovan } 4361*0a708f8fSGustavo F. Padovan 4362*0a708f8fSGustavo F. Padovan req_seq = __get_reqseq(control); 4363*0a708f8fSGustavo F. Padovan req_seq_offset = (req_seq - pi->expected_ack_seq) % 64; 4364*0a708f8fSGustavo F. Padovan if (req_seq_offset < 0) 4365*0a708f8fSGustavo F. Padovan req_seq_offset += 64; 4366*0a708f8fSGustavo F. Padovan 4367*0a708f8fSGustavo F. Padovan next_tx_seq_offset = 4368*0a708f8fSGustavo F. Padovan (pi->next_tx_seq - pi->expected_ack_seq) % 64; 4369*0a708f8fSGustavo F. Padovan if (next_tx_seq_offset < 0) 4370*0a708f8fSGustavo F. Padovan next_tx_seq_offset += 64; 4371*0a708f8fSGustavo F. Padovan 4372*0a708f8fSGustavo F. Padovan /* check for invalid req-seq */ 4373*0a708f8fSGustavo F. Padovan if (req_seq_offset > next_tx_seq_offset) { 4374*0a708f8fSGustavo F. Padovan l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); 4375*0a708f8fSGustavo F. Padovan goto drop; 4376*0a708f8fSGustavo F. Padovan } 4377*0a708f8fSGustavo F. Padovan 4378*0a708f8fSGustavo F. Padovan if (__is_iframe(control)) { 4379*0a708f8fSGustavo F. Padovan if (len < 0) { 4380*0a708f8fSGustavo F. Padovan l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); 4381*0a708f8fSGustavo F. Padovan goto drop; 4382*0a708f8fSGustavo F. Padovan } 4383*0a708f8fSGustavo F. Padovan 4384*0a708f8fSGustavo F. Padovan l2cap_data_channel_iframe(sk, control, skb); 4385*0a708f8fSGustavo F. Padovan } else { 4386*0a708f8fSGustavo F. Padovan if (len != 0) { 4387*0a708f8fSGustavo F. Padovan BT_ERR("%d", len); 4388*0a708f8fSGustavo F. Padovan l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); 4389*0a708f8fSGustavo F. Padovan goto drop; 4390*0a708f8fSGustavo F. Padovan } 4391*0a708f8fSGustavo F. Padovan 4392*0a708f8fSGustavo F. Padovan l2cap_data_channel_sframe(sk, control, skb); 4393*0a708f8fSGustavo F. Padovan } 4394*0a708f8fSGustavo F. Padovan 4395*0a708f8fSGustavo F. Padovan return 0; 4396*0a708f8fSGustavo F. Padovan 4397*0a708f8fSGustavo F. Padovan drop: 4398*0a708f8fSGustavo F. Padovan kfree_skb(skb); 4399*0a708f8fSGustavo F. Padovan return 0; 4400*0a708f8fSGustavo F. Padovan } 4401*0a708f8fSGustavo F. Padovan 4402*0a708f8fSGustavo F. Padovan static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb) 4403*0a708f8fSGustavo F. Padovan { 4404*0a708f8fSGustavo F. Padovan struct sock *sk; 4405*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi; 4406*0a708f8fSGustavo F. Padovan u16 control; 4407*0a708f8fSGustavo F. Padovan u8 tx_seq; 4408*0a708f8fSGustavo F. Padovan int len; 4409*0a708f8fSGustavo F. Padovan 4410*0a708f8fSGustavo F. Padovan sk = l2cap_get_chan_by_scid(&conn->chan_list, cid); 4411*0a708f8fSGustavo F. Padovan if (!sk) { 4412*0a708f8fSGustavo F. Padovan BT_DBG("unknown cid 0x%4.4x", cid); 4413*0a708f8fSGustavo F. Padovan goto drop; 4414*0a708f8fSGustavo F. Padovan } 4415*0a708f8fSGustavo F. Padovan 4416*0a708f8fSGustavo F. Padovan pi = l2cap_pi(sk); 4417*0a708f8fSGustavo F. Padovan 4418*0a708f8fSGustavo F. Padovan BT_DBG("sk %p, len %d", sk, skb->len); 4419*0a708f8fSGustavo F. Padovan 4420*0a708f8fSGustavo F. Padovan if (sk->sk_state != BT_CONNECTED) 4421*0a708f8fSGustavo F. Padovan goto drop; 4422*0a708f8fSGustavo F. Padovan 4423*0a708f8fSGustavo F. Padovan switch (pi->mode) { 4424*0a708f8fSGustavo F. Padovan case L2CAP_MODE_BASIC: 4425*0a708f8fSGustavo F. Padovan /* If socket recv buffers overflows we drop data here 4426*0a708f8fSGustavo F. Padovan * which is *bad* because L2CAP has to be reliable. 4427*0a708f8fSGustavo F. Padovan * But we don't have any other choice. L2CAP doesn't 4428*0a708f8fSGustavo F. Padovan * provide flow control mechanism. */ 4429*0a708f8fSGustavo F. Padovan 4430*0a708f8fSGustavo F. Padovan if (pi->imtu < skb->len) 4431*0a708f8fSGustavo F. Padovan goto drop; 4432*0a708f8fSGustavo F. Padovan 4433*0a708f8fSGustavo F. Padovan if (!sock_queue_rcv_skb(sk, skb)) 4434*0a708f8fSGustavo F. Padovan goto done; 4435*0a708f8fSGustavo F. Padovan break; 4436*0a708f8fSGustavo F. Padovan 4437*0a708f8fSGustavo F. Padovan case L2CAP_MODE_ERTM: 4438*0a708f8fSGustavo F. Padovan if (!sock_owned_by_user(sk)) { 4439*0a708f8fSGustavo F. Padovan l2cap_ertm_data_rcv(sk, skb); 4440*0a708f8fSGustavo F. Padovan } else { 4441*0a708f8fSGustavo F. Padovan if (sk_add_backlog(sk, skb)) 4442*0a708f8fSGustavo F. Padovan goto drop; 4443*0a708f8fSGustavo F. Padovan } 4444*0a708f8fSGustavo F. Padovan 4445*0a708f8fSGustavo F. Padovan goto done; 4446*0a708f8fSGustavo F. Padovan 4447*0a708f8fSGustavo F. Padovan case L2CAP_MODE_STREAMING: 4448*0a708f8fSGustavo F. Padovan control = get_unaligned_le16(skb->data); 4449*0a708f8fSGustavo F. Padovan skb_pull(skb, 2); 4450*0a708f8fSGustavo F. Padovan len = skb->len; 4451*0a708f8fSGustavo F. Padovan 4452*0a708f8fSGustavo F. Padovan if (l2cap_check_fcs(pi, skb)) 4453*0a708f8fSGustavo F. Padovan goto drop; 4454*0a708f8fSGustavo F. Padovan 4455*0a708f8fSGustavo F. Padovan if (__is_sar_start(control)) 4456*0a708f8fSGustavo F. Padovan len -= 2; 4457*0a708f8fSGustavo F. Padovan 4458*0a708f8fSGustavo F. Padovan if (pi->fcs == L2CAP_FCS_CRC16) 4459*0a708f8fSGustavo F. Padovan len -= 2; 4460*0a708f8fSGustavo F. Padovan 4461*0a708f8fSGustavo F. Padovan if (len > pi->mps || len < 0 || __is_sframe(control)) 4462*0a708f8fSGustavo F. Padovan goto drop; 4463*0a708f8fSGustavo F. Padovan 4464*0a708f8fSGustavo F. Padovan tx_seq = __get_txseq(control); 4465*0a708f8fSGustavo F. Padovan 4466*0a708f8fSGustavo F. Padovan if (pi->expected_tx_seq == tx_seq) 4467*0a708f8fSGustavo F. Padovan pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64; 4468*0a708f8fSGustavo F. Padovan else 4469*0a708f8fSGustavo F. Padovan pi->expected_tx_seq = (tx_seq + 1) % 64; 4470*0a708f8fSGustavo F. Padovan 4471*0a708f8fSGustavo F. Padovan l2cap_streaming_reassembly_sdu(sk, skb, control); 4472*0a708f8fSGustavo F. Padovan 4473*0a708f8fSGustavo F. Padovan goto done; 4474*0a708f8fSGustavo F. Padovan 4475*0a708f8fSGustavo F. Padovan default: 4476*0a708f8fSGustavo F. Padovan BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode); 4477*0a708f8fSGustavo F. Padovan break; 4478*0a708f8fSGustavo F. Padovan } 4479*0a708f8fSGustavo F. Padovan 4480*0a708f8fSGustavo F. Padovan drop: 4481*0a708f8fSGustavo F. Padovan kfree_skb(skb); 4482*0a708f8fSGustavo F. Padovan 4483*0a708f8fSGustavo F. Padovan done: 4484*0a708f8fSGustavo F. Padovan if (sk) 4485*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 4486*0a708f8fSGustavo F. Padovan 4487*0a708f8fSGustavo F. Padovan return 0; 4488*0a708f8fSGustavo F. Padovan } 4489*0a708f8fSGustavo F. Padovan 4490*0a708f8fSGustavo F. Padovan static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb) 4491*0a708f8fSGustavo F. Padovan { 4492*0a708f8fSGustavo F. Padovan struct sock *sk; 4493*0a708f8fSGustavo F. Padovan 4494*0a708f8fSGustavo F. Padovan sk = l2cap_get_sock_by_psm(0, psm, conn->src); 4495*0a708f8fSGustavo F. Padovan if (!sk) 4496*0a708f8fSGustavo F. Padovan goto drop; 4497*0a708f8fSGustavo F. Padovan 4498*0a708f8fSGustavo F. Padovan bh_lock_sock(sk); 4499*0a708f8fSGustavo F. Padovan 4500*0a708f8fSGustavo F. Padovan BT_DBG("sk %p, len %d", sk, skb->len); 4501*0a708f8fSGustavo F. Padovan 4502*0a708f8fSGustavo F. Padovan if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED) 4503*0a708f8fSGustavo F. Padovan goto drop; 4504*0a708f8fSGustavo F. Padovan 4505*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->imtu < skb->len) 4506*0a708f8fSGustavo F. Padovan goto drop; 4507*0a708f8fSGustavo F. Padovan 4508*0a708f8fSGustavo F. Padovan if (!sock_queue_rcv_skb(sk, skb)) 4509*0a708f8fSGustavo F. Padovan goto done; 4510*0a708f8fSGustavo F. Padovan 4511*0a708f8fSGustavo F. Padovan drop: 4512*0a708f8fSGustavo F. Padovan kfree_skb(skb); 4513*0a708f8fSGustavo F. Padovan 4514*0a708f8fSGustavo F. Padovan done: 4515*0a708f8fSGustavo F. Padovan if (sk) 4516*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 4517*0a708f8fSGustavo F. Padovan return 0; 4518*0a708f8fSGustavo F. Padovan } 4519*0a708f8fSGustavo F. Padovan 4520*0a708f8fSGustavo F. Padovan static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) 4521*0a708f8fSGustavo F. Padovan { 4522*0a708f8fSGustavo F. Padovan struct l2cap_hdr *lh = (void *) skb->data; 4523*0a708f8fSGustavo F. Padovan u16 cid, len; 4524*0a708f8fSGustavo F. Padovan __le16 psm; 4525*0a708f8fSGustavo F. Padovan 4526*0a708f8fSGustavo F. Padovan skb_pull(skb, L2CAP_HDR_SIZE); 4527*0a708f8fSGustavo F. Padovan cid = __le16_to_cpu(lh->cid); 4528*0a708f8fSGustavo F. Padovan len = __le16_to_cpu(lh->len); 4529*0a708f8fSGustavo F. Padovan 4530*0a708f8fSGustavo F. Padovan if (len != skb->len) { 4531*0a708f8fSGustavo F. Padovan kfree_skb(skb); 4532*0a708f8fSGustavo F. Padovan return; 4533*0a708f8fSGustavo F. Padovan } 4534*0a708f8fSGustavo F. Padovan 4535*0a708f8fSGustavo F. Padovan BT_DBG("len %d, cid 0x%4.4x", len, cid); 4536*0a708f8fSGustavo F. Padovan 4537*0a708f8fSGustavo F. Padovan switch (cid) { 4538*0a708f8fSGustavo F. Padovan case L2CAP_CID_SIGNALING: 4539*0a708f8fSGustavo F. Padovan l2cap_sig_channel(conn, skb); 4540*0a708f8fSGustavo F. Padovan break; 4541*0a708f8fSGustavo F. Padovan 4542*0a708f8fSGustavo F. Padovan case L2CAP_CID_CONN_LESS: 4543*0a708f8fSGustavo F. Padovan psm = get_unaligned_le16(skb->data); 4544*0a708f8fSGustavo F. Padovan skb_pull(skb, 2); 4545*0a708f8fSGustavo F. Padovan l2cap_conless_channel(conn, psm, skb); 4546*0a708f8fSGustavo F. Padovan break; 4547*0a708f8fSGustavo F. Padovan 4548*0a708f8fSGustavo F. Padovan default: 4549*0a708f8fSGustavo F. Padovan l2cap_data_channel(conn, cid, skb); 4550*0a708f8fSGustavo F. Padovan break; 4551*0a708f8fSGustavo F. Padovan } 4552*0a708f8fSGustavo F. Padovan } 4553*0a708f8fSGustavo F. Padovan 4554*0a708f8fSGustavo F. Padovan /* ---- L2CAP interface with lower layer (HCI) ---- */ 4555*0a708f8fSGustavo F. Padovan 4556*0a708f8fSGustavo F. Padovan static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 4557*0a708f8fSGustavo F. Padovan { 4558*0a708f8fSGustavo F. Padovan int exact = 0, lm1 = 0, lm2 = 0; 4559*0a708f8fSGustavo F. Padovan register struct sock *sk; 4560*0a708f8fSGustavo F. Padovan struct hlist_node *node; 4561*0a708f8fSGustavo F. Padovan 4562*0a708f8fSGustavo F. Padovan if (type != ACL_LINK) 4563*0a708f8fSGustavo F. Padovan return -EINVAL; 4564*0a708f8fSGustavo F. Padovan 4565*0a708f8fSGustavo F. Padovan BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); 4566*0a708f8fSGustavo F. Padovan 4567*0a708f8fSGustavo F. Padovan /* Find listening sockets and check their link_mode */ 4568*0a708f8fSGustavo F. Padovan read_lock(&l2cap_sk_list.lock); 4569*0a708f8fSGustavo F. Padovan sk_for_each(sk, node, &l2cap_sk_list.head) { 4570*0a708f8fSGustavo F. Padovan if (sk->sk_state != BT_LISTEN) 4571*0a708f8fSGustavo F. Padovan continue; 4572*0a708f8fSGustavo F. Padovan 4573*0a708f8fSGustavo F. Padovan if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) { 4574*0a708f8fSGustavo F. Padovan lm1 |= HCI_LM_ACCEPT; 4575*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->role_switch) 4576*0a708f8fSGustavo F. Padovan lm1 |= HCI_LM_MASTER; 4577*0a708f8fSGustavo F. Padovan exact++; 4578*0a708f8fSGustavo F. Padovan } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) { 4579*0a708f8fSGustavo F. Padovan lm2 |= HCI_LM_ACCEPT; 4580*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->role_switch) 4581*0a708f8fSGustavo F. Padovan lm2 |= HCI_LM_MASTER; 4582*0a708f8fSGustavo F. Padovan } 4583*0a708f8fSGustavo F. Padovan } 4584*0a708f8fSGustavo F. Padovan read_unlock(&l2cap_sk_list.lock); 4585*0a708f8fSGustavo F. Padovan 4586*0a708f8fSGustavo F. Padovan return exact ? lm1 : lm2; 4587*0a708f8fSGustavo F. Padovan } 4588*0a708f8fSGustavo F. Padovan 4589*0a708f8fSGustavo F. Padovan static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status) 4590*0a708f8fSGustavo F. Padovan { 4591*0a708f8fSGustavo F. Padovan struct l2cap_conn *conn; 4592*0a708f8fSGustavo F. Padovan 4593*0a708f8fSGustavo F. Padovan BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); 4594*0a708f8fSGustavo F. Padovan 4595*0a708f8fSGustavo F. Padovan if (hcon->type != ACL_LINK) 4596*0a708f8fSGustavo F. Padovan return -EINVAL; 4597*0a708f8fSGustavo F. Padovan 4598*0a708f8fSGustavo F. Padovan if (!status) { 4599*0a708f8fSGustavo F. Padovan conn = l2cap_conn_add(hcon, status); 4600*0a708f8fSGustavo F. Padovan if (conn) 4601*0a708f8fSGustavo F. Padovan l2cap_conn_ready(conn); 4602*0a708f8fSGustavo F. Padovan } else 4603*0a708f8fSGustavo F. Padovan l2cap_conn_del(hcon, bt_err(status)); 4604*0a708f8fSGustavo F. Padovan 4605*0a708f8fSGustavo F. Padovan return 0; 4606*0a708f8fSGustavo F. Padovan } 4607*0a708f8fSGustavo F. Padovan 4608*0a708f8fSGustavo F. Padovan static int l2cap_disconn_ind(struct hci_conn *hcon) 4609*0a708f8fSGustavo F. Padovan { 4610*0a708f8fSGustavo F. Padovan struct l2cap_conn *conn = hcon->l2cap_data; 4611*0a708f8fSGustavo F. Padovan 4612*0a708f8fSGustavo F. Padovan BT_DBG("hcon %p", hcon); 4613*0a708f8fSGustavo F. Padovan 4614*0a708f8fSGustavo F. Padovan if (hcon->type != ACL_LINK || !conn) 4615*0a708f8fSGustavo F. Padovan return 0x13; 4616*0a708f8fSGustavo F. Padovan 4617*0a708f8fSGustavo F. Padovan return conn->disc_reason; 4618*0a708f8fSGustavo F. Padovan } 4619*0a708f8fSGustavo F. Padovan 4620*0a708f8fSGustavo F. Padovan static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason) 4621*0a708f8fSGustavo F. Padovan { 4622*0a708f8fSGustavo F. Padovan BT_DBG("hcon %p reason %d", hcon, reason); 4623*0a708f8fSGustavo F. Padovan 4624*0a708f8fSGustavo F. Padovan if (hcon->type != ACL_LINK) 4625*0a708f8fSGustavo F. Padovan return -EINVAL; 4626*0a708f8fSGustavo F. Padovan 4627*0a708f8fSGustavo F. Padovan l2cap_conn_del(hcon, bt_err(reason)); 4628*0a708f8fSGustavo F. Padovan 4629*0a708f8fSGustavo F. Padovan return 0; 4630*0a708f8fSGustavo F. Padovan } 4631*0a708f8fSGustavo F. Padovan 4632*0a708f8fSGustavo F. Padovan static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt) 4633*0a708f8fSGustavo F. Padovan { 4634*0a708f8fSGustavo F. Padovan if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM) 4635*0a708f8fSGustavo F. Padovan return; 4636*0a708f8fSGustavo F. Padovan 4637*0a708f8fSGustavo F. Padovan if (encrypt == 0x00) { 4638*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) { 4639*0a708f8fSGustavo F. Padovan l2cap_sock_clear_timer(sk); 4640*0a708f8fSGustavo F. Padovan l2cap_sock_set_timer(sk, HZ * 5); 4641*0a708f8fSGustavo F. Padovan } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH) 4642*0a708f8fSGustavo F. Padovan __l2cap_sock_close(sk, ECONNREFUSED); 4643*0a708f8fSGustavo F. Padovan } else { 4644*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) 4645*0a708f8fSGustavo F. Padovan l2cap_sock_clear_timer(sk); 4646*0a708f8fSGustavo F. Padovan } 4647*0a708f8fSGustavo F. Padovan } 4648*0a708f8fSGustavo F. Padovan 4649*0a708f8fSGustavo F. Padovan static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) 4650*0a708f8fSGustavo F. Padovan { 4651*0a708f8fSGustavo F. Padovan struct l2cap_chan_list *l; 4652*0a708f8fSGustavo F. Padovan struct l2cap_conn *conn = hcon->l2cap_data; 4653*0a708f8fSGustavo F. Padovan struct sock *sk; 4654*0a708f8fSGustavo F. Padovan 4655*0a708f8fSGustavo F. Padovan if (!conn) 4656*0a708f8fSGustavo F. Padovan return 0; 4657*0a708f8fSGustavo F. Padovan 4658*0a708f8fSGustavo F. Padovan l = &conn->chan_list; 4659*0a708f8fSGustavo F. Padovan 4660*0a708f8fSGustavo F. Padovan BT_DBG("conn %p", conn); 4661*0a708f8fSGustavo F. Padovan 4662*0a708f8fSGustavo F. Padovan read_lock(&l->lock); 4663*0a708f8fSGustavo F. Padovan 4664*0a708f8fSGustavo F. Padovan for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { 4665*0a708f8fSGustavo F. Padovan bh_lock_sock(sk); 4666*0a708f8fSGustavo F. Padovan 4667*0a708f8fSGustavo F. Padovan if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) { 4668*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 4669*0a708f8fSGustavo F. Padovan continue; 4670*0a708f8fSGustavo F. Padovan } 4671*0a708f8fSGustavo F. Padovan 4672*0a708f8fSGustavo F. Padovan if (!status && (sk->sk_state == BT_CONNECTED || 4673*0a708f8fSGustavo F. Padovan sk->sk_state == BT_CONFIG)) { 4674*0a708f8fSGustavo F. Padovan l2cap_check_encryption(sk, encrypt); 4675*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 4676*0a708f8fSGustavo F. Padovan continue; 4677*0a708f8fSGustavo F. Padovan } 4678*0a708f8fSGustavo F. Padovan 4679*0a708f8fSGustavo F. Padovan if (sk->sk_state == BT_CONNECT) { 4680*0a708f8fSGustavo F. Padovan if (!status) { 4681*0a708f8fSGustavo F. Padovan struct l2cap_conn_req req; 4682*0a708f8fSGustavo F. Padovan req.scid = cpu_to_le16(l2cap_pi(sk)->scid); 4683*0a708f8fSGustavo F. Padovan req.psm = l2cap_pi(sk)->psm; 4684*0a708f8fSGustavo F. Padovan 4685*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->ident = l2cap_get_ident(conn); 4686*0a708f8fSGustavo F. Padovan l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND; 4687*0a708f8fSGustavo F. Padovan 4688*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, l2cap_pi(sk)->ident, 4689*0a708f8fSGustavo F. Padovan L2CAP_CONN_REQ, sizeof(req), &req); 4690*0a708f8fSGustavo F. Padovan } else { 4691*0a708f8fSGustavo F. Padovan l2cap_sock_clear_timer(sk); 4692*0a708f8fSGustavo F. Padovan l2cap_sock_set_timer(sk, HZ / 10); 4693*0a708f8fSGustavo F. Padovan } 4694*0a708f8fSGustavo F. Padovan } else if (sk->sk_state == BT_CONNECT2) { 4695*0a708f8fSGustavo F. Padovan struct l2cap_conn_rsp rsp; 4696*0a708f8fSGustavo F. Padovan __u16 result; 4697*0a708f8fSGustavo F. Padovan 4698*0a708f8fSGustavo F. Padovan if (!status) { 4699*0a708f8fSGustavo F. Padovan sk->sk_state = BT_CONFIG; 4700*0a708f8fSGustavo F. Padovan result = L2CAP_CR_SUCCESS; 4701*0a708f8fSGustavo F. Padovan } else { 4702*0a708f8fSGustavo F. Padovan sk->sk_state = BT_DISCONN; 4703*0a708f8fSGustavo F. Padovan l2cap_sock_set_timer(sk, HZ / 10); 4704*0a708f8fSGustavo F. Padovan result = L2CAP_CR_SEC_BLOCK; 4705*0a708f8fSGustavo F. Padovan } 4706*0a708f8fSGustavo F. Padovan 4707*0a708f8fSGustavo F. Padovan rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); 4708*0a708f8fSGustavo F. Padovan rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); 4709*0a708f8fSGustavo F. Padovan rsp.result = cpu_to_le16(result); 4710*0a708f8fSGustavo F. Padovan rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); 4711*0a708f8fSGustavo F. Padovan l2cap_send_cmd(conn, l2cap_pi(sk)->ident, 4712*0a708f8fSGustavo F. Padovan L2CAP_CONN_RSP, sizeof(rsp), &rsp); 4713*0a708f8fSGustavo F. Padovan } 4714*0a708f8fSGustavo F. Padovan 4715*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 4716*0a708f8fSGustavo F. Padovan } 4717*0a708f8fSGustavo F. Padovan 4718*0a708f8fSGustavo F. Padovan read_unlock(&l->lock); 4719*0a708f8fSGustavo F. Padovan 4720*0a708f8fSGustavo F. Padovan return 0; 4721*0a708f8fSGustavo F. Padovan } 4722*0a708f8fSGustavo F. Padovan 4723*0a708f8fSGustavo F. Padovan static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) 4724*0a708f8fSGustavo F. Padovan { 4725*0a708f8fSGustavo F. Padovan struct l2cap_conn *conn = hcon->l2cap_data; 4726*0a708f8fSGustavo F. Padovan 4727*0a708f8fSGustavo F. Padovan if (!conn) 4728*0a708f8fSGustavo F. Padovan conn = l2cap_conn_add(hcon, 0); 4729*0a708f8fSGustavo F. Padovan 4730*0a708f8fSGustavo F. Padovan if (!conn) 4731*0a708f8fSGustavo F. Padovan goto drop; 4732*0a708f8fSGustavo F. Padovan 4733*0a708f8fSGustavo F. Padovan BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags); 4734*0a708f8fSGustavo F. Padovan 4735*0a708f8fSGustavo F. Padovan if (!(flags & ACL_CONT)) { 4736*0a708f8fSGustavo F. Padovan struct l2cap_hdr *hdr; 4737*0a708f8fSGustavo F. Padovan struct sock *sk; 4738*0a708f8fSGustavo F. Padovan u16 cid; 4739*0a708f8fSGustavo F. Padovan int len; 4740*0a708f8fSGustavo F. Padovan 4741*0a708f8fSGustavo F. Padovan if (conn->rx_len) { 4742*0a708f8fSGustavo F. Padovan BT_ERR("Unexpected start frame (len %d)", skb->len); 4743*0a708f8fSGustavo F. Padovan kfree_skb(conn->rx_skb); 4744*0a708f8fSGustavo F. Padovan conn->rx_skb = NULL; 4745*0a708f8fSGustavo F. Padovan conn->rx_len = 0; 4746*0a708f8fSGustavo F. Padovan l2cap_conn_unreliable(conn, ECOMM); 4747*0a708f8fSGustavo F. Padovan } 4748*0a708f8fSGustavo F. Padovan 4749*0a708f8fSGustavo F. Padovan /* Start fragment always begin with Basic L2CAP header */ 4750*0a708f8fSGustavo F. Padovan if (skb->len < L2CAP_HDR_SIZE) { 4751*0a708f8fSGustavo F. Padovan BT_ERR("Frame is too short (len %d)", skb->len); 4752*0a708f8fSGustavo F. Padovan l2cap_conn_unreliable(conn, ECOMM); 4753*0a708f8fSGustavo F. Padovan goto drop; 4754*0a708f8fSGustavo F. Padovan } 4755*0a708f8fSGustavo F. Padovan 4756*0a708f8fSGustavo F. Padovan hdr = (struct l2cap_hdr *) skb->data; 4757*0a708f8fSGustavo F. Padovan len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE; 4758*0a708f8fSGustavo F. Padovan cid = __le16_to_cpu(hdr->cid); 4759*0a708f8fSGustavo F. Padovan 4760*0a708f8fSGustavo F. Padovan if (len == skb->len) { 4761*0a708f8fSGustavo F. Padovan /* Complete frame received */ 4762*0a708f8fSGustavo F. Padovan l2cap_recv_frame(conn, skb); 4763*0a708f8fSGustavo F. Padovan return 0; 4764*0a708f8fSGustavo F. Padovan } 4765*0a708f8fSGustavo F. Padovan 4766*0a708f8fSGustavo F. Padovan BT_DBG("Start: total len %d, frag len %d", len, skb->len); 4767*0a708f8fSGustavo F. Padovan 4768*0a708f8fSGustavo F. Padovan if (skb->len > len) { 4769*0a708f8fSGustavo F. Padovan BT_ERR("Frame is too long (len %d, expected len %d)", 4770*0a708f8fSGustavo F. Padovan skb->len, len); 4771*0a708f8fSGustavo F. Padovan l2cap_conn_unreliable(conn, ECOMM); 4772*0a708f8fSGustavo F. Padovan goto drop; 4773*0a708f8fSGustavo F. Padovan } 4774*0a708f8fSGustavo F. Padovan 4775*0a708f8fSGustavo F. Padovan sk = l2cap_get_chan_by_scid(&conn->chan_list, cid); 4776*0a708f8fSGustavo F. Padovan 4777*0a708f8fSGustavo F. Padovan if (sk && l2cap_pi(sk)->imtu < len - L2CAP_HDR_SIZE) { 4778*0a708f8fSGustavo F. Padovan BT_ERR("Frame exceeding recv MTU (len %d, MTU %d)", 4779*0a708f8fSGustavo F. Padovan len, l2cap_pi(sk)->imtu); 4780*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 4781*0a708f8fSGustavo F. Padovan l2cap_conn_unreliable(conn, ECOMM); 4782*0a708f8fSGustavo F. Padovan goto drop; 4783*0a708f8fSGustavo F. Padovan } 4784*0a708f8fSGustavo F. Padovan 4785*0a708f8fSGustavo F. Padovan if (sk) 4786*0a708f8fSGustavo F. Padovan bh_unlock_sock(sk); 4787*0a708f8fSGustavo F. Padovan 4788*0a708f8fSGustavo F. Padovan /* Allocate skb for the complete frame (with header) */ 4789*0a708f8fSGustavo F. Padovan conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC); 4790*0a708f8fSGustavo F. Padovan if (!conn->rx_skb) 4791*0a708f8fSGustavo F. Padovan goto drop; 4792*0a708f8fSGustavo F. Padovan 4793*0a708f8fSGustavo F. Padovan skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len), 4794*0a708f8fSGustavo F. Padovan skb->len); 4795*0a708f8fSGustavo F. Padovan conn->rx_len = len - skb->len; 4796*0a708f8fSGustavo F. Padovan } else { 4797*0a708f8fSGustavo F. Padovan BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len); 4798*0a708f8fSGustavo F. Padovan 4799*0a708f8fSGustavo F. Padovan if (!conn->rx_len) { 4800*0a708f8fSGustavo F. Padovan BT_ERR("Unexpected continuation frame (len %d)", skb->len); 4801*0a708f8fSGustavo F. Padovan l2cap_conn_unreliable(conn, ECOMM); 4802*0a708f8fSGustavo F. Padovan goto drop; 4803*0a708f8fSGustavo F. Padovan } 4804*0a708f8fSGustavo F. Padovan 4805*0a708f8fSGustavo F. Padovan if (skb->len > conn->rx_len) { 4806*0a708f8fSGustavo F. Padovan BT_ERR("Fragment is too long (len %d, expected %d)", 4807*0a708f8fSGustavo F. Padovan skb->len, conn->rx_len); 4808*0a708f8fSGustavo F. Padovan kfree_skb(conn->rx_skb); 4809*0a708f8fSGustavo F. Padovan conn->rx_skb = NULL; 4810*0a708f8fSGustavo F. Padovan conn->rx_len = 0; 4811*0a708f8fSGustavo F. Padovan l2cap_conn_unreliable(conn, ECOMM); 4812*0a708f8fSGustavo F. Padovan goto drop; 4813*0a708f8fSGustavo F. Padovan } 4814*0a708f8fSGustavo F. Padovan 4815*0a708f8fSGustavo F. Padovan skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len), 4816*0a708f8fSGustavo F. Padovan skb->len); 4817*0a708f8fSGustavo F. Padovan conn->rx_len -= skb->len; 4818*0a708f8fSGustavo F. Padovan 4819*0a708f8fSGustavo F. Padovan if (!conn->rx_len) { 4820*0a708f8fSGustavo F. Padovan /* Complete frame received */ 4821*0a708f8fSGustavo F. Padovan l2cap_recv_frame(conn, conn->rx_skb); 4822*0a708f8fSGustavo F. Padovan conn->rx_skb = NULL; 4823*0a708f8fSGustavo F. Padovan } 4824*0a708f8fSGustavo F. Padovan } 4825*0a708f8fSGustavo F. Padovan 4826*0a708f8fSGustavo F. Padovan drop: 4827*0a708f8fSGustavo F. Padovan kfree_skb(skb); 4828*0a708f8fSGustavo F. Padovan return 0; 4829*0a708f8fSGustavo F. Padovan } 4830*0a708f8fSGustavo F. Padovan 4831*0a708f8fSGustavo F. Padovan static int l2cap_debugfs_show(struct seq_file *f, void *p) 4832*0a708f8fSGustavo F. Padovan { 4833*0a708f8fSGustavo F. Padovan struct sock *sk; 4834*0a708f8fSGustavo F. Padovan struct hlist_node *node; 4835*0a708f8fSGustavo F. Padovan 4836*0a708f8fSGustavo F. Padovan read_lock_bh(&l2cap_sk_list.lock); 4837*0a708f8fSGustavo F. Padovan 4838*0a708f8fSGustavo F. Padovan sk_for_each(sk, node, &l2cap_sk_list.head) { 4839*0a708f8fSGustavo F. Padovan struct l2cap_pinfo *pi = l2cap_pi(sk); 4840*0a708f8fSGustavo F. Padovan 4841*0a708f8fSGustavo F. Padovan seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n", 4842*0a708f8fSGustavo F. Padovan batostr(&bt_sk(sk)->src), 4843*0a708f8fSGustavo F. Padovan batostr(&bt_sk(sk)->dst), 4844*0a708f8fSGustavo F. Padovan sk->sk_state, __le16_to_cpu(pi->psm), 4845*0a708f8fSGustavo F. Padovan pi->scid, pi->dcid, 4846*0a708f8fSGustavo F. Padovan pi->imtu, pi->omtu, pi->sec_level); 4847*0a708f8fSGustavo F. Padovan } 4848*0a708f8fSGustavo F. Padovan 4849*0a708f8fSGustavo F. Padovan read_unlock_bh(&l2cap_sk_list.lock); 4850*0a708f8fSGustavo F. Padovan 4851*0a708f8fSGustavo F. Padovan return 0; 4852*0a708f8fSGustavo F. Padovan } 4853*0a708f8fSGustavo F. Padovan 4854*0a708f8fSGustavo F. Padovan static int l2cap_debugfs_open(struct inode *inode, struct file *file) 4855*0a708f8fSGustavo F. Padovan { 4856*0a708f8fSGustavo F. Padovan return single_open(file, l2cap_debugfs_show, inode->i_private); 4857*0a708f8fSGustavo F. Padovan } 4858*0a708f8fSGustavo F. Padovan 4859*0a708f8fSGustavo F. Padovan static const struct file_operations l2cap_debugfs_fops = { 4860*0a708f8fSGustavo F. Padovan .open = l2cap_debugfs_open, 4861*0a708f8fSGustavo F. Padovan .read = seq_read, 4862*0a708f8fSGustavo F. Padovan .llseek = seq_lseek, 4863*0a708f8fSGustavo F. Padovan .release = single_release, 4864*0a708f8fSGustavo F. Padovan }; 4865*0a708f8fSGustavo F. Padovan 4866*0a708f8fSGustavo F. Padovan static struct dentry *l2cap_debugfs; 4867*0a708f8fSGustavo F. Padovan 4868*0a708f8fSGustavo F. Padovan static const struct proto_ops l2cap_sock_ops = { 4869*0a708f8fSGustavo F. Padovan .family = PF_BLUETOOTH, 4870*0a708f8fSGustavo F. Padovan .owner = THIS_MODULE, 4871*0a708f8fSGustavo F. Padovan .release = l2cap_sock_release, 4872*0a708f8fSGustavo F. Padovan .bind = l2cap_sock_bind, 4873*0a708f8fSGustavo F. Padovan .connect = l2cap_sock_connect, 4874*0a708f8fSGustavo F. Padovan .listen = l2cap_sock_listen, 4875*0a708f8fSGustavo F. Padovan .accept = l2cap_sock_accept, 4876*0a708f8fSGustavo F. Padovan .getname = l2cap_sock_getname, 4877*0a708f8fSGustavo F. Padovan .sendmsg = l2cap_sock_sendmsg, 4878*0a708f8fSGustavo F. Padovan .recvmsg = l2cap_sock_recvmsg, 4879*0a708f8fSGustavo F. Padovan .poll = bt_sock_poll, 4880*0a708f8fSGustavo F. Padovan .ioctl = bt_sock_ioctl, 4881*0a708f8fSGustavo F. Padovan .mmap = sock_no_mmap, 4882*0a708f8fSGustavo F. Padovan .socketpair = sock_no_socketpair, 4883*0a708f8fSGustavo F. Padovan .shutdown = l2cap_sock_shutdown, 4884*0a708f8fSGustavo F. Padovan .setsockopt = l2cap_sock_setsockopt, 4885*0a708f8fSGustavo F. Padovan .getsockopt = l2cap_sock_getsockopt 4886*0a708f8fSGustavo F. Padovan }; 4887*0a708f8fSGustavo F. Padovan 4888*0a708f8fSGustavo F. Padovan static const struct net_proto_family l2cap_sock_family_ops = { 4889*0a708f8fSGustavo F. Padovan .family = PF_BLUETOOTH, 4890*0a708f8fSGustavo F. Padovan .owner = THIS_MODULE, 4891*0a708f8fSGustavo F. Padovan .create = l2cap_sock_create, 4892*0a708f8fSGustavo F. Padovan }; 4893*0a708f8fSGustavo F. Padovan 4894*0a708f8fSGustavo F. Padovan static struct hci_proto l2cap_hci_proto = { 4895*0a708f8fSGustavo F. Padovan .name = "L2CAP", 4896*0a708f8fSGustavo F. Padovan .id = HCI_PROTO_L2CAP, 4897*0a708f8fSGustavo F. Padovan .connect_ind = l2cap_connect_ind, 4898*0a708f8fSGustavo F. Padovan .connect_cfm = l2cap_connect_cfm, 4899*0a708f8fSGustavo F. Padovan .disconn_ind = l2cap_disconn_ind, 4900*0a708f8fSGustavo F. Padovan .disconn_cfm = l2cap_disconn_cfm, 4901*0a708f8fSGustavo F. Padovan .security_cfm = l2cap_security_cfm, 4902*0a708f8fSGustavo F. Padovan .recv_acldata = l2cap_recv_acldata 4903*0a708f8fSGustavo F. Padovan }; 4904*0a708f8fSGustavo F. Padovan 4905*0a708f8fSGustavo F. Padovan static int __init l2cap_init(void) 4906*0a708f8fSGustavo F. Padovan { 4907*0a708f8fSGustavo F. Padovan int err; 4908*0a708f8fSGustavo F. Padovan 4909*0a708f8fSGustavo F. Padovan err = proto_register(&l2cap_proto, 0); 4910*0a708f8fSGustavo F. Padovan if (err < 0) 4911*0a708f8fSGustavo F. Padovan return err; 4912*0a708f8fSGustavo F. Padovan 4913*0a708f8fSGustavo F. Padovan _busy_wq = create_singlethread_workqueue("l2cap"); 4914*0a708f8fSGustavo F. Padovan if (!_busy_wq) { 4915*0a708f8fSGustavo F. Padovan proto_unregister(&l2cap_proto); 4916*0a708f8fSGustavo F. Padovan return -ENOMEM; 4917*0a708f8fSGustavo F. Padovan } 4918*0a708f8fSGustavo F. Padovan 4919*0a708f8fSGustavo F. Padovan err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops); 4920*0a708f8fSGustavo F. Padovan if (err < 0) { 4921*0a708f8fSGustavo F. Padovan BT_ERR("L2CAP socket registration failed"); 4922*0a708f8fSGustavo F. Padovan goto error; 4923*0a708f8fSGustavo F. Padovan } 4924*0a708f8fSGustavo F. Padovan 4925*0a708f8fSGustavo F. Padovan err = hci_register_proto(&l2cap_hci_proto); 4926*0a708f8fSGustavo F. Padovan if (err < 0) { 4927*0a708f8fSGustavo F. Padovan BT_ERR("L2CAP protocol registration failed"); 4928*0a708f8fSGustavo F. Padovan bt_sock_unregister(BTPROTO_L2CAP); 4929*0a708f8fSGustavo F. Padovan goto error; 4930*0a708f8fSGustavo F. Padovan } 4931*0a708f8fSGustavo F. Padovan 4932*0a708f8fSGustavo F. Padovan if (bt_debugfs) { 4933*0a708f8fSGustavo F. Padovan l2cap_debugfs = debugfs_create_file("l2cap", 0444, 4934*0a708f8fSGustavo F. Padovan bt_debugfs, NULL, &l2cap_debugfs_fops); 4935*0a708f8fSGustavo F. Padovan if (!l2cap_debugfs) 4936*0a708f8fSGustavo F. Padovan BT_ERR("Failed to create L2CAP debug file"); 4937*0a708f8fSGustavo F. Padovan } 4938*0a708f8fSGustavo F. Padovan 4939*0a708f8fSGustavo F. Padovan BT_INFO("L2CAP ver %s", VERSION); 4940*0a708f8fSGustavo F. Padovan BT_INFO("L2CAP socket layer initialized"); 4941*0a708f8fSGustavo F. Padovan 4942*0a708f8fSGustavo F. Padovan return 0; 4943*0a708f8fSGustavo F. Padovan 4944*0a708f8fSGustavo F. Padovan error: 4945*0a708f8fSGustavo F. Padovan destroy_workqueue(_busy_wq); 4946*0a708f8fSGustavo F. Padovan proto_unregister(&l2cap_proto); 4947*0a708f8fSGustavo F. Padovan return err; 4948*0a708f8fSGustavo F. Padovan } 4949*0a708f8fSGustavo F. Padovan 4950*0a708f8fSGustavo F. Padovan static void __exit l2cap_exit(void) 4951*0a708f8fSGustavo F. Padovan { 4952*0a708f8fSGustavo F. Padovan debugfs_remove(l2cap_debugfs); 4953*0a708f8fSGustavo F. Padovan 4954*0a708f8fSGustavo F. Padovan flush_workqueue(_busy_wq); 4955*0a708f8fSGustavo F. Padovan destroy_workqueue(_busy_wq); 4956*0a708f8fSGustavo F. Padovan 4957*0a708f8fSGustavo F. Padovan if (bt_sock_unregister(BTPROTO_L2CAP) < 0) 4958*0a708f8fSGustavo F. Padovan BT_ERR("L2CAP socket unregistration failed"); 4959*0a708f8fSGustavo F. Padovan 4960*0a708f8fSGustavo F. Padovan if (hci_unregister_proto(&l2cap_hci_proto) < 0) 4961*0a708f8fSGustavo F. Padovan BT_ERR("L2CAP protocol unregistration failed"); 4962*0a708f8fSGustavo F. Padovan 4963*0a708f8fSGustavo F. Padovan proto_unregister(&l2cap_proto); 4964*0a708f8fSGustavo F. Padovan } 4965*0a708f8fSGustavo F. Padovan 4966*0a708f8fSGustavo F. Padovan void l2cap_load(void) 4967*0a708f8fSGustavo F. Padovan { 4968*0a708f8fSGustavo F. Padovan /* Dummy function to trigger automatic L2CAP module loading by 4969*0a708f8fSGustavo F. Padovan * other modules that use L2CAP sockets but don't use any other 4970*0a708f8fSGustavo F. Padovan * symbols from it. */ 4971*0a708f8fSGustavo F. Padovan } 4972*0a708f8fSGustavo F. Padovan EXPORT_SYMBOL(l2cap_load); 4973*0a708f8fSGustavo F. Padovan 4974*0a708f8fSGustavo F. Padovan module_init(l2cap_init); 4975*0a708f8fSGustavo F. Padovan module_exit(l2cap_exit); 4976*0a708f8fSGustavo F. Padovan 4977*0a708f8fSGustavo F. Padovan module_param(disable_ertm, bool, 0644); 4978*0a708f8fSGustavo F. Padovan MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode"); 4979*0a708f8fSGustavo F. Padovan 4980*0a708f8fSGustavo F. Padovan MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); 4981*0a708f8fSGustavo F. Padovan MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION); 4982*0a708f8fSGustavo F. Padovan MODULE_VERSION(VERSION); 4983*0a708f8fSGustavo F. Padovan MODULE_LICENSE("GPL"); 4984*0a708f8fSGustavo F. Padovan MODULE_ALIAS("bt-proto-0"); 4985