Bluetooth: SMP: Add support for Identity Information over BR/EDR

Allow to handle IRK distributed by remote device.

> ACL Data RX: Handle 11 flags 0x02 dlen 21
      BR/EDR SMP: Identity Information (0x08) len 16
        Identity resolving key: 286f917356baf6aa27f169fe30030c88
> ACL Data RX: Handle 11 flags 0x02 dlen 12
      BR/EDR SMP: Identity Address Information (0x09) len 7
        Address type: Public (0x00)
        Address: 20:68:9D:60:A1:E4

Jira: ZEP-605

Change-Id: I3c7d32cc6e4cf4d8690edb92089bd433e06f1b4d
Signed-off-by: Szymon Janc <ext.szymon.janc@tieto.com>
This commit is contained in:
Szymon Janc 2016-09-09 16:11:46 +02:00 committed by Johan Hedberg
commit f711962344

View file

@ -1045,14 +1045,73 @@ static uint8_t smp_br_pairing_failed(struct bt_smp *smp, struct net_buf *buf)
static uint8_t smp_br_ident_info(struct bt_smp *smp, struct net_buf *buf)
{
/* TODO */
return BT_SMP_ERR_CMD_NOTSUPP;
struct bt_smp_ident_info *req = (void *)buf->data;
struct bt_conn *conn = smp->chan.chan.conn;
struct bt_keys *keys;
bt_addr_le_t addr;
BT_DBG("");
/* TODO should we resolve LE address if matching RPA is connected? */
/*
* For dualmode devices LE address is same as BR/EDR address and is of
* public type.
*/
bt_addr_copy(&addr.a, &conn->br.dst);
addr.type = BT_ADDR_LE_PUBLIC;
keys = bt_keys_get_type(BT_KEYS_IRK, &addr);
if (!keys) {
BT_ERR("Unable to get keys for %s", bt_addr_le_str(&addr));
return BT_SMP_ERR_UNSPECIFIED;
}
memcpy(keys->irk.val, req->irk, sizeof(keys->irk.val));
atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_IDENT_ADDR_INFO);
return 0;
}
static uint8_t smp_br_ident_addr_info(struct bt_smp *smp, struct net_buf *buf)
{
/* TODO */
return BT_SMP_ERR_CMD_NOTSUPP;
struct bt_conn *conn = smp->chan.chan.conn;
struct bt_smp_ident_addr_info *req = (void *)buf->data;
bt_addr_le_t addr;
BT_DBG("identity %s", bt_addr_le_str(&req->addr));
/*
* For dual mode device identity address must be same as BR/EDR address
* and be of public type. So if received one doesn't match BR/EDR
* address we fail.
*/
bt_addr_copy(&addr.a, &conn->br.dst);
addr.type = BT_ADDR_LE_PUBLIC;
if (bt_addr_le_cmp(&addr, &req->addr)) {
return BT_SMP_ERR_UNSPECIFIED;
}
smp->remote_dist &= ~BT_SMP_DIST_ID_KEY;
if (smp->remote_dist & BT_SMP_DIST_SIGN) {
atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_SIGNING_INFO);
}
if (atomic_test_bit(smp->flags, SMP_FLAG_BR_INITIATOR) &&
!smp->remote_dist) {
smp_br_distribute_keys(smp);
}
/* if all keys were distributed, pairing is done */
if (!smp->local_dist && !smp->remote_dist) {
/* TODO */
}
return 0;
}
static uint8_t smp_br_signing_info(struct bt_smp *smp, struct net_buf *buf)