/*  Bluetooth Mesh */

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

#include <zephyr.h>
#include <string.h>
#include <errno.h>
#include <stdbool.h>
#include <atomic.h>
#include <misc/util.h>
#include <misc/byteorder.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_NET)
#include "common/log.h"

#include "crypto.h"
#include "adv.h"
#include "mesh.h"
#include "net.h"
#include "lpn.h"
#include "friend.h"
#include "proxy.h"
#include "transport.h"
#include "access.h"
#include "foundation.h"
#include "beacon.h"

/* Seq limit after IV Update is triggered */
#define IV_UPDATE_SEQ_LIMIT 8000000

#if defined(CONFIG_BT_MESH_IV_UPDATE_TEST)
/* Small test timeout for IV Update Procedure testing */
#define IV_UPDATE_TIMEOUT  K_SECONDS(120)
#else
/* Maximum time to stay in IV Update mode (96 < time < 144) */
#define IV_UPDATE_TIMEOUT  K_HOURS(120)
#endif /* CONFIG_BT_MESH_IV_UPDATE_TEST */

#define IVI(pdu)           ((pdu)[0] >> 7)
#define NID(pdu)           ((pdu)[0] & 0x7f)
#define CTL(pdu)           ((pdu)[1] >> 7)
#define TTL(pdu)           ((pdu)[1] & 0x7f)

/* Determine how many friendship credentials we need */
#if defined(CONFIG_BT_MESH_FRIEND)
#define FRIEND_CRED_COUNT CONFIG_BT_MESH_FRIEND_LPN_COUNT
#elif defined(CONFIG_BT_MESH_LOW_POWER)
#define FRIEND_CRED_COUNT CONFIG_BT_MESH_SUBNET_COUNT
#else
#define FRIEND_CRED_COUNT 0
#endif

#if FRIEND_CRED_COUNT > 0
static struct bt_mesh_friend_cred friend_cred[FRIEND_CRED_COUNT];
#endif

static u64_t msg_cache[CONFIG_BT_MESH_MSG_CACHE_SIZE];
static u16_t msg_cache_next;

/* Singleton network context (the implementation only supports one) */
struct bt_mesh_net bt_mesh = {
	.local_queue = _K_FIFO_INITIALIZER(bt_mesh.local_queue),
	.sub = {
		[0 ... (CONFIG_BT_MESH_SUBNET_COUNT - 1)] = {
			.net_idx = BT_MESH_KEY_UNUSED,
		}
	},
	.app_keys = {
		[0 ... (CONFIG_BT_MESH_APP_KEY_COUNT - 1)] = {
			.net_idx = BT_MESH_KEY_UNUSED,
		}
	},
};

static u32_t dup_cache[4];
static int   dup_cache_next;

static bool check_dup(struct net_buf_simple *data)
{
	const u8_t *tail = net_buf_simple_tail(data);
	u32_t val;
	int i;

	val = sys_get_be32(tail - 4) ^ sys_get_be32(tail - 8);

	for (i = 0; i < ARRAY_SIZE(dup_cache); i++) {
		if (dup_cache[i] == val) {
			return true;
		}
	}

	dup_cache[dup_cache_next++] = val;
	dup_cache_next %= ARRAY_SIZE(dup_cache);

	return false;
}

static u64_t msg_hash(struct net_buf_simple *pdu)
{
	u8_t *tpdu_last;
	u64_t hash;

	/* Last byte of TransportPDU */
	tpdu_last = net_buf_simple_tail(pdu) - (CTL(pdu->data) ? 8 : 4) - 1;

	((u8_t *)(&hash))[0] = pdu->data[0];
	((u8_t *)(&hash))[1] = (pdu->data[1] & 0xc0);
	((u8_t *)(&hash))[2] = *tpdu_last;
	memcpy(&((u8_t *)&hash)[3], &pdu->data[2], 5);

	return hash;
}

static void msg_cache_add(u64_t new_hash)
{
	msg_cache[msg_cache_next++] = new_hash;
	msg_cache_next %= ARRAY_SIZE(msg_cache);
}

static bool msg_is_known(u64_t hash)
{
	u16_t i;

	for (i = 0; i < ARRAY_SIZE(msg_cache); i++) {
		if (msg_cache[i] == hash) {
			return true;
		}
	}

	return false;
}

static inline u32_t net_seq(struct net_buf_simple *buf)
{
	return ((net_buf_simple_pull_u8(buf) << 16) & 0xff0000) |
		((net_buf_simple_pull_u8(buf) << 8) & 0xff00) |
		net_buf_simple_pull_u8(buf);
}

struct bt_mesh_subnet *bt_mesh_subnet_get(u16_t net_idx)
{
	int i;

	if (net_idx == BT_MESH_KEY_ANY) {
		return &bt_mesh.sub[0];
	}

	for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
		if (bt_mesh.sub[i].net_idx == net_idx) {
			return &bt_mesh.sub[i];
		}
	}

	return NULL;
}

int bt_mesh_net_keys_create(struct bt_mesh_subnet_keys *keys,
			    const u8_t key[16])
{
	u8_t p[] = { 0 };
	u8_t nid;
	int err;

	err = bt_mesh_k2(key, p, sizeof(p), &nid, keys->enc, keys->privacy);
	if (err) {
		BT_ERR("Unable to generate NID, EncKey & PrivacyKey");
		return err;
	}

	memcpy(keys->net, key, 16);

	keys->nid = nid;

	BT_DBG("NID 0x%02x EncKey %s", keys->nid, bt_hex(keys->enc, 16));
	BT_DBG("PrivacyKey %s", bt_hex(keys->privacy, 16));

	err = bt_mesh_k3(key, keys->net_id);
	if (err) {
		BT_ERR("Unable to generate Net ID");
		return err;
	}

	BT_DBG("NetID %s", bt_hex(keys->net_id, 8));

#if defined(CONFIG_BT_MESH_GATT_PROXY)
	err = bt_mesh_identity_key(key, keys->identity);
	if (err) {
		BT_ERR("Unable to generate IdentityKey");
		return err;
	}

	BT_DBG("IdentityKey %s", bt_hex(keys->identity, 16));
#endif /* GATT_PROXY */

	err = bt_mesh_beacon_key(key, keys->beacon);
	if (err) {
		BT_ERR("Unable to generate beacon key");
		return err;
	}

	BT_DBG("BeaconKey %s", bt_hex(keys->beacon, 16));

	return 0;
}

#if (defined(CONFIG_BT_MESH_LOW_POWER) || \
     defined(CONFIG_BT_MESH_FRIEND))
int bt_mesh_friend_cred_set(struct bt_mesh_friend_cred *cred, u8_t idx,
			    const u8_t net_key[16])
{
	u16_t lpn_addr, frnd_addr;
	int err;
	u8_t p[9];

#if defined(CONFIG_BT_MESH_LOW_POWER)
	if (cred->addr == bt_mesh.lpn.frnd) {
		lpn_addr = bt_mesh_primary_addr();
		frnd_addr = cred->addr;
	} else {
		lpn_addr = cred->addr;
		frnd_addr = bt_mesh_primary_addr();
	}
#else
	lpn_addr = cred->addr;
	frnd_addr = bt_mesh_primary_addr();
#endif

	BT_DBG("LPNAddress 0x%04x FriendAddress 0x%04x", lpn_addr, frnd_addr);
	BT_DBG("LPNCounter 0x%04x FriendCounter 0x%04x", cred->lpn_counter,
	       cred->frnd_counter);

	p[0] = 0x01;
	sys_put_be16(lpn_addr, p + 1);
	sys_put_be16(frnd_addr, p + 3);
	sys_put_be16(cred->lpn_counter, p + 5);
	sys_put_be16(cred->frnd_counter, p + 7);

	err = bt_mesh_k2(net_key, p, sizeof(p), &cred->cred[idx].nid,
			 cred->cred[idx].enc, cred->cred[idx].privacy);
	if (err) {
		BT_ERR("Unable to generate NID, EncKey & PrivacyKey");
		return err;
	}

	BT_DBG("Friend NID 0x%02x EncKey %s", cred->cred[idx].nid,
	       bt_hex(cred->cred[idx].enc, 16));
	BT_DBG("Friend PrivacyKey %s", bt_hex(cred->cred[idx].privacy, 16));

	return 0;
}

void bt_mesh_friend_cred_refresh(u16_t net_idx)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(friend_cred); i++) {
		struct bt_mesh_friend_cred *cred = &friend_cred[i];

		if (cred->addr != BT_MESH_ADDR_UNASSIGNED &&
		    cred->net_idx == net_idx) {
			memcpy(&cred->cred[0], &cred->cred[1],
			       sizeof(cred->cred[0]));
		}
	}
}

int bt_mesh_friend_cred_update(u16_t net_idx, u8_t idx, const u8_t net_key[16])
{
	int err, i;

	for (i = 0; i < ARRAY_SIZE(friend_cred); i++) {
		struct bt_mesh_friend_cred *cred = &friend_cred[i];

		if (cred->addr == BT_MESH_ADDR_UNASSIGNED ||
		    cred->net_idx != net_idx) {
			continue;
		}

		err = bt_mesh_friend_cred_set(cred, idx, net_key);
		if (err) {
			return err;
		}
	}

	return 0;
}

struct bt_mesh_friend_cred *bt_mesh_friend_cred_add(u16_t net_idx,
						    const u8_t net_key[16],
						    u8_t idx, u16_t addr,
						    u16_t lpn_counter,
						    u16_t frnd_counter)
{
	struct bt_mesh_friend_cred *cred;
	int i, err;

	BT_DBG("net_idx 0x%04x addr 0x%04x idx %u", net_idx, addr, idx);

	for (cred = NULL, i = 0; i < ARRAY_SIZE(friend_cred); i++) {
		if ((friend_cred[i].addr == BT_MESH_ADDR_UNASSIGNED) ||
		    (friend_cred[i].addr == addr &&
		     friend_cred[i].net_idx == net_idx)) {
			cred = &friend_cred[i];
			break;
		}
	}

	if (!cred) {
		return NULL;
	}

	cred->net_idx = net_idx;
	cred->addr = addr;
	cred->lpn_counter = lpn_counter;
	cred->frnd_counter = frnd_counter;

	err = bt_mesh_friend_cred_set(cred, idx, net_key);
	if (err) {
		bt_mesh_friend_cred_clear(cred);
		return NULL;
	}

	return cred;
}

void bt_mesh_friend_cred_clear(struct bt_mesh_friend_cred *cred)
{
	cred->net_idx = BT_MESH_KEY_UNUSED;
	cred->addr = BT_MESH_ADDR_UNASSIGNED;
	cred->lpn_counter = 0;
	cred->frnd_counter = 0;
	memset(cred->cred, 0, sizeof(cred->cred));
}

int bt_mesh_friend_cred_del(u16_t net_idx, u16_t addr)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(friend_cred); i++) {
		struct bt_mesh_friend_cred *cred = &friend_cred[i];

		if (cred->addr == addr && cred->net_idx == net_idx) {
			bt_mesh_friend_cred_clear(cred);
			return 0;
		}
	}

	return -ENOENT;
}

static int friend_cred_get(u16_t net_idx, u16_t addr, u8_t idx,
			   u8_t *nid, const u8_t **enc, const u8_t **priv)
{
	int i;

	BT_DBG("net_idx 0x%04x addr 0x%04x idx %u", net_idx, addr, idx);

	for (i = 0; i < ARRAY_SIZE(friend_cred); i++) {
		struct bt_mesh_friend_cred *cred = &friend_cred[i];

		if (cred->net_idx != net_idx) {
			continue;
		}

		if (addr != BT_MESH_ADDR_UNASSIGNED && cred->addr != addr) {
			continue;
		}

		if (nid) {
			*nid = cred->cred[idx].nid;
		}

		if (enc) {
			*enc = cred->cred[idx].enc;
		}

		if (priv) {
			*priv = cred->cred[idx].privacy;
		}

		return 0;
	}

	return -ENOENT;
}
#else
static inline int friend_cred_get(u16_t net_idx, u16_t addr, u8_t idx,
				  u8_t *nid, const u8_t **enc,
				  const u8_t **priv)
{
	return -ENOENT;
}
#endif /* FRIEND || LOW_POWER */

int bt_mesh_net_beacon_update(struct bt_mesh_subnet *sub)
{
	struct bt_mesh_subnet_keys *keys;
	u8_t flags;

	if (sub->kr_flag) {
		BT_DBG("NetIndex %u Using new key", sub->net_idx);
		flags = BT_MESH_NET_FLAG_KR;
		keys = &sub->keys[1];
	} else {
		BT_DBG("NetIndex %u Using current key", sub->net_idx);
		flags = 0x00;
		keys = &sub->keys[0];
	}

	if (bt_mesh.iv_update) {
		flags |= BT_MESH_NET_FLAG_IVU;
	}

	BT_DBG("flags 0x%02x, IVI 0x%08x", flags, bt_mesh.iv_index);

	return bt_mesh_beacon_auth(keys->beacon, flags, keys->net_id,
				   bt_mesh.iv_index, sub->auth);
}

int bt_mesh_net_create(u16_t idx, u8_t flags, const u8_t key[16],
		       u32_t iv_index)
{
	struct bt_mesh_subnet *sub;
	int err;

	BT_DBG("idx %u iv_index %u", idx, iv_index);

	BT_DBG("NetKey %s", bt_hex(key, 16));

	if (bt_mesh.valid) {
		return -EALREADY;
	}

	sub = &bt_mesh.sub[0];

	err = bt_mesh_net_keys_create(&sub->keys[0], key);
	if (err) {
		return -EIO;
	}

	bt_mesh.valid = 1;
	sub->net_idx = idx;

	if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
		sub->node_id = BT_MESH_NODE_IDENTITY_RUNNING;
	} else {
		sub->node_id = BT_MESH_NODE_IDENTITY_NOT_SUPPORTED;
	}

	sub->kr_flag = BT_MESH_KEY_REFRESH(flags);
	if (sub->kr_flag) {
		memcpy(&sub->keys[1], &sub->keys[0], sizeof(sub->keys[0]));
		sub->kr_phase = BT_MESH_KR_PHASE_2;
	}

	bt_mesh.iv_index = iv_index;
	bt_mesh.iv_update = BT_MESH_IV_UPDATE(flags);

	/* Set initial IV Update procedure state time-stamp */
	bt_mesh.last_update = k_uptime_get();

	return 0;
}

void bt_mesh_net_revoke_keys(struct bt_mesh_subnet *sub)
{
	int i;

	BT_DBG("idx 0x%04x", sub->net_idx);

	memcpy(&sub->keys[0], &sub->keys[1], sizeof(sub->keys[0]));

	for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) {
		struct bt_mesh_app_key *key = &bt_mesh.app_keys[i];

		if (key->net_idx != sub->net_idx || !key->updated) {
			continue;
		}

		memcpy(&key->keys[0], &key->keys[1], sizeof(key->keys[0]));
		key->updated = false;
	}
}

bool bt_mesh_kr_update(struct bt_mesh_subnet *sub, u8_t new_kr, bool new_key)
{
	if (new_kr != sub->kr_flag && sub->kr_phase == BT_MESH_KR_NORMAL) {
		BT_WARN("KR change in normal operation. Are we blacklisted?");
		return false;
	}

	sub->kr_flag = new_kr;

	if (sub->kr_flag) {
		if (sub->kr_phase == BT_MESH_KR_PHASE_1) {
			BT_DBG("Phase 1 -> Phase 2");
			sub->kr_phase = BT_MESH_KR_PHASE_2;
			return true;
		}
	} else {
		switch (sub->kr_phase) {
		case BT_MESH_KR_PHASE_1:
			if (!new_key) {
				/* Ignore */
				break;
			}
		/* Upon receiving a Secure Network beacon with the KR flag set
		 * to 0 using the new NetKey in Phase 1, the node shall
		 * immediately transition to Phase 3, which effectively skips
		 * Phase 2.
		 *
		 * Intentional fall-through.
		 */
		case BT_MESH_KR_PHASE_2:
			BT_DBG("KR Phase 0x%02x -> Normal", sub->kr_phase);
			bt_mesh_net_revoke_keys(sub);
			if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) ||
			    IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
				bt_mesh_friend_cred_refresh(sub->net_idx);
			}
			sub->kr_phase = BT_MESH_KR_NORMAL;
			return true;
		}
	}

	return false;
}

void bt_mesh_rpl_reset(void)
{
	int i;

	/* Discard "old old" IV Index entries from RPL and flag
	 * any other ones (which are valid) as old.
	 */
	for (i = 0; i < ARRAY_SIZE(bt_mesh.rpl); i++) {
		struct bt_mesh_rpl *rpl = &bt_mesh.rpl[i];

		if (rpl->src) {
			if (rpl->old_iv) {
				memset(rpl, 0, sizeof(*rpl));
			} else {
				rpl->old_iv = true;
			}
		}
	}
}

void bt_mesh_iv_update(u32_t iv_index, bool iv_update)
{
	int i;

	if (iv_index < bt_mesh.iv_index || iv_index > bt_mesh.iv_index + 42) {
		BT_ERR("IV Index completely out of sync: 0x%08x != 0x%08x",
			iv_index, bt_mesh.iv_index);
		return;
	}

	if (iv_index > bt_mesh.iv_index + 1) {
		BT_WARN("Performing IV Index Recovery");
		memset(bt_mesh.rpl, 0, sizeof(bt_mesh.rpl));
		bt_mesh.iv_index = iv_index;
		bt_mesh.seq = 0;
		goto do_update;
	}

	if (iv_update == bt_mesh.iv_update) {
		if (iv_index != bt_mesh.iv_index) {
			BT_WARN("No update, but IV Index 0x%08x != 0x%08x",
				iv_index, bt_mesh.iv_index);
		}
		return;
	}

	if (bt_mesh.iv_update) {
		if (iv_index != bt_mesh.iv_index) {
			BT_WARN("IV Index mismatch: 0x%08x != 0x%08x",
				iv_index, bt_mesh.iv_index);
			return;
		}
	} else {
		if (iv_index != bt_mesh.iv_index + 1) {
			BT_WARN("Wrong new IV Index: 0x%08x != 0x%08x + 1",
				iv_index, bt_mesh.iv_index);
			return;
		}
	}

	if (!IS_ENABLED(CONFIG_BT_MESH_IV_UPDATE_TEST)) {
		s64_t delta = k_uptime_get() - bt_mesh.last_update;

		if (delta < K_HOURS(96)) {
			BT_WARN("IV Update before minimum duration");
			return;
		}
	}

	/* Defer change to Normal Operation if there are pending acks */
	if (!iv_update && bt_mesh_tx_in_progress()) {
		BT_WARN("IV Update deferred because of pending transfer");
		bt_mesh.pending_update = 1;
		return;
	}

do_update:
	bt_mesh.iv_update = iv_update;

	if (bt_mesh.iv_update) {
		bt_mesh.iv_index = iv_index;
		BT_DBG("IV Update state entered. New index 0x%08x",
		       bt_mesh.iv_index);

		bt_mesh_rpl_reset();

		k_delayed_work_submit(&bt_mesh.ivu_complete,
				      IV_UPDATE_TIMEOUT);
	} else {
		BT_DBG("Normal mode entered");
		bt_mesh.seq = 0;
		k_delayed_work_cancel(&bt_mesh.ivu_complete);
	}

	/* Store time-stamp of the IV procedure state change */
	bt_mesh.last_update = k_uptime_get();

	for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
		if (bt_mesh.sub[i].net_idx != BT_MESH_KEY_UNUSED) {
			bt_mesh_net_beacon_update(&bt_mesh.sub[i]);
		}
	}
}

int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct net_buf *buf,
		       bool new_key, bool friend_cred, bt_mesh_adv_func_t cb)
{
	const u8_t *enc, *priv;
	int err;

	BT_DBG("net_idx 0x%04x, len %u", sub->net_idx, buf->len);

	if (friend_cred) {
		err = friend_cred_get(sub->net_idx, BT_MESH_ADDR_UNASSIGNED,
				      new_key, NULL, &enc, &priv);
		if (err) {
			return err;
		}
	} else {
		enc = sub->keys[new_key].enc;
		priv = sub->keys[new_key].privacy;
	}

	err = bt_mesh_net_obfuscate(buf->data, BT_MESH_NET_IVI_TX, priv);
	if (err) {
		BT_ERR("deobfuscate failed (err %d)", err);
		return err;
	}

	err = bt_mesh_net_decrypt(enc, &buf->b, BT_MESH_NET_IVI_TX, false);
	if (err) {
		BT_ERR("decrypt failed (err %d)", err);
		return err;
	}

	/* Update with a new sequence number */
	buf->data[2] = (bt_mesh.seq >> 16);
	buf->data[3] = (bt_mesh.seq >> 8);
	buf->data[4] = bt_mesh.seq++;

	err = bt_mesh_net_encrypt(enc, &buf->b, BT_MESH_NET_IVI_TX, false);
	if (err) {
		BT_ERR("encrypt failed (err %d)", err);
		return err;
	}

	err = bt_mesh_net_obfuscate(buf->data, BT_MESH_NET_IVI_TX, priv);
	if (err) {
		BT_ERR("obfuscate failed (err %d)", err);
		return err;
	}

	bt_mesh_adv_send(buf, cb);

	if (!bt_mesh.iv_update && bt_mesh.seq > IV_UPDATE_SEQ_LIMIT) {
		bt_mesh_beacon_ivu_initiator(true);
		bt_mesh_iv_update(bt_mesh.iv_index + 1, true);
	}

	return 0;
}

static void bt_mesh_net_local(struct k_work *work)
{
	struct net_buf *buf;

	while ((buf = net_buf_get(&bt_mesh.local_queue, K_NO_WAIT))) {
		BT_DBG("len %u: %s", buf->len, bt_hex(buf->data, buf->len));
		bt_mesh_net_recv(&buf->b, 0, BT_MESH_NET_IF_LOCAL);
		net_buf_unref(buf);
	}
}

int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct net_buf_simple *buf,
		       bool proxy)
{
	const bool ctl = (tx->ctx->app_idx == BT_MESH_KEY_UNUSED);
	u8_t nid;
	const u8_t *enc, *priv;
	u8_t *seq;
	int err;

	if (ctl && net_buf_simple_tailroom(buf) < 8) {
		BT_ERR("Insufficient MIC space for CTL PDU");
		return -EINVAL;
	} else if (net_buf_simple_tailroom(buf) < 4) {
		BT_ERR("Insufficient MIC space for PDU");
		return -EINVAL;
	}

	BT_DBG("src 0x%04x dst 0x%04x ctl %u seq 0x%06x",
	       tx->src, tx->ctx->addr, ctl, bt_mesh.seq);

	net_buf_simple_push_be16(buf, tx->ctx->addr);
	net_buf_simple_push_be16(buf, tx->src);

	seq = net_buf_simple_push(buf, 3);
	seq[0] = (bt_mesh.seq >> 16);
	seq[1] = (bt_mesh.seq >> 8);
	seq[2] = bt_mesh.seq++;

	if (ctl) {
		net_buf_simple_push_u8(buf, tx->ctx->send_ttl | 0x80);
	} else {
		net_buf_simple_push_u8(buf, tx->ctx->send_ttl);
	}

	if (tx->sub->kr_phase == BT_MESH_KR_PHASE_2) {
		if (tx->ctx->friend_cred) {
			err = friend_cred_get(tx->sub->net_idx,
					      BT_MESH_ADDR_UNASSIGNED,
					      1, &nid, &enc, &priv);
			if (err) {
				return err;
			}
		} else {
			nid = tx->sub->keys[1].nid;
			enc = tx->sub->keys[1].enc;
			priv = tx->sub->keys[1].privacy;
		}
	} else {
		if (tx->ctx->friend_cred) {
			err = friend_cred_get(tx->sub->net_idx,
					      BT_MESH_ADDR_UNASSIGNED,
					      0, &nid, &enc, &priv);
			if (err) {
				return err;
			}
		} else {
			nid = tx->sub->keys[0].nid;
			enc = tx->sub->keys[0].enc;
			priv = tx->sub->keys[0].privacy;
		}
	}

	net_buf_simple_push_u8(buf, (nid | (BT_MESH_NET_IVI_TX & 1) << 7));

	err = bt_mesh_net_encrypt(enc, buf, BT_MESH_NET_IVI_TX, proxy);
	if (err) {
		return err;
	}

	return bt_mesh_net_obfuscate(buf->data, BT_MESH_NET_IVI_TX, priv);
}

int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf,
		     bt_mesh_adv_func_t cb)
{
	int err;

	BT_DBG("src 0x%04x dst 0x%04x len %u headroom %zu tailroom %zu",
	       tx->src, tx->ctx->addr, buf->len, net_buf_headroom(buf),
	       net_buf_tailroom(buf));
	BT_DBG("Payload len %u: %s", buf->len, bt_hex(buf->data, buf->len));
	BT_DBG("Seq 0x%06x", bt_mesh.seq);

#if defined(CONFIG_BT_MESH_LOW_POWER)
	/* Communication between LPN & Friend should always be using
	 * the Friendship Credentials. Any other destination should
	 * use the Master Credentials.
	 */
	if (bt_mesh_lpn_established()) {
		tx->ctx->friend_cred = (tx->ctx->addr == bt_mesh.lpn.frnd);
	}
#endif

	if (tx->ctx->send_ttl == BT_MESH_TTL_DEFAULT) {
		tx->ctx->send_ttl = bt_mesh_default_ttl_get();
	}

	err = bt_mesh_net_encode(tx, &buf->b, false);
	if (err) {
		goto done;
	}

	/* Deliver to GATT Proxy Clients if necessary */
	if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
		if (bt_mesh_proxy_relay(&buf->b, tx->ctx->addr) &&
		    BT_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) {
			err = 0;
			goto done;
		}
	}

	/* Deliver to local network interface if necessary */
	if (bt_mesh_fixed_group_match(tx->ctx->addr) ||
	    bt_mesh_elem_find(tx->ctx->addr)) {
		net_buf_put(&bt_mesh.local_queue, net_buf_ref(buf));
		if (cb) {
			cb(buf, 0);
		}
		k_work_submit(&bt_mesh.local_work);
	} else {
		bt_mesh_adv_send(buf, cb);
	}

done:
	net_buf_unref(buf);
	return err;
}

static bool auth_match(struct bt_mesh_subnet_keys *keys,
		       const u8_t net_id[8], u8_t flags,
		       u32_t iv_index, const u8_t auth[8])
{
	u8_t net_auth[8];

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

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

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

	return true;
}

struct bt_mesh_subnet *bt_mesh_subnet_find(const u8_t net_id[8], u8_t flags,
					   u32_t iv_index, const u8_t auth[8],
					   bool *new_key)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
		struct bt_mesh_subnet *sub = &bt_mesh.sub[i];

		if (sub->net_idx == BT_MESH_KEY_UNUSED) {
			continue;
		}

		if (auth_match(&sub->keys[0], net_id, flags, iv_index, auth)) {
			*new_key = false;
			return sub;
		}

		if (sub->kr_phase == BT_MESH_KR_NORMAL) {
			continue;
		}

		if (auth_match(&sub->keys[1], net_id, flags, iv_index, auth)) {
			*new_key = true;
			return sub;
		}
	}

	return NULL;
}

static int net_decrypt(struct bt_mesh_subnet *sub, u8_t idx, const u8_t *data,
		       size_t data_len, struct bt_mesh_net_rx *rx,
		       struct net_buf_simple *buf)
{
	const u8_t *enc, *priv;

	BT_DBG("NID 0x%02x, PDU NID 0x%02x net_idx 0x%04x idx %u",
	       sub->keys[idx].nid, NID(data), sub->net_idx, idx);

	if (NID(data) == sub->keys[idx].nid) {
		rx->ctx.friend_cred = false;
		enc = sub->keys[idx].enc;
		priv = sub->keys[idx].privacy;
		rx->ctx.friend_cred = 0;
	} else {
		u8_t nid;

		if (friend_cred_get(sub->net_idx, BT_MESH_ADDR_UNASSIGNED, idx,
				    &nid, &enc, &priv)) {
			return -ENOENT;
		}

		if (nid != NID(data)) {
			return -ENOENT;
		}

		rx->ctx.friend_cred = 1;
	}

	BT_DBG("IVI %u net->iv_index 0x%08x", IVI(data), bt_mesh.iv_index);

	rx->old_iv = (IVI(data) != (bt_mesh.iv_index & 0x01));

	net_buf_simple_init(buf, 0);
	memcpy(net_buf_simple_add(buf, data_len), data, data_len);

	if (bt_mesh_net_obfuscate(buf->data, BT_MESH_NET_IVI_RX(rx), priv)) {
		return -ENOENT;
	}

	if (msg_is_known(rx->hash)) {
		return -EALREADY;
	}

	rx->ctx.addr = sys_get_be16(&buf->data[5]);
	if (!BT_MESH_ADDR_IS_UNICAST(rx->ctx.addr)) {
		BT_WARN("Ignoring non-unicast src addr 0x%04x", rx->ctx.addr);
		return -EINVAL;
	}

	BT_DBG("src 0x%04x", rx->ctx.addr);

	if (IS_ENABLED(CONFIG_BT_MESH_PROXY) &&
	    rx->net_if == BT_MESH_NET_IF_PROXY_CFG) {
		return bt_mesh_net_decrypt(enc, buf, BT_MESH_NET_IVI_RX(rx),
					   true);
	}

	return bt_mesh_net_decrypt(enc, buf, BT_MESH_NET_IVI_RX(rx), false);
}

static int net_find_and_decrypt(const u8_t *data, size_t data_len,
				struct bt_mesh_net_rx *rx,
				struct net_buf_simple *buf)
{
	int i;

	BT_DBG("");

	for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
		struct bt_mesh_subnet *sub = &bt_mesh.sub[i];
		int err;

		if (sub->net_idx == BT_MESH_KEY_UNUSED) {
			continue;
		}

		err = net_decrypt(sub, 0, data, data_len, rx, buf);
		if (!err) {
			rx->ctx.net_idx = sub->net_idx;
			rx->sub = sub;
			return true;
		}

		if (sub->kr_phase == BT_MESH_KR_NORMAL) {
			continue;
		}

		err = net_decrypt(sub, 1, data, data_len, rx, buf);
		if (!err) {
			rx->ctx.net_idx = sub->net_idx;
			rx->sub = sub;
			rx->new_key = 1;
			return true;
		}
	}

	return false;
}

static void bt_mesh_net_relay(struct net_buf_simple *sbuf,
			      struct bt_mesh_net_rx *rx)
{
	const u8_t *enc, *priv;
	struct net_buf *buf;
	u8_t nid, transmit;

	BT_DBG("TTL %u CTL %u dst 0x%04x", rx->ctx.recv_ttl, CTL(sbuf->data),
	       rx->dst);

	if (rx->net_if != BT_MESH_NET_IF_LOCAL && rx->ctx.recv_ttl <= 1) {
		return;
	}

	transmit = bt_mesh_relay_retransmit_get();
	buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, TRANSMIT_COUNT(transmit),
				 TRANSMIT_INT(transmit), K_NO_WAIT);
	if (!buf) {
		BT_ERR("Out of relay buffers");
		return;
	}

	net_buf_add_mem(buf, sbuf->data, sbuf->len);

	/* Only decrement TTL for non-locally originated packets */
	if (rx->net_if != BT_MESH_NET_IF_LOCAL) {
		/* Leave CTL bit intact */
		buf->data[1] &= 0x80;
		buf->data[1] |= rx->ctx.recv_ttl - 1;
	}

	if (rx->sub->kr_phase == BT_MESH_KR_PHASE_2) {
		if (bt_mesh_friend_dst_is_lpn(rx->dst)) {
			if (friend_cred_get(rx->sub->net_idx,
					    BT_MESH_ADDR_UNASSIGNED,
					    1, &nid, &enc, &priv)) {
				BT_ERR("friend_cred_get failed");
				goto done;
			}
		} else {
			enc = rx->sub->keys[1].enc;
			priv = rx->sub->keys[1].privacy;
			nid = rx->sub->keys[1].nid;
		}
	} else {
		if (bt_mesh_friend_dst_is_lpn(rx->dst)) {
			if (friend_cred_get(rx->sub->net_idx,
					    BT_MESH_ADDR_UNASSIGNED,
					    0, &nid, &enc, &priv)) {
				BT_ERR("friend_cred_get failed");
				goto done;
			}
		} else  {
			enc = rx->sub->keys[0].enc;
			priv = rx->sub->keys[0].privacy;
			nid = rx->sub->keys[0].nid;
		}
	}

	BT_DBG("Relaying packet. TTL is now %u", TTL(buf->data));

	/* Update NID if RX or TX is with friend credentials */
	if (rx->ctx.friend_cred || bt_mesh_friend_dst_is_lpn(rx->dst)) {
		buf->data[0] &= 0x80; /* Clear everything except IVI */
		buf->data[0] |= nid;
	}

	/* We re-encrypt and obfuscate using the received IVI rather than
	 * the normal TX IVI (which may be different) since the transport
	 * layer nonce includes the IVI.
	 */
	if (bt_mesh_net_encrypt(enc, &buf->b, BT_MESH_NET_IVI_RX(rx), false)) {
		BT_ERR("Re-encrypting failed");
		goto done;
	}

	if (bt_mesh_net_obfuscate(buf->data, BT_MESH_NET_IVI_RX(rx), priv)) {
		BT_ERR("Re-obfuscating failed");
		goto done;
	}

	if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
		if (bt_mesh_friend_enqueue(buf, rx->dst) &&
		    BT_MESH_ADDR_IS_UNICAST(rx->dst)) {
			goto done;
		}
	}

	if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
		if (bt_mesh_proxy_relay(&buf->b, rx->dst) &&
			    BT_MESH_ADDR_IS_UNICAST(rx->dst)) {
			goto done;
		}
	}

	if (rx->net_if != BT_MESH_NET_IF_ADV ||
	    bt_mesh_relay_get() == BT_MESH_RELAY_ENABLED) {
		bt_mesh_adv_send(buf, NULL);
	}

done:
	net_buf_unref(buf);
}

int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if,
		       struct bt_mesh_net_rx *rx, struct net_buf_simple *buf,
		       struct net_buf_simple_state *state)
{
	if (data->len < 18) {
		BT_WARN("Dropping too short mesh packet (len %u)", data->len);
		BT_WARN("%s", bt_hex(data->data, data->len));
		return -EINVAL;
	}

	if (net_if == BT_MESH_NET_IF_ADV && check_dup(data)) {
		return -EINVAL;
	}

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

	rx->net_if = net_if;

	if (net_if == BT_MESH_NET_IF_ADV) {
		rx->hash = msg_hash(data);
	}

	if (!net_find_and_decrypt(data->data, data->len, rx, buf)) {
		BT_DBG("Unable to find matching net for packet");
		return -ENOENT;
	}

	/* Initialize AppIdx to a sane value */
	rx->ctx.app_idx = BT_MESH_KEY_UNUSED;

	/* Save parsing state so the buffer can later be relayed */
	if (state) {
		net_buf_simple_save(buf, state);
	}

	rx->ctx.recv_ttl = TTL(buf->data);

	/* Default to responding with TTL 0 for non-routed messages */
	if (rx->ctx.recv_ttl == 0) {
		rx->ctx.send_ttl = 0;
	} else {
		rx->ctx.send_ttl = BT_MESH_TTL_DEFAULT;
	}

	rx->ctl = CTL(buf->data);
	net_buf_simple_pull(buf, 2); /* SRC, already parsed by net_decrypt() */
	rx->seq = net_seq(buf);
	net_buf_simple_pull(buf, 2);
	rx->dst = net_buf_simple_pull_be16(buf);

	BT_DBG("Decryption successful. Payload len %u", buf->len);

	if (net_if != BT_MESH_NET_IF_PROXY_CFG &&
	    rx->dst == BT_MESH_ADDR_UNASSIGNED) {
		BT_ERR("Destination address is unassigned; dropping packet");
		return -EBADMSG;
	}

	if (BT_MESH_ADDR_IS_RFU(rx->dst)) {
		BT_ERR("Destination address is RFU; dropping packet");
		return -EBADMSG;
	}

	if (net_if != BT_MESH_NET_IF_LOCAL && bt_mesh_elem_find(rx->ctx.addr)) {
		BT_DBG("Dropping locally originated packet");
		return -EBADMSG;
	}

	if (net_if == BT_MESH_NET_IF_ADV) {
		msg_cache_add(rx->hash);
	}

	BT_DBG("src 0x%04x dst 0x%04x ttl %u", rx->ctx.addr, rx->dst,
	       rx->ctx.recv_ttl);
	BT_DBG("PDU: %s", bt_hex(buf->data, buf->len));

	return 0;
}

void bt_mesh_net_recv(struct net_buf_simple *data, s8_t rssi,
		      enum bt_mesh_net_if net_if)
{
	struct net_buf_simple *buf = NET_BUF_SIMPLE(29);
	struct net_buf_simple_state state;
	struct bt_mesh_net_rx rx;

	BT_DBG("rssi %d net_if %u", rssi, net_if);

	if (!bt_mesh_is_provisioned()) {
		return;
	}

	if (bt_mesh_net_decode(data, net_if, &rx, buf, &state)) {
		return;
	}

	if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) &&
	    net_if == BT_MESH_NET_IF_PROXY) {
		bt_mesh_proxy_addr_add(data, rx.ctx.addr);
	}

	if (bt_mesh_fixed_group_match(rx.dst) || bt_mesh_elem_find(rx.dst)) {
		bt_mesh_trans_recv(buf, &rx);

		if (BT_MESH_ADDR_IS_UNICAST(rx.dst)) {
			return;
		}
	}

	net_buf_simple_restore(buf, &state);
	bt_mesh_net_relay(buf, &rx);
}

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

	bt_mesh_beacon_ivu_initiator(true);
	bt_mesh_iv_update(bt_mesh.iv_index, false);
}

void bt_mesh_net_init(void)
{
	k_delayed_work_init(&bt_mesh.ivu_complete, ivu_complete);

	k_work_init(&bt_mesh.local_work, bt_mesh_net_local);
}
