in nimble/host/mesh/src/provisioner.c [465:556]
static void send_prov_data(void)
{
struct os_mbuf *pdu = PROV_BUF(PDU_LEN_DATA);
#if MYNEWT_VAL(BLE_MESH_CDB)
struct bt_mesh_cdb_subnet *sub;
#else
struct bt_mesh_subnet *sub;
#endif
uint8_t session_key[16];
uint8_t nonce[13];
int err;
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_dev_key(bt_mesh_prov_link.dhkey,
bt_mesh_prov_link.prov_salt, prov_device.node->dev_key);
if (err) {
BT_ERR("Unable to generate device key");
prov_fail(PROV_ERR_UNEXP_ERR);
return;
}
BT_DBG("DevKey: %s", bt_hex(prov_device.node->dev_key, 16));
#if MYNEWT_VAL(BLE_MESH_CDB)
sub = bt_mesh_cdb_subnet_get(prov_device.node->net_idx);
if (sub == NULL) {
BT_ERR("No subnet with net_idx %u",
prov_device.node->net_idx);
prov_fail(PROV_ERR_UNEXP_ERR);
return;
}
#else
sub = bt_mesh_subnet_get(prov_device.node->net_idx);
if (sub == NULL) {
BT_ERR("No subnet with net_idx %u",
prov_device.node->net_idx);
prov_fail(PROV_ERR_UNEXP_ERR);
return;
}
#endif
bt_mesh_prov_buf_init(pdu, PROV_DATA);
#if MYNEWT_VAL(BLE_MESH_CDB)
net_buf_simple_add_mem(pdu, sub->keys[SUBNET_KEY_TX_IDX(sub)].net_key, 16);
net_buf_simple_add_be16(pdu, prov_device.node->net_idx);
net_buf_simple_add_u8(pdu, bt_mesh_cdb_subnet_flags(sub));
net_buf_simple_add_be32(pdu, bt_mesh_cdb.iv_index);
#else
net_buf_simple_add_mem(pdu, sub->keys[SUBNET_KEY_TX_IDX(sub)].net, 16);
net_buf_simple_add_be16(pdu, prov_device.node->net_idx);
net_buf_simple_add_u8(pdu, bt_mesh_net_flags(sub));
net_buf_simple_add_be32(pdu, bt_mesh.iv_index);
#endif
net_buf_simple_add_be16(pdu, prov_device.node->addr);
net_buf_simple_add(pdu, 8); /* For MIC */
BT_DBG("net_idx %u, iv_index 0x%08x, addr 0x%04x",
prov_device.node->net_idx, bt_mesh.iv_index,
prov_device.node->addr);
err = bt_mesh_prov_encrypt(session_key, nonce, &pdu->om_data[1],
&pdu->om_data[1]);
if (err) {
BT_ERR("Unable to encrypt provisioning data");
prov_fail(PROV_ERR_DECRYPT);
return;
}
if (bt_mesh_prov_send(pdu, NULL)) {
BT_ERR("Failed to send Provisioning Data");
return;
}
bt_mesh_prov_link.expect = PROV_COMPLETE;
}