/*
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdlib.h>
#include <zephyr/sys/slist.h>
#include <zephyr/random/random.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/mesh/rpr_srv.h>
#include <common/bt_str.h>
#include <zephyr/bluetooth/mesh/sar_cfg.h>
#include <zephyr/bluetooth/mesh/keys.h>
#include "access.h"
#include "prov.h"
#include "crypto.h"
#include "rpr.h"
#include "net.h"
#include "mesh.h"

#define LOG_LEVEL CONFIG_BT_MESH_MODEL_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(bt_mesh_rpr_srv);

#define LINK_OPEN_TIMEOUT_DEFAULT 10

#define LINK_CTX(_cli, _send_rel)                                              \
	{                                                                      \
		.net_idx = (_cli)->net_idx, .app_idx = BT_MESH_KEY_DEV_LOCAL,  \
		.addr = (_cli)->addr, .send_ttl = (_cli)->ttl,                 \
		.send_rel = (_send_rel)                                        \
	}

enum {
	SCANNING,
	SCAN_REPORT_PENDING,
	SCAN_EXT_HAS_ADDR,
	NODE_REFRESH,
	URI_MATCHED,
	URI_REQUESTED,

	RPR_SRV_NUM_FLAGS,
};

/** Remote provisioning server instance. */
static struct {
	const struct bt_mesh_model *mod;

	ATOMIC_DEFINE(flags, RPR_SRV_NUM_FLAGS);

	struct {
		struct bt_mesh_rpr_unprov
			devs[CONFIG_BT_MESH_RPR_SRV_SCANNED_ITEMS_MAX];
		uint8_t max_devs;
		enum bt_mesh_rpr_scan state;
		struct k_work_delayable report;
		struct k_work_delayable timeout;
		/* Extended scanning */
		bt_addr_le_t addr;
		uint8_t ad[CONFIG_BT_MESH_RPR_AD_TYPES_MAX];
		uint8_t ad_count;
		/* Time to do regular scanning after extended scanning ends: */
		uint32_t additional_time;
		struct net_buf_simple *adv_data;
		struct bt_mesh_rpr_node cli;
		struct bt_mesh_rpr_unprov *dev;
	} scan;
	struct {
		struct k_work report;
		enum bt_mesh_rpr_link_state state;
		enum bt_mesh_rpr_status status;
		uint8_t close_reason;
		uint8_t tx_pdu;
		uint8_t rx_pdu;
		struct bt_mesh_rpr_node cli;
		struct bt_mesh_rpr_unprov *dev;
	} link;
	struct {
		const struct prov_bearer_cb *cb;
		enum bt_mesh_rpr_node_refresh procedure;
		void *cb_data;
		struct {
			prov_bearer_send_complete_t cb;
			void *cb_data;
		} tx;
	} refresh;
} srv = {
	.scan = {
		.adv_data = NET_BUF_SIMPLE(CONFIG_BT_MESH_RPR_SRV_AD_DATA_MAX)
	}
};

enum bt_mesh_rpr_node_refresh bt_mesh_node_refresh_get(void)
{
	return srv.refresh.procedure;
}

static struct bt_mesh_rpr_unprov *unprov_get(const uint8_t uuid[16])
{
	int i;

	for (i = 0; i < srv.scan.max_devs; ++i) {
		if (uuid) {
			if ((srv.scan.devs[i].flags & BT_MESH_RPR_UNPROV_ACTIVE) &&
			    !memcmp(srv.scan.devs[i].uuid, uuid, 16)) {
				return &srv.scan.devs[i];
			}
		} else if (!(srv.scan.devs[i].flags & BT_MESH_RPR_UNPROV_ACTIVE)) {
			return &srv.scan.devs[i];
		}
	}

	return NULL;
}

static uint8_t *get_ad_type(uint8_t *list, size_t count, uint8_t ad)
{
	int i;

	for (i = 0; i < count; ++i) {
		if (ad == list[i] || (ad == BT_DATA_NAME_SHORTENED &&
				      list[i] == BT_DATA_NAME_COMPLETE)) {
			return &list[i];
		}
	}

	return NULL;
}

static void cli_scan_clear(void)
{
	srv.scan.cli.addr = BT_MESH_ADDR_UNASSIGNED;
	srv.scan.cli.net_idx = BT_MESH_KEY_UNUSED;
}

static void cli_link_clear(void)
{
	srv.link.cli.addr = BT_MESH_ADDR_UNASSIGNED;
	srv.link.cli.net_idx = BT_MESH_KEY_UNUSED;
}

static void scan_status_send(struct bt_mesh_msg_ctx *ctx,
			     enum bt_mesh_rpr_status status)
{
	uint8_t timeout = 0;

	if (atomic_test_bit(srv.flags, SCANNING)) {
		timeout = k_ticks_to_ms_floor32(
			k_work_delayable_remaining_get(&srv.scan.timeout)) /
			MSEC_PER_SEC;
	}

	BT_MESH_MODEL_BUF_DEFINE(rsp, RPR_OP_SCAN_STATUS, 4);
	bt_mesh_model_msg_init(&rsp, RPR_OP_SCAN_STATUS);
	net_buf_simple_add_u8(&rsp, status);
	net_buf_simple_add_u8(&rsp, srv.scan.state);
	net_buf_simple_add_u8(&rsp, srv.scan.max_devs);
	net_buf_simple_add_u8(&rsp, timeout);

	bt_mesh_model_send(srv.mod, ctx, &rsp, NULL, NULL);
}

static void link_status_send(struct bt_mesh_msg_ctx *ctx,
			     enum bt_mesh_rpr_status status)
{
	BT_MESH_MODEL_BUF_DEFINE(buf, RPR_OP_LINK_STATUS, 2);
	bt_mesh_model_msg_init(&buf, RPR_OP_LINK_STATUS);
	net_buf_simple_add_u8(&buf, status);
	net_buf_simple_add_u8(&buf, srv.link.state);

	bt_mesh_model_send(srv.mod, ctx, &buf, NULL, NULL);
}

static void link_report_send(void)
{
	struct bt_mesh_msg_ctx ctx = LINK_CTX(&srv.link.cli, true);

	BT_MESH_MODEL_BUF_DEFINE(buf, RPR_OP_LINK_REPORT, 3);
	bt_mesh_model_msg_init(&buf, RPR_OP_LINK_REPORT);
	net_buf_simple_add_u8(&buf, srv.link.status);
	net_buf_simple_add_u8(&buf, srv.link.state);
	if (srv.link.status == BT_MESH_RPR_ERR_LINK_CLOSED_BY_SERVER ||
	    srv.link.status == BT_MESH_RPR_ERR_LINK_CLOSED_BY_DEVICE) {
		net_buf_simple_add_u8(&buf, srv.link.close_reason);
	}

	LOG_DBG("%u %u", srv.link.status, srv.link.state);

	bt_mesh_model_send(srv.mod, &ctx, &buf, NULL, NULL);
}

static void scan_report_schedule(void)
{
	uint32_t delay;

	if (k_work_delayable_remaining_get(&srv.scan.report) ||
	    atomic_test_bit(srv.flags, SCAN_REPORT_PENDING)) {
		return;
	}

	delay = (sys_rand32_get() % 480) + 20;

	k_work_reschedule(&srv.scan.report, K_MSEC(delay));
}

static void scan_report_sent(int err, void *cb_data)
{
	atomic_clear_bit(srv.flags, SCAN_REPORT_PENDING);
	k_work_reschedule(&srv.scan.report, K_NO_WAIT);
}

static const struct bt_mesh_send_cb report_cb = {
	.end = scan_report_sent,
};

static void scan_report_send(void)
{
	struct bt_mesh_msg_ctx ctx = LINK_CTX(&srv.scan.cli, true);
	int i, err;

	if (atomic_test_bit(srv.flags, SCAN_REPORT_PENDING)) {
		return;
	}

	for (i = 0; i < srv.scan.max_devs; ++i) {
		struct bt_mesh_rpr_unprov *dev = &srv.scan.devs[i];

		if (!(dev->flags & BT_MESH_RPR_UNPROV_FOUND) ||
		    (dev->flags & BT_MESH_RPR_UNPROV_REPORTED)) {
			continue;
		}

		BT_MESH_MODEL_BUF_DEFINE(buf, RPR_OP_SCAN_REPORT, 23);
		bt_mesh_model_msg_init(&buf, RPR_OP_SCAN_REPORT);
		net_buf_simple_add_u8(&buf, dev->rssi);
		net_buf_simple_add_mem(&buf, dev->uuid, 16);
		net_buf_simple_add_le16(&buf, dev->oob);
		if (dev->flags & BT_MESH_RPR_UNPROV_HASH) {
			net_buf_simple_add_mem(&buf, &dev->hash, 4);
		}

		atomic_set_bit(srv.flags, SCAN_REPORT_PENDING);

		err = bt_mesh_model_send(srv.mod, &ctx, &buf, &report_cb, NULL);
		if (err) {
			atomic_clear_bit(srv.flags, SCAN_REPORT_PENDING);
			LOG_DBG("tx failed: %d", err);
			break;
		}

		LOG_DBG("Reported unprov #%u", i);
		dev->flags |= BT_MESH_RPR_UNPROV_REPORTED;
		break;
	}
}

static void scan_ext_report_send(void)
{
	struct bt_mesh_msg_ctx ctx = LINK_CTX(&srv.scan.cli, true);
	int err;

	BT_MESH_MODEL_BUF_DEFINE(buf, RPR_OP_EXTENDED_SCAN_REPORT,
				 19 + CONFIG_BT_MESH_RPR_SRV_AD_DATA_MAX);
	bt_mesh_model_msg_init(&buf, RPR_OP_EXTENDED_SCAN_REPORT);
	net_buf_simple_add_u8(&buf, BT_MESH_RPR_SUCCESS);
	net_buf_simple_add_mem(&buf, srv.scan.dev->uuid, 16);

	if (srv.scan.dev->flags & BT_MESH_RPR_UNPROV_FOUND) {
		net_buf_simple_add_le16(&buf, srv.scan.dev->oob);
	} else {
		LOG_DBG("not found");
		goto send;
	}

	if (srv.scan.dev->flags & BT_MESH_RPR_UNPROV_EXT_ADV_RXD) {
		net_buf_simple_add_mem(&buf, srv.scan.adv_data->data,
				       srv.scan.adv_data->len);
		LOG_DBG("adv data: %s",
			bt_hex(srv.scan.adv_data->data, srv.scan.adv_data->len));
	}

	srv.scan.dev->flags &= ~BT_MESH_RPR_UNPROV_EXT_ADV_RXD;
send:
	err = bt_mesh_model_send(srv.mod, &ctx, &buf, NULL, NULL);
	if (!err) {
		srv.scan.dev->flags |= BT_MESH_RPR_UNPROV_REPORTED;
	}
}

static void scan_stop(void)
{
	LOG_DBG("");

	k_work_cancel_delayable(&srv.scan.report);
	k_work_cancel_delayable(&srv.scan.timeout);
	srv.scan.state = BT_MESH_RPR_SCAN_IDLE;
	cli_scan_clear();
	atomic_clear_bit(srv.flags, SCANNING);
}

static void scan_report_timeout(struct k_work *work)
{
	scan_report_send();
}

static void scan_ext_stop(uint32_t remaining_time)
{
	atomic_clear_bit(srv.flags, URI_MATCHED);
	atomic_clear_bit(srv.flags, URI_REQUESTED);

	if ((remaining_time + srv.scan.additional_time) &&
	    srv.scan.state != BT_MESH_RPR_SCAN_IDLE) {
		k_work_reschedule(
			&srv.scan.timeout,
			K_MSEC(remaining_time + srv.scan.additional_time));
	} else if (srv.scan.state == BT_MESH_RPR_SCAN_MULTI) {
		/* Extended scan might have finished early */
		scan_ext_report_send();
	} else if (srv.scan.state != BT_MESH_RPR_SCAN_IDLE) {
		scan_report_send();
		scan_stop();
	} else {
		atomic_clear_bit(srv.flags, SCANNING);
	}

	if (!(srv.scan.dev->flags & BT_MESH_RPR_UNPROV_REPORTED)) {
		scan_ext_report_send();
	}

	bt_mesh_scan_active_set(false);
	srv.scan.dev = NULL;
}

static void adv_handle_ext_scan(const struct bt_le_scan_recv_info *info,
				struct net_buf_simple *buf);

static void scan_timeout(struct k_work *work)
{
	LOG_DBG("%s", (srv.scan.dev ? "Extended scanning" : "Normal scanning"));

	if (srv.scan.dev) {
		scan_ext_stop(0);
	} else {
		scan_report_send();
		scan_stop();
	}
}

static void link_close(enum bt_mesh_rpr_status status,
		       enum prov_bearer_link_status reason)
{
	srv.link.status = status;
	srv.link.close_reason = reason;
	srv.link.state = BT_MESH_RPR_LINK_CLOSING;

	LOG_DBG("status: %u reason: %u", status, reason);

	if (atomic_test_and_clear_bit(srv.flags, NODE_REFRESH)) {
		/* Link closing is an atomic operation: */
		srv.link.state = BT_MESH_RPR_LINK_IDLE;
		link_report_send();
		srv.refresh.cb->link_closed(&pb_remote_srv, srv.refresh.cb_data,
					    srv.link.close_reason);

		cli_link_clear();
	} else {
		bt_mesh_pb_adv.link_close(reason);
	}
}

static void outbound_pdu_report_send(void)
{
	struct bt_mesh_msg_ctx ctx = LINK_CTX(&srv.link.cli, true);

	BT_MESH_MODEL_BUF_DEFINE(buf, RPR_OP_PDU_OUTBOUND_REPORT, 1);
	bt_mesh_model_msg_init(&buf, RPR_OP_PDU_OUTBOUND_REPORT);
	net_buf_simple_add_u8(&buf, srv.link.tx_pdu);

	LOG_DBG("%u", srv.link.tx_pdu);

	bt_mesh_model_send(srv.mod, &ctx, &buf, NULL, NULL);
}

static void pdu_send_complete(int err, void *cb_data)
{
	if (err) {
		link_close(BT_MESH_RPR_ERR_LINK_CLOSED_AS_CANNOT_SEND_PDU,
			   PROV_BEARER_LINK_STATUS_FAIL);
	} else if (srv.link.state == BT_MESH_RPR_LINK_SENDING) {
		srv.link.state = BT_MESH_RPR_LINK_ACTIVE;
		srv.link.tx_pdu++;
		outbound_pdu_report_send();
	}
}

static int inbound_pdu_send(struct net_buf_simple *buf,
			    const struct bt_mesh_send_cb *cb)
{
	struct bt_mesh_msg_ctx ctx = LINK_CTX(&srv.link.cli, true);

	BT_MESH_MODEL_BUF_DEFINE(msg, RPR_OP_PDU_REPORT, 66);
	bt_mesh_model_msg_init(&msg, RPR_OP_PDU_REPORT);
	net_buf_simple_add_u8(&msg, srv.link.rx_pdu);
	net_buf_simple_add_mem(&msg, buf->data, buf->len);

	return bt_mesh_model_send(srv.mod, &ctx, &msg, cb, NULL);
}

static void subnet_evt_handler(struct bt_mesh_subnet *subnet,
			       enum bt_mesh_key_evt evt)
{
	if (!srv.mod || evt != BT_MESH_KEY_DELETED) {
		return;
	}

	LOG_DBG("Subnet deleted");

	if (srv.link.state != BT_MESH_RPR_LINK_IDLE &&
	    subnet->net_idx == srv.link.cli.net_idx) {
		link_close(BT_MESH_RPR_ERR_LINK_CLOSED_BY_SERVER,
			   PROV_BEARER_LINK_STATUS_FAIL);
		/* Skip the link closing stage, as specified in the Bluetooth
		 * MshPRTv1.1: 4.4.5.4.
		 */
		srv.link.state = BT_MESH_RPR_LINK_IDLE;
	} else if (atomic_test_bit(srv.flags, SCANNING) &&
		   subnet->net_idx == srv.scan.cli.net_idx) {
		scan_stop();
	}
}

BT_MESH_SUBNET_CB_DEFINE(rpr_srv) = {
	.evt_handler = subnet_evt_handler
};

/*******************************************************************************
 * Prov bearer interface
 ******************************************************************************/
static void pb_link_opened(const struct prov_bearer *bearer, void *cb_data)
{
	LOG_DBG("");

	srv.link.state = BT_MESH_RPR_LINK_ACTIVE;
	srv.link.status = BT_MESH_RPR_SUCCESS;
	link_report_send();
}

static void link_report_send_and_clear(struct k_work *work)
{
	link_report_send();
	cli_link_clear();
}

static void pb_link_closed(const struct prov_bearer *bearer, void *cb_data,
			   enum prov_bearer_link_status reason)
{
	if (srv.link.state == BT_MESH_RPR_LINK_IDLE) {
		return;
	}

	LOG_DBG("%u", reason);

	if (srv.link.state == BT_MESH_RPR_LINK_OPENING) {
		srv.link.status = BT_MESH_RPR_ERR_LINK_OPEN_FAILED;
	} else if (reason == PROV_BEARER_LINK_STATUS_TIMEOUT) {
		if (srv.link.state == BT_MESH_RPR_LINK_SENDING) {
			srv.link.status =
				BT_MESH_RPR_ERR_LINK_CLOSED_AS_CANNOT_SEND_PDU;
		} else {
			srv.link.status = BT_MESH_RPR_ERR_LINK_CLOSED_BY_SERVER;
		}
	} else if (reason == PROV_BEARER_LINK_STATUS_FAIL &&
	   srv.link.status != BT_MESH_RPR_ERR_LINK_CLOSED_BY_CLIENT &&
	   srv.link.status != BT_MESH_RPR_ERR_LINK_CLOSED_BY_SERVER) {
		srv.link.status = BT_MESH_RPR_ERR_LINK_CLOSED_BY_DEVICE;
	}

	if (reason == PROV_BEARER_LINK_STATUS_SUCCESS) {
		srv.link.close_reason = PROV_BEARER_LINK_STATUS_SUCCESS;
	} else {
		srv.link.close_reason = PROV_BEARER_LINK_STATUS_FAIL;
	}

	srv.link.state = BT_MESH_RPR_LINK_IDLE;
	k_work_submit(&srv.link.report);
}

static void pb_error(const struct prov_bearer *bearer, void *cb_data,
		     uint8_t err)
{
	if (srv.link.state == BT_MESH_RPR_LINK_IDLE) {
		return;
	}

	LOG_DBG("%d", err);
	srv.link.close_reason = err;
	srv.link.state = BT_MESH_RPR_LINK_IDLE;
	srv.link.status = BT_MESH_RPR_ERR_LINK_CLOSED_AS_CANNOT_RECEIVE_PDU;
	link_report_send();
	cli_link_clear();
}

static void pb_rx(const struct prov_bearer *bearer, void *cb_data,
		  struct net_buf_simple *buf)
{
	int err;

	if (srv.link.state != BT_MESH_RPR_LINK_ACTIVE &&
	    srv.link.state != BT_MESH_RPR_LINK_SENDING) {
		return;
	}

	srv.link.rx_pdu++;
	LOG_DBG("");

	err = inbound_pdu_send(buf, NULL);
	if (err) {
		LOG_ERR("PDU send fail: %d", err);
		link_close(BT_MESH_RPR_ERR_LINK_CLOSED_AS_CANNOT_SEND_PDU,
			   PROV_BEARER_LINK_STATUS_FAIL);
		bt_mesh_pb_adv.link_close(PROV_ERR_RESOURCES);
	}
}

static const struct prov_bearer_cb prov_bearer_cb = {
	.link_opened = pb_link_opened,
	.link_closed = pb_link_closed,
	.error = pb_error,
	.recv = pb_rx,
};

/*******************************************************************************
 * Message handlers
 ******************************************************************************/

static int handle_scan_caps_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
				struct net_buf_simple *buf)
{
	BT_MESH_MODEL_BUF_DEFINE(rsp, RPR_OP_SCAN_CAPS_STATUS, 2);
	bt_mesh_model_msg_init(&rsp, RPR_OP_SCAN_CAPS_STATUS);
	net_buf_simple_add_u8(&rsp, CONFIG_BT_MESH_RPR_SRV_SCANNED_ITEMS_MAX);
	net_buf_simple_add_u8(&rsp, true);

	bt_mesh_model_send(srv.mod, ctx, &rsp, NULL, NULL);

	return 0;
}

static int handle_scan_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
			   struct net_buf_simple *buf)
{
	scan_status_send(ctx, BT_MESH_RPR_SUCCESS);

	return 0;
}

static int handle_scan_start(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
			     struct net_buf_simple *buf)
{
	struct bt_mesh_rpr_node cli = RPR_NODE(ctx);
	enum bt_mesh_rpr_status status;
	const uint8_t *uuid = NULL;
	uint8_t max_devs;
	uint8_t timeout;
	int i;

	max_devs = net_buf_simple_pull_u8(buf);
	timeout = net_buf_simple_pull_u8(buf);
	if (!timeout) {
		return -EINVAL;
	}

	if (buf->len == 16) {
		uuid = net_buf_simple_pull_mem(buf, 16);
	} else if (buf->len) {
		return -EINVAL;
	}

	LOG_DBG("max %u devs, %u s %s", max_devs, timeout,
		uuid ? bt_hex(uuid, 16) : "");

	if (max_devs > CONFIG_BT_MESH_RPR_SRV_SCANNED_ITEMS_MAX) {
		status = BT_MESH_RPR_ERR_SCANNING_CANNOT_START;
		goto rsp;
	}

	if (srv.scan.state != BT_MESH_RPR_SCAN_IDLE &&
	    !rpr_node_equal(&cli, &srv.scan.cli)) {
		status = BT_MESH_RPR_ERR_INVALID_STATE;
		goto rsp;
	}

	for (i = 0; i < ARRAY_SIZE(srv.scan.devs); ++i) {
		srv.scan.devs[i].flags = 0;
	}

	if (uuid) {
		srv.scan.state = BT_MESH_RPR_SCAN_SINGLE;

		srv.scan.devs[0].flags = BT_MESH_RPR_UNPROV_ACTIVE;
		memcpy(srv.scan.devs[0].uuid, uuid, 16);
	} else {
		srv.scan.state = BT_MESH_RPR_SCAN_MULTI;
	}

	srv.scan.max_devs =
		(max_devs ? max_devs :
			    CONFIG_BT_MESH_RPR_SRV_SCANNED_ITEMS_MAX);
	srv.scan.cli = cli;
	status = BT_MESH_RPR_SUCCESS;

	atomic_set_bit(srv.flags, SCANNING);
	k_work_reschedule(&srv.scan.timeout, K_SECONDS(timeout));

rsp:
	scan_status_send(ctx, status);

	return 0;
}

static int handle_extended_scan_start(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
				      struct net_buf_simple *buf)
{
	BT_MESH_MODEL_BUF_DEFINE(rsp, RPR_OP_EXTENDED_SCAN_REPORT,
				 19 + CONFIG_BT_MESH_RPR_SRV_AD_DATA_MAX);
	struct bt_mesh_rpr_node cli = RPR_NODE(ctx);
	enum bt_mesh_rpr_status status;
	const uint8_t *uuid;
	uint8_t *ad = NULL;
	uint8_t ad_count;
	uint8_t timeout;
	int i;

	/* According to MshPRTv1.1: 4.4.5.5.1.7, scan reports shall be
	 * sent as segmented messages.
	 */
	ctx->send_rel = true;

	ad_count = net_buf_simple_pull_u8(buf);
	if (buf->len < ad_count || ad_count == 0 || ad_count > 0x10) {
		/* Prohibited */
		return -EINVAL;
	}

	ad = net_buf_simple_pull_mem(buf, ad_count);
	for (i = 0; i < ad_count; ++i) {
		if (ad[i] == BT_DATA_NAME_SHORTENED ||
		    ad[i] == BT_DATA_UUID16_SOME ||
		    ad[i] == BT_DATA_UUID32_SOME ||
		    ad[i] == BT_DATA_UUID128_SOME) {
			return -EINVAL;
		}

		for (int j = 0; j < i; j++) {
			if (ad[i] == ad[j]) {
				/* Duplicate entry */
				return -EINVAL;
			}
		}
	}

	ad_count = MIN(ad_count, CONFIG_BT_MESH_RPR_AD_TYPES_MAX);

	if (!buf->len) {
		const struct bt_mesh_prov *prov = bt_mesh_prov_get();

		LOG_DBG("Self scan");

		/* Want our local info. Could also include additional adv data,
		 * but there's no functionality for this in the mesh stack at
		 * the moment, so we'll only include the URI (if requested)
		 */
		bt_mesh_model_msg_init(&rsp, RPR_OP_EXTENDED_SCAN_REPORT);

		net_buf_simple_add_u8(&rsp, BT_MESH_RPR_SUCCESS);
		net_buf_simple_add_mem(&rsp, prov->uuid, 16);
		net_buf_simple_add_le16(&rsp, prov->oob_info);

		if (prov->uri && get_ad_type(ad, ad_count, BT_DATA_URI)) {
			uint8_t uri_len = strlen(prov->uri);

			if (uri_len < CONFIG_BT_MESH_RPR_SRV_AD_DATA_MAX - 2) {
				net_buf_simple_add_u8(&rsp, uri_len + 1);
				net_buf_simple_add_u8(&rsp, BT_DATA_URI);
				net_buf_simple_add_mem(&rsp, prov->uri,
						       uri_len);
				LOG_DBG("URI added: %s", prov->uri);
			} else {
				LOG_WRN("URI data won't fit in scan report");
			}
		}

		bt_mesh_model_send(mod, ctx, &rsp, NULL, NULL);
		return 0;
	}

	if (buf->len != 17) {
		return -EINVAL;
	}

	uuid = net_buf_simple_pull_mem(buf, 16);
	timeout = net_buf_simple_pull_u8(buf);

	if (IS_ENABLED(CONFIG_BT_MESH_MODEL_LOG_LEVEL_DBG)) {
		struct bt_uuid_128 uuid_repr = { .uuid = { BT_UUID_TYPE_128 } };

		memcpy(uuid_repr.val, uuid, 16);
		LOG_DBG("%s AD types: %s", bt_uuid_str(&uuid_repr.uuid),
			bt_hex(ad, ad_count));
	}

	if (timeout < BT_MESH_RPR_EXT_SCAN_TIME_MIN ||
	    timeout > BT_MESH_RPR_EXT_SCAN_TIME_MAX) {
		LOG_ERR("Invalid extended scan timeout %u", timeout);
		return -EINVAL;
	}

	if (srv.link.state != BT_MESH_RPR_LINK_IDLE) {
		status = BT_MESH_RPR_ERR_LIMITED_RESOURCES;
		goto rsp;
	}

	if (srv.scan.dev && (memcmp(srv.scan.dev->uuid, uuid, 16) ||
			!rpr_node_equal(&srv.scan.cli, &cli))) {
		LOG_WRN("Extended scan fail: Busy");
		status = BT_MESH_RPR_ERR_LIMITED_RESOURCES;
		goto rsp;
	}

	if (srv.scan.state == BT_MESH_RPR_SCAN_IDLE) {
		srv.scan.max_devs = 1;
		srv.scan.devs[0].flags = 0;
	}

	srv.scan.dev = unprov_get(uuid);
	if (!srv.scan.dev) {
		srv.scan.dev = unprov_get(NULL);
		if (!srv.scan.dev) {
			LOG_WRN("Extended scan fail: No memory");
			status = BT_MESH_RPR_ERR_LIMITED_RESOURCES;
			goto rsp;
		}

		memcpy(srv.scan.dev->uuid, uuid, 16);
		srv.scan.dev->oob = 0;
		srv.scan.dev->flags = 0;
	}

	memcpy(srv.scan.ad, ad, ad_count);
	srv.scan.ad_count = ad_count;
	net_buf_simple_reset(srv.scan.adv_data);

	atomic_set_bit(srv.flags, SCANNING);
	atomic_clear_bit(srv.flags, SCAN_EXT_HAS_ADDR);
	srv.scan.dev->flags &= ~BT_MESH_RPR_UNPROV_REPORTED;
	srv.scan.dev->flags |= BT_MESH_RPR_UNPROV_ACTIVE | BT_MESH_RPR_UNPROV_EXT;

	if (srv.scan.state == BT_MESH_RPR_SCAN_IDLE) {
		srv.scan.additional_time = 0;
		srv.scan.cli = cli;
	} else if (k_ticks_to_ms_floor32(
			k_work_delayable_remaining_get(&srv.scan.timeout)) <
			(timeout * MSEC_PER_SEC)) {
		srv.scan.additional_time = 0;
	} else {
		srv.scan.additional_time =
			k_ticks_to_ms_floor32(k_work_delayable_remaining_get(&srv.scan.timeout)) -
			(timeout * MSEC_PER_SEC);
	}

	bt_mesh_scan_active_set(true);
	k_work_reschedule(&srv.scan.timeout, K_SECONDS(timeout));
	return 0;

rsp:
	bt_mesh_model_msg_init(&rsp, RPR_OP_EXTENDED_SCAN_REPORT);
	net_buf_simple_add_u8(&rsp, status);
	net_buf_simple_add_mem(&rsp, uuid, 16);
	bt_mesh_model_send(mod, ctx, &rsp, NULL, NULL);

	return 0;
}

static int handle_scan_stop(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
			    struct net_buf_simple *buf)
{
	if (atomic_test_bit(srv.flags, SCANNING)) {
		scan_report_send();
		scan_stop();
	}

	scan_status_send(ctx, BT_MESH_RPR_SUCCESS);

	return 0;
}

static int handle_link_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
			   struct net_buf_simple *buf)
{
	LOG_DBG("");

	link_status_send(ctx, BT_MESH_RPR_SUCCESS);

	return 0;
}

static int handle_link_open(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
			    struct net_buf_simple *buf)
{
	bool is_refresh_procedure = (buf->len == 1);
	struct bt_mesh_rpr_node cli = RPR_NODE(ctx);
	int8_t timeout = LINK_OPEN_TIMEOUT_DEFAULT;
	enum bt_mesh_rpr_status status;
	const uint8_t *uuid;
	uint8_t refresh;
	int err;

	if (buf->len != 1 && buf->len != 16 && buf->len != 17) {
		return -EINVAL;
	}

	if (srv.link.state == BT_MESH_RPR_LINK_CLOSING ||
	    srv.link.state == BT_MESH_RPR_LINK_SENDING) {
		status = BT_MESH_RPR_ERR_INVALID_STATE;
		LOG_ERR("Invalid state: %u", srv.link.state);
		goto rsp;
	}

	if (srv.link.state == BT_MESH_RPR_LINK_OPENING ||
	    srv.link.state == BT_MESH_RPR_LINK_ACTIVE) {

		if (!rpr_node_equal(&cli, &srv.link.cli)) {
			status = BT_MESH_RPR_ERR_LINK_CANNOT_OPEN;
			goto rsp;
		}

		if (is_refresh_procedure) {
			refresh = net_buf_simple_pull_u8(buf);
			if (!atomic_test_bit(srv.flags, NODE_REFRESH) ||
			    srv.refresh.procedure != refresh) {
				status = BT_MESH_RPR_ERR_LINK_CANNOT_OPEN;
			} else {
				status = BT_MESH_RPR_SUCCESS;
			}

			goto rsp;
		}

		if (atomic_test_bit(srv.flags, NODE_REFRESH)) {
			status = BT_MESH_RPR_ERR_LINK_CANNOT_OPEN;
			goto rsp;
		}

		uuid = net_buf_simple_pull_mem(buf, 16);

		if (memcmp(uuid, srv.link.dev->uuid, 16)) {
			status = BT_MESH_RPR_ERR_LINK_CANNOT_OPEN;
		} else {
			status = BT_MESH_RPR_SUCCESS;
		}

		goto rsp;
	}

	/* Link state is IDLE */

	if (is_refresh_procedure) {
		refresh = net_buf_simple_pull_u8(buf);
		if (refresh > BT_MESH_RPR_NODE_REFRESH_COMPOSITION) {
			LOG_ERR("Invalid refresh: %u", refresh);
			return -EINVAL;
		}

		if (refresh == BT_MESH_RPR_NODE_REFRESH_COMPOSITION &&
		    !atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY)) {
			LOG_WRN("Composition data page 128 is equal to page 0");
			status = BT_MESH_RPR_ERR_LINK_CANNOT_OPEN;
			goto rsp;
		}

		LOG_DBG("Node Refresh: %u", refresh);

		atomic_set_bit(srv.flags, NODE_REFRESH);
		srv.refresh.procedure = refresh;
		srv.link.cli = cli;
		srv.link.rx_pdu = 0;
		srv.link.tx_pdu = 0;
		srv.link.state = BT_MESH_RPR_LINK_ACTIVE;
		srv.link.status = BT_MESH_RPR_SUCCESS;
		srv.refresh.cb->link_opened(&pb_remote_srv, &srv);
		status = BT_MESH_RPR_SUCCESS;
		link_report_send();
		goto rsp;
	}

	uuid = net_buf_simple_pull_mem(buf, 16);
	if (buf->len) {
		timeout = net_buf_simple_pull_u8(buf);
		if (!timeout || timeout > 0x3c) {
			LOG_ERR("Invalid timeout: %u", timeout);
			return -EINVAL;
		}
	}

	LOG_DBG("0x%04x: %s", cli.addr, bt_hex(uuid, 16));

	/* Attempt to reuse the scanned unprovisioned device, to preserve as
	 * much information as possible, but fall back to hijacking the first
	 * slot if none was found.
	 */
	srv.link.dev = unprov_get(uuid);
	if (!srv.link.dev) {
		srv.link.dev = &srv.scan.devs[0];
		memcpy(srv.link.dev->uuid, uuid, 16);
		srv.link.dev->flags = 0;
	}

	err = bt_mesh_pb_adv.link_open(uuid, timeout, &prov_bearer_cb, &srv);
	if (err) {
		status = BT_MESH_RPR_ERR_LINK_CANNOT_OPEN;
		goto rsp;
	}

	srv.link.cli = cli;
	srv.link.rx_pdu = 0;
	srv.link.tx_pdu = 0;
	srv.link.state = BT_MESH_RPR_LINK_OPENING;
	srv.link.status = BT_MESH_RPR_SUCCESS;
	srv.link.dev->flags |= BT_MESH_RPR_UNPROV_HAS_LINK;
	status = BT_MESH_RPR_SUCCESS;

rsp:
	link_status_send(ctx, status);

	return 0;
}

static int handle_link_close(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
			     struct net_buf_simple *buf)
{
	struct bt_mesh_rpr_node cli = RPR_NODE(ctx);
	enum prov_bearer_link_status reason;

	reason = net_buf_simple_pull_u8(buf);
	if (reason != PROV_BEARER_LINK_STATUS_SUCCESS &&
	    reason != PROV_BEARER_LINK_STATUS_FAIL) {
		return -EINVAL;
	}

	LOG_DBG("");

	if (srv.link.state == BT_MESH_RPR_LINK_IDLE ||
	    srv.link.state == BT_MESH_RPR_LINK_CLOSING) {
		link_status_send(ctx, BT_MESH_RPR_SUCCESS);
		return 0;
	}

	if (!rpr_node_equal(&cli, &srv.link.cli)) {
		link_status_send(ctx, BT_MESH_RPR_ERR_INVALID_STATE);
		return 0;
	}

	srv.link.state = BT_MESH_RPR_LINK_CLOSING;

	/* Note: The response status isn't the same as the link status state,
	 * which will be used in the link report when the link is fully closed.
	 */

	/* Disable randomization for the Remote Provisioning Link Status message to avoid reordering
	 * of it with the Remote Provisioning Link Report message that shall be sent in a sequence
	 * when closing an active link (see section 4.4.5.5.3.3 of MshPRTv1.1).
	 */
	ctx->rnd_delay = false;

	link_status_send(ctx, BT_MESH_RPR_SUCCESS);
	link_close(BT_MESH_RPR_ERR_LINK_CLOSED_BY_CLIENT, reason);

	return 0;
}

static int handle_pdu_send(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
			   struct net_buf_simple *buf)
{
	struct bt_mesh_rpr_node cli = RPR_NODE(ctx);
	uint8_t pdu_num;
	int err;

	pdu_num = net_buf_simple_pull_u8(buf);

	if (srv.link.state != BT_MESH_RPR_LINK_ACTIVE) {
		LOG_WRN("Sending PDU while busy (state %u)", srv.link.state);
		return 0;
	}

	if (!rpr_node_equal(&cli, &srv.link.cli)) {
		LOG_WRN("Unknown client 0x%04x", cli.addr);
		return 0;
	}

	if (pdu_num != srv.link.tx_pdu + 1) {
		LOG_WRN("Invalid pdu number: %u, expected %u", pdu_num,
			srv.link.tx_pdu + 1);
		outbound_pdu_report_send();
		return 0;
	}

	LOG_DBG("0x%02x", buf->data[0]);

	if (atomic_test_bit(srv.flags, NODE_REFRESH)) {
		srv.link.tx_pdu++;
		outbound_pdu_report_send();
		srv.refresh.cb->recv(&pb_remote_srv, srv.refresh.cb_data, buf);
	} else {
		srv.link.state = BT_MESH_RPR_LINK_SENDING;
		err = bt_mesh_pb_adv.send(buf, pdu_send_complete, &srv);
		if (err) {
			link_close(
				BT_MESH_RPR_ERR_LINK_CLOSED_AS_CANNOT_SEND_PDU,
				PROV_BEARER_LINK_STATUS_FAIL);
		}
	}

	return 0;
}

const struct bt_mesh_model_op _bt_mesh_rpr_srv_op[] = {
	{ RPR_OP_SCAN_CAPS_GET, BT_MESH_LEN_EXACT(0), handle_scan_caps_get },
	{ RPR_OP_SCAN_GET, BT_MESH_LEN_EXACT(0), handle_scan_get },
	{ RPR_OP_SCAN_START, BT_MESH_LEN_MIN(2), handle_scan_start },
	{ RPR_OP_EXTENDED_SCAN_START, BT_MESH_LEN_MIN(1), handle_extended_scan_start },
	{ RPR_OP_SCAN_STOP, BT_MESH_LEN_EXACT(0), handle_scan_stop },
	{ RPR_OP_LINK_GET, BT_MESH_LEN_EXACT(0), handle_link_get },
	{ RPR_OP_LINK_OPEN, BT_MESH_LEN_MIN(1), handle_link_open },
	{ RPR_OP_LINK_CLOSE, BT_MESH_LEN_EXACT(1), handle_link_close },
	{ RPR_OP_PDU_SEND, BT_MESH_LEN_MIN(1), handle_pdu_send },
	BT_MESH_MODEL_OP_END,
};

static struct bt_mesh_rpr_unprov *
adv_handle_beacon(const struct bt_le_scan_recv_info *info,
		  struct bt_data *ad)
{
	struct bt_uuid_128 uuid_repr = { .uuid = { BT_UUID_TYPE_128 } };
	struct bt_mesh_rpr_unprov *dev = NULL;
	const uint8_t *uuid;

	if (ad->data[0] != 0x00 || (ad->data_len != 19 && ad->data_len != 23)) {
		return NULL;
	}

	uuid = &ad->data[1];

	dev = unprov_get(uuid);
	if (!dev) {
		if (srv.scan.state != BT_MESH_RPR_SCAN_MULTI) {
			return NULL;
		}

		dev = unprov_get(NULL);
		if (!dev) {
			return NULL;
		}

		memcpy(dev->uuid, uuid, 16);
		dev->flags = BT_MESH_RPR_UNPROV_ACTIVE;
	} else if (dev->flags & BT_MESH_RPR_UNPROV_FOUND) {
		return dev;
	}

	dev->oob = sys_get_be16(&ad->data[17]);
	dev->rssi = info->rssi;

	if (ad->data_len == 23) {
		memcpy(&dev->hash, &ad->data[19], 4);
		dev->flags |= BT_MESH_RPR_UNPROV_HASH;
	}

	dev->flags |= BT_MESH_RPR_UNPROV_FOUND;
	memcpy(uuid_repr.val, uuid, 16);

	LOG_DBG("Unprov #%u: %s OOB: 0x%04x %s", dev - &srv.scan.devs[0],
		bt_uuid_str(&uuid_repr.uuid), dev->oob,
		(dev->flags & BT_MESH_RPR_UNPROV_HASH) ? bt_hex(&dev->hash, 4) :
							 "(no hash)");

	if (dev != srv.scan.dev && !(dev->flags & BT_MESH_RPR_UNPROV_REPORTED)) {
		scan_report_schedule();
	}

	return dev;
}

static bool pull_ad_data(struct net_buf_simple *buf, struct bt_data *ad)
{
	uint8_t len;

	if (!buf->len) {
		return false;
	}

	len = net_buf_simple_pull_u8(buf);
	if (!len || len > buf->len) {
		return false;
	}

	ad->type = net_buf_simple_pull_u8(buf);
	ad->data_len = len - sizeof(ad->type);
	ad->data = net_buf_simple_pull_mem(buf, ad->data_len);
	return true;
}

static void adv_handle_ext_scan(const struct bt_le_scan_recv_info *info,
				struct net_buf_simple *buf)
{
	struct bt_mesh_rpr_unprov *dev = NULL;
	struct net_buf_simple_state initial;
	struct bt_data ad;
	bool uri_match = false;
	bool uri_present = false;
	bool is_beacon = false;

	if (atomic_test_bit(srv.flags, SCAN_EXT_HAS_ADDR) &&
	    !bt_addr_le_cmp(&srv.scan.addr, info->addr)) {
		dev = srv.scan.dev;
	}

	/* Do AD data walk in two rounds: First to figure out which
	 * unprovisioned device this is (if any), and the second to copy out
	 * relevant AD data to the extended scan report.
	 */

	net_buf_simple_save(buf, &initial);
	while (pull_ad_data(buf, &ad)) {
		if (ad.type == BT_DATA_URI) {
			uri_present = true;
		}

		if (ad.type == BT_DATA_MESH_BEACON && !dev) {
			dev = adv_handle_beacon(info, &ad);
			is_beacon = true;
		} else if (ad.type == BT_DATA_URI &&
			   (srv.scan.dev->flags & BT_MESH_RPR_UNPROV_HASH)) {
			uint8_t hash[16];

			if (bt_mesh_s1(ad.data, ad.data_len, hash) ||
			    memcmp(hash, &srv.scan.dev->hash, 4)) {
				continue;
			}

			LOG_DBG("Found matching URI");
			uri_match = true;
			dev = srv.scan.dev;
			srv.scan.dev->flags |= BT_MESH_RPR_UNPROV_EXT_ADV_RXD;
		}
	}

	if (uri_match) {
		atomic_set_bit(srv.flags, URI_MATCHED);
	}

	if (!dev) {
		return;
	}

	/* Do not process advertisement if it was not identified by URI hash from beacon */
	if (!(dev->flags & BT_MESH_RPR_UNPROV_EXT_ADV_RXD)) {
		return;
	}

	srv.scan.addr = *info->addr;
	atomic_set_bit(srv.flags, SCAN_EXT_HAS_ADDR);

	if (IS_ENABLED(CONFIG_BT_MESH_DEBUG_MODEL)) {
		struct bt_uuid_128 uuid_repr = { .uuid = { BT_UUID_TYPE_128 } };

		memcpy(uuid_repr.val, dev->uuid, 16);
		LOG_DBG("Is %s", bt_uuid_str(&uuid_repr.uuid));
	}

	net_buf_simple_restore(buf, &initial);

	/* The ADTypeFilter field of the Remote Provisioning Extended Scan Start message
	 * contains only the URI AD Type, and the URI Hash is not available for the device
	 * with the Device UUID that was requested in the Remote Provisioning Extended Scan
	 * Start message.
	 */
	if (srv.scan.ad_count == 1 &&
	    get_ad_type(srv.scan.ad, 1, BT_DATA_URI) &&
	    !uri_match) {
		goto complete;
	}

	while (srv.scan.ad_count && pull_ad_data(buf, &ad)) {
		uint8_t *ad_entry;

		ad_entry = get_ad_type(srv.scan.ad, srv.scan.ad_count, ad.type);
		if (!ad_entry || (ad.type == BT_DATA_URI && !uri_match)) {
			continue;
		}

		LOG_DBG("AD type 0x%02x", ad.type);

		if (ad.type == BT_DATA_URI) {
			atomic_set_bit(srv.flags, URI_REQUESTED);
		}

		if (ad.data_len + 2 >
		    net_buf_simple_tailroom(srv.scan.adv_data)) {
			LOG_WRN("Can't fit AD 0x%02x in scan report", ad.type);
			continue;
		}

		net_buf_simple_add_u8(srv.scan.adv_data, ad.data_len + 1);
		net_buf_simple_add_u8(srv.scan.adv_data, ad.type);
		net_buf_simple_add_mem(srv.scan.adv_data, ad.data, ad.data_len);

		*ad_entry = srv.scan.ad[--srv.scan.ad_count];
	}

	/* The Remote Provisioning Server collects AD structures corresponding to all
	 * AD Types specified in the ADTypeFilter field of the Remote Provisioning Extended
	 * Scan Start message. The timeout specified in the Timeout field of the Remote
	 * Provisioning Extended Scan Start message expires.
	 * OR
	 * The ADTypeFilter field of the Remote Provisioning Extended Scan Start message
	 * contains only the URI AD Type, and the Remote Provisioning Server has received
	 * an advertising report or scan response with the URI corresponding to the URI Hash
	 * of the device with the Device UUID that was requested in the Remote Provisioning
	 * Extended Scan Start message.
	 */
	if (!srv.scan.ad_count) {
		goto complete;
	}

	/* The ADTypeFilter field of the Remote Provisioning Extended Scan Start message does
	 * not contain the URI AD Type, and the Remote Provisioning Server receives and processes
	 * the scan response data from the device with Device UUID requested in the Remote
	 * Provisioning Extended Scan Start message.
	 */
	if (!is_beacon && !uri_present &&
	    info->adv_type == BT_GAP_ADV_TYPE_SCAN_RSP) {
		goto complete;
	}

	/* The ADTypeFilter field of the Remote Provisioning Extended Scan Start message contains
	 * the URI AD Type and at least one different AD Type in the ADTypeFilter field, and the
	 * Remote Provisioning Server has received an advertising report or scan response with the
	 * URI corresponding to the URI Hash of the device with the Device UUID that was requested
	 * in the Remote Provisioning Extended Scan Start message, and the Remote Provisioning
	 * Server received the scan response from the same device.
	 * OR
	 * The ADTypeFilter field of the Remote Provisioning Extended Scan Start message contains
	 * the URI AD Type and at least one different AD Type in the ADTypeFilter field, and the
	 * URI Hash is not available for the device with the Device UUID that was requested in the
	 * Remote Provisioning Extended Scan Start message, and the Remote Provisioning Server
	 * received the scan response from the same device.
	 */
	if (atomic_get(srv.flags) & URI_REQUESTED &&
	    (atomic_get(srv.flags) & URI_MATCHED ||
	    (dev->flags & ~BT_MESH_RPR_UNPROV_HASH)) &&
	    info->adv_type == BT_GAP_ADV_TYPE_SCAN_RSP) {
		goto complete;
	}

	return;
complete:
	srv.scan.additional_time = 0;
	if (srv.scan.state != BT_MESH_RPR_SCAN_MULTI) {
		k_work_cancel_delayable(&srv.scan.timeout);
	}
	scan_ext_stop(0);
}

static void adv_handle_scan(const struct bt_le_scan_recv_info *info,
			    struct net_buf_simple *buf)
{
	struct bt_data ad;

	if (info->adv_type != BT_HCI_ADV_NONCONN_IND) {
		return;
	}

	while (pull_ad_data(buf, &ad)) {
		if (ad.type == BT_DATA_MESH_BEACON) {
			adv_handle_beacon(info, &ad);
			return;
		}
	}
}

static void scan_packet_recv(const struct bt_le_scan_recv_info *info,
			     struct net_buf_simple *buf)
{
	if (!atomic_test_bit(srv.flags, SCANNING)) {
		return;
	}

	if (srv.scan.dev) {
		adv_handle_ext_scan(info, buf);
	} else {
		adv_handle_scan(info, buf);
	}
}

static struct bt_le_scan_cb scan_cb = {
	.recv = scan_packet_recv,
};

static int rpr_srv_init(const struct bt_mesh_model *mod)
{
	if (mod->rt->elem_idx || srv.mod) {
		LOG_ERR("Remote provisioning server must be initialized "
			"on first element");
		return -EINVAL;
	}

	srv.mod = mod;

	net_buf_simple_init(srv.scan.adv_data, 0);

	k_work_init_delayable(&srv.scan.timeout, scan_timeout);
	k_work_init_delayable(&srv.scan.report, scan_report_timeout);
	k_work_init(&srv.link.report, link_report_send_and_clear);
	bt_le_scan_cb_register(&scan_cb);
	mod->keys[0] = BT_MESH_KEY_DEV_LOCAL;
	mod->rt->flags |= BT_MESH_MOD_DEVKEY_ONLY;

	return 0;
}

static void rpr_srv_reset(const struct bt_mesh_model *mod)
{
	cli_link_clear();
	cli_scan_clear();
	srv.scan.state = BT_MESH_RPR_SCAN_IDLE;
	srv.link.state = BT_MESH_RPR_LINK_IDLE;
	k_work_cancel_delayable(&srv.scan.timeout);
	k_work_cancel_delayable(&srv.scan.report);
	net_buf_simple_init(srv.scan.adv_data, 0);
	atomic_clear(srv.flags);
	srv.link.dev = NULL;
	srv.scan.dev = NULL;
}

const struct bt_mesh_model_cb _bt_mesh_rpr_srv_cb = {
	.init = rpr_srv_init,
	.reset = rpr_srv_reset,
};

static int node_refresh_link_accept(const struct prov_bearer_cb *cb,
				    void *cb_data)
{
	srv.refresh.cb = cb;
	srv.refresh.cb_data = cb_data;

	return 0;
}

static void node_refresh_tx_complete(int err, void *cb_data)
{
	if (err) {
		link_close(BT_MESH_RPR_ERR_LINK_CLOSED_AS_CANNOT_SEND_PDU,
			   PROV_BEARER_LINK_STATUS_FAIL);
		return;
	}

	if (srv.refresh.tx.cb) {
		srv.refresh.tx.cb(err, srv.refresh.tx.cb_data);
	}
}

static int node_refresh_buf_send(struct net_buf_simple *buf,
				 prov_bearer_send_complete_t cb, void *cb_data)
{
	static const struct bt_mesh_send_cb send_cb = {
		.end = node_refresh_tx_complete,
	};
	int err;

	if (!atomic_test_bit(srv.flags, NODE_REFRESH)) {
		return -EBUSY;
	}

	srv.refresh.tx.cb = cb;
	srv.refresh.tx.cb_data = cb_data;
	srv.link.rx_pdu++;

	LOG_DBG("%u", srv.link.rx_pdu);

	err = inbound_pdu_send(buf, &send_cb);
	if (err) {
		link_close(BT_MESH_RPR_ERR_LINK_CLOSED_BY_SERVER,
			   PROV_BEARER_LINK_STATUS_FAIL);
	}

	return err;
}

static void node_refresh_clear_tx(void)
{
	/* Nothing can be done */
}

const struct prov_bearer pb_remote_srv = {
	.type = BT_MESH_PROV_REMOTE,

	.link_accept = node_refresh_link_accept,
	.send = node_refresh_buf_send,
	.clear_tx = node_refresh_clear_tx,
};
