bluetooth: host: convert conn address on identity resolution

Fix an issue in the CCC configuration when the Peripheral device
maintains two or more distinct connections on different identities
with the same peer. The issue occurs when the local device performs
the pairing and the bonding procedure on a connection associated
with one of the Bluetooth identities. During the identity resolution,
the peer address field in the CCC descriptor is converted from the
RPA-type address to the Identity Address. However, the destination
address on the remaining connection objects associated with other
Bluetooth identities is not converted. Due to this, their CCC
configuration is reset and GATT indications and notification fail
to be sent even if the Central device subscribed to them.

Added necessary code to iterate over all connection objects during
the identity resolution phase and aligned their destination address
from the RPA-type to the Identity Address.

Signed-off-by: Kamil Piszczek <Kamil.Piszczek@nordicsemi.no>
This commit is contained in:
Kamil Piszczek 2023-07-31 14:16:39 +02:00 committed by Carles Cufí
commit 42c904526b

View file

@ -3815,6 +3815,20 @@ static uint8_t smp_id_add_replace(struct bt_smp *smp, struct bt_keys *new_bond)
return 0;
}
struct addr_match {
const bt_addr_le_t *rpa;
const bt_addr_le_t *id_addr;
};
static void convert_to_id_on_match(struct bt_conn *conn, void *data)
{
struct addr_match *addr_match = data;
if (bt_addr_le_eq(&conn->le.dst, addr_match->rpa)) {
bt_addr_le_copy(&conn->le.dst, addr_match->id_addr);
}
}
static uint8_t smp_ident_addr_info(struct bt_smp *smp, struct net_buf *buf)
{
struct bt_conn *conn = smp->chan.chan.conn;
@ -3876,8 +3890,15 @@ static uint8_t smp_ident_addr_info(struct bt_smp *smp, struct net_buf *buf)
* present before ie. due to re-pairing.
*/
if (!bt_addr_le_is_identity(&conn->le.dst)) {
struct addr_match addr_match = {
.rpa = &conn->le.dst,
.id_addr = &req->addr,
};
bt_conn_foreach(BT_CONN_TYPE_LE,
convert_to_id_on_match,
&addr_match);
bt_addr_le_copy(&keys->addr, &req->addr);
bt_addr_le_copy(&conn->le.dst, &req->addr);
bt_conn_identity_resolved(conn);
}