Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
[deliverable/linux.git] / net / bluetooth / l2cap_core.c
index 293b78a6c6448e4d110053001f1aa5d1921254f2..4ca88247b7c25595b8a1c05141e74be4e714a641 100644 (file)
 
 #include <linux/module.h>
 
-#include <linux/types.h>
-#include <linux/capability.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/fcntl.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/socket.h>
-#include <linux/skbuff.h>
-#include <linux/list.h>
-#include <linux/device.h>
 #include <linux/debugfs.h>
-#include <linux/seq_file.h>
-#include <linux/uaccess.h>
 #include <linux/crc16.h>
-#include <net/sock.h>
-
-#include <asm/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/l2cap.h>
 #include <net/bluetooth/smp.h>
+#include <net/bluetooth/a2mp.h>
 
-bool disable_ertm = 1;
+bool disable_ertm;
 
 static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
 static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP, };
@@ -73,7 +55,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
 static void l2cap_send_disconn_req(struct l2cap_conn *conn,
                                   struct l2cap_chan *chan, int err);
 
-static int l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
+static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
                    struct sk_buff_head *skbs, u8 event);
 
 /* ---- L2CAP channels ---- */
@@ -199,7 +181,7 @@ static void __l2cap_state_change(struct l2cap_chan *chan, int state)
                                                state_to_string(state));
 
        chan->state = state;
-       chan->ops->state_change(chan->data, state);
+       chan->ops->state_change(chan, state);
 }
 
 static void l2cap_state_change(struct l2cap_chan *chan, int state)
@@ -400,7 +382,7 @@ static void l2cap_chan_timeout(struct work_struct *work)
 
        l2cap_chan_unlock(chan);
 
-       chan->ops->close(chan->data);
+       chan->ops->close(chan);
        mutex_unlock(&conn->chan_lock);
 
        l2cap_chan_put(chan);
@@ -467,7 +449,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
        case L2CAP_CHAN_CONN_ORIENTED:
                if (conn->hcon->type == LE_LINK) {
                        /* LE connection */
-                       chan->omtu = L2CAP_LE_DEFAULT_MTU;
+                       chan->omtu = L2CAP_DEFAULT_MTU;
                        chan->scid = L2CAP_CID_LE_DATA;
                        chan->dcid = L2CAP_CID_LE_DATA;
                } else {
@@ -484,6 +466,13 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
                chan->omtu = L2CAP_DEFAULT_MTU;
                break;
 
+       case L2CAP_CHAN_CONN_FIX_A2MP:
+               chan->scid = L2CAP_CID_A2MP;
+               chan->dcid = L2CAP_CID_A2MP;
+               chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
+               chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
+               break;
+
        default:
                /* Raw socket can send/recv signalling messages only */
                chan->scid = L2CAP_CID_SIGNALING;
@@ -503,18 +492,16 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
        list_add(&chan->list, &conn->chan_l);
 }
 
-static void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
+void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
 {
        mutex_lock(&conn->chan_lock);
        __l2cap_chan_add(conn, chan);
        mutex_unlock(&conn->chan_lock);
 }
 
-static void l2cap_chan_del(struct l2cap_chan *chan, int err)
+void l2cap_chan_del(struct l2cap_chan *chan, int err)
 {
-       struct sock *sk = chan->sk;
        struct l2cap_conn *conn = chan->conn;
-       struct sock *parent = bt_sk(sk)->parent;
 
        __clear_chan_timer(chan);
 
@@ -527,31 +514,22 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err)
                l2cap_chan_put(chan);
 
                chan->conn = NULL;
-               hci_conn_put(conn->hcon);
-       }
-
-       lock_sock(sk);
-
-       __l2cap_state_change(chan, BT_CLOSED);
-       sock_set_flag(sk, SOCK_ZAPPED);
 
-       if (err)
-               __l2cap_chan_set_err(chan, err);
-
-       if (parent) {
-               bt_accept_unlink(sk);
-               parent->sk_data_ready(parent, 0);
-       } else
-               sk->sk_state_change(sk);
+               if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
+                       hci_conn_put(conn->hcon);
+       }
 
-       release_sock(sk);
+       if (chan->ops->teardown)
+               chan->ops->teardown(chan, err);
 
        if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
                return;
 
-       skb_queue_purge(&chan->tx_q);
+       switch(chan->mode) {
+       case L2CAP_MODE_BASIC:
+               break;
 
-       if (chan->mode == L2CAP_MODE_ERTM) {
+       case L2CAP_MODE_ERTM:
                __clear_retrans_timer(chan);
                __clear_monitor_timer(chan);
                __clear_ack_timer(chan);
@@ -560,26 +538,15 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err)
 
                l2cap_seq_list_free(&chan->srej_list);
                l2cap_seq_list_free(&chan->retrans_list);
-       }
-}
 
-static void l2cap_chan_cleanup_listen(struct sock *parent)
-{
-       struct sock *sk;
-
-       BT_DBG("parent %p", parent);
-
-       /* Close not yet accepted channels */
-       while ((sk = bt_accept_dequeue(parent, NULL))) {
-               struct l2cap_chan *chan = l2cap_pi(sk)->chan;
-
-               l2cap_chan_lock(chan);
-               __clear_chan_timer(chan);
-               l2cap_chan_close(chan, ECONNRESET);
-               l2cap_chan_unlock(chan);
+               /* fall through */
 
-               chan->ops->close(chan->data);
+       case L2CAP_MODE_STREAMING:
+               skb_queue_purge(&chan->tx_q);
+               break;
        }
+
+       return;
 }
 
 void l2cap_chan_close(struct l2cap_chan *chan, int reason)
@@ -592,12 +559,8 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
 
        switch (chan->state) {
        case BT_LISTEN:
-               lock_sock(sk);
-               l2cap_chan_cleanup_listen(sk);
-
-               __l2cap_state_change(chan, BT_CLOSED);
-               sock_set_flag(sk, SOCK_ZAPPED);
-               release_sock(sk);
+               if (chan->ops->teardown)
+                       chan->ops->teardown(chan, 0);
                break;
 
        case BT_CONNECTED:
@@ -625,7 +588,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
                        rsp.scid   = cpu_to_le16(chan->dcid);
                        rsp.dcid   = cpu_to_le16(chan->scid);
                        rsp.result = cpu_to_le16(result);
-                       rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
+                       rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
                        l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
                                                        sizeof(rsp), &rsp);
                }
@@ -639,9 +602,8 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
                break;
 
        default:
-               lock_sock(sk);
-               sock_set_flag(sk, SOCK_ZAPPED);
-               release_sock(sk);
+               if (chan->ops->teardown)
+                       chan->ops->teardown(chan, 0);
                break;
        }
 }
@@ -657,7 +619,7 @@ static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
                default:
                        return HCI_AT_NO_BONDING;
                }
-       } else if (chan->psm == cpu_to_le16(0x0001)) {
+       } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
                if (chan->sec_level == BT_SECURITY_LOW)
                        chan->sec_level = BT_SECURITY_SDP;
 
@@ -862,17 +824,20 @@ static inline void __pack_control(struct l2cap_chan *chan,
        }
 }
 
+static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
+{
+       if (test_bit(FLAG_EXT_CTRL, &chan->flags))
+               return L2CAP_EXT_HDR_SIZE;
+       else
+               return L2CAP_ENH_HDR_SIZE;
+}
+
 static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
                                               u32 control)
 {
        struct sk_buff *skb;
        struct l2cap_hdr *lh;
-       int hlen;
-
-       if (test_bit(FLAG_EXT_CTRL, &chan->flags))
-               hlen = L2CAP_EXT_HDR_SIZE;
-       else
-               hlen = L2CAP_ENH_HDR_SIZE;
+       int hlen = __ertm_hdr_size(chan);
 
        if (chan->fcs == L2CAP_FCS_CRC16)
                hlen += L2CAP_FCS_SIZE;
@@ -979,26 +944,13 @@ static void l2cap_send_conn_req(struct l2cap_chan *chan)
 
 static void l2cap_chan_ready(struct l2cap_chan *chan)
 {
-       struct sock *sk = chan->sk;
-       struct sock *parent;
-
-       lock_sock(sk);
-
-       parent = bt_sk(sk)->parent;
-
-       BT_DBG("sk %p, parent %p", sk, parent);
-
        /* This clears all conf flags, including CONF_NOT_COMPLETE */
        chan->conf_state = 0;
        __clear_chan_timer(chan);
 
-       __l2cap_state_change(chan, BT_CONNECTED);
-       sk->sk_state_change(sk);
-
-       if (parent)
-               parent->sk_data_ready(parent, 0);
+       chan->state = BT_CONNECTED;
 
-       release_sock(sk);
+       chan->ops->ready(chan);
 }
 
 static void l2cap_do_start(struct l2cap_chan *chan)
@@ -1019,7 +971,7 @@ static void l2cap_do_start(struct l2cap_chan *chan)
                        l2cap_send_conn_req(chan);
        } else {
                struct l2cap_info_req req;
-               req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
+               req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
 
                conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
                conn->info_ident = l2cap_get_ident(conn);
@@ -1061,6 +1013,11 @@ static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *c
                __clear_ack_timer(chan);
        }
 
+       if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
+               __l2cap_state_change(chan, BT_DISCONN);
+               return;
+       }
+
        req.dcid = cpu_to_le16(chan->dcid);
        req.scid = cpu_to_le16(chan->scid);
        l2cap_send_cmd(conn, l2cap_get_ident(conn),
@@ -1119,20 +1076,20 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
                                if (test_bit(BT_SK_DEFER_SETUP,
                                             &bt_sk(sk)->flags)) {
                                        struct sock *parent = bt_sk(sk)->parent;
-                                       rsp.result = cpu_to_le16(L2CAP_CR_PEND);
-                                       rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
+                                       rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
+                                       rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
                                        if (parent)
                                                parent->sk_data_ready(parent, 0);
 
                                } else {
                                        __l2cap_state_change(chan, BT_CONFIG);
-                                       rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
-                                       rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
+                                       rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
+                                       rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
                                }
                                release_sock(sk);
                        } else {
-                               rsp.result = cpu_to_le16(L2CAP_CR_PEND);
-                               rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
+                               rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
+                               rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
                        }
 
                        l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
@@ -1216,13 +1173,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
 
        lock_sock(parent);
 
-       /* Check for backlog size */
-       if (sk_acceptq_is_full(parent)) {
-               BT_DBG("backlog full %d", parent->sk_ack_backlog);
-               goto clean;
-       }
-
-       chan = pchan->ops->new_connection(pchan->data);
+       chan = pchan->ops->new_connection(pchan);
        if (!chan)
                goto clean;
 
@@ -1237,10 +1188,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
 
        l2cap_chan_add(conn, chan);
 
-       __set_chan_timer(chan, sk->sk_sndtimeo);
-
-       __l2cap_state_change(chan, BT_CONNECTED);
-       parent->sk_data_ready(parent, 0);
+       l2cap_chan_ready(chan);
 
 clean:
        release_sock(parent);
@@ -1264,6 +1212,11 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
 
                l2cap_chan_lock(chan);
 
+               if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
+                       l2cap_chan_unlock(chan);
+                       continue;
+               }
+
                if (conn->hcon->type == LE_LINK) {
                        if (smp_conn_security(conn, chan->sec_level))
                                l2cap_chan_ready(chan);
@@ -1336,7 +1289,7 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
 
                l2cap_chan_unlock(chan);
 
-               chan->ops->close(chan->data);
+               chan->ops->close(chan);
                l2cap_chan_put(chan);
        }
 
@@ -1361,7 +1314,12 @@ static void security_timeout(struct work_struct *work)
        struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
                                                security_timer.work);
 
-       l2cap_conn_del(conn->hcon, ETIMEDOUT);
+       BT_DBG("conn %p", conn);
+
+       if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
+               smp_chan_destroy(conn);
+               l2cap_conn_del(conn->hcon, ETIMEDOUT);
+       }
 }
 
 static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
@@ -1505,21 +1463,17 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
                goto done;
        }
 
-       lock_sock(sk);
-
-       switch (sk->sk_state) {
+       switch (chan->state) {
        case BT_CONNECT:
        case BT_CONNECT2:
        case BT_CONFIG:
                /* Already connecting */
                err = 0;
-               release_sock(sk);
                goto done;
 
        case BT_CONNECTED:
                /* Already connected */
                err = -EISCONN;
-               release_sock(sk);
                goto done;
 
        case BT_OPEN:
@@ -1529,13 +1483,12 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
 
        default:
                err = -EBADFD;
-               release_sock(sk);
                goto done;
        }
 
        /* Set destination address and psm */
+       lock_sock(sk);
        bacpy(&bt_sk(sk)->dst, dst);
-
        release_sock(sk);
 
        chan->psm = psm;
@@ -1649,7 +1602,7 @@ static void l2cap_monitor_timeout(struct work_struct *work)
                return;
        }
 
-       l2cap_tx(chan, 0, 0, L2CAP_EV_MONITOR_TO);
+       l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
 
        l2cap_chan_unlock(chan);
        l2cap_chan_put(chan);
@@ -1670,22 +1623,19 @@ static void l2cap_retrans_timeout(struct work_struct *work)
                return;
        }
 
-       l2cap_tx(chan, 0, 0, L2CAP_EV_RETRANS_TO);
+       l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
        l2cap_chan_unlock(chan);
        l2cap_chan_put(chan);
 }
 
-static int l2cap_streaming_send(struct l2cap_chan *chan,
-                               struct sk_buff_head *skbs)
+static void l2cap_streaming_send(struct l2cap_chan *chan,
+                                struct sk_buff_head *skbs)
 {
        struct sk_buff *skb;
        struct l2cap_ctrl *control;
 
        BT_DBG("chan %p, skbs %p", chan, skbs);
 
-       if (chan->state != BT_CONNECTED)
-               return -ENOTCONN;
-
        skb_queue_splice_tail_init(skbs, &chan->tx_q);
 
        while (!skb_queue_empty(&chan->tx_q)) {
@@ -1712,8 +1662,6 @@ static int l2cap_streaming_send(struct l2cap_chan *chan,
                chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
                chan->frames_sent++;
        }
-
-       return 0;
 }
 
 static int l2cap_ertm_send(struct l2cap_chan *chan)
@@ -2078,10 +2026,7 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
        if (!conn)
                return ERR_PTR(-ENOTCONN);
 
-       if (test_bit(FLAG_EXT_CTRL, &chan->flags))
-               hlen = L2CAP_EXT_HDR_SIZE;
-       else
-               hlen = L2CAP_ENH_HDR_SIZE;
+       hlen = __ertm_hdr_size(chan);
 
        if (sdulen)
                hlen += L2CAP_SDULEN_SIZE;
@@ -2128,7 +2073,6 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan,
        struct sk_buff *skb;
        u16 sdu_len;
        size_t pdu_len;
-       int err = 0;
        u8 sar;
 
        BT_DBG("chan %p, msg %p, len %d", chan, msg, (int)len);
@@ -2144,7 +2088,10 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan,
        pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
 
        /* Adjust for largest possible L2CAP overhead. */
-       pdu_len -= L2CAP_EXT_HDR_SIZE + L2CAP_FCS_SIZE;
+       if (chan->fcs)
+               pdu_len -= L2CAP_FCS_SIZE;
+
+       pdu_len -= __ertm_hdr_size(chan);
 
        /* Remote device may have requested smaller PDUs */
        pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
@@ -2184,7 +2131,7 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan,
                }
        }
 
-       return err;
+       return 0;
 }
 
 int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
@@ -2247,13 +2194,11 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
                        break;
 
                if (chan->mode == L2CAP_MODE_ERTM)
-                       err = l2cap_tx(chan, 0, &seg_queue,
-                                      L2CAP_EV_DATA_REQUEST);
+                       l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
                else
-                       err = l2cap_streaming_send(chan, &seg_queue);
+                       l2cap_streaming_send(chan, &seg_queue);
 
-               if (!err)
-                       err = len;
+               err = len;
 
                /* If the skbs were not queued for sending, they'll still be in
                 * seg_queue and need to be purged.
@@ -2376,12 +2321,10 @@ static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
        chan->rx_state = L2CAP_RX_STATE_RECV;
 }
 
-static int l2cap_tx_state_xmit(struct l2cap_chan *chan,
-                              struct l2cap_ctrl *control,
-                              struct sk_buff_head *skbs, u8 event)
+static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
+                               struct l2cap_ctrl *control,
+                               struct sk_buff_head *skbs, u8 event)
 {
-       int err = 0;
-
        BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
               event);
 
@@ -2448,16 +2391,12 @@ static int l2cap_tx_state_xmit(struct l2cap_chan *chan,
        default:
                break;
        }
-
-       return err;
 }
 
-static int l2cap_tx_state_wait_f(struct l2cap_chan *chan,
-                                struct l2cap_ctrl *control,
-                                struct sk_buff_head *skbs, u8 event)
+static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
+                                 struct l2cap_ctrl *control,
+                                 struct sk_buff_head *skbs, u8 event)
 {
-       int err = 0;
-
        BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
               event);
 
@@ -2530,45 +2469,39 @@ static int l2cap_tx_state_wait_f(struct l2cap_chan *chan,
        default:
                break;
        }
-
-       return err;
 }
 
-static int l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
-                   struct sk_buff_head *skbs, u8 event)
+static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
+                    struct sk_buff_head *skbs, u8 event)
 {
-       int err = 0;
-
        BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
               chan, control, skbs, event, chan->tx_state);
 
        switch (chan->tx_state) {
        case L2CAP_TX_STATE_XMIT:
-               err = l2cap_tx_state_xmit(chan, control, skbs, event);
+               l2cap_tx_state_xmit(chan, control, skbs, event);
                break;
        case L2CAP_TX_STATE_WAIT_F:
-               err = l2cap_tx_state_wait_f(chan, control, skbs, event);
+               l2cap_tx_state_wait_f(chan, control, skbs, event);
                break;
        default:
                /* Ignore event */
                break;
        }
-
-       return err;
 }
 
 static void l2cap_pass_to_tx(struct l2cap_chan *chan,
                             struct l2cap_ctrl *control)
 {
        BT_DBG("chan %p, control %p", chan, control);
-       l2cap_tx(chan, control, 0, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
+       l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
 }
 
 static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
                                  struct l2cap_ctrl *control)
 {
        BT_DBG("chan %p, control %p", chan, control);
-       l2cap_tx(chan, control, 0, L2CAP_EV_RECV_FBIT);
+       l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
 }
 
 /* Copy frame to all raw sockets on that connection */
@@ -2593,7 +2526,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
                if (!nskb)
                        continue;
 
-               if (chan->ops->recv(chan->data, nskb))
+               if (chan->ops->recv(chan, nskb))
                        kfree_skb(nskb);
        }
 
@@ -2623,9 +2556,9 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
        lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
 
        if (conn->hcon->type == LE_LINK)
-               lh->cid = cpu_to_le16(L2CAP_CID_LE_SIGNALING);
+               lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
        else
-               lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
+               lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
 
        cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
        cmd->code  = code;
@@ -2737,8 +2670,8 @@ static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
                efs.stype       = chan->local_stype;
                efs.msdu        = cpu_to_le16(chan->local_msdu);
                efs.sdu_itime   = cpu_to_le32(chan->local_sdu_itime);
-               efs.acc_lat     = cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
-               efs.flush_to    = cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO);
+               efs.acc_lat     = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
+               efs.flush_to    = __constant_cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO);
                break;
 
        case L2CAP_MODE_STREAMING:
@@ -2778,7 +2711,7 @@ static void l2cap_ack_timeout(struct work_struct *work)
        l2cap_chan_put(chan);
 }
 
-static inline int l2cap_ertm_init(struct l2cap_chan *chan)
+int l2cap_ertm_init(struct l2cap_chan *chan)
 {
        int err;
 
@@ -2941,6 +2874,7 @@ done:
                break;
 
        case L2CAP_MODE_STREAMING:
+               l2cap_txwin_setup(chan);
                rfc.mode            = L2CAP_MODE_STREAMING;
                rfc.txwin_size      = 0;
                rfc.max_transmit    = 0;
@@ -2971,7 +2905,7 @@ done:
        }
 
        req->dcid  = cpu_to_le16(chan->dcid);
-       req->flags = cpu_to_le16(0);
+       req->flags = __constant_cpu_to_le16(0);
 
        return ptr - data;
 }
@@ -3191,7 +3125,7 @@ done:
        }
        rsp->scid   = cpu_to_le16(chan->dcid);
        rsp->result = cpu_to_le16(result);
-       rsp->flags  = cpu_to_le16(0x0000);
+       rsp->flags  = __constant_cpu_to_le16(0);
 
        return ptr - data;
 }
@@ -3290,7 +3224,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi
        }
 
        req->dcid   = cpu_to_le16(chan->dcid);
-       req->flags  = cpu_to_le16(0x0000);
+       req->flags  = __constant_cpu_to_le16(0);
 
        return ptr - data;
 }
@@ -3317,8 +3251,8 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
 
        rsp.scid   = cpu_to_le16(chan->dcid);
        rsp.dcid   = cpu_to_le16(chan->scid);
-       rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
-       rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
+       rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
+       rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
        l2cap_send_cmd(conn, chan->ident,
                                L2CAP_CONN_RSP, sizeof(rsp), &rsp);
 
@@ -3356,8 +3290,8 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
         * did not send an RFC option.
         */
        rfc.mode = chan->mode;
-       rfc.retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
-       rfc.monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
+       rfc.retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
+       rfc.monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
        rfc.max_pdu_size = cpu_to_le16(chan->imtu);
 
        BT_ERR("Expected RFC option was not found, using defaults");
@@ -3420,7 +3354,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
        lock_sock(parent);
 
        /* Check if the ACL is secure enough (if not SDP) */
-       if (psm != cpu_to_le16(0x0001) &&
+       if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
                                !hci_conn_check_link_mode(conn->hcon)) {
                conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
                result = L2CAP_CR_SEC_BLOCK;
@@ -3429,25 +3363,16 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
 
        result = L2CAP_CR_NO_MEM;
 
-       /* Check for backlog size */
-       if (sk_acceptq_is_full(parent)) {
-               BT_DBG("backlog full %d", parent->sk_ack_backlog);
+       /* Check if we already have channel with that dcid */
+       if (__l2cap_get_chan_by_dcid(conn, scid))
                goto response;
-       }
 
-       chan = pchan->ops->new_connection(pchan->data);
+       chan = pchan->ops->new_connection(pchan);
        if (!chan)
                goto response;
 
        sk = chan->sk;
 
-       /* Check if we already have channel with that dcid */
-       if (__l2cap_get_chan_by_dcid(conn, scid)) {
-               sock_set_flag(sk, SOCK_ZAPPED);
-               chan->ops->close(chan->data);
-               goto response;
-       }
-
        hci_conn_hold(conn->hcon);
 
        bacpy(&bt_sk(sk)->src, conn->src);
@@ -3501,7 +3426,7 @@ sendresp:
 
        if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
                struct l2cap_info_req info;
-               info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
+               info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
 
                conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
                conn->info_ident = l2cap_get_ident(conn);
@@ -3623,7 +3548,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
        if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
                struct l2cap_cmd_rej_cid rej;
 
-               rej.reason = cpu_to_le16(L2CAP_REJ_INVALID_CID);
+               rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
                rej.scid = cpu_to_le16(chan->scid);
                rej.dcid = cpu_to_le16(chan->dcid);
 
@@ -3645,11 +3570,11 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
        memcpy(chan->conf_req + chan->conf_len, req->data, len);
        chan->conf_len += len;
 
-       if (flags & 0x0001) {
+       if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
                /* Incomplete config. Send empty response. */
                l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
                                l2cap_build_conf_rsp(chan, rsp,
-                                       L2CAP_CONF_SUCCESS, 0x0001), rsp);
+                                       L2CAP_CONF_SUCCESS, flags), rsp);
                goto unlock;
        }
 
@@ -3672,8 +3597,6 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
        if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
                set_default_fcs(chan);
 
-               l2cap_state_change(chan, BT_CONNECTED);
-
                if (chan->mode == L2CAP_MODE_ERTM ||
                    chan->mode == L2CAP_MODE_STREAMING)
                        err = l2cap_ertm_init(chan);
@@ -3705,7 +3628,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
 
                l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
                                        l2cap_build_conf_rsp(chan, rsp,
-                                       L2CAP_CONF_SUCCESS, 0x0000), rsp);
+                                       L2CAP_CONF_SUCCESS, flags), rsp);
        }
 
 unlock:
@@ -3796,7 +3719,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
                goto done;
        }
 
-       if (flags & 0x01)
+       if (flags & L2CAP_CONF_FLAG_CONTINUATION)
                goto done;
 
        set_bit(CONF_INPUT_DONE, &chan->conf_state);
@@ -3804,7 +3727,6 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
        if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
                set_default_fcs(chan);
 
-               l2cap_state_change(chan, BT_CONNECTED);
                if (chan->mode == L2CAP_MODE_ERTM ||
                    chan->mode == L2CAP_MODE_STREAMING)
                        err = l2cap_ertm_init(chan);
@@ -3858,7 +3780,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
 
        l2cap_chan_unlock(chan);
 
-       chan->ops->close(chan->data);
+       chan->ops->close(chan);
        l2cap_chan_put(chan);
 
        mutex_unlock(&conn->chan_lock);
@@ -3892,7 +3814,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
 
        l2cap_chan_unlock(chan);
 
-       chan->ops->close(chan->data);
+       chan->ops->close(chan);
        l2cap_chan_put(chan);
 
        mutex_unlock(&conn->chan_lock);
@@ -3913,8 +3835,8 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cm
                u8 buf[8];
                u32 feat_mask = l2cap_feat_mask;
                struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
-               rsp->type   = cpu_to_le16(L2CAP_IT_FEAT_MASK);
-               rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
+               rsp->type   = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
+               rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
                if (!disable_ertm)
                        feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
                                                         | L2CAP_FEAT_FCS;
@@ -3934,15 +3856,15 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cm
                else
                        l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
 
-               rsp->type   = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
-               rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
+               rsp->type   = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
+               rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
                memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
                l2cap_send_cmd(conn, cmd->ident,
                                        L2CAP_INFO_RSP, sizeof(buf), buf);
        } else {
                struct l2cap_info_rsp rsp;
                rsp.type   = cpu_to_le16(type);
-               rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
+               rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
                l2cap_send_cmd(conn, cmd->ident,
                                        L2CAP_INFO_RSP, sizeof(rsp), &rsp);
        }
@@ -3982,7 +3904,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
 
                if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
                        struct l2cap_info_req req;
-                       req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
+                       req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
 
                        conn->info_ident = l2cap_get_ident(conn);
 
@@ -4217,9 +4139,9 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
 
        err = l2cap_check_conn_param(min, max, latency, to_multiplier);
        if (err)
-               rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
+               rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
        else
-               rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
+               rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
 
        l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
                                                        sizeof(rsp), &rsp);
@@ -4367,7 +4289,7 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn,
                        BT_ERR("Wrong link type (%d)", err);
 
                        /* FIXME: Map err to a valid reason */
-                       rej.reason = cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
+                       rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
                        l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
                }
 
@@ -4399,7 +4321,7 @@ static int l2cap_check_fcs(struct l2cap_chan *chan,  struct sk_buff *skb)
        return 0;
 }
 
-static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
+static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
 {
        struct l2cap_ctrl control;
 
@@ -4462,7 +4384,7 @@ static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
                if (chan->sdu)
                        break;
 
-               err = chan->ops->recv(chan->data, skb);
+               err = chan->ops->recv(chan, skb);
                break;
 
        case L2CAP_SAR_START:
@@ -4512,7 +4434,7 @@ static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
                if (chan->sdu->len != chan->sdu_len)
                        break;
 
-               err = chan->ops->recv(chan->data, chan->sdu);
+               err = chan->ops->recv(chan, chan->sdu);
 
                if (!err) {
                        /* Reassembly complete */
@@ -4542,7 +4464,7 @@ void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
                return;
 
        event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
-       l2cap_tx(chan, 0, 0, event);
+       l2cap_tx(chan, NULL, NULL, event);
 }
 
 static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
@@ -5207,16 +5129,27 @@ drop:
        return 0;
 }
 
-static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
+static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
+                              struct sk_buff *skb)
 {
        struct l2cap_chan *chan;
 
        chan = l2cap_get_chan_by_scid(conn, cid);
        if (!chan) {
-               BT_DBG("unknown cid 0x%4.4x", cid);
-               /* Drop packet and return */
-               kfree_skb(skb);
-               return 0;
+               if (cid == L2CAP_CID_A2MP) {
+                       chan = a2mp_channel_create(conn, skb);
+                       if (!chan) {
+                               kfree_skb(skb);
+                               return;
+                       }
+
+                       l2cap_chan_lock(chan);
+               } else {
+                       BT_DBG("unknown cid 0x%4.4x", cid);
+                       /* Drop packet and return */
+                       kfree_skb(skb);
+                       return;
+               }
        }
 
        BT_DBG("chan %p, len %d", chan, skb->len);
@@ -5234,7 +5167,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
                if (chan->imtu < skb->len)
                        goto drop;
 
-               if (!chan->ops->recv(chan->data, skb))
+               if (!chan->ops->recv(chan, skb))
                        goto done;
                break;
 
@@ -5253,11 +5186,10 @@ drop:
 
 done:
        l2cap_chan_unlock(chan);
-
-       return 0;
 }
 
-static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
+static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
+                                 struct sk_buff *skb)
 {
        struct l2cap_chan *chan;
 
@@ -5273,17 +5205,15 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str
        if (chan->imtu < skb->len)
                goto drop;
 
-       if (!chan->ops->recv(chan->data, skb))
-               return 0;
+       if (!chan->ops->recv(chan, skb))
+               return;
 
 drop:
        kfree_skb(skb);
-
-       return 0;
 }
 
-static inline int l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
-                                   struct sk_buff *skb)
+static void l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
+                             struct sk_buff *skb)
 {
        struct l2cap_chan *chan;
 
@@ -5299,13 +5229,11 @@ static inline int l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
        if (chan->imtu < skb->len)
                goto drop;
 
-       if (!chan->ops->recv(chan->data, skb))
-               return 0;
+       if (!chan->ops->recv(chan, skb))
+               return;
 
 drop:
        kfree_skb(skb);
-
-       return 0;
 }
 
 static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
@@ -5333,7 +5261,7 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
 
        case L2CAP_CID_CONN_LESS:
                psm = get_unaligned((__le16 *) skb->data);
-               skb_pull(skb, 2);
+               skb_pull(skb, L2CAP_PSMLEN_SIZE);
                l2cap_conless_channel(conn, psm, skb);
                break;
 
@@ -5527,6 +5455,17 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
                        rsp.status = cpu_to_le16(stat);
                        l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
                                                        sizeof(rsp), &rsp);
+
+                       if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
+                           res == L2CAP_CR_SUCCESS) {
+                               char buf[128];
+                               set_bit(CONF_REQ_SENT, &chan->conf_state);
+                               l2cap_send_cmd(conn, l2cap_get_ident(conn),
+                                              L2CAP_CONF_REQ,
+                                              l2cap_build_conf_req(chan, buf),
+                                              buf);
+                               chan->num_conf_req++;
+                       }
                }
 
                l2cap_chan_unlock(chan);
This page took 0.047018 seconds and 5 git commands to generate.