static void secure_beacon_recv()

in nimble/host/mesh/src/beacon.c [302:369]


static void secure_beacon_recv(struct os_mbuf *buf)
{
	struct beacon_params params;
	struct bt_mesh_subnet *sub;
	uint8_t *data;

	if (buf->om_len < 21) {
		BT_ERR("Too short secure beacon (len %u)", buf->om_len);
		return;
	}

	sub = bt_mesh_subnet_find(cache_check, buf->om_data);
	if (sub) {
		/* We've seen this beacon before - just update the stats */
		goto update_stats;
	}

	/* So we can add to the cache if auth matches */
	data = buf->om_data;

	params.flags = net_buf_simple_pull_u8(buf);
	params.net_id = net_buf_simple_pull_mem(buf, 8);
	params.iv_index = net_buf_simple_pull_be32(buf);
	params.auth = buf->om_data;

	BT_DBG("flags 0x%02x id %s iv_index 0x%08x",
	       params.flags, bt_hex(params.net_id, 8), params.iv_index);

	sub = bt_mesh_subnet_find(subnet_by_id, &params);
	if (!sub) {
		BT_DBG("No subnet that matched beacon");
		return;
	}

	if (sub->kr_phase == BT_MESH_KR_PHASE_2 && !params.new_key) {
		BT_WARN("Ignoring Phase 2 KR Update secured using old key");
		return;
	}

	cache_add(data, sub);

	bt_mesh_kr_update(sub, BT_MESH_KEY_REFRESH(params.flags),
			  params.new_key);

	/* If we have NetKey0 accept initiation only from it */
	if (bt_mesh_subnet_get(BT_MESH_KEY_PRIMARY) &&
	    sub->net_idx != BT_MESH_KEY_PRIMARY) {
		BT_WARN("Ignoring secure beacon on non-primary subnet");
		goto update_stats;
	}

	BT_DBG("net_idx 0x%04x iv_index 0x%08x, current iv_index 0x%08x",
	       sub->net_idx, params.iv_index, bt_mesh.iv_index);

	if (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_INITIATOR) &&
	    (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS) ==
	     BT_MESH_IV_UPDATE(params.flags))) {
		bt_mesh_beacon_ivu_initiator(false);
	}

	bt_mesh_net_iv_update(params.iv_index, BT_MESH_IV_UPDATE(params.flags));

update_stats:
	if (bt_mesh_beacon_enabled() &&
	    sub->beacons_cur < 0xff) {
		sub->beacons_cur++;
	}
}