/*
 * 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 "adv.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 {
	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
		 * Mesh Profile specification, section 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(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(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(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(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 the Bluetooth Mesh specification, section 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(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(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(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(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.
	 */

	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(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(struct bt_mesh_model *mod)
{
	if (mod->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->flags |= BT_MESH_MOD_DEVKEY_ONLY;

	return 0;
}

static void rpr_srv_reset(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,
};
