Bluetooth: notify userspace of security level change
[linux-flexiantxendom0-3.2.10.git] / net / bluetooth / l2cap_core.c
index df3be69..6f9c25b 100644 (file)
@@ -49,7 +49,6 @@
 #include <linux/crc16.h>
 #include <net/sock.h>
 
-#include <asm/system.h>
 #include <asm/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
@@ -700,8 +699,7 @@ static void l2cap_do_start(struct l2cap_chan *chan)
                conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
                conn->info_ident = l2cap_get_ident(conn);
 
-               schedule_delayed_work(&conn->info_timer,
-                                       msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
+               schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
 
                l2cap_send_cmd(conn, conn->info_ident,
                                        L2CAP_INFO_REQ, sizeof(req), &req);
@@ -1310,6 +1308,7 @@ static void l2cap_monitor_timeout(struct work_struct *work)
        if (chan->retry_count >= chan->remote_max_tx) {
                l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
                l2cap_chan_unlock(chan);
+               l2cap_chan_put(chan);
                return;
        }
 
@@ -1318,6 +1317,7 @@ static void l2cap_monitor_timeout(struct work_struct *work)
 
        l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);
        l2cap_chan_unlock(chan);
+       l2cap_chan_put(chan);
 }
 
 static void l2cap_retrans_timeout(struct work_struct *work)
@@ -1337,6 +1337,7 @@ static void l2cap_retrans_timeout(struct work_struct *work)
        l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);
 
        l2cap_chan_unlock(chan);
+       l2cap_chan_put(chan);
 }
 
 static void l2cap_drop_acked_frames(struct l2cap_chan *chan)
@@ -1547,7 +1548,9 @@ static void l2cap_send_srejtail(struct l2cap_chan *chan)
        l2cap_send_sframe(chan, control);
 }
 
-static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan, struct msghdr *msg, int len, int count, struct sk_buff *skb)
+static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
+                                        struct msghdr *msg, int len,
+                                        int count, struct sk_buff *skb)
 {
        struct l2cap_conn *conn = chan->conn;
        struct sk_buff **frag;
@@ -1565,7 +1568,8 @@ static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan, struct msghdr
                count = min_t(unsigned int, conn->mtu, len);
 
                *frag = chan->ops->alloc_skb(chan, count,
-                                       msg->msg_flags & MSG_DONTWAIT, &err);
+                                            msg->msg_flags & MSG_DONTWAIT,
+                                            &err);
 
                if (!*frag)
                        return err;
@@ -1597,7 +1601,7 @@ static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
        count = min_t(unsigned int, (conn->mtu - hlen), len);
 
        skb = chan->ops->alloc_skb(chan, count + hlen,
-                                       msg->msg_flags & MSG_DONTWAIT, &err);
+                                  msg->msg_flags & MSG_DONTWAIT, &err);
 
        if (!skb)
                return ERR_PTR(err);
@@ -1632,7 +1636,7 @@ static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
        count = min_t(unsigned int, (conn->mtu - hlen), len);
 
        skb = chan->ops->alloc_skb(chan, count + hlen,
-                                       msg->msg_flags & MSG_DONTWAIT, &err);
+                                  msg->msg_flags & MSG_DONTWAIT, &err);
 
        if (!skb)
                return ERR_PTR(err);
@@ -2741,8 +2745,7 @@ sendresp:
                conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
                conn->info_ident = l2cap_get_ident(conn);
 
-               schedule_delayed_work(&conn->info_timer,
-                                       msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
+               schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
 
                l2cap_send_cmd(conn, conn->info_ident,
                                        L2CAP_INFO_REQ, sizeof(info), &info);
@@ -3028,8 +3031,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
        default:
                l2cap_chan_set_err(chan, ECONNRESET);
 
-               __set_chan_timer(chan,
-                               msecs_to_jiffies(L2CAP_DISC_REJ_TIMEOUT));
+               __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
                l2cap_send_disconn_req(conn, chan, ECONNRESET);
                goto done;
        }
@@ -3209,7 +3211,8 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
                return 0;
        }
 
-       if (type == L2CAP_IT_FEAT_MASK) {
+       switch (type) {
+       case L2CAP_IT_FEAT_MASK:
                conn->feat_mask = get_unaligned_le32(rsp->data);
 
                if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
@@ -3226,11 +3229,15 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
 
                        l2cap_conn_start(conn);
                }
-       } else if (type == L2CAP_IT_FIXED_CHAN) {
+               break;
+
+       case L2CAP_IT_FIXED_CHAN:
+               conn->fixed_chan_mask = rsp->data[0];
                conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
                conn->info_ident = 0;
 
                l2cap_conn_start(conn);
+               break;
        }
 
        return 0;
@@ -4534,8 +4541,7 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
        if (encrypt == 0x00) {
                if (chan->sec_level == BT_SECURITY_MEDIUM) {
                        __clear_chan_timer(chan);
-                       __set_chan_timer(chan,
-                                       msecs_to_jiffies(L2CAP_ENC_TIMEOUT));
+                       __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
                } else if (chan->sec_level == BT_SECURITY_HIGH)
                        l2cap_chan_close(chan, ECONNREFUSED);
        } else {
@@ -4583,6 +4589,11 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
 
                if (!status && (chan->state == BT_CONNECTED ||
                                                chan->state == BT_CONFIG)) {
+                       struct sock *sk = chan->sk;
+
+                       bt_sk(sk)->suspended = false;
+                       sk->sk_state_change(sk);
+
                        l2cap_check_encryption(chan, encrypt);
                        l2cap_chan_unlock(chan);
                        continue;
@@ -4593,8 +4604,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
                                l2cap_send_conn_req(chan);
                        } else {
                                __clear_chan_timer(chan);
-                               __set_chan_timer(chan,
-                                       msecs_to_jiffies(L2CAP_DISC_TIMEOUT));
+                               __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
                        }
                } else if (chan->state == BT_CONNECT2) {
                        struct sock *sk = chan->sk;
@@ -4617,8 +4627,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
                                }
                        } else {
                                __l2cap_state_change(chan, BT_DISCONN);
-                               __set_chan_timer(chan,
-                                       msecs_to_jiffies(L2CAP_DISC_TIMEOUT));
+                               __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
                                res = L2CAP_CR_SEC_BLOCK;
                                stat = L2CAP_CS_NO_INFO;
                        }