/*
 * Copyright (c) 2017 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdint.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/iterable_sections.h>
#include <zephyr/net/buf.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/mesh.h>

#include "crypto.h"
#include "mesh.h"
#include "net.h"
#include "transport.h"
#include "heartbeat.h"
#include "access.h"
#include "beacon.h"
#include "foundation.h"
#include "lpn.h"

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

/**
 * Log modes other than the deferred may cause unintended delays during processing of log messages.
 * This in turns will affect scheduling of the receive delay and receive window.
 */
#if !defined(CONFIG_TEST) && !defined(CONFIG_ARCH_POSIX) && \
	defined(CONFIG_LOG) && !defined(CONFIG_LOG_MODE_DEFERRED) && \
	(LOG_LEVEL >= LOG_LEVEL_INF)
#warning Frienship feature may work unstable when non-deferred log mode is selected. Use the \
	 CONFIG_LOG_MODE_DEFERRED Kconfig option when Low Power node feature is enabled.
#endif

#if defined(CONFIG_BT_MESH_ADV_LEGACY)
#define RX_DELAY_CORRECTION(lpn) ((lpn)->adv_duration)
#else
#define RX_DELAY_CORRECTION(lpn) 0
#endif

#if defined(CONFIG_BT_MESH_LPN_AUTO)
#define LPN_AUTO_TIMEOUT (CONFIG_BT_MESH_LPN_AUTO_TIMEOUT * MSEC_PER_SEC)
#else
#define LPN_AUTO_TIMEOUT 0
#endif

#define LPN_RECV_DELAY            CONFIG_BT_MESH_LPN_RECV_DELAY
#define SCAN_LATENCY              MIN(CONFIG_BT_MESH_LPN_SCAN_LATENCY, \
				      LPN_RECV_DELAY)

#define FRIEND_REQ_RETRY_TIMEOUT  K_SECONDS(CONFIG_BT_MESH_LPN_RETRY_TIMEOUT)

#define FRIEND_REQ_WAIT           100
#define FRIEND_REQ_SCAN           (1 * MSEC_PER_SEC)
#define FRIEND_REQ_TIMEOUT        (FRIEND_REQ_WAIT + FRIEND_REQ_SCAN)

#define POLL_RETRY_TIMEOUT        100

#define REQ_RETRY_DURATION(lpn)   (LPN_RECV_DELAY + (lpn)->adv_duration + \
				      (lpn)->recv_win + POLL_RETRY_TIMEOUT)

#define POLL_TIMEOUT_INIT         (CONFIG_BT_MESH_LPN_INIT_POLL_TIMEOUT * 100)

#define POLL_TIMEOUT              (CONFIG_BT_MESH_LPN_POLL_TIMEOUT * 100)

#define REQ_ATTEMPTS_MAX          6
#define REQ_ATTEMPTS(lpn)         MIN(REQ_ATTEMPTS_MAX, \
			  POLL_TIMEOUT / REQ_RETRY_DURATION(lpn))

#define POLL_TIMEOUT_MAX(lpn)     (POLL_TIMEOUT - \
			  (REQ_ATTEMPTS(lpn) * REQ_RETRY_DURATION(lpn)))

#define CLEAR_ATTEMPTS            3

#define LPN_CRITERIA ((CONFIG_BT_MESH_LPN_MIN_QUEUE_SIZE) | \
		      (CONFIG_BT_MESH_LPN_RSSI_FACTOR << 3) | \
		      (CONFIG_BT_MESH_LPN_RECV_WIN_FACTOR << 5))

#define POLL_TO(to) { (uint8_t)((to) >> 16), (uint8_t)((to) >> 8), (uint8_t)(to) }
#define LPN_POLL_TO POLL_TO(CONFIG_BT_MESH_LPN_POLL_TIMEOUT)

/* 1 transmission, 20ms interval */
#define POLL_XMIT BT_MESH_TRANSMIT(0, 20)

#if defined(CONFIG_BT_MESH_LOW_POWER_LOG_LEVEL_DBG)
static const char *state2str(int state)
{
	switch (state) {
	case BT_MESH_LPN_DISABLED:
		return "disabled";
	case BT_MESH_LPN_CLEAR:
		return "clear";
	case BT_MESH_LPN_TIMER:
		return "timer";
	case BT_MESH_LPN_ENABLED:
		return "enabled";
	case BT_MESH_LPN_REQ_WAIT:
		return "req wait";
	case BT_MESH_LPN_WAIT_OFFER:
		return "wait offer";
	case BT_MESH_LPN_ESTABLISHED:
		return "established";
	case BT_MESH_LPN_RECV_DELAY:
		return "recv delay";
	case BT_MESH_LPN_WAIT_UPDATE:
		return "wait update";
	default:
		return "(unknown)";
	}
}
#endif /* CONFIG_BT_MESH_LOW_POWER_LOG_LEVEL_DBG */

static int32_t poll_timeout(struct bt_mesh_lpn *lpn)
{
	/* If we're waiting for segment acks keep polling at high freq */
	if (bt_mesh_tx_in_progress()) {
		LOG_DBG("Tx is in progress. Keep polling");
		return MIN(POLL_TIMEOUT_MAX(lpn), 1 * MSEC_PER_SEC);
	}

	if (lpn->poll_timeout < POLL_TIMEOUT_MAX(lpn)) {
		lpn->poll_timeout *= 2;
		lpn->poll_timeout =
			MIN(lpn->poll_timeout, POLL_TIMEOUT_MAX(lpn));
	}

	LOG_DBG("Poll Timeout is %ums", lpn->poll_timeout);

	return lpn->poll_timeout;
}

static inline void lpn_set_state(int state)
{
#if defined(CONFIG_BT_MESH_LOW_POWER_LOG_LEVEL_DBG)
	LOG_DBG("%s -> %s", state2str(bt_mesh.lpn.state), state2str(state));
#endif
	bt_mesh.lpn.state = state;
}

static inline void group_zero(atomic_t *target)
{
#if CONFIG_BT_MESH_LPN_GROUPS > 32
	int i;

	for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) {
		atomic_set(&target[i], 0);
	}
#else
	atomic_set(target, 0);
#endif
}

static inline void group_set(atomic_t *target, atomic_t *source)
{
#if CONFIG_BT_MESH_LPN_GROUPS > 32
	int i;

	for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) {
		(void)atomic_or(&target[i], atomic_get(&source[i]));
	}
#else
	(void)atomic_or(target, atomic_get(source));
#endif
}

static inline void group_clear(atomic_t *target, atomic_t *source)
{
#if CONFIG_BT_MESH_LPN_GROUPS > 32
	int i;

	for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) {
		(void)atomic_and(&target[i], ~atomic_get(&source[i]));
	}
#else
	(void)atomic_and(target, ~atomic_get(source));
#endif
}

static void clear_friendship(bool force, bool disable);

static void friend_clear_sent(int err, void *user_data)
{
	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;

	bt_mesh_scan_enable();

	lpn->req_attempts++;

	if (err) {
		LOG_ERR("Sending Friend Request failed (err %d)", err);
		lpn_set_state(BT_MESH_LPN_ENABLED);
		clear_friendship(false, lpn->disable);
		return;
	}

	lpn_set_state(BT_MESH_LPN_CLEAR);
	k_work_reschedule(&lpn->timer, K_MSEC(FRIEND_REQ_TIMEOUT));
}

static const struct bt_mesh_send_cb clear_sent_cb = {
	.end = friend_clear_sent,
};

static int send_friend_clear(void)
{
	struct bt_mesh_msg_ctx ctx = {
		.net_idx     = bt_mesh.lpn.sub->net_idx,
		.app_idx     = BT_MESH_KEY_UNUSED,
		.addr        = bt_mesh.lpn.frnd,
		.send_ttl    = 0,
	};
	struct bt_mesh_net_tx tx = {
		.sub = bt_mesh.lpn.sub,
		.ctx = &ctx,
		.src = bt_mesh_primary_addr(),
		.xmit = bt_mesh_net_transmit_get(),
	};
	struct bt_mesh_ctl_friend_clear req = {
		.lpn_addr    = sys_cpu_to_be16(tx.src),
		.lpn_counter = sys_cpu_to_be16(bt_mesh.lpn.lpn_counter),
	};

	LOG_DBG("");

	return bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_CLEAR, &req,
				sizeof(req), &clear_sent_cb, NULL);
}

static void clear_friendship(bool force, bool disable)
{
	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
	bool was_established = lpn->established;
	uint16_t frnd = lpn->frnd;
	uint16_t net_idx = lpn->sub->net_idx;

	LOG_DBG("force %u disable %u", force, disable);

	if (!force && lpn->established && !lpn->clear_success &&
	    lpn->req_attempts < CLEAR_ATTEMPTS) {
		send_friend_clear();
		lpn->disable = disable;
		return;
	}

	bt_mesh_rx_reset();

	/* Disable LPN while clearing, in case the work handler gets a chance to fire. */
	lpn_set_state(BT_MESH_LPN_DISABLED);
	/* The timer handler returns without any actions if this fails. */
	(void)k_work_cancel_delayable(&lpn->timer);

	if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT) || disable) {
		bt_mesh_scan_disable();
	}

	if (lpn->clear_success) {
		lpn->old_friend = BT_MESH_ADDR_UNASSIGNED;
	} else {
		lpn->old_friend = lpn->frnd;
	}

	for (int i = 0; i < ARRAY_SIZE(lpn->cred); i++) {
		if (lpn->sub->keys[i].valid) {
			bt_mesh_friend_cred_destroy(&lpn->cred[i]);
		}
	}

	lpn->frnd = BT_MESH_ADDR_UNASSIGNED;
	lpn->fsn = 0U;
	lpn->req_attempts = 0U;
	lpn->recv_win = 0U;
	lpn->queue_size = 0U;
	lpn->disable = 0U;
	lpn->sent_req = 0U;
	lpn->established = 0U;
	lpn->clear_success = 0U;
	lpn->sub = NULL;

	group_zero(lpn->added);
	group_zero(lpn->pending);
	group_zero(lpn->to_remove);

	/* Set this to 1 to force group subscription when the next
	 * Friendship is created, in case lpn->groups doesn't get
	 * modified meanwhile.
	 */
	lpn->groups_changed = 1U;

	bt_mesh_hb_feature_changed(BT_MESH_FEAT_LOW_POWER);

	if (!disable) {
		lpn_set_state(BT_MESH_LPN_ENABLED);

		if (!IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
			bt_mesh_scan_enable();
		}

		k_work_reschedule(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT);
	}

	if (was_established) {
		STRUCT_SECTION_FOREACH(bt_mesh_lpn_cb, cb) {
			if (cb->terminated) {
				cb->terminated(net_idx, frnd);
			}
		}
	}
}

static void friend_req_send_end(int err, void *user_data)
{
	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;

	if (lpn->state != BT_MESH_LPN_ENABLED) {
		return;
	}

	if (err) {
		LOG_ERR("Sending Friend Request failed (err %d)", err);
		return;
	}

	lpn->adv_duration = k_uptime_get_32() - lpn->adv_start_time;

	if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
		k_work_reschedule(&lpn->timer,
				  K_MSEC(FRIEND_REQ_WAIT - (int32_t)lpn->adv_duration));
		lpn_set_state(BT_MESH_LPN_REQ_WAIT);
	} else {
		k_work_reschedule(&lpn->timer, K_MSEC(FRIEND_REQ_TIMEOUT));
		lpn_set_state(BT_MESH_LPN_WAIT_OFFER);
	}
}

static void friend_req_send_start(uint16_t duration, int err, void *user_data)
{
	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;

	lpn->adv_start_time = k_uptime_get_32();

	if (err) {
		friend_req_send_end(err, user_data);
	}
}

static const struct bt_mesh_send_cb friend_req_send_cb = {
	.start = friend_req_send_start,
	.end = friend_req_send_end,
};

static int send_friend_req(struct bt_mesh_lpn *lpn)
{
	const struct bt_mesh_comp *comp = bt_mesh_comp_get();
	struct bt_mesh_msg_ctx ctx = {
		.app_idx  = BT_MESH_KEY_UNUSED,
		.addr     = BT_MESH_ADDR_FRIENDS,
		.send_ttl = 0,
	};
	struct bt_mesh_net_tx tx = {
		.ctx = &ctx,
		.src = bt_mesh_primary_addr(),
		.xmit = POLL_XMIT,
	};

	lpn->lpn_counter++;

	struct bt_mesh_ctl_friend_req req = {
		.criteria    = LPN_CRITERIA,
		.recv_delay  = LPN_RECV_DELAY,
		.poll_to     = LPN_POLL_TO,
		.prev_addr   = sys_cpu_to_be16(lpn->old_friend),
		.num_elem    = comp->elem_count,
		.lpn_counter = sys_cpu_to_be16(lpn->lpn_counter),
	};

	LOG_DBG("");

	lpn->sub = bt_mesh_subnet_next(NULL);
	if (!lpn->sub) {
		LOG_ERR("No subnets, can't start LPN mode");
		return -ENOENT;
	}

	ctx.net_idx = lpn->sub->net_idx;
	tx.sub = lpn->sub;

	return bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_REQ, &req,
				sizeof(req), &friend_req_send_cb, NULL);
}

static void req_send_end(int err, void *user_data)
{
	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
	bool retry;

	if (lpn->state == BT_MESH_LPN_DISABLED) {
		return;
	}

	lpn->adv_duration = k_uptime_get_32() - lpn->adv_start_time;

#if defined(CONFIG_BT_MESH_LOW_POWER_LOG_LEVEL_DBG)
	LOG_DBG("req 0x%02x duration %u err %d state %s", lpn->sent_req, lpn->adv_duration, err,
		state2str(lpn->state));
#endif

	if (err) {
		LOG_ERR("Sending request failed (err %d)", err);
		lpn->sent_req = 0U;
		group_zero(lpn->pending);
		return;
	}

	retry = (lpn->req_attempts > 0);

	lpn->req_attempts++;

	if (lpn->established || IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
		lpn_set_state(BT_MESH_LPN_RECV_DELAY);
		/* We start scanning a bit early to eliminate risk of missing
		 * response data due to HCI and other latencies.
		 */
		k_work_reschedule(&lpn->timer,
				  K_MSEC(LPN_RECV_DELAY - SCAN_LATENCY - RX_DELAY_CORRECTION(lpn)));
	} else {
		lpn_set_state(BT_MESH_LPN_WAIT_UPDATE);
		k_work_reschedule(&lpn->timer, K_MSEC(LPN_RECV_DELAY + lpn->recv_win));
	}

	STRUCT_SECTION_FOREACH(bt_mesh_lpn_cb, cb) {
		if (cb->polled) {
			cb->polled(lpn->sub->net_idx, lpn->frnd, retry);
		}
	}
}

static void req_send_start(uint16_t duration, int err, void *user_data)
{
	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;

	lpn->adv_start_time = k_uptime_get_32();

	if (err) {
		req_send_end(err, user_data);
	}
}

static const struct bt_mesh_send_cb req_send_cb = {
	.start = req_send_start,
	.end = req_send_end,
};

static int send_friend_poll(void)
{
	struct bt_mesh_msg_ctx ctx = {
		.net_idx     = bt_mesh.lpn.sub->net_idx,
		.app_idx     = BT_MESH_KEY_UNUSED,
		.addr        = bt_mesh.lpn.frnd,
		.send_ttl    = 0,
	};
	struct bt_mesh_net_tx tx = {
		.sub = bt_mesh.lpn.sub,
		.ctx = &ctx,
		.src = bt_mesh_primary_addr(),
		.xmit = POLL_XMIT,
		.friend_cred = true,
	};
	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
	uint8_t fsn = lpn->fsn;
	int err;

	LOG_DBG("lpn->sent_req 0x%02x", lpn->sent_req);

	if (lpn->sent_req) {
		if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) {
			lpn->pending_poll = 1U;
		}

		return 0;
	}

	err = bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_POLL, &fsn, 1,
			       &req_send_cb, NULL);
	if (err == 0) {
		lpn->pending_poll = 0U;
		lpn->sent_req = TRANS_CTL_OP_FRIEND_POLL;
	}

	return err;
}

void bt_mesh_lpn_disable(bool force)
{
	if (bt_mesh.lpn.state == BT_MESH_LPN_DISABLED) {
		return;
	}

	clear_friendship(force, true);
}

int bt_mesh_lpn_set(bool enable)
{
	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;

	if (enable) {
		if (lpn->state != BT_MESH_LPN_DISABLED) {
			return 0;
		}
	} else {
		if (lpn->state == BT_MESH_LPN_DISABLED) {
			return 0;
		}
	}

	if (!bt_mesh_is_provisioned()) {
		if (enable) {
			lpn_set_state(BT_MESH_LPN_ENABLED);
		} else {
			lpn_set_state(BT_MESH_LPN_DISABLED);
		}

		return 0;
	}

	if (enable) {
		lpn_set_state(BT_MESH_LPN_ENABLED);

		if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
			bt_mesh_scan_disable();
		}

		send_friend_req(lpn);
	} else {
		if (IS_ENABLED(CONFIG_BT_MESH_LPN_AUTO) &&
		    lpn->state == BT_MESH_LPN_TIMER) {
			/* If this fails, the work handler will just exit on the
			 * next timeout.
			 */
			(void)k_work_cancel_delayable(&lpn->timer);
			lpn_set_state(BT_MESH_LPN_DISABLED);
		} else {
			bt_mesh_lpn_disable(false);
		}
	}

	return 0;
}

void bt_mesh_lpn_friendship_end(void)
{
	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;

	if (!lpn->established) {
		return;
	}

	clear_friendship(true, false);
}

static void friend_response_received(struct bt_mesh_lpn *lpn)
{
	LOG_DBG("lpn->sent_req 0x%02x", lpn->sent_req);

	if (lpn->sent_req == TRANS_CTL_OP_FRIEND_POLL) {
		lpn->fsn++;
	}

	bt_mesh_scan_disable();
	lpn_set_state(BT_MESH_LPN_ESTABLISHED);
	lpn->req_attempts = 0U;
	lpn->sent_req = 0U;

	/* Schedule the next poll. This may be overridden by additional
	 * processing of the received response.
	 */
	int32_t timeout = poll_timeout(lpn);

	k_work_reschedule(&lpn->timer, K_MSEC(timeout));
}

void bt_mesh_lpn_msg_received(struct bt_mesh_net_rx *rx)
{
	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;

	if (lpn->state == BT_MESH_LPN_TIMER) {
		LOG_DBG("Restarting establishment timer");
		k_work_reschedule(&lpn->timer, K_MSEC(LPN_AUTO_TIMEOUT));
		return;
	}

	/* If the message was a Friend control message, it's possible that a
	 * Poll was already queued for sending. In this case, we're already in
	 * a different state.
	 */
	if (lpn->state != BT_MESH_LPN_WAIT_UPDATE) {
		return;
	}

	if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) {
		LOG_WRN("Unexpected message without a preceding Poll");
		return;
	}

	friend_response_received(lpn);

	LOG_DBG("Requesting more messages from Friend");

	send_friend_poll();
}

static int friend_cred_create(struct bt_mesh_net_cred *cred, const struct bt_mesh_key *key)
{
	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;

	return bt_mesh_friend_cred_create(cred, bt_mesh_primary_addr(),
					  lpn->frnd, lpn->lpn_counter,
					  lpn->frnd_counter, key);
}

int bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx,
			     struct net_buf_simple *buf)
{
	struct bt_mesh_ctl_friend_offer *msg = (void *)buf->data;
	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
	uint16_t frnd_counter;
	int err;

	if (buf->len < sizeof(*msg)) {
		LOG_WRN("Too short Friend Offer");
		return -EBADMSG;
	}

	if (lpn->state != BT_MESH_LPN_WAIT_OFFER) {
		LOG_WRN("Ignoring unexpected Friend Offer");
		return 0;
	}

	if (!msg->recv_win) {
		LOG_WRN("Prohibited ReceiveWindow value");
		return -EBADMSG;
	}

	frnd_counter = sys_be16_to_cpu(msg->frnd_counter);

	LOG_DBG("recv_win %u queue_size %u sub_list_size %u rssi %d counter %u", msg->recv_win,
		msg->queue_size, msg->sub_list_size, msg->rssi, frnd_counter);

	lpn->frnd_counter = frnd_counter;
	lpn->frnd = rx->ctx.addr;

	/* Create friend credentials for each of the valid keys in the
	 * friendship subnet:
	 */
	for (int i = 0; i < ARRAY_SIZE(lpn->cred); i++) {
		if (!lpn->sub->keys[i].valid) {
			continue;
		}

		err = friend_cred_create(&lpn->cred[i], &lpn->sub->keys[i].net);
		if (err) {
			lpn->frnd = BT_MESH_ADDR_UNASSIGNED;
			return err;
		}
	}

	/* TODO: Add offer acceptance criteria check */

	lpn->recv_win = msg->recv_win;
	lpn->queue_size = msg->queue_size;

	err = send_friend_poll();
	if (err) {
		LOG_WRN("LPN didn't succeed poll sending (err %d)", err);
		for (int i = 0; i < ARRAY_SIZE(lpn->cred); i++) {
			if (lpn->sub->keys[i].valid) {
				bt_mesh_friend_cred_destroy(&lpn->cred[i]);
			}
		}

		lpn->sub = NULL;
		lpn->frnd = BT_MESH_ADDR_UNASSIGNED;
		lpn->recv_win = 0U;
		lpn->queue_size = 0U;
	}

	return 0;
}

int bt_mesh_lpn_friend_clear_cfm(struct bt_mesh_net_rx *rx,
				 struct net_buf_simple *buf)
{
	struct bt_mesh_ctl_friend_clear_confirm *msg = (void *)buf->data;
	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
	uint16_t addr, counter;

	if (buf->len < sizeof(*msg)) {
		LOG_WRN("Too short Friend Clear Confirm");
		return -EBADMSG;
	}

	if (lpn->state != BT_MESH_LPN_CLEAR) {
		LOG_WRN("Ignoring unexpected Friend Clear Confirm");
		return 0;
	}

	addr = sys_be16_to_cpu(msg->lpn_addr);
	counter = sys_be16_to_cpu(msg->lpn_counter);

	LOG_DBG("LPNAddress 0x%04x LPNCounter 0x%04x", addr, counter);

	if (addr != bt_mesh_primary_addr() || counter != lpn->lpn_counter) {
		LOG_WRN("Invalid parameters in Friend Clear Confirm");
		return 0;
	}

	lpn->clear_success = 1U;
	clear_friendship(false, lpn->disable);

	return 0;
}

static void lpn_group_add(uint16_t group)
{
	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
	uint16_t *free_slot = NULL;
	int i;

	for (i = 0; i < ARRAY_SIZE(lpn->groups); i++) {
		if (lpn->groups[i] == group) {
			atomic_clear_bit(lpn->to_remove, i);
			return;
		}

		if (!free_slot && lpn->groups[i] == BT_MESH_ADDR_UNASSIGNED) {
			free_slot = &lpn->groups[i];
		}
	}

	if (!free_slot) {
		LOG_WRN("Friend Subscription List exceeded!");
		return;
	}

	*free_slot = group;
	lpn->groups_changed = 1U;
}

static void lpn_group_del(uint16_t group)
{
	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
	int i;

	for (i = 0; i < ARRAY_SIZE(lpn->groups); i++) {
		if (lpn->groups[i] == group) {
			if (atomic_test_bit(lpn->added, i) ||
			    atomic_test_bit(lpn->pending, i)) {
				atomic_set_bit(lpn->to_remove, i);
				lpn->groups_changed = 1U;
			} else {
				lpn->groups[i] = BT_MESH_ADDR_UNASSIGNED;
			}
		}
	}
}

static inline int group_popcount(atomic_t *target)
{
#if CONFIG_BT_MESH_LPN_GROUPS > 32
	int i, count = 0;

	for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) {
		count += POPCOUNT(atomic_get(&target[i]));
	}
#else
	return POPCOUNT(atomic_get(target));
#endif
}

static bool sub_update(uint8_t op)
{
	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
	int added_count = group_popcount(lpn->added);
	struct bt_mesh_msg_ctx ctx = {
		.net_idx     = lpn->sub->net_idx,
		.app_idx     = BT_MESH_KEY_UNUSED,
		.addr        = lpn->frnd,
		.send_ttl    = 0,
	};
	struct bt_mesh_net_tx tx = {
		.sub = lpn->sub,
		.ctx = &ctx,
		.src = bt_mesh_primary_addr(),
		.xmit = POLL_XMIT,
		.friend_cred = true,
	};
	struct bt_mesh_ctl_friend_sub req;
	size_t i, g;

	LOG_DBG("op 0x%02x sent_req 0x%02x", op, lpn->sent_req);

	if (lpn->sent_req) {
		return false;
	}

	for (i = 0, g = 0; i < ARRAY_SIZE(lpn->groups); i++) {
		if (lpn->groups[i] == BT_MESH_ADDR_UNASSIGNED) {
			continue;
		}

		if (op == TRANS_CTL_OP_FRIEND_SUB_ADD) {
			if (atomic_test_bit(lpn->added, i)) {
				continue;
			}
		} else {
			if (!atomic_test_bit(lpn->to_remove, i)) {
				continue;
			}
		}

		if (added_count + g >= lpn->queue_size) {
			LOG_WRN("Friend Queue Size exceeded");
			break;
		}

		req.addr_list[g++] = sys_cpu_to_be16(lpn->groups[i]);
		atomic_set_bit(lpn->pending, i);

		if (g == ARRAY_SIZE(req.addr_list)) {
			break;
		}
	}

	if (g == 0) {
		group_zero(lpn->pending);
		return false;
	}

	req.xact = lpn->xact_next++;

	if (bt_mesh_ctl_send(&tx, op, &req, 1 + g * 2,
			     &req_send_cb, NULL) < 0) {
		group_zero(lpn->pending);
		return false;
	}

	lpn->xact_pending = req.xact;
	lpn->sent_req = op;
	return true;
}

static void update_timeout(struct bt_mesh_lpn *lpn)
{
	if (lpn->established) {
		LOG_WRN("No response from Friend during ReceiveWindow");
		bt_mesh_scan_disable();
		lpn_set_state(BT_MESH_LPN_ESTABLISHED);
		k_work_reschedule(&lpn->timer, K_MSEC(POLL_RETRY_TIMEOUT));
	} else {
		if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
			bt_mesh_scan_disable();
		}

		if (lpn->req_attempts < REQ_ATTEMPTS(lpn)) {
			LOG_WRN("Retrying first Friend Poll");
			lpn->sent_req = 0U;
			if (send_friend_poll() == 0) {
				return;
			}
		}

		LOG_ERR("Timed out waiting for first Friend Update");
		clear_friendship(false, false);
	}
}

static void lpn_timeout(struct k_work *work)
{
	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;

#if defined(CONFIG_BT_MESH_LOW_POWER_LOG_LEVEL_DBG)
	LOG_DBG("state: %s", state2str(lpn->state));
#endif

	switch (lpn->state) {
	case BT_MESH_LPN_DISABLED:
		break;
	case BT_MESH_LPN_CLEAR:
		clear_friendship(false, bt_mesh.lpn.disable);
		break;
	case BT_MESH_LPN_TIMER:
		LOG_DBG("Starting to look for Friend nodes");
		lpn_set_state(BT_MESH_LPN_ENABLED);
		if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
			bt_mesh_scan_disable();
		}
		__fallthrough;
	case BT_MESH_LPN_ENABLED:
		send_friend_req(lpn);
		break;
	case BT_MESH_LPN_REQ_WAIT:
		bt_mesh_scan_enable();
		k_work_reschedule(&lpn->timer, K_MSEC(lpn->adv_duration + FRIEND_REQ_SCAN));
		lpn_set_state(BT_MESH_LPN_WAIT_OFFER);
		break;
	case BT_MESH_LPN_WAIT_OFFER:
		LOG_WRN("No acceptable Friend Offers received");
		if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
			bt_mesh_scan_disable();
		}

		lpn_set_state(BT_MESH_LPN_ENABLED);
		lpn->sent_req = 0U;
		k_work_reschedule(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT);
		break;
	case BT_MESH_LPN_ESTABLISHED:
		if (lpn->req_attempts < REQ_ATTEMPTS(lpn)) {
			uint8_t req = lpn->sent_req;

			lpn->sent_req = 0U;

			if (!req || req == TRANS_CTL_OP_FRIEND_POLL) {
				send_friend_poll();
			} else {
				sub_update(req);
			}

			break;
		}

		LOG_ERR("No response from Friend after %u retries", lpn->req_attempts);
		lpn->req_attempts = 0U;
		clear_friendship(true, false);
		break;
	case BT_MESH_LPN_RECV_DELAY:
		k_work_reschedule(&lpn->timer,
				  K_MSEC(SCAN_LATENCY + lpn->recv_win + RX_DELAY_CORRECTION(lpn)));
		bt_mesh_scan_enable();
		lpn_set_state(BT_MESH_LPN_WAIT_UPDATE);
		break;
	case BT_MESH_LPN_WAIT_UPDATE:
		update_timeout(lpn);
		break;
	default:
		__ASSERT(0, "Unhandled LPN state");
		break;
	}
}

void bt_mesh_lpn_group_add(uint16_t group)
{
	LOG_DBG("group 0x%04x", group);

	lpn_group_add(group);

	if (!bt_mesh_lpn_established() || bt_mesh.lpn.sent_req) {
		return;
	}

	sub_update(TRANS_CTL_OP_FRIEND_SUB_ADD);
}

void bt_mesh_lpn_group_del(const uint16_t *groups, size_t group_count)
{
	int i;

	for (i = 0; i < group_count; i++) {
		if (groups[i] != BT_MESH_ADDR_UNASSIGNED) {
			LOG_DBG("group 0x%04x", groups[i]);
			lpn_group_del(groups[i]);
		}
	}

	if (!bt_mesh_lpn_established() || bt_mesh.lpn.sent_req) {
		return;
	}

	sub_update(TRANS_CTL_OP_FRIEND_SUB_REM);
}

int bt_mesh_lpn_friend_sub_cfm(struct bt_mesh_net_rx *rx,
			       struct net_buf_simple *buf)
{
	struct bt_mesh_ctl_friend_sub_confirm *msg = (void *)buf->data;
	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;

	if (buf->len < sizeof(*msg)) {
		LOG_WRN("Too short Friend Subscription Confirm");
		return -EBADMSG;
	}

	LOG_DBG("xact 0x%02x", msg->xact);

	if (!lpn->sent_req) {
		LOG_WRN("No pending subscription list message");
		return 0;
	}

	if (msg->xact != lpn->xact_pending) {
		LOG_WRN("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 {
		LOG_WRN("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 = 0U;
		}
	}

	if (lpn->pending_poll) {
		send_friend_poll();
	}

	return 0;
}

int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx,
			      struct net_buf_simple *buf)
{
	struct bt_mesh_ctl_friend_update *msg = (void *)buf->data;
	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
	struct bt_mesh_subnet *sub = rx->sub;
	uint32_t iv_index;
	bool established = false;

	if (buf->len < sizeof(*msg)) {
		LOG_WRN("Too short Friend Update");
		return -EBADMSG;
	}

	if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) {
		LOG_WRN("Unexpected friend update");
		return 0;
	}

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

	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(msg->flags))) {
		bt_mesh_beacon_ivu_initiator(false);
	}

	if (!lpn->established) {
		/* This is normally checked on the transport layer, however
		 * in this state we're also still accepting flooding
		 * credentials so we need to ensure the right ones (Friend
		 * Credentials) were used for this message.
		 */
		if (!rx->friend_cred) {
			LOG_WRN("Friend Update with wrong credentials");
			return -EINVAL;
		}

		lpn->established = 1U;

		LOG_INF("Friendship established with 0x%04x", lpn->frnd);

		bt_mesh_hb_feature_changed(BT_MESH_FEAT_LOW_POWER);

		/* Set initial poll timeout */
		lpn->poll_timeout = MIN(POLL_TIMEOUT_MAX(lpn),
					POLL_TIMEOUT_INIT);

		established = true;
	}

	friend_response_received(lpn);

	iv_index = sys_be32_to_cpu(msg->iv_index);

	LOG_DBG("flags 0x%02x iv_index 0x%08x md %u", msg->flags, iv_index, msg->md);

	bt_mesh_kr_update(sub, BT_MESH_KEY_REFRESH(msg->flags), rx->new_key);
	bt_mesh_net_iv_update(iv_index, BT_MESH_IV_UPDATE(msg->flags));

	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 = 0U;
		}
	}

	if (msg->md) {
		LOG_DBG("Requesting for more messages");
		send_friend_poll();
	}

	if (established) {
		STRUCT_SECTION_FOREACH(bt_mesh_lpn_cb, cb) {
			if (cb->established) {
				cb->established(lpn->sub->net_idx, lpn->frnd, lpn->queue_size,
						lpn->recv_win);
			}
		}
	}

	return 0;
}

int bt_mesh_lpn_poll(void)
{
	if (!bt_mesh.lpn.established) {
		return -EAGAIN;
	}

	LOG_DBG("Requesting more messages");

	return send_friend_poll();
}

static void subnet_evt(struct bt_mesh_subnet *sub, enum bt_mesh_key_evt evt)
{
	switch (evt) {
	case BT_MESH_KEY_DELETED:
		if (sub == bt_mesh.lpn.sub) {
			LOG_DBG("NetKey deleted");
			clear_friendship(true, false);
		}
		break;
	case BT_MESH_KEY_UPDATED:
		LOG_DBG("NetKey updated");
		friend_cred_create(&bt_mesh.lpn.cred[1], &sub->keys[1].net);
		break;
	default:
		break;
	}
}

BT_MESH_SUBNET_CB_DEFINE(lpn) = {
	.evt_handler = subnet_evt,
};

int bt_mesh_lpn_init(void)
{
	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;

	LOG_DBG("");

	k_work_init_delayable(&lpn->timer, lpn_timeout);

	if (lpn->state == BT_MESH_LPN_ENABLED) {
		if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
			bt_mesh_scan_disable();
		} else {
			bt_mesh_scan_enable();
		}

		send_friend_req(lpn);
	} else {
		bt_mesh_scan_enable();

		if (IS_ENABLED(CONFIG_BT_MESH_LPN_AUTO)) {
			LOG_DBG("Waiting %u ms for messages", LPN_AUTO_TIMEOUT);
			lpn_set_state(BT_MESH_LPN_TIMER);
			k_work_reschedule(&lpn->timer,
					  K_MSEC(LPN_AUTO_TIMEOUT));
		}
	}

	return 0;
}
