Bluetooth: Fix updating Identity Address in L2CAP channels
authorJohan Hedberg <johan.hedberg@intel.com>
Tue, 18 Feb 2014 19:41:33 +0000 (21:41 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Tue, 18 Feb 2014 19:48:55 +0000 (11:48 -0800)
When we receive a remote identity address during SMP key distribution we
should ensure that any associated L2CAP channel instances get their
address information correspondingly updated (so that e.g. doing
getpeername on associated sockets returns the correct address).

This patch adds a new L2CAP core function l2cap_conn_update_id_addr()
which is used to iterate through all L2CAP channels associated with a
connection and update their address information.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
include/net/bluetooth/l2cap.h
net/bluetooth/l2cap_core.c
net/bluetooth/smp.c

index 13bec91785f421ca215661c4dbb14a74a958c6fd..4abdcb220e3ac7a0558a9a0115b873a5312f3f07 100644 (file)
@@ -881,6 +881,7 @@ int l2cap_ertm_init(struct l2cap_chan *chan);
 void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
 void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
 void l2cap_chan_del(struct l2cap_chan *chan, int err);
+void l2cap_conn_update_id_addr(struct hci_conn *hcon);
 void l2cap_send_conn_req(struct l2cap_chan *chan);
 void l2cap_move_start(struct l2cap_chan *chan);
 void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
index 6e6b3a9c8e6d55e6aad9b6ad545e34d85c3c80cc..c3bda6445f3d7e02598a510acb262780e7385645 100644 (file)
@@ -609,6 +609,23 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
        return;
 }
 
+void l2cap_conn_update_id_addr(struct hci_conn *hcon)
+{
+       struct l2cap_conn *conn = hcon->l2cap_data;
+       struct l2cap_chan *chan;
+
+       mutex_lock(&conn->chan_lock);
+
+       list_for_each_entry(chan, &conn->chan_l, list) {
+               l2cap_chan_lock(chan);
+               bacpy(&chan->dst, &hcon->dst);
+               chan->dst_type = bdaddr_type(hcon, hcon->dst_type);
+               l2cap_chan_unlock(chan);
+       }
+
+       mutex_unlock(&conn->chan_lock);
+}
+
 static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan)
 {
        struct l2cap_conn *conn = chan->conn;
index af29afed0cca10642060df53aa9a64da89d40724..b6a2a8942b2df833bd650d2ce5eac9edf5c829ed 100644 (file)
@@ -991,6 +991,8 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
        bacpy(&hcon->dst, &smp->id_addr);
        hcon->dst_type = smp->id_addr_type;
 
+       l2cap_conn_update_id_addr(hcon);
+
        smp_distribute_keys(conn, 1);
 
        return 0;