in nimble/host/mesh/src/prov_device.c [463:552]
static void prov_data(const uint8_t *data)
{
struct os_mbuf *msg = PROV_BUF(PDU_LEN_COMPLETE);
uint8_t session_key[16];
uint8_t nonce[13];
uint8_t dev_key[16];
uint8_t pdu[25];
uint8_t flags;
uint32_t iv_index;
uint16_t addr;
uint16_t net_idx;
int err;
bool identity_enable;
BT_DBG("");
err = bt_mesh_session_key(bt_mesh_prov_link.dhkey,
bt_mesh_prov_link.prov_salt, session_key);
if (err) {
BT_ERR("Unable to generate session key");
prov_fail(PROV_ERR_UNEXP_ERR);
return;
}
BT_DBG("SessionKey: %s", bt_hex(session_key, 16));
err = bt_mesh_prov_nonce(bt_mesh_prov_link.dhkey,
bt_mesh_prov_link.prov_salt, nonce);
if (err) {
BT_ERR("Unable to generate session nonce");
prov_fail(PROV_ERR_UNEXP_ERR);
return;
}
BT_DBG("Nonce: %s", bt_hex(nonce, 13));
err = bt_mesh_prov_decrypt(session_key, nonce, data, pdu);
if (err) {
BT_ERR("Unable to decrypt provisioning data");
prov_fail(PROV_ERR_DECRYPT);
return;
}
err = bt_mesh_dev_key(bt_mesh_prov_link.dhkey,
bt_mesh_prov_link.prov_salt, dev_key);
if (err) {
BT_ERR("Unable to generate device key");
prov_fail(PROV_ERR_UNEXP_ERR);
return;
}
BT_DBG("DevKey: %s", bt_hex(dev_key, 16));
net_idx = sys_get_be16(&pdu[16]);
flags = pdu[18];
iv_index = sys_get_be32(&pdu[19]);
addr = sys_get_be16(&pdu[23]);
BT_DBG("net_idx %u iv_index 0x%08x, addr 0x%04x",
net_idx, iv_index, addr);
bt_mesh_prov_buf_init(msg, PROV_COMPLETE);
if (bt_mesh_prov_send(msg, NULL)) {
BT_ERR("Failed to send Provisioning Complete");
return;
}
/* Ignore any further PDUs on this link */
bt_mesh_prov_link.expect = PROV_NO_PDU;
/* Store info, since bt_mesh_provision() will end up clearing it */
if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
identity_enable = is_pb_gatt();
} else {
identity_enable = false;
}
err = bt_mesh_provision(pdu, net_idx, flags, iv_index, addr, dev_key);
if (err) {
BT_ERR("Failed to provision (err %d)", err);
return;
}
/* After PB-GATT provisioning we should start advertising
* using Node Identity.
*/
if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) && identity_enable) {
bt_mesh_proxy_identity_enable();
}
}