in nimble/host/mesh/src/lpn.c [891:950]
int bt_mesh_lpn_friend_sub_cfm(struct bt_mesh_net_rx *rx,
struct os_mbuf *buf)
{
struct bt_mesh_ctl_friend_sub_confirm *msg = (void *)buf->om_data;
struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
if (buf->om_len < sizeof(*msg)) {
BT_WARN("Too short Friend Subscription Confirm");
return -EINVAL;
}
BT_DBG("xact 0x%02x", msg->xact);
if (!lpn->sent_req) {
BT_WARN("No pending subscription list message");
return 0;
}
if (msg->xact != lpn->xact_pending) {
BT_WARN("Transaction mismatch (0x%02x != 0x%02x)",
msg->xact, lpn->xact_pending);
return 0;
}
if (lpn->sent_req == TRANS_CTL_OP_FRIEND_SUB_ADD) {
group_set(lpn->added, lpn->pending);
group_zero(lpn->pending);
} else if (lpn->sent_req == TRANS_CTL_OP_FRIEND_SUB_REM) {
int i;
group_clear(lpn->added, lpn->pending);
for (i = 0; i < ARRAY_SIZE(lpn->groups); i++) {
if (atomic_test_and_clear_bit(lpn->pending, i) &&
atomic_test_and_clear_bit(lpn->to_remove, i)) {
lpn->groups[i] = BT_MESH_ADDR_UNASSIGNED;
}
}
} else {
BT_WARN("Unexpected Friend Subscription Confirm");
return 0;
}
friend_response_received(lpn);
if (lpn->groups_changed) {
sub_update(TRANS_CTL_OP_FRIEND_SUB_ADD);
sub_update(TRANS_CTL_OP_FRIEND_SUB_REM);
if (!lpn->sent_req) {
lpn->groups_changed = 0;
}
}
if (lpn->pending_poll) {
send_friend_poll();
}
return 0;
}