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

#include <zephyr.h>
#include <errno.h>
#include <sys/util.h>

#include <net/buf.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/conn.h>
#include <bluetooth/mesh.h>

#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_BEACON)
#define LOG_MODULE_NAME bt_mesh_beacon
#include "common/log.h"

#include "adv.h"
#include "mesh.h"
#include "net.h"
#include "prov.h"
#include "crypto.h"
#include "beacon.h"
#include "foundation.h"

#define PROVISIONED_INTERVAL       K_SECONDS(10)

#define BEACON_TYPE_UNPROVISIONED  0x00
#define BEACON_TYPE_SECURE         0x01

/* 3 transmissions, 20ms interval */
#define UNPROV_XMIT                BT_MESH_TRANSMIT(2, 20)

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

static struct k_work_delayable beacon_timer;

static int cache_check(struct bt_mesh_subnet *sub, void *beacon_data)
{
	return !memcmp(sub->beacon_cache, beacon_data, 21);
}

static void cache_add(uint8_t data[21], struct bt_mesh_subnet *sub)
{
	memcpy(sub->beacon_cache, data, 21);
}

static void beacon_complete(int err, void *user_data)
{
	struct bt_mesh_subnet *sub = user_data;

	BT_DBG("err %d", err);

	sub->beacon_sent = k_uptime_get_32();
}

void bt_mesh_beacon_create(struct bt_mesh_subnet *sub,
			   struct net_buf_simple *buf)
{
	uint8_t flags = bt_mesh_net_flags(sub);
	struct bt_mesh_subnet_keys *keys;

	net_buf_simple_add_u8(buf, BEACON_TYPE_SECURE);

	keys = &sub->keys[SUBNET_KEY_TX_IDX(sub)];

	net_buf_simple_add_u8(buf, flags);

	/* Network ID */
	net_buf_simple_add_mem(buf, keys->net_id, 8);

	/* IV Index */
	net_buf_simple_add_be32(buf, bt_mesh.iv_index);

	net_buf_simple_add_mem(buf, sub->auth, 8);

	BT_DBG("net_idx 0x%04x flags 0x%02x NetID %s", sub->net_idx,
	       flags, bt_hex(keys->net_id, 8));
	BT_DBG("IV Index 0x%08x Auth %s", bt_mesh.iv_index,
	       bt_hex(sub->auth, 8));
}

/* If the interval has passed or is within 5 seconds from now send a beacon */
#define BEACON_THRESHOLD(sub) \
	((10 * ((sub)->beacons_last + 1)) * MSEC_PER_SEC - (5 * MSEC_PER_SEC))

static int secure_beacon_send(struct bt_mesh_subnet *sub, void *cb_data)
{
	static const struct bt_mesh_send_cb send_cb = {
		.end = beacon_complete,
	};
	uint32_t now = k_uptime_get_32();
	struct net_buf *buf;
	uint32_t time_diff;

	BT_DBG("");

	time_diff = now - sub->beacon_sent;
	if (time_diff < (600 * MSEC_PER_SEC) &&
		time_diff < BEACON_THRESHOLD(sub)) {
		return 0;
	}

	buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, PROV_XMIT, K_NO_WAIT);
	if (!buf) {
		BT_ERR("Unable to allocate beacon buffer");
		return -ENOMEM;
	}

	bt_mesh_beacon_create(sub, &buf->b);

	bt_mesh_adv_send(buf, &send_cb, sub);
	net_buf_unref(buf);

	return 0;
}

static int unprovisioned_beacon_send(void)
{
	const struct bt_mesh_prov *prov;
	uint8_t uri_hash[16] = { 0 };
	struct net_buf *buf;
	uint16_t oob_info;

	BT_DBG("");

	buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, UNPROV_XMIT, K_NO_WAIT);
	if (!buf) {
		BT_ERR("Unable to allocate beacon buffer");
		return -ENOBUFS;
	}

	prov = bt_mesh_prov_get();

	net_buf_add_u8(buf, BEACON_TYPE_UNPROVISIONED);
	net_buf_add_mem(buf, prov->uuid, 16);

	if (prov->uri && bt_mesh_s1(prov->uri, uri_hash) == 0) {
		oob_info = prov->oob_info | BT_MESH_PROV_OOB_URI;
	} else {
		oob_info = prov->oob_info;
	}

	net_buf_add_be16(buf, oob_info);
	net_buf_add_mem(buf, uri_hash, 4);

	bt_mesh_adv_send(buf, NULL, NULL);
	net_buf_unref(buf);

	if (prov->uri) {
		size_t len;

		buf = bt_mesh_adv_create(BT_MESH_ADV_URI, UNPROV_XMIT,
					 K_NO_WAIT);
		if (!buf) {
			BT_ERR("Unable to allocate URI buffer");
			return -ENOBUFS;
		}

		len = strlen(prov->uri);
		if (net_buf_tailroom(buf) < len) {
			BT_WARN("Too long URI to fit advertising data");
		} else {
			net_buf_add_mem(buf, prov->uri, len);
			bt_mesh_adv_send(buf, NULL, NULL);
		}

		net_buf_unref(buf);
	}

	return 0;
}

static void unprovisioned_beacon_recv(struct net_buf_simple *buf)
{
	const struct bt_mesh_prov *prov;
	uint8_t *uuid;
	uint16_t oob_info;
	uint32_t uri_hash_val;
	uint32_t *uri_hash = NULL;

	if (buf->len != 18 && buf->len != 22) {
		BT_ERR("Invalid unprovisioned beacon length (%u)", buf->len);
		return;
	}

	uuid = net_buf_simple_pull_mem(buf, 16);
	oob_info = net_buf_simple_pull_be16(buf);

	if (buf->len == 4) {
		uri_hash_val = net_buf_simple_pull_be32(buf);
		uri_hash = &uri_hash_val;
	}

	BT_DBG("uuid %s", bt_hex(uuid, 16));

	prov = bt_mesh_prov_get();

	if (prov->unprovisioned_beacon) {
		prov->unprovisioned_beacon(uuid,
					   (bt_mesh_prov_oob_info_t)oob_info,
					   uri_hash);
	}
}

static void sub_update_beacon_observation(struct bt_mesh_subnet *sub)
{
	sub->beacons_last = sub->beacons_cur;
	sub->beacons_cur = 0U;
}

static void update_beacon_observation(void)
{
	static bool first_half;

	/* Observation period is 20 seconds, whereas the beacon timer
	 * runs every 10 seconds. We process what's happened during the
	 * window only after the seconnd half.
	 */
	first_half = !first_half;
	if (first_half) {
		return;
	}

	bt_mesh_subnet_foreach(sub_update_beacon_observation);
}

static void beacon_send(struct k_work *work)
{
	BT_DBG("");

	if (bt_mesh_is_provisioned()) {
		if (!bt_mesh_beacon_enabled() &&
		    !atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_INITIATOR)) {
			return;
		}

		update_beacon_observation();
		(void)bt_mesh_subnet_find(secure_beacon_send, NULL);

		k_work_schedule(&beacon_timer, PROVISIONED_INTERVAL);
		return;
	}

	if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV)) {
		/* Don't send anything if we have an active provisioning link */
		if (!bt_mesh_prov_active()) {
			unprovisioned_beacon_send();
		}

		k_work_schedule(&beacon_timer, K_SECONDS(CONFIG_BT_MESH_UNPROV_BEACON_INT));
	}

}

struct beacon_params {
	const uint8_t *net_id;
	const uint8_t *auth;
	uint32_t iv_index;
	uint8_t flags;

	bool new_key;
};

static bool auth_match(struct bt_mesh_subnet_keys *keys,
		       const struct beacon_params *params)
{
	uint8_t net_auth[8];

	if (memcmp(params->net_id, keys->net_id, 8)) {
		return false;
	}

	bt_mesh_beacon_auth(keys->beacon, params->flags, keys->net_id,
			    params->iv_index, net_auth);

	if (memcmp(params->auth, net_auth, 8)) {
		BT_WARN("Authentication Value %s != %s",
			bt_hex(params->auth, 8), bt_hex(net_auth, 8));
		return false;
	}

	return true;
}

static int subnet_by_id(struct bt_mesh_subnet *sub, void *cb_data)
{
	struct beacon_params *params = cb_data;

	for (int i = 0; i < ARRAY_SIZE(sub->keys); i++) {
		if (sub->keys[i].valid && auth_match(&sub->keys[i], params)) {
			params->new_key = (i > 0);
			return true;
		}
	}

	return false;
}

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

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

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

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

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

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

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

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

	cache_add(data, sub);

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

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

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

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

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

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

void bt_mesh_beacon_recv(struct net_buf_simple *buf)
{
	uint8_t type;

	BT_DBG("%u bytes: %s", buf->len, bt_hex(buf->data, buf->len));

	if (buf->len < 1) {
		BT_ERR("Too short beacon");
		return;
	}

	type = net_buf_simple_pull_u8(buf);
	switch (type) {
	case BEACON_TYPE_UNPROVISIONED:
		if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV)) {
			unprovisioned_beacon_recv(buf);
		}
		break;
	case BEACON_TYPE_SECURE:
		secure_beacon_recv(buf);
		break;
	default:
		BT_WARN("Unknown beacon type 0x%02x", type);
		break;
	}
}

void bt_mesh_beacon_update(struct bt_mesh_subnet *sub)
{
	uint8_t flags = bt_mesh_net_flags(sub);
	struct bt_mesh_subnet_keys *keys;
	int err;

	keys = &sub->keys[SUBNET_KEY_TX_IDX(sub)];

	BT_DBG("NetIndex 0x%03x Using %s key", sub->net_idx,
	       SUBNET_KEY_TX_IDX(sub) ? "new" : "current");
	BT_DBG("flags 0x%02x, IVI 0x%08x", flags, bt_mesh.iv_index);

	err = bt_mesh_beacon_auth(keys->beacon, flags, keys->net_id,
				   bt_mesh.iv_index, sub->auth);
	if (err) {
		BT_ERR("Failed updating net beacon for 0x%03x", sub->net_idx);
	}
}

static void subnet_evt(struct bt_mesh_subnet *sub, enum bt_mesh_key_evt evt)
{
	if (evt != BT_MESH_KEY_DELETED) {
		bt_mesh_beacon_update(sub);
	}
}

BT_MESH_SUBNET_CB_DEFINE(subnet_evt);

void bt_mesh_beacon_init(void)
{
	k_work_init_delayable(&beacon_timer, beacon_send);
}

void bt_mesh_beacon_ivu_initiator(bool enable)
{
	atomic_set_bit_to(bt_mesh.flags, BT_MESH_IVU_INITIATOR, enable);

	/* Fire the beacon handler straight away if it's not already pending -
	 * in which case we'll fire according to the ongoing periodic sending.
	 * If beacons are disabled, the handler will exit early.
	 *
	 * An alternative solution would be to check whether beacons are enabled
	 * here, and cancel if not. As the cancel operation may fail, we would
	 * still have to implement an early exit mechanism, so we might as well
	 * just use this every time.
	 */
	k_work_schedule(&beacon_timer, K_NO_WAIT);
}

static void subnet_beacon_enable(struct bt_mesh_subnet *sub)
{
	sub->beacons_last = 0U;
	sub->beacons_cur = 0U;

	bt_mesh_beacon_update(sub);
}

void bt_mesh_beacon_enable(void)
{
	if (bt_mesh_is_provisioned()) {
		bt_mesh_subnet_foreach(subnet_beacon_enable);
	}

	k_work_reschedule(&beacon_timer, K_NO_WAIT);
}

void bt_mesh_beacon_disable(void)
{
	if (!atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_INITIATOR)) {
		/* If this fails, we'll do an early exit in the work handler. */
		(void)k_work_cancel_delayable(&beacon_timer);
	}
}
