Bluetooth: Host: Fix wrong init address when controller resolved address

The init addr should contain the on-air address used to establish the
connection. The dst address contains either the current RPA of the
unknown peer, or the identity address after identity information has
been exchanged.

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
This commit is contained in:
Joakim Andersson 2019-08-02 16:04:01 +02:00 committed by Carles Cufí
commit 45da629b24
3 changed files with 33 additions and 20 deletions

View file

@ -1929,6 +1929,7 @@ struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer,
const struct bt_le_conn_param *param)
{
struct bt_conn *conn;
bt_addr_le_t dst;
if (!atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
return NULL;
@ -1957,7 +1958,15 @@ struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer,
}
}
conn = bt_conn_add_le(peer);
if (peer->type == BT_ADDR_LE_PUBLIC_ID ||
peer->type == BT_ADDR_LE_RANDOM_ID) {
bt_addr_le_copy(&dst, peer);
dst.type -= BT_ADDR_LE_PUBLIC_ID;
} else {
bt_addr_le_copy(&dst, bt_lookup_id_addr(BT_ID_DEFAULT, peer));
}
conn = bt_conn_add_le(&dst);
if (!conn) {
return NULL;
}
@ -1965,9 +1974,6 @@ struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer,
/* Only default identity supported for now */
conn->id = BT_ID_DEFAULT;
/* Set initial address - will be updated later if necessary. */
bt_addr_le_copy(&conn->le.resp_addr, peer);
bt_conn_set_param_le(conn, param);
bt_conn_set_state(conn, BT_CONN_CONNECT_SCAN);

View file

@ -356,7 +356,7 @@ int bt_hci_cmd_send_sync(u16_t opcode, struct net_buf *buf,
}
#if defined(CONFIG_BT_OBSERVER) || defined(CONFIG_BT_CONN)
static const bt_addr_le_t *find_id_addr(u8_t id, const bt_addr_le_t *addr)
const bt_addr_le_t *bt_lookup_id_addr(u8_t id, const bt_addr_le_t *addr)
{
if (IS_ENABLED(CONFIG_BT_SMP)) {
struct bt_keys *keys;
@ -703,8 +703,8 @@ static int hci_le_create_conn(const struct bt_conn *conn)
cp->scan_interval = sys_cpu_to_le16(BT_GAP_SCAN_FAST_INTERVAL);
cp->scan_window = cp->scan_interval;
bt_addr_le_copy(&cp->peer_addr, &conn->le.resp_addr);
cp->own_addr_type = conn->le.init_addr.type;
bt_addr_le_copy(&cp->peer_addr, &conn->le.dst);
cp->own_addr_type = conn->le.dst.type;
cp->conn_interval_min = sys_cpu_to_le16(conn->le.interval_min);
cp->conn_interval_max = sys_cpu_to_le16(conn->le.interval_max);
cp->conn_latency = sys_cpu_to_le16(conn->le.latency);
@ -1059,6 +1059,18 @@ static void enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt)
}
}
if (conn->role == BT_HCI_ROLE_MASTER) {
bt_addr_le_copy(&conn->le.resp_addr, &peer_addr);
if (IS_ENABLED(CONFIG_BT_PRIVACY)) {
bt_addr_copy(&conn->le.init_addr.a, &evt->local_rpa);
conn->le.init_addr.type = BT_ADDR_LE_RANDOM;
} else {
bt_addr_le_copy(&conn->le.init_addr,
&bt_dev.id_addr[conn->id]);
}
}
bt_conn_set_state(conn, BT_CONN_CONNECTED);
/*
@ -1135,9 +1147,9 @@ static void le_legacy_conn_complete(struct net_buf *buf)
}
if (evt->role == BT_HCI_ROLE_SLAVE) {
id_addr = find_id_addr(bt_dev.adv_id, &enh.peer_addr);
id_addr = bt_lookup_id_addr(bt_dev.adv_id, &enh.peer_addr);
} else {
id_addr = find_id_addr(BT_ID_DEFAULT, &enh.peer_addr);
id_addr = bt_lookup_id_addr(BT_ID_DEFAULT, &enh.peer_addr);
}
if (id_addr != &enh.peer_addr) {
@ -1420,24 +1432,18 @@ static void check_pending_conn(const bt_addr_le_t *id_addr,
if (le_set_private_addr(BT_ID_DEFAULT)) {
goto failed;
}
bt_addr_le_copy(&conn->le.init_addr, &bt_dev.random_addr);
} else {
const bt_addr_le_t *addr = &bt_dev.id_addr[conn->id];
const bt_addr_le_t *own_addr = &bt_dev.id_addr[conn->id];
/* If Static Random address is used as Identity address we
* need to restore it before creating connection. Otherwise
* NRPA used for active scan could be used for connection.
*/
if (addr->type == BT_ADDR_LE_RANDOM) {
set_random_address(&addr->a);
if (own_addr->type == BT_ADDR_LE_RANDOM) {
set_random_address(&own_addr->a);
}
bt_addr_le_copy(&conn->le.init_addr, addr);
}
bt_addr_le_copy(&conn->le.resp_addr, addr);
if (hci_le_create_conn(conn)) {
goto failed;
}
@ -3419,8 +3425,8 @@ static void le_adv_report(struct net_buf *buf)
id_addr.type -= BT_ADDR_LE_PUBLIC_ID;
} else {
bt_addr_le_copy(&id_addr,
find_id_addr(bt_dev.adv_id,
&info->addr));
bt_lookup_id_addr(bt_dev.adv_id,
&info->addr));
}
if (scan_dev_found_cb) {

View file

@ -186,6 +186,7 @@ bool bt_le_conn_params_valid(const struct bt_le_conn_param *param);
int bt_le_scan_update(bool fast_scan);
bool bt_addr_le_is_bonded(u8_t id, const bt_addr_le_t *addr);
const bt_addr_le_t *bt_lookup_id_addr(u8_t id, const bt_addr_le_t *addr);
int bt_send(struct net_buf *buf);