aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth_mgmt
diff options
context:
space:
mode:
authorcodeworkx <daniel.hillenbrand@codeworkx.de>2012-08-03 23:12:09 +0200
committercodeworkx <daniel.hillenbrand@codeworkx.de>2012-08-03 23:12:09 +0200
commit52215890ef7c4d06fd3323f8315d85f14d637a91 (patch)
tree2f97aaab909de9fa903ba52224f6f643e2f25cf5 /net/bluetooth_mgmt
parent4309a7ffa8aa46ac2fc4090cebc3efeb00dce72f (diff)
downloadkernel_samsung_smdk4412-52215890ef7c4d06fd3323f8315d85f14d637a91.zip
kernel_samsung_smdk4412-52215890ef7c4d06fd3323f8315d85f14d637a91.tar.gz
kernel_samsung_smdk4412-52215890ef7c4d06fd3323f8315d85f14d637a91.tar.bz2
samsung opensource update4
Change-Id: I9db25f213bb1577c4468873c66b230a0566b6cf2
Diffstat (limited to 'net/bluetooth_mgmt')
-rw-r--r--net/bluetooth_mgmt/l2cap_core.c50
-rw-r--r--net/bluetooth_mgmt/mgmt.c19
-rw-r--r--net/bluetooth_mgmt/smp.c13
3 files changed, 71 insertions, 11 deletions
diff --git a/net/bluetooth_mgmt/l2cap_core.c b/net/bluetooth_mgmt/l2cap_core.c
index 884f61c..ab3369f 100644
--- a/net/bluetooth_mgmt/l2cap_core.c
+++ b/net/bluetooth_mgmt/l2cap_core.c
@@ -393,6 +393,13 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err)
BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
+ if (chan->mode == L2CAP_MODE_ERTM) {
+ BT_DBG("L2CAP_MODE_ERTM __clear_ack_timer");
+ __clear_ack_timer(chan);
+ __clear_retrans_timer(chan);
+ __clear_monitor_timer(chan);
+ }
+
if (conn) {
/* Delete from channel list */
write_lock_bh(&conn->chan_lock);
@@ -448,9 +455,11 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err)
if (chan->mode == L2CAP_MODE_ERTM) {
struct srej_list *l, *tmp;
+ /*
__clear_retrans_timer(chan);
__clear_monitor_timer(chan);
__clear_ack_timer(chan);
+ */
skb_queue_purge(&chan->srej_q);
@@ -1465,7 +1474,7 @@ static int l2cap_retransmit_frames(struct l2cap_chan *chan)
ret = l2cap_ertm_send(chan);
return ret;
}
-
+/*
static void l2cap_send_ack(struct l2cap_chan *chan)
{
u16 control = 0;
@@ -1485,6 +1494,34 @@ static void l2cap_send_ack(struct l2cap_chan *chan)
control |= L2CAP_SUPER_RCV_READY;
l2cap_send_sframe(chan, control);
}
+*/
+
+static void __l2cap_send_ack(struct l2cap_chan *chan)
+{
+ u16 control = 0;
+
+ control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+
+ if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
+ control |= L2CAP_SUPER_RCV_NOT_READY;
+ set_bit(CONN_RNR_SENT, &chan->conn_state);
+ l2cap_send_sframe(chan, control);
+ return;
+ }
+
+ if (l2cap_ertm_send(chan) > 0)
+ return;
+
+ control |= L2CAP_SUPER_RCV_READY;
+ l2cap_send_sframe(chan, control);
+}
+
+static void l2cap_send_ack(struct l2cap_chan *chan)
+{
+ BT_DBG("l2cap_send_ack");
+ __clear_ack_timer(chan);
+ __l2cap_send_ack(chan);
+}
static void l2cap_send_srejtail(struct l2cap_chan *chan)
{
@@ -1920,7 +1957,8 @@ static void l2cap_ack_timeout(unsigned long arg)
struct l2cap_chan *chan = (void *) arg;
spin_lock_bh(&((chan->sk)->sk_lock.slock));
- l2cap_send_ack(chan);
+ /* l2cap_send_ack(chan);*/
+ __l2cap_send_ack(chan);
spin_unlock_bh(&((chan->sk)->sk_lock.slock));
}
@@ -3652,11 +3690,13 @@ expected:
l2cap_retransmit_frames(chan);
}
- __set_ack_timer(chan);
-
chan->num_acked = (chan->num_acked + 1) % num_to_ack;
- if (chan->num_acked == num_to_ack - 1)
+ if (chan->num_acked == num_to_ack - 1) {
l2cap_send_ack(chan);
+ } else {
+ BT_DBG("__set_ack_timer");
+ __set_ack_timer(chan);
+ }
return 0;
diff --git a/net/bluetooth_mgmt/mgmt.c b/net/bluetooth_mgmt/mgmt.c
index dd23eb7..04eaf75 100644
--- a/net/bluetooth_mgmt/mgmt.c
+++ b/net/bluetooth_mgmt/mgmt.c
@@ -1627,6 +1627,22 @@ static void pairing_complete_cb(struct hci_conn *conn, u8 status)
pairing_complete(cmd, status);
}
+static void le_connect_complete_cb(struct hci_conn *conn, u8 status)
+{
+ struct pending_cmd *cmd;
+
+ BT_DBG("status %u", status);
+
+ if (!status)
+ return;
+
+ cmd = find_pairing(conn);
+ if (!cmd)
+ BT_DBG("Unable to find a pending command");
+ else
+ pairing_complete(cmd, mgmt_status(status));
+}
+
static int pair_device(struct sock *sk, u16 index, void *data, u16 len)
{
struct hci_dev *hdev;
@@ -1687,9 +1703,10 @@ static int pair_device(struct sock *sk, u16 index, void *data, u16 len)
goto unlock;
}
- /* For LE, just connecting isn't a proof that the pairing finished */
if (cp->addr.type == MGMT_ADDR_BREDR)
conn->connect_cfm_cb = pairing_complete_cb;
+ else
+ conn->connect_cfm_cb = le_connect_complete_cb;
conn->security_cfm_cb = pairing_complete_cb;
conn->disconn_cfm_cb = pairing_complete_cb;
diff --git a/net/bluetooth_mgmt/smp.c b/net/bluetooth_mgmt/smp.c
index a40db2d..0786fde 100644
--- a/net/bluetooth_mgmt/smp.c
+++ b/net/bluetooth_mgmt/smp.c
@@ -294,11 +294,16 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send)
* 3 - NoInputNoOutput
* 4 - KeyboardDisplay
*/
+
+/* gen_method[3][4] is changed to JUST_WORKS.
+ *Although JUST_CFM works with pin 0000, when interacting with NoInputNoOutput,
+ * such a gesture might be confusing to user. Hence its changed to JUST_WORKS
+ */
static const u8 gen_method[5][5] = {
{ JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
{ JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
- { JUST_WORKS, JUST_CFM, JUST_WORKS, JUST_WORKS, JUST_CFM },
+ { JUST_WORKS, JUST_CFM, JUST_WORKS, JUST_WORKS, JUST_WORKS },
{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP },
};
@@ -325,7 +330,7 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
remote_io > SMP_IO_KEYBOARD_DISPLAY)
method = JUST_WORKS;
else
- method = gen_method[local_io][remote_io];
+ method = gen_method[remote_io][local_io];
/* If not bonding, don't ask user to confirm a Zero TK */
if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM)
@@ -629,8 +634,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
/* Request setup of TK */
- /* SSBT :: KJH * loc, rem */
- ret = tk_request(conn, 0, auth, req->io_capability, rsp.io_capability);
+ ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
if (ret)
return SMP_UNSPECIFIED;
@@ -671,7 +675,6 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
- /* SSBT :: KJH * loc, rem */
ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
if (ret)
return SMP_UNSPECIFIED;