/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2018  Intel Corporation. All rights reserved.
 *
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
#include <ell/ell.h>

#include "mesh/mesh-defs.h"
#include "mesh/util.h"

#include "mesh/display.h"
#include "mesh/crypto.h"
#include "mesh/mesh.h"
#include "mesh/node.h"
#include "mesh/net.h"
#include "mesh/mesh-io.h"
#include "mesh/friend.h"
#include "mesh/storage.h"
#include "mesh/model.h"
#include "mesh/appkey.h"
#include "mesh/prov.h"
#include "mesh/provision.h"

#define abs_diff(a, b) ((a) > (b) ? (a) - (b) : (b) - (a))

#define IV_IDX_DIFF_RANGE	42

/* #define IV_IDX_UPD_MIN	(60)		1 minute for Testing */
#define IV_IDX_UPD_MIN	(60 * 60 * 96)	/* 96 Hours - per Spec */
#define IV_IDX_UPD_HOLD	(IV_IDX_UPD_MIN/2)
#define IV_IDX_UPD_MAX	(IV_IDX_UPD_MIN + IV_IDX_UPD_HOLD)

#define iv_is_updating(net) ((net)->iv_upd_state == IV_UPD_UPDATING)

#define IV_UPDATE_SEQ_TRIGGER 0x800000  /* Half of Seq-Nums expended */

#define SEG_TO	2
#define MSG_TO	60

#define DEFAULT_MIN_DELAY		0
#define DEFAULT_MAX_DELAY		25

#define DEFAULT_TRANSMIT_COUNT		1
#define DEFAULT_TRANSMIT_INTERVAL	100

#define BEACON_TYPE_SNB		0x01

#define BEACON_INTERVAL_MIN	10
#define BEACON_INTERVAL_MAX	600

#define SAR_KEY(src, seq0)	((((uint32_t)(seq0)) << 16) | (src))

enum _iv_upd_state {
	/* Allows acceptance of any iv_index secure net beacon */
	IV_UPD_INIT,
	/* Normal, can transition, accept current or old */
	IV_UPD_NORMAL,
	/* Updating proc running, we use old, accept old or new */
	IV_UPD_UPDATING,
	/* Normal, can *not* transition, accept current or old iv_index */
	IV_UPD_NORMAL_HOLD,
};

struct net_key {
	struct mesh_key_set key_set;
	unsigned int beacon_id;
	uint8_t key[16];
	uint8_t beacon_key[16];
	uint8_t network_id[8];
};

struct mesh_beacon {
	struct l_timeout *timeout;
	uint32_t ts;
	uint16_t observe_period;
	uint16_t observed;
	uint16_t expected;
	uint8_t half_period;
	uint8_t beacon[23];
};

struct mesh_subnet {
	struct mesh_net *net;
	uint16_t idx;
	struct net_key *tx;
	struct net_key current;
	struct net_key updated;
	struct mesh_beacon snb;
	uint8_t key_refresh;
	uint8_t kr_phase;
};

struct mesh_net {
	int ref_count;
	struct mesh_io *io;
	struct mesh_node *local_node;
	struct mesh_prov *prov;
	void *jconfig_local;
	const char *cfg_file;
	struct l_queue *app_keys;
	unsigned int pkt_id;
	unsigned int bea_id;
	unsigned int beacon_id;
	unsigned int key_id_next;
	unsigned int sar_id_next;

	bool friend_enable;
	bool beacon_enable;
	bool proxy_enable;
	bool provisioner;
	bool provisioned;
	bool friend_seq;
	struct l_timeout *iv_update_timeout;
	enum _iv_upd_state iv_upd_state;

	bool iv_update;
	uint32_t instant; /* Controller Instant of recent Rx */
	uint32_t iv_index;
	uint32_t seq_num;
	uint32_t cached_seq_num;
	uint16_t crpl;
	uint16_t src_addr;
	uint16_t last_addr;
	uint16_t friend_addr;
	uint16_t tx_interval;
	uint16_t tx_cnt;
	uint8_t chan; /* Channel of recent Rx */
	uint8_t default_ttl;
	uint8_t tid;
	uint8_t window_accuracy;

	struct {
		bool enable;
		uint16_t interval;
		uint8_t count;
	} relay;

	struct mesh_net_heartbeat heartbeat;

	struct l_queue *subnets;
	struct l_queue *msg_cache;
	struct l_queue *sar_in;
	struct l_queue *sar_out;
	struct l_queue *frnd_msgs;
	struct l_queue *friends;
	struct l_queue *destinations;
	struct l_queue *fast_cache;
	struct l_queue *key_sets;

	uint8_t prov_priv_key[32];

	/* Unprovisioned Identity */
	char id_name[20];
	uint8_t id_uuid[16];

	/* Provisioner: unicast address range */
	struct mesh_net_addr_range prov_uni_addr;

	/* Test Data */
	uint8_t prov_rand[16];
	uint8_t test_bd_addr[6];
	struct mesh_net_prov_caps prov_caps;
	bool test_mode;
};

struct mesh_msg {
	uint16_t src;
	uint32_t seq;
	uint32_t mic;
};

struct mesh_sar {
	unsigned int id;
	struct l_timeout *seg_timeout;
	struct l_timeout *msg_timeout;
	mesh_net_status_func_t status_func;
	void *user_data;
	uint32_t flags;
	uint32_t last_nak;
	uint32_t iv_index;
	uint32_t seqAuth;
	uint16_t seqZero;
	uint16_t app_idx;
	uint16_t src;
	uint16_t remote;
	uint16_t len;
	bool szmic;
	bool frnd;
	bool frnd_cred;
	uint8_t ttl;
	uint8_t last_seg;
	uint8_t key_id;
	uint8_t buf[4]; /* Large enough for ACK-Flags and MIC */
};

struct mesh_destination {
	uint16_t dst;
	uint16_t ref_cnt;
};

struct msg_rx {
	const uint8_t *data;
	uint32_t iv_index;
	uint32_t seq;
	uint16_t src;
	uint16_t dst;
	uint16_t size;
	uint8_t tc;
	bool done;
	bool szmic;
	union {
		struct {
			uint16_t app_idx;
			uint8_t key_id;
		} m;
		struct {
			uint16_t seq0;
		} a;
		struct {
			uint8_t opcode;
		} c;
	} u;
};

struct net_decode {
	struct mesh_net *net;
	struct mesh_friend *frnd;
	struct mesh_key_set *key_set;
	uint8_t *packet;
	uint32_t iv_index;
	uint8_t size;
	uint8_t nid;
	bool proxy;
};

static inline struct mesh_subnet *get_primary_subnet(struct mesh_net *net)
{
	return l_queue_peek_head(net->subnets);
}

static bool match_key_index(const void *a, const void *b)
{
	const struct mesh_subnet *subnet = a;
	uint16_t idx = L_PTR_TO_UINT(b);

	return subnet->idx == idx;
}

static bool match_key_set(const void *a, const void *b)
{
	const struct mesh_subnet *subnet = a;
	const struct mesh_key_set *key_set = b;

	return (key_set == &subnet->current.key_set) ||
					(key_set == &subnet->updated.key_set);
}

static bool match_network_id(const void *a, const void *b)
{
	const struct mesh_subnet *subnet = a;
	const uint8_t *network_id = b;

	return ((memcmp(subnet->current.network_id, network_id, 8) == 0) ||
		(memcmp(subnet->updated.network_id, network_id, 8) == 0));
}

static void idle_mesh_heartbeat_send(void *net)
{
	mesh_net_heartbeat_send(net);
}

static void trigger_heartbeat(struct mesh_net *net, uint16_t feature,
								bool in_use)
{
	struct mesh_net_heartbeat *hb = &net->heartbeat;

	l_info("%s: %4.4x --> %d", __func__, feature, in_use);
	if (in_use) {
		if (net->heartbeat.features & feature)
			return; /* no change */

		hb->features |= feature;
	} else {
		if (!(hb->features & feature))
			return; /* no change */

		hb->features &= ~feature;
	}

	if (!(hb->pub_features & feature))
		return; /* not interested in this feature */

	l_idle_oneshot(idle_mesh_heartbeat_send, net, NULL);

}

static bool match_by_friend(const void *a, const void *b)
{
	const struct mesh_friend *frnd = a;
	uint16_t dst = L_PTR_TO_UINT(b);

	return frnd->dst == dst;
}

static void free_friend_internals(struct mesh_friend *frnd)
{
	if (frnd->pkt_cache)
		l_queue_destroy(frnd->pkt_cache, l_free);

	if (frnd->grp_list)
		l_free(frnd->grp_list);

	frnd->pkt_cache = NULL;
	frnd->grp_list = NULL;
	mesh_net_remove_keyset(frnd->net, &frnd->key_set);
	mesh_net_remove_keyset(frnd->net, &frnd->new_key_set);
}

static void frnd_kr_phase1(void *a, void *b)
{
	struct mesh_friend *frnd = a;
	const uint8_t *key = b;
	uint8_t p[9] = {0x01};

	l_put_be16(frnd->dst, p + 1);
	l_put_be16(frnd->net->src_addr, p + 3);
	l_put_be16(frnd->lp_cnt, p + 5);
	l_put_be16(frnd->fn_cnt, p + 7);

	mesh_crypto_k2(key, p, sizeof(p), &frnd->new_key_set.nid,
				frnd->new_key_set.enc_key,
				frnd->new_key_set.privacy_key);

	mesh_net_add_keyset(frnd->net, &frnd->new_key_set);
	l_info("Add New KeySet %2.2x for %4.4x",
					frnd->new_key_set.nid, frnd->dst);
	l_info("Outgoing with %2.2x", frnd->key_set.nid);
}

static void frnd_kr_phase2(void *a, void *b)
{
	struct mesh_friend *frnd = a;

	/*
	 * I think that a Friend should use Old Key as long as possible
	 * Because a Friend Node will enter Phase 3 before it's LPN.
	 * Alternatively, the FN could keep the Old Friend Keys until it
	 * receives it's first Poll using the new keys (?)
	 */

	l_info("Use Both KeySet %2.2x && %2.2x for %4.4x",
			frnd->key_set.nid, frnd->new_key_set.nid, frnd->dst);
}

static void frnd_kr_phase3(void *a, void *b)
{
	struct mesh_friend *frnd = a;
	struct mesh_net *net = b;

	l_info("Replace KeySet %2.2x with %2.2x for %4.4x",
			frnd->key_set.nid, frnd->new_key_set.nid, frnd->dst);
	frnd->key_set = frnd->new_key_set;
	mesh_net_remove_keyset(net, &frnd->new_key_set);
	frnd->new_key_set.nid = 0xff;
}

/* TODO: add net key idx? For now, use primary net key */
struct mesh_friend *mesh_friend_new(struct mesh_net *net, uint16_t dst,
					uint8_t ele_cnt, uint8_t frd,
					uint8_t frw, uint32_t fpt,
					uint16_t fn_cnt, uint16_t lp_cnt)
{
	struct mesh_subnet *subnet;
	uint8_t p[9] = {0x01};
	struct mesh_friend *frnd = l_queue_find(net->friends,
					match_by_friend, L_UINT_TO_PTR(dst));

	if (frnd) {
		/* Kill all timers and empty cache for this friend */
		free_friend_internals(frnd);
		l_timeout_remove(frnd->timeout);
		frnd->timeout = NULL;
	} else {
		frnd = l_new(struct mesh_friend, 1);
		l_queue_push_head(net->friends, frnd);
	}

	/* add _k2 */
	frnd->net = net;
	frnd->dst = dst;
	frnd->frd = frd;
	frnd->frw = frw;
	frnd->fn_cnt = fn_cnt;
	frnd->lp_cnt = lp_cnt;
	frnd->poll_timeout = fpt;
	frnd->ele_cnt = ele_cnt;
	frnd->pkt_cache = l_queue_new();
	frnd->new_key_set.nid = NET_NID_INVALID;

	l_put_be16(dst, p + 1);
	l_put_be16(net->src_addr, p + 3);
	l_put_be16(lp_cnt, p + 5);
	l_put_be16(fn_cnt, p + 7);

	subnet = get_primary_subnet(net);
	/* TODO: the primary key must be present, do we need to add check?. */

	mesh_crypto_k2(subnet->current.key, p, sizeof(p),
				&frnd->key_set.nid,
				frnd->key_set.enc_key,
				frnd->key_set.privacy_key);

	frnd->key_set.frnd = true;
	mesh_net_add_keyset(net, &frnd->key_set);

	if (subnet->updated.key_set.nid == NET_NID_INVALID)
		return frnd;

	mesh_crypto_k2(subnet->updated.key, p, sizeof(p),
				&frnd->new_key_set.nid,
				frnd->new_key_set.enc_key,
				frnd->new_key_set.privacy_key);
	frnd->new_key_set.frnd = true;
	mesh_net_add_keyset(net, &frnd->new_key_set);

	return frnd;
}

void mesh_friend_free(void *data)
{
	struct mesh_friend *frnd = data;

	free_friend_internals(frnd);
	l_timeout_remove(frnd->timeout);
	l_free(frnd);
}

bool mesh_friend_clear(struct mesh_net *net, struct mesh_friend *frnd)
{
	bool removed = l_queue_remove(net->friends, frnd);

	free_friend_internals(frnd);

	return removed;
}

bool mesh_net_add_keyset(struct mesh_net *net, struct mesh_key_set *key_set)
{
	if (!net)
		return false;

	l_info("Add KEY_SET %2.2x (%d) %p",
					key_set->nid, key_set->frnd, key_set);
	return l_queue_push_tail(net->key_sets, key_set);
}

bool mesh_net_remove_keyset(struct mesh_net *net, struct mesh_key_set *key_set)
{
	if (!net || !net->key_sets)
		return false;

	l_info("DEL KEY_SET %2.2x (%d) %p",
					key_set->nid, key_set->frnd, key_set);
	return l_queue_remove(net->key_sets, key_set);
}

void mesh_friend_sub_add(struct mesh_net *net, uint16_t lpn, uint8_t ele_cnt,
							uint8_t grp_cnt,
							const uint8_t *list)
{
	uint16_t *new_list;
	uint16_t *grp_list;
	struct mesh_friend *frnd = l_queue_find(net->friends,
							match_by_friend,
							L_UINT_TO_PTR(lpn));
	if (!frnd)
		return;

	new_list = l_malloc((grp_cnt + frnd->grp_cnt) * sizeof(uint16_t));
	grp_list = frnd->grp_list;

	if (grp_list && frnd->grp_cnt)
		memcpy(new_list, grp_list, frnd->grp_cnt * sizeof(uint16_t));

	memcpy(&new_list[frnd->grp_cnt], list, grp_cnt * sizeof(uint16_t));
	l_free(grp_list);
	frnd->ele_cnt = ele_cnt;
	frnd->grp_list = new_list;
	frnd->grp_cnt += grp_cnt;
}

void mesh_friend_sub_del(struct mesh_net *net, uint16_t lpn,
						uint8_t cnt,
						const uint8_t *del_list)
{
	uint16_t *grp_list;
	int16_t i, grp_cnt;
	size_t cnt16 = cnt * sizeof(uint16_t);
	struct mesh_friend *frnd = l_queue_find(net->friends,
							match_by_friend,
							L_UINT_TO_PTR(lpn));
	if (!frnd)
		return;

	grp_cnt = frnd->grp_cnt;
	grp_list = frnd->grp_list;

	while (cnt-- && grp_cnt) {
		cnt16 -= sizeof(uint16_t);
		for (i = grp_cnt - 1; i >= 0; i--) {
			if (l_get_le16(del_list + cnt16) == grp_list[i]) {
				grp_cnt--;
				memcpy(&grp_list[i], &grp_list[i + 1],
					(grp_cnt - i) * sizeof(uint16_t));
				break;
			}
		}
	}

	frnd->grp_cnt = grp_cnt;

	if (!grp_cnt) {
		l_free(frnd->grp_list);
		frnd->grp_list = NULL;
	}
}

uint32_t mesh_net_next_seq_num(struct mesh_net *net)
{
	uint32_t seq = net->seq_num;

	net->seq_num++;

	/* Periodically store advanced sequence number */
	if (net->seq_num + MIN_SEQ_TRIGGER >= net->cached_seq_num) {
		net->cached_seq_num = net->seq_num +
					node_seq_cache(net->local_node);
		node_set_sequence_number(net->local_node, net->cached_seq_num);
	}

	return seq;
}

static struct mesh_sar *mesh_sar_new(size_t len)
{
	size_t size = sizeof(struct mesh_sar) + len;
	struct mesh_sar *sar;

	sar = l_malloc(size);

	memset(sar, 0, size);

	return sar;
}

static void mesh_sar_free(void *data)
{
	struct mesh_sar *sar = data;

	if (!sar)
		return;

	l_timeout_remove(sar->seg_timeout);
	l_timeout_remove(sar->msg_timeout);
	l_free(sar);
}

static void mesh_msg_free(void *data)
{
	struct mesh_msg *msg = data;

	l_free(msg);
}

static void lpn_process_beacon(void *user_data, const void *data, uint8_t size,
								int8_t rssi);

static struct mesh_subnet *subnet_new(struct mesh_net *net, uint16_t idx)
{
	struct mesh_subnet *subnet;

	subnet = l_new(struct mesh_subnet, 1);
	if (!subnet)
		return NULL;

	subnet->net = net;
	subnet->idx = idx;
	subnet->tx = &subnet->current;
	subnet->updated.key_set.nid = NET_NID_INVALID;
	subnet->snb.beacon[0] = MESH_AD_TYPE_BEACON;
	return subnet;
}

static bool create_keys(struct mesh_net *net, struct net_key *keys,
			const uint8_t *net_key)
{
	uint8_t nid[1];
	uint8_t enc_key[16];
	uint8_t privacy_key[16];
	uint8_t network_id[8];
	uint8_t p[] = {0};

	if (!mesh_crypto_k2(net_key, p, sizeof(p),
				nid, enc_key, privacy_key))
		return false;

	if (!mesh_crypto_k3(net_key, network_id))
		return false;

	if (!mesh_crypto_nkbk(net_key, keys->beacon_key))
		return false;

	keys->key_set.frnd = false;
	keys->key_set.nid = nid[0];
	memcpy(keys->key_set.enc_key, enc_key, 16);
	memcpy(keys->key_set.privacy_key, privacy_key, 16);
	memcpy(keys->network_id, network_id, 8);
	memcpy(keys->key, net_key, 16);
	return true;
}

static bool create_secure_beacon(struct mesh_net *net,
					struct mesh_subnet *subnet,
					uint8_t *beacon_data, uint8_t size)
{
	uint64_t cmac;

	if (size < 22)
		return false;

	beacon_data[0] = BEACON_TYPE_SNB;
	beacon_data[1] = 0;

	if (subnet->key_refresh)
		beacon_data[1] |= 0x01;

	if (iv_is_updating(net))
		beacon_data[1] |= 0x02;

	memcpy(beacon_data + 2, subnet->tx->network_id, 8);
	l_put_be32(net->iv_index, beacon_data + 10);

	if (!mesh_crypto_beacon_cmac(subnet->tx->beacon_key,
					subnet->tx->network_id,
					net->iv_index, subnet->key_refresh,
					iv_is_updating(net), &cmac))
		return false;

	l_put_be64(cmac, beacon_data + 14);

	return true;
}

static void send_network_beacon(struct mesh_subnet *subnet,
							struct mesh_net *net)
{
	struct mesh_io_send_info info = {
		.type = MESH_IO_TIMING_TYPE_GENERAL,
		.u.gen.interval = net->tx_interval,
		.u.gen.cnt = 1,
		.u.gen.min_delay = DEFAULT_MIN_DELAY,
		.u.gen.max_delay = DEFAULT_MAX_DELAY
	};

	l_info("Send SNB on network %3.3x", subnet->idx);
	mesh_io_send(net->io, &info, subnet->snb.beacon,
						sizeof(subnet->snb.beacon));
}

static void network_beacon_timeout(struct l_timeout *timeout, void *user_data)
{
	struct mesh_subnet *subnet = user_data;
	uint32_t interval;

	send_network_beacon(subnet, subnet->net);

	if (!subnet->snb.half_period) {
		l_debug("beacon TO period %d, observed %d, expected %d",
						subnet->snb.observe_period,
						subnet->snb.observed,
						subnet->snb.expected);
		interval = subnet->snb.observe_period *
			(subnet->snb.observed + 1) / subnet->snb.expected;
		subnet->snb.observe_period = interval * 2;
		subnet->snb.expected = subnet->snb.observe_period / 10;
		subnet->snb.observed = 0;
	} else
		interval = subnet->snb.observe_period / 2;

	if (interval < BEACON_INTERVAL_MIN)
		interval = BEACON_INTERVAL_MIN;

	if (interval > BEACON_INTERVAL_MAX)
		interval = BEACON_INTERVAL_MAX;

	subnet->snb.ts = get_timestamp_secs();
	subnet->snb.half_period ^= 1;
	l_timeout_modify(timeout, interval);
}

static void start_network_beacon(void *a, void *b)
{
	struct mesh_subnet *subnet = a;
	struct mesh_net *net = b;

	if (!net->beacon_enable) {
		if (subnet->snb.timeout)
			l_timeout_remove(subnet->snb.timeout);
		subnet->snb.timeout = NULL;
		return;
	}

	/* If timeout is active, let it run it's course */
	if (subnet->snb.timeout)
		return;

	send_network_beacon(subnet, subnet->net);

	subnet->snb.ts = get_timestamp_secs();
	subnet->snb.expected = 2;
	subnet->snb.observed = 0;
	subnet->snb.half_period = 1;
	subnet->snb.observe_period = BEACON_INTERVAL_MIN * 2;

	subnet->snb.timeout = l_timeout_create(BEACON_INTERVAL_MIN,
				network_beacon_timeout, subnet, NULL);
}

struct mesh_net *mesh_net_new(uint16_t index)
{
	struct mesh_net *net;

	net = l_new(struct mesh_net, 1);

	if (!net)
		return NULL;

	net->pkt_id = 0;
	net->bea_id = 0;
	net->key_id_next = 0;

	net->beacon_enable = true;
	net->proxy_enable = false;
	net->relay.enable = false;

	net->seq_num = 0x000000;
	net->src_addr = 0x0000;
	net->default_ttl = 0x00;

	net->provisioner = false;

	net->test_mode = false;
	memset(&net->prov_caps, 0, sizeof(net->prov_caps));
	net->prov_caps.algorithms = 1;

	net->tx_cnt = DEFAULT_TRANSMIT_COUNT;
	net->tx_interval = DEFAULT_TRANSMIT_INTERVAL;

	net->subnets = l_queue_new();
	net->key_sets = l_queue_new();
	net->fast_cache = l_queue_new();
	net->msg_cache = l_queue_new();
	net->sar_in = l_queue_new();
	net->sar_out = l_queue_new();
	net->frnd_msgs = l_queue_new();
	net->friends = l_queue_new();
	net->destinations = l_queue_new();
	net->app_keys = l_queue_new();

	memset(&net->heartbeat, 0, sizeof(net->heartbeat));

	return mesh_net_ref(net);
}

struct mesh_net *mesh_net_ref(struct mesh_net *net)
{
	if (!net)
		return NULL;

	__sync_fetch_and_add(&net->ref_count, 1);

	return net;
}

void mesh_net_unref(struct mesh_net *net)
{
	if (!net)
		return;

	if (__sync_sub_and_fetch(&net->ref_count, 1))
		return;

	/* key_sets are not allocated to this queue. Only Borrowed */
	l_queue_destroy(net->key_sets, NULL);
	net->key_sets = NULL;

	l_queue_destroy(net->subnets, l_free);
	l_queue_destroy(net->fast_cache, mesh_msg_free);
	l_queue_destroy(net->msg_cache, mesh_msg_free);
	l_queue_destroy(net->sar_in, mesh_sar_free);
	l_queue_destroy(net->sar_out, mesh_sar_free);
	l_queue_destroy(net->frnd_msgs, l_free);
	l_queue_destroy(net->friends, mesh_friend_free);
	l_queue_destroy(net->destinations, l_free);
	l_queue_destroy(net->app_keys, appkey_key_free);

	l_free(net);
}

bool mesh_net_set_seq_num(struct mesh_net *net, uint32_t number)
{
	if (!net)
		return false;

	net->cached_seq_num = net->seq_num = number;

	return true;
}

bool mesh_net_set_default_ttl(struct mesh_net *net, uint8_t ttl)
{
	if (!net)
		return false;

	net->default_ttl = ttl;

	return true;
}

uint32_t mesh_net_get_seq_num(struct mesh_net *net)
{
	if (!net)
		return 0;

	return net->seq_num;
}

uint8_t mesh_net_get_default_ttl(struct mesh_net *net)
{
	if (!net)
		return 0;

	return net->default_ttl;
}

uint16_t mesh_net_get_address(struct mesh_net *net)
{
	if (!net)
		return 0;

	return net->src_addr;
}

bool mesh_net_register_unicast(struct mesh_net *net,
					uint16_t address, uint8_t num_ele)
{
	if (!net || !IS_UNICAST(address) || !num_ele)
		return false;

	l_info("mesh_net_set_address: 0x%x", address);
	net->src_addr = address;
	net->last_addr = address + num_ele - 1;
	if (net->last_addr < net->src_addr)
		return false;

	do {
		mesh_net_dst_reg(net, address);
		address++;
		num_ele--;
	} while (num_ele > 0);

	return true;
}

uint8_t mesh_net_get_num_ele(struct mesh_net *net)
{
	if (!net)
		return 0;

	return net->last_addr - net->src_addr + 1;
}

bool mesh_net_set_proxy_mode(struct mesh_net *net, bool enable)
{
	if (!net)
		return false;

	/* No support for proxy yet */
	if (enable) {
		l_error("Proxy not supported!");
		return false;
	}

	trigger_heartbeat(net, FEATURE_PROXY, enable);
	return true;
}

bool mesh_net_set_friend_mode(struct mesh_net *net, bool enable)
{
	if (!net)
		return false;

	if (net->friend_enable && !enable)
		l_queue_clear(net->friends, mesh_friend_free);

	net->friend_enable = enable;
	trigger_heartbeat(net, FEATURE_FRIEND, enable);
	return true;
}

bool mesh_net_set_relay_mode(struct mesh_net *net, bool enable,
				uint8_t cnt, uint8_t interval)
{
	if (!net)
		return false;

	net->relay.enable = enable;
	net->relay.count = cnt;
	net->relay.interval = interval;
	trigger_heartbeat(net, FEATURE_RELAY, enable);
	return true;
}

struct mesh_net_prov_caps *mesh_net_prov_caps_get(struct mesh_net *net)
{
	if (net)
		return &net->prov_caps;

	return NULL;
}

char *mesh_net_id_name(struct mesh_net *net)
{
	if (net && net->id_name[0])
		return net->id_name;

	return NULL;
}

bool mesh_net_id_uuid_set(struct mesh_net *net, uint8_t uuid[16])
{
	if (!net)
		return false;

	memcpy(net->id_uuid, uuid, 16);

	return true;
}

uint8_t *mesh_net_priv_key_get(struct mesh_net *net)
{
	if (net)
		return net->prov_priv_key;

	return NULL;
}

bool mesh_net_priv_key_set(struct mesh_net *net, uint8_t key[32])
{
	if (!net)
		return false;

	memcpy(net->prov_priv_key, key, 32);
	return true;
}

uint8_t *mesh_net_test_addr(struct mesh_net *net)
{
	const uint8_t zero_addr[] = {0, 0, 0, 0, 0, 0};

	if (net && memcmp(net->test_bd_addr, zero_addr, 6))
		return net->test_bd_addr;

	return NULL;
}

uint8_t *mesh_net_prov_rand(struct mesh_net *net)
{
	if (net)
		return net->prov_rand;

	return NULL;
}

uint16_t mesh_net_prov_uni(struct mesh_net *net, uint8_t ele_cnt)
{
	uint16_t uni;
	uint16_t next;

	if (!net)
		return 0;

	next = net->prov_uni_addr.next + ele_cnt;
	if (next > 0x8000 || next > net->prov_uni_addr.high)
		return UNASSIGNED_ADDRESS;

	uni = net->prov_uni_addr.next;
	net->prov_uni_addr.next = next;

	return uni;
}

bool mesh_net_test_mode(struct mesh_net *net)
{
	if (net)
		return net->test_mode;

	return false;
}

int mesh_net_get_identity_mode(struct mesh_net *net, uint16_t idx,
								uint8_t *mode)
{
	struct mesh_subnet *subnet;

	if (!net)
		return MESH_STATUS_UNSPECIFIED_ERROR;

	subnet = l_queue_find(net->subnets, match_key_index,
							L_UINT_TO_PTR(idx));
	if (!subnet)
		return MESH_STATUS_INVALID_NETKEY;

	/* Currently, proxy mode is not supported */
	*mode = MESH_MODE_UNSUPPORTED;

	return MESH_STATUS_SUCCESS;
}

int mesh_net_del_key(struct mesh_net *net, uint16_t idx)
{
	struct mesh_subnet *subnet;

	if (!net)
		return MESH_STATUS_UNSPECIFIED_ERROR;

	/* Cannot remove primary key */
	if (l_queue_length(net->subnets) <= 1)
		return MESH_STATUS_CANNOT_REMOVE;

	subnet = l_queue_find(net->subnets, match_key_index,
							L_UINT_TO_PTR(idx));
	if (!subnet)
		return MESH_STATUS_CANNOT_REMOVE;

	/* Delete associated app keys */
	appkey_delete_bound_keys(net, idx);

	/* Disable hearbeat publication on this subnet */
	if (idx == net->heartbeat.pub_net_idx)
		net->heartbeat.pub_dst = UNASSIGNED_ADDRESS;

	mesh_net_remove_keyset(net, &subnet->current.key_set);
	mesh_net_remove_keyset(net, &subnet->updated.key_set);

	/* TODO: cancel beacon_enable on this subnet */

	l_queue_remove(net->subnets, subnet);
	if (!storage_local_net_key_del(net, idx))
		return MESH_STATUS_STORAGE_FAIL;

	return MESH_STATUS_SUCCESS;
}

int mesh_net_add_key(struct mesh_net *net, bool update, uint16_t idx,
							const void *value)
{
	int status;
	struct mesh_subnet *subnet;

	subnet = l_queue_find(net->subnets, match_key_index,
							L_UINT_TO_PTR(idx));

	if (update) {
		if (subnet && subnet->kr_phase == KEY_REFRESH_PHASE_NONE) {
			l_info("Start key refresh");
			status = mesh_net_kr_phase_one(net, idx, value);
			if (status == MESH_STATUS_SUCCESS &&
				!storage_local_net_key_add(net, idx,
						value, KEY_REFRESH_PHASE_ONE))
				return MESH_STATUS_STORAGE_FAIL;
		} else
			return MESH_STATUS_CANNOT_UPDATE;
	}

	if (subnet)
		return memcmp(subnet->current.key, value, 16) ?
			MESH_STATUS_IDX_ALREADY_STORED : MESH_STATUS_SUCCESS;

	subnet = subnet_new(net, idx);
	if (!subnet)
		return MESH_STATUS_INSUFF_RESOURCES;

	if (!create_keys(net, &subnet->current, value) ||
			!mesh_net_add_keyset(net, &subnet->current.key_set)) {
		l_free(subnet);
		return MESH_STATUS_INSUFF_RESOURCES;
	}

	if (!create_secure_beacon(net, subnet, &subnet->snb.beacon[1], 22) ||
				!l_queue_push_tail(net->subnets, subnet)) {
		mesh_net_remove_keyset(net, &subnet->current.key_set);
		l_free(subnet);
		return MESH_STATUS_INSUFF_RESOURCES;
	}

	if (!storage_local_net_key_add(net, idx, value,
					KEY_REFRESH_PHASE_NONE)) {
		l_queue_remove(net->subnets, subnet);
		mesh_net_remove_keyset(net, &subnet->current.key_set);
		l_free(subnet);
		return MESH_STATUS_STORAGE_FAIL;
	}

	start_network_beacon(subnet, net);

	return MESH_STATUS_SUCCESS;
}

void mesh_net_flush_msg_queues(struct mesh_net *net)
{
	l_queue_clear(net->msg_cache, mesh_msg_free);
	l_queue_clear(net->fast_cache, mesh_msg_free);
}

uint32_t mesh_net_get_iv_index(struct mesh_net *net)
{
	if (!net)
		return 0xffffffff;

	return net->iv_index - (iv_is_updating(net) ? 1 : 0);
}

/* TODO: net key index? */
void mesh_net_get_snb_state(struct mesh_net *net, uint8_t *flags,
							uint32_t *iv_index)
{
	struct mesh_subnet *subnet;

	if (!net || !flags || !iv_index)
		return;

	*iv_index = net->iv_index;
	*flags = (net->iv_upd_state == IV_UPD_UPDATING) ? 0x02 : 0x00;

	subnet = get_primary_subnet(net);
	if (subnet)
		*flags |= subnet->key_refresh ? 0x01 : 0x00;
}

bool mesh_net_get_key(struct mesh_net *net, bool new_key, uint16_t idx,
							uint8_t key_buf[16])
{
	struct mesh_subnet *subnet;

	if (!net)
		return false;

	subnet = l_queue_find(net->subnets, match_key_index,
							L_UINT_TO_PTR(idx));
	if (!subnet)
		return false;

	if (!new_key) {
		memcpy(key_buf, subnet->current.key, 16);
		return true;
	}

	if (subnet->updated.key_set.nid == NET_NID_INVALID)
		return false;

	memcpy(key_buf, subnet->updated.key, 16);
	return true;
}

bool mesh_net_key_list_get(struct mesh_net *net, uint8_t *buf, uint16_t *size)
{
	const struct l_queue_entry *entry;
	uint16_t n, buf_size;

	if (!net || !buf || !size)
		return false;

	buf_size = *size;
	if (buf_size < l_queue_length(net->subnets) * 2)
		return false;

	n = 0;
	entry = l_queue_get_entries(net->subnets);

	for (; entry; entry = entry->next) {
		struct mesh_subnet *subnet = entry->data;

		l_put_le16(subnet->idx, buf);
		n += 2;
	}

	*size = n;
	return true;
}

bool mesh_net_get_frnd_seq(struct mesh_net *net)
{
	if (!net)
		return false;

	return net->friend_seq;
}

void mesh_net_set_frnd_seq(struct mesh_net *net, bool seq)
{
	if (!net)
		return;

	net->friend_seq = seq;
}

static bool match_cache(const void *a, const void *b)
{
	const struct mesh_msg *msg = a;
	const struct mesh_msg *tst = b;

	if (msg->seq != tst->seq || msg->mic != tst->mic ||
					msg->src != tst->src)
		return false;

	return true;
}

static bool msg_in_cache(struct mesh_net *net, uint16_t src, uint32_t seq,
								uint32_t mic)
{
	struct mesh_msg *msg;
	struct mesh_msg tst = {
		.src = src,
		.seq = seq,
		.mic = mic,
	};

	msg = l_queue_remove_if(net->msg_cache, match_cache, &tst);

	if (msg) {
		l_debug("Supressing duplicate %4.4x + %6.6x + %8.8x",
							src, seq, mic);
		l_queue_push_head(net->msg_cache, msg);
		return true;
	}

	msg = l_new(struct mesh_msg, 1);
	*msg = tst;
	l_queue_push_head(net->msg_cache, msg);
	l_debug("Add %4.4x + %6.6x + %8.8x", src, seq, mic);

	if (l_queue_length(net->msg_cache) > MSG_CACHE_SIZE) {
		msg = l_queue_peek_tail(net->msg_cache);
		/* Remove Tail (oldest msg in cache) */
		l_debug("Remove %4.4x + %6.6x + %8.8x",
						msg->src, msg->seq, msg->mic);
		if (l_queue_remove(net->msg_cache, msg))
			l_free(msg);
	}

	return false;
}

static bool match_sar_seq0(const void *a, const void *b)
{
	const struct mesh_sar *sar = a;
	uint16_t seqZero = L_PTR_TO_UINT(b);

	return sar->seqZero == seqZero;
}

static bool match_sar_remote(const void *a, const void *b)
{
	const struct mesh_sar *sar = a;
	uint16_t remote = L_PTR_TO_UINT(b);

	return sar->remote == remote;
}

static bool match_msg_timeout(const void *a, const void *b)
{
	const struct mesh_sar *sar = a;
	const struct l_timeout *msg_timeout = b;

	return sar->msg_timeout == msg_timeout;
}

static bool match_sar_id(const void *a, const void *b)
{
	const struct mesh_sar *sar = a;
	unsigned int id = L_PTR_TO_UINT(b);

	return sar->id == id;
}

static bool match_seg_timeout(const void *a, const void *b)
{
	const struct mesh_sar *sar = a;
	const struct l_timeout *seg_timeout = b;

	return sar->seg_timeout == seg_timeout;
}

static bool match_dest_dst(const void *a, const void *b)
{
	const struct mesh_destination *dest = a;
	uint16_t dst = L_PTR_TO_UINT(b);

	return dst == dest->dst;
}

static bool match_frnd_dst(const void *a, const void *b)
{
	const struct mesh_friend *frnd = a;
	uint16_t dst = L_PTR_TO_UINT(b);
	int16_t i, grp_cnt = frnd->grp_cnt;
	uint16_t *grp_list = frnd->grp_list;

	/*
	 * Determine if this message is for this friends unicast
	 * address, and/or one of it's group/virtual addresses
	 */
	if (dst >= frnd->dst && dst < (frnd->dst + frnd->ele_cnt))
		return true;

	if (!(dst & 0x8000))
		return false;

	for (i = 0; i < grp_cnt; i++) {
		if (dst == grp_list[i])
			return true;
	}

	return false;
}

static bool is_lpn_friend(struct mesh_net *net, uint16_t addr, bool frnd)
{
	void *tst;

	if (!frnd)
		return false;

	tst = l_queue_find(net->friends, match_frnd_dst, L_UINT_TO_PTR(addr));

	return tst != NULL;
}

static bool is_us(struct mesh_net *net, uint16_t addr, bool src)
{
	void *tst;

	if (IS_ALL_NODES(addr))
		return true;

	if (addr == FRIENDS_ADDRESS)
		return net->friend_enable;

	if (addr == RELAYS_ADDRESS)
		return net->relay.enable;

	if (addr == PROXIES_ADDRESS)
		return net->proxy_enable;

	if (addr >= net->src_addr && addr <= net->last_addr)
		return true;

	tst = l_queue_find(net->destinations, match_dest_dst,
							L_UINT_TO_PTR(addr));

	if (tst == NULL && !src)
		tst = l_queue_find(net->friends, match_frnd_dst,
							L_UINT_TO_PTR(addr));

	return tst != NULL;
}

static struct mesh_friend_msg *mesh_friend_msg_new(uint8_t seg_max)
{
	struct mesh_friend_msg *frnd_msg;

	if (seg_max) {
		size_t size = sizeof(struct mesh_friend_msg) -
					sizeof(struct mesh_friend_seg_one);

		size += (seg_max + 1) * sizeof(struct mesh_friend_seg_12);
		frnd_msg =  (struct mesh_friend_msg *) l_new(uint8_t, size);
	} else
		frnd_msg = l_new(struct mesh_friend_msg, 1);


	return frnd_msg;
}


static bool match_ack(const void *a, const void *b)
{
	const struct mesh_friend_msg *old = a;
	const struct mesh_friend_msg *rx = b;
	uint32_t old_hdr;
	uint32_t new_hdr;

	/* Determine if old pkt is ACK to same SAR message that new ACK is */
	if (!old->ctl || old->src != rx->src)
		return false;

	/* Check the quickest items first before digging deeper */
	old_hdr = old->u.one[0].hdr & HDR_ACK_MASK;
	new_hdr = rx->u.one[0].hdr & HDR_ACK_MASK;

	return old_hdr == new_hdr;
}

static void enqueue_friend_pkt(void *a, void *b)
{
	struct mesh_friend *frnd = a;
	struct mesh_friend_msg *pkt, *rx = b;
	size_t size;
	int16_t i;

	if (rx->done)
		return;

	/*
	 * Determine if this message is for this friends unicast
	 * address, and/or one of it's group/virtual addresses
	 */
	if (rx->dst >= frnd->dst && (rx->dst - frnd->dst) < frnd->ele_cnt) {
		rx->done = true;
		goto enqueue;
	}

	if (!(rx->dst & 0x8000))
		return;

	if (!IS_ALL_NODES(rx->dst)) {
		for (i = 0; i < frnd->grp_cnt; i++) {
			if (rx->dst == frnd->grp_list[i])
				goto enqueue;
		}
		return;
	}

enqueue:
	/* Special handling for Seg Ack -- Only one per message queue */
	if (((rx->u.one[0].hdr >> OPCODE_HDR_SHIFT) & OPCODE_MASK) ==
						NET_OP_SEG_ACKNOWLEDGE) {
		void *old_head = l_queue_peek_head(frnd->pkt_cache);
		/* Suppress duplicate ACKs */
		do {
			void *old = l_queue_remove_if(frnd->pkt_cache,
							match_ack, rx);

			if (old) {
				if (old_head == old) {
					/*
					 * If we are discarding head for any
					 * reason, reset FRND SEQ
					 */
					frnd->last = frnd->seq;
				}

				l_free(old);
			} else
				break;

		} while (true);
	}

	l_debug("%s for %4.4x from %4.4x ttl: %2.2x (seq: %6.6x) (ctl: %d)",
			__func__, frnd->dst, rx->src, rx->ttl,
			rx->u.one[0].seq, rx->ctl);

	if (rx->cnt_in) {
		size = sizeof(struct mesh_friend_msg) -
				sizeof(struct mesh_friend_seg_one);
		size += (rx->cnt_in + 1) * sizeof(struct mesh_friend_seg_12);
	} else
		size = sizeof(struct mesh_friend_msg);

	pkt = l_malloc(size);
	memcpy(pkt, rx, size);

	l_queue_push_tail(frnd->pkt_cache, pkt);

	if (l_queue_length(frnd->pkt_cache) > FRND_CACHE_MAX) {
		/*
		 * TODO: Guard against popping UPDATE packets
		 * (disallowed per spec)
		 */
		pkt = l_queue_pop_head(frnd->pkt_cache);
		l_free(pkt);
		frnd->last = frnd->seq;
	}
}

static void enqueue_update(void *a, void *b)
{
	struct mesh_friend *frnd = a;
	struct mesh_friend_msg *pkt = b;

	pkt->dst = frnd->dst;
	pkt->done = false;
	enqueue_friend_pkt(frnd, pkt);
}

static uint32_t seq_auth(uint32_t seq, uint16_t seqZero)
{
	uint32_t seqAuth = seqZero & SEQ_ZERO_MASK;

	seqAuth |= seq & (~SEQ_ZERO_MASK);
	if (seqAuth > seq)
		seqAuth -= (SEQ_ZERO_MASK + 1);

	return seqAuth;
}

static bool friend_packet_queue(struct mesh_net *net,
					uint32_t iv_index,
					bool ctl, uint8_t ttl,
					uint32_t seq,
					uint16_t src, uint16_t dst,
					uint32_t hdr,
					const uint8_t *data, uint16_t size)
{
	struct mesh_friend_msg *frnd_msg;
	uint8_t seg_max = SEG_TOTAL(hdr);
	bool ret;

	if (seg_max && !IS_SEGMENTED(hdr))
		return false;

	frnd_msg = mesh_friend_msg_new(seg_max);

	if (IS_SEGMENTED(hdr)) {
		uint32_t seqAuth = seq_auth(seq, hdr >> SEQ_ZERO_HDR_SHIFT);
		uint8_t i;

		for (i = 0; i <= seg_max; i++) {
			memcpy(frnd_msg->u.s12[i].data, data, 12);
			frnd_msg->u.s12[i].hdr = hdr;
			frnd_msg->u.s12[i].seq = seqAuth + i;
			data += 12;
			hdr += (1 << SEGO_HDR_SHIFT);
		}
		frnd_msg->u.s12[seg_max].seq = seq;
		frnd_msg->cnt_in = seg_max;
		frnd_msg->last_len = size % 12;
		if (!frnd_msg->last_len)
			frnd_msg->last_len = 12;
	} else {
		uint8_t opcode = hdr >> OPCODE_HDR_SHIFT;

		if (ctl && opcode != NET_OP_SEG_ACKNOWLEDGE) {

			/* Don't cache Friend Ctl opcodes */
			if (FRND_OPCODE(opcode)) {
				l_free(frnd_msg);
				return false;
			}

			memcpy(frnd_msg->u.one[0].data + 1, data, size);
			frnd_msg->last_len = size + 1;
			frnd_msg->u.one[0].data[0] = opcode;
		} else {
			memcpy(frnd_msg->u.one[0].data, data, size);
			frnd_msg->last_len = size;
		}
		frnd_msg->u.one[0].hdr = hdr;
		frnd_msg->u.one[0].seq = seq;
	}

	frnd_msg->iv_index = iv_index;
	frnd_msg->src = src;
	frnd_msg->dst = dst;
	frnd_msg->ctl = ctl;
	frnd_msg->ttl = ttl;

	/* Re-Package into Friend Delivery payload */
	l_queue_foreach(net->friends, enqueue_friend_pkt, frnd_msg);
	ret = frnd_msg->done;

	/* TODO Optimization(?): Unicast messages keep this buffer */
	l_free(frnd_msg);

	return ret;
}

static void friend_ack_rxed(struct mesh_net *net, uint32_t iv_index,
					uint32_t seq,
					uint16_t src, uint16_t dst,
					const uint8_t *pkt)
{
	uint32_t hdr = l_get_be32(pkt) &
		((SEQ_ZERO_MASK << SEQ_ZERO_HDR_SHIFT) | /* Preserve SeqZero */
		 (true << RELAY_HDR_SHIFT));		/* Preserve Relay bit */
	uint32_t flags = l_get_be32(pkt + 3);
	struct mesh_friend_msg frnd_ack = {
		.ctl = true,
		.iv_index = iv_index,
		.src = src,
		.dst = dst,
		.last_len = sizeof(flags),
		.u.one[0].seq = seq,
		.done = false,
	};

	hdr |= NET_OP_SEG_ACKNOWLEDGE << OPCODE_HDR_SHIFT;
	frnd_ack.u.one[0].hdr = hdr;
	l_put_be32(flags, frnd_ack.u.one[0].data);
	l_queue_foreach(net->friends, enqueue_friend_pkt, &frnd_ack);
}

static bool send_seg(struct mesh_net *net, struct mesh_sar *msg, uint8_t seg);

static void send_frnd_ack(struct mesh_net *net, uint16_t src, uint16_t dst,
						uint32_t hdr, uint32_t flags)
{
	uint32_t expected;
	uint8_t msg[7];

	/* We don't ACK from multicast destinations */
	if (src & 0x8000)
		return;

	/* Calculate the "Full ACK" mask */
	expected = 0xffffffff >> (31 - SEG_TOTAL(hdr));

	/* Clear Hdr bits that don't apply to Seg ACK */
	hdr &= ~((true << SEG_HDR_SHIFT) |
			(OPCODE_MASK << OPCODE_HDR_SHIFT) |
			(true << SZMIC_HDR_SHIFT) |
			(SEG_MASK << SEGO_HDR_SHIFT) |
			(SEG_MASK << SEGN_HDR_SHIFT));

	hdr |= NET_OP_SEG_ACKNOWLEDGE << OPCODE_HDR_SHIFT;
	hdr |= true << RELAY_HDR_SHIFT;

	/* Clear all unexpected bits */
	flags &= expected;

	l_put_be32(hdr, msg);
	l_put_be32(flags, msg + 3);

	l_info("Send Friend ACK to Segs: %8.8x", flags);

	if (is_lpn_friend(net, dst, true)) {
		/* If we are acking our LPN Friend, queue, don't send */
		friend_ack_rxed(net, mesh_net_get_iv_index(net),
				mesh_net_next_seq_num(net), 0, dst, msg);
	} else {
		mesh_net_transport_send(net, NULL, false,
				mesh_net_get_iv_index(net), DEFAULT_TTL,
				0, 0, dst, msg, sizeof(msg));
	}
}

static void send_net_ack(struct mesh_net *net, struct mesh_sar *sar,
								uint32_t flags)
{
	uint8_t msg[7];
	uint32_t hdr;
	uint16_t src = sar->src;
	uint16_t dst = sar->remote;

	/* We don't ACK from multicast destinations */
	if (src & 0x8000)
		return;

	/* We don't ACK segments as a Low Power Node */
	if (net->friend_addr)
		return;

	hdr = NET_OP_SEG_ACKNOWLEDGE << OPCODE_HDR_SHIFT;
	hdr |= sar->seqZero << SEQ_ZERO_HDR_SHIFT;

	if (is_lpn_friend(net, src, true))
		hdr |= true << RELAY_HDR_SHIFT;

	l_put_be32(hdr, msg);
	l_put_be32(flags, msg + 3);
	l_info("Send%s ACK to Segs: %8.8x", sar->frnd ? " Friend" : "", flags);

	if (is_lpn_friend(net, dst, true)) {
		/* If we are acking our LPN Friend, queue, don't send */
		friend_ack_rxed(net, mesh_net_get_iv_index(net),
				mesh_net_next_seq_num(net), src, dst, msg);
		return;
	}

	mesh_net_transport_send(net, NULL, false,
				mesh_net_get_iv_index(net), DEFAULT_TTL,
				0, src, dst, msg, sizeof(msg));
}

static void inseg_to(struct l_timeout *seg_timeout, void *user_data)
{
	struct mesh_net *net = user_data;
	struct mesh_sar *sar = l_queue_find(net->sar_in,
					match_seg_timeout, seg_timeout);

	l_timeout_remove(seg_timeout);
	if (!sar)
		return;

	/* Send NAK */
	l_info("Timeout %p %3.3x", sar, sar->app_idx);
	send_net_ack(net, sar, sar->flags);

	sar->seg_timeout = l_timeout_create(SEG_TO, inseg_to, net, NULL);
}

static void inmsg_to(struct l_timeout *msg_timeout, void *user_data)
{
	struct mesh_net *net = user_data;
	struct mesh_sar *sar = l_queue_remove_if(net->sar_in,
			match_msg_timeout, msg_timeout);

	l_timeout_remove(msg_timeout);
	if (!sar)
		return;

	sar->msg_timeout = NULL;

	/* print_packet("Incoming SAR Timeout", sar->buf, sar->len); */
	mesh_sar_free(sar);
}

static void outmsg_to(struct l_timeout *msg_timeout, void *user_data)
{
	struct mesh_net *net = user_data;
	struct mesh_sar *sar = l_queue_remove_if(net->sar_out,
			match_msg_timeout, msg_timeout);

	l_timeout_remove(msg_timeout);
	if (!sar)
		return;

	sar->msg_timeout = NULL;

	if (sar->status_func)
		sar->status_func(sar->remote, 1,
				sar->buf, sar->len - 4,
				sar->user_data);

	/* print_packet("Outgoing SAR Timeout", sar->buf, sar->len); */
	mesh_sar_free(sar);
}

static void outseg_to(struct l_timeout *seg_timeout, void *user_data);
static void ack_received(struct mesh_net *net, bool timeout,
				uint16_t src, uint16_t dst,
				uint16_t seq0, uint32_t ack_flag)
{
	struct mesh_sar *outgoing;
	uint32_t seg_flag = 0x00000001;
	uint32_t ack_copy = ack_flag;
	uint16_t i;

	l_info("ACK Rxed (%x) (to:%d): %8.8x", seq0, timeout, ack_flag);

	outgoing = l_queue_find(net->sar_out, match_sar_seq0,
							L_UINT_TO_PTR(seq0));

	if (!outgoing) {
		l_info("Not Found: %4.4x", seq0);
		return;
	}

	/*
	 * TODO -- If we receive from different
	 * SRC than we are sending to, make sure the OBO flag is set
	 */

	if ((!timeout && !ack_flag) ||
			(outgoing->flags & ack_flag) == outgoing->flags) {
		l_debug("ob_sar_removal (%x)", outgoing->flags);

		/* Note: ack_flags == 0x00000000 is a remote Cancel request */
		if (outgoing->status_func)
			outgoing->status_func(src, ack_flag ? 0 : 1,
					outgoing->buf,
					outgoing->len - 4, outgoing->user_data);

		l_queue_remove(net->sar_out, outgoing);
		mesh_sar_free(outgoing);

		return;
	}

	outgoing->last_nak |= ack_flag;

	ack_copy &= outgoing->flags;

	for (i = 0; i <= SEG_MAX(outgoing->len); i++, seg_flag <<= 1) {
		if (seg_flag & ack_flag) {
			l_debug("Skipping Seg %d of %d",
					i, SEG_MAX(outgoing->len));
			continue;
		}

		ack_copy |= seg_flag;

		l_info("Resend Seg %d net:%p dst:%x app_idx:%3.3x",
				i, net, outgoing->remote, outgoing->app_idx);

		send_seg(net, outgoing, i);
	}

	l_timeout_remove(outgoing->seg_timeout);
	outgoing->seg_timeout = l_timeout_create(SEG_TO, outseg_to, net, NULL);
}

static void outack_to(struct l_timeout *seg_timeout, void *user_data)
{
	struct mesh_net *net = user_data;
	struct mesh_sar *sar = l_queue_find(net->sar_out,
					match_seg_timeout, seg_timeout);

	l_timeout_remove(seg_timeout);
	if (!sar)
		return;

	sar->seg_timeout = NULL;

	/* Re-Send missing segments by faking NAK */
	ack_received(net, true, sar->remote, sar->src,
				sar->seqZero, sar->last_nak);
}

static void outseg_to(struct l_timeout *seg_timeout, void *user_data)
{
	struct mesh_net *net = user_data;
	struct mesh_sar *sar = l_queue_find(net->sar_out,
					match_seg_timeout, seg_timeout);

	l_timeout_remove(seg_timeout);
	if (!sar)
		return;

	sar->seg_timeout = NULL;

	if (net->friend_addr) {
		/* We are LPN -- Poll for ACK */
		frnd_ack_poll(net);
		sar->seg_timeout = l_timeout_create(SEG_TO,
				outack_to, net, NULL);
	} else {
		/* Re-Send missing segments by faking NACK */
		ack_received(net, true, sar->remote, sar->src,
					sar->seqZero, sar->last_nak);
	}
}

static bool msg_rxed(struct mesh_net *net, bool frnd,
					uint32_t iv_index,
					uint8_t ttl,
					uint32_t seq,
					uint16_t src, uint16_t dst,
					uint8_t key_id,
					bool szmic, uint16_t seqZero,
					const uint8_t *data, uint16_t size)
{
	uint32_t seqAuth = seq_auth(seq, seqZero);

	/* Sanity check seqAuth */
	if (seqAuth > seq)
		return false;

	/* Save un-decrypted messages for our friends */
	if (!frnd && l_queue_length(net->friends)) {
		uint32_t hdr = key_id << KEY_HDR_SHIFT;
		uint8_t frnd_ttl = ttl;

		/* If not from us, decrement for our hop */
		if (src < net->src_addr || src > net->last_addr) {
			if (frnd_ttl > 1)
				frnd_ttl--;
			else
				goto not_for_friend;
		}

		if (szmic || size > 15) {
			hdr |= true << SEG_HDR_SHIFT;
			hdr |= szmic << SZMIC_HDR_SHIFT;
			hdr |= (seqZero & SEQ_ZERO_MASK) << SEQ_ZERO_HDR_SHIFT;
			hdr |= SEG_MAX(size) << SEGN_HDR_SHIFT;
		}

		if (friend_packet_queue(net, iv_index, false, frnd_ttl,
					seq, src, dst,
					hdr, data, size))
			return true;
	}

not_for_friend:
	return mesh_model_rx(net, szmic, seqAuth, seq, iv_index,
					ttl, src, dst, key_id, data, size);
}

static bool match_frnd_sar_dst(const void *a, const void *b)
{
	const struct mesh_friend_msg *frnd_msg = a;
	uint16_t dst = L_PTR_TO_UINT(b);

	return frnd_msg->dst == dst;
}

static void friend_seg_rxed(struct mesh_net *net,
				uint32_t iv_index,
				uint8_t ttl, uint32_t seq,
				uint16_t src, uint16_t dst, uint32_t hdr,
				const uint8_t *data, uint8_t size)
{
	struct mesh_friend *frnd = NULL;
	struct mesh_friend_msg *frnd_msg = NULL;
	uint8_t cnt;
	uint8_t segN = hdr & 0x1f;
	uint8_t segO = ((hdr >> 5) & 0x1f);
	uint32_t expected = 0xffffffff >> (31 - segN);
	uint32_t this_seg_flag = 0x00000001 << segO;
	uint32_t largest = (0xffffffff << segO) & expected;
	uint32_t hdr_key =  hdr & HDR_KEY_MASK;

	frnd = l_queue_find(net->friends, match_frnd_dst,
			L_UINT_TO_PTR(dst));
	if (!frnd)
		return;

	if (frnd->last_hdr == hdr_key) {
		/* We are no longer receiving this msg. Resend final ACK */
		send_frnd_ack(net, dst, src, frnd->last_hdr, 0xffffffff);
		return;
	}

	/* Check if we have a SAR-in-progress that matches incoming segment */
	frnd_msg = l_queue_find(net->frnd_msgs, match_frnd_sar_dst,
			L_UINT_TO_PTR(dst));

	if (frnd_msg) {
		/* Flush if SZMICN or IV Index has changed */
		if (frnd_msg->iv_index != iv_index)
			frnd_msg->u.s12[0].hdr = 0;

		/* Flush incomplete old SAR message if it doesn't match */
		if ((frnd_msg->u.s12[0].hdr & HDR_KEY_MASK) != hdr_key) {
			l_queue_remove(net->frnd_msgs, frnd_msg);
			l_free(frnd_msg);
			frnd_msg = NULL;
		}
	}

	if (!frnd_msg) {
		frnd_msg = mesh_friend_msg_new(segN);
		frnd_msg->iv_index = iv_index;
		frnd_msg->src = src;
		frnd_msg->dst = dst;
		frnd_msg->ttl = ttl;
		l_queue_push_tail(net->frnd_msgs, frnd_msg);
	} else if (frnd_msg->flags & this_seg_flag) /* Ignore dup segs */
		return;

	cnt = frnd_msg->cnt_in;
	frnd_msg->flags |= this_seg_flag;

	frnd_msg->u.s12[cnt].hdr = hdr;
	frnd_msg->u.s12[cnt].seq = seq;
	memcpy(frnd_msg->u.s12[cnt].data, data, size);

	/* Last segment could be short */
	if (segN == segO)
		frnd_msg->last_len = size;

	l_info("RXed Seg %d, Flags %8.8x (cnt: %d)",
						segO, frnd_msg->flags, cnt);

	/* In reality, if one of these is true, then *both* must be true */
	if ((cnt == segN) || (frnd_msg->flags == expected)) {
		l_info("Full ACK");
		send_frnd_ack(net, dst, src, hdr, frnd_msg->flags);

		if (frnd_msg->ttl > 1) {
			frnd_msg->ttl--;
			/* Add to friends cache  */
			l_queue_foreach(net->friends,
					enqueue_friend_pkt, frnd_msg);
		}

		/* Remove from "in progress" queue */
		l_queue_remove(net->frnd_msgs, frnd_msg);

		/* TODO Optimization(?): Unicast messages keep this buffer */
		l_free(frnd_msg);
		return;
	}

	/* Always ACK if this is the largest outstanding segment */
	if ((largest & frnd_msg->flags) == largest) {
		l_info("Partial ACK");
		send_frnd_ack(net, dst, src, hdr, frnd_msg->flags);
	}

	frnd_msg->cnt_in++;
}

static bool seg_rxed(struct mesh_net *net, bool frnd,
					uint32_t iv_index,
					uint8_t ttl,
					uint32_t seq,
					uint16_t src, uint16_t dst,
					uint8_t key_id,
					bool szmic, uint16_t seqZero,
					uint8_t segO, uint8_t segN,
					const uint8_t *data, uint8_t size)
{
	struct mesh_sar *sar_in = NULL;
	uint16_t seg_off = 0;
	uint32_t expected, this_seg_flag, largest, seqAuth;
	bool reset_seg_to = true;

	/*
	 * DST could receive additional Segments after
	 * completing due to a lost ACK, so re-ACK and discard
	 */
	sar_in = l_queue_find(net->sar_in, match_sar_remote,
						L_UINT_TO_PTR(src));

	/* Discard *old* incoming-SAR-in-progress if this segment newer */
	seqAuth = seq_auth(seq, seqZero);
	if (sar_in && (sar_in->seqAuth != seqAuth ||
				sar_in->iv_index != iv_index)) {
		bool newer;

		if (iv_index > sar_in->iv_index)
			newer = true;
		else if (iv_index == sar_in->iv_index)
			newer = seqAuth > sar_in->seqAuth;
		else
			newer = false;

		if (newer) {
			/* Cancel Old, start New */
			l_queue_remove(net->sar_in, sar_in);
			mesh_sar_free(sar_in);
			sar_in = NULL;
		} else
			/* Ignore Old */
			return false;
	}

	expected = 0xffffffff >> (31 - segN);

	if (sar_in) {
		l_info("RXed (old: %04x %06x size:%d) %d of %d",
					seqZero, seq, size, segO, segN);
		/* Sanity Check--> certain things must match */
		if (SEG_MAX(sar_in->len) != segN ||
				sar_in->key_id != key_id)
			return false;

		if (sar_in->flags == expected) {
			/* Re-Send ACK for full msg */
			if (!net->friend_addr)
				send_net_ack(net, sar_in, expected);
			return true;
		}
	} else {
		uint16_t len = MAX_SEG_TO_LEN(segN);

		l_info("RXed (new: %04x %06x size: %d len: %d) %d of %d",
				seqZero, seq, size, len, segO, segN);
		l_debug("Queue Size: %d", l_queue_length(net->sar_in));
		sar_in = mesh_sar_new(len);
		sar_in->seqAuth = seqAuth;
		sar_in->iv_index = iv_index;
		sar_in->src = dst;
		sar_in->remote = src;
		sar_in->seqZero = seqZero;
		sar_in->key_id = key_id;
		sar_in->len = len;
		sar_in->last_seg = 0xff;
		if (!net->friend_addr)
			sar_in->msg_timeout = l_timeout_create(MSG_TO,
					inmsg_to, net, NULL);

		l_debug("First Seg %4.4x", sar_in->flags);
		l_queue_push_head(net->sar_in, sar_in);
	}
	/* print_packet("Seg", data, size); */

	seg_off = segO * MAX_SEG_LEN;
	memcpy(sar_in->buf + seg_off, data, size);
	this_seg_flag = 0x00000001 << segO;

	/* Don't reset Seg TO or NAK if we already have this seg */
	if (this_seg_flag & sar_in->flags)
		reset_seg_to = false;

	sar_in->flags |= this_seg_flag;
	sar_in->ttl = ttl;

	l_debug("Have Frags %4.4x", sar_in->flags);

	/* Msg length only definitive on last segment */
	if (segO == segN)
		sar_in->len = segN * MAX_SEG_LEN + size;

	if (sar_in->flags == expected) {
		/* Got it all */
		if (!net->friend_addr)
			send_net_ack(net, sar_in, expected);

		msg_rxed(net, frnd,
				iv_index,
				ttl,
				seq,
				sar_in->remote, dst,
				key_id,
				szmic, sar_in->seqZero,
				sar_in->buf, sar_in->len);

		/* Kill Inter-Seg timeout */
		l_timeout_remove(sar_in->seg_timeout);
		sar_in->seg_timeout = NULL;
		return true;

	} else if (reset_seg_to) {
		/* Restart Inter-Seg Timeout */
		l_timeout_remove(sar_in->seg_timeout);

		/* if this is the largest outstanding segment, send NAK now */
		if (!net->friend_addr) {
			largest = (0xffffffff << segO) & expected;
			if ((largest & sar_in->flags) == largest)
				send_net_ack(net, sar_in, sar_in->flags);

			sar_in->seg_timeout = l_timeout_create(SEG_TO,
				inseg_to, net, NULL);
		}
	}

	l_debug("NAK: %d expected:%08x largest:%08x flags:%08x",
			reset_seg_to, expected, largest, sar_in->flags);
	return false;
}

static bool ctl_received(struct mesh_net *net, bool frnd, uint32_t iv_index,
						uint8_t ttl,
						uint32_t seq,
						uint16_t src, uint16_t dst,
						uint8_t opcode, int8_t rssi,
						const uint8_t *pkt, uint8_t len)
{
	uint8_t msg[12];
	uint8_t rsp_ttl = DEFAULT_TTL;
	uint8_t n = 0;

	if (!frnd && ttl > 1) {
		uint32_t hdr = opcode << OPCODE_HDR_SHIFT;
		uint8_t frnd_ttl = ttl - 1;

		if (friend_packet_queue(net, iv_index,
					true, frnd_ttl,
					seq,
					src, dst,
					hdr,
					pkt, len))
			return true;
	}

	/* Don't process other peoples Unicast destinations */
	if (dst < 0x8000 && (dst < net->src_addr || dst > net->last_addr))
		return false;

	switch (opcode) {
	default:
		l_error("Unsupported Ctl Opcode: %2.2x", opcode);
		break;

	case NET_OP_FRND_POLL:
		if (len != 1 || ttl)
			return false;

		print_packet("Rx-NET_OP_FRND_POLL", pkt, len);
		friend_poll(net, src, !!(pkt[0]),
				l_queue_find(net->friends,
						match_by_friend,
						L_UINT_TO_PTR(src)));
		break;

	case NET_OP_FRND_UPDATE:
		if (ttl)
			return false;

		print_packet("Rx-NET_OP_FRND_UPDATE", pkt, len);
		lpn_process_beacon(net, pkt, len, 0);
		break;

	case NET_OP_FRND_REQUEST:
		if (!net->friend_enable)
			return false;

		if (!IS_ALL_NODES(dst) && dst != FRIENDS_ADDRESS)
			return false;

		if (len != 10 || ttl)
			return false;

		print_packet("Rx-NET_OP_FRND_REQUEST", pkt, len);
		friend_request(net, src, pkt[0], pkt[1],
				l_get_be32(pkt + 1) & 0xffffff,
				l_get_be16(pkt + 5), pkt[7],
				l_get_be16(pkt + 8), rssi);
		break;

	case NET_OP_FRND_OFFER:
		if (len != 6 || ttl)
			return false;

		print_packet("Rx-NET_OP_FRND_OFFER", pkt, len);
		frnd_offer(net, src, pkt[0], pkt[1], pkt[2],
				(int8_t) pkt[3], rssi, l_get_be16(pkt + 4));
		break;

	case NET_OP_FRND_CLEAR_CONFIRM:
		if (len != 4)
			return false;

		print_packet("Rx-NET_OP_FRND_CLEAR_CONFIRM", pkt, len);
		friend_clear_confirm(net, src, l_get_be16(pkt),
						l_get_be16(pkt + 2));
		break;

	case NET_OP_FRND_CLEAR:
		if (len != 4 || dst != net->src_addr)
			return false;

		print_packet("Rx-NET_OP_FRND_CLEAR", pkt, len);
		friend_clear(net, src, l_get_be16(pkt), l_get_be16(pkt + 2),
				l_queue_find(net->friends,
					match_by_friend,
					L_UINT_TO_PTR(l_get_be16(pkt))));
		l_info("Remaining Friends: %d", l_queue_length(net->friends));
		break;

	case NET_OP_PROXY_SUB_ADD:
		if (ttl)
			return false;

		print_packet("Rx-NET_OP_PROXY_SUB_ADD", pkt, len);
		friend_sub_add(net, l_queue_find(net->friends,
					match_by_friend, L_UINT_TO_PTR(src)),
				pkt, len);
		break;

	case NET_OP_PROXY_SUB_REMOVE:
		if (ttl)
			return false;

		print_packet("Rx-NET_OP_PROXY_SUB_REMOVE", pkt, len);
		friend_sub_del(net, l_queue_find(net->friends,
					match_by_friend, L_UINT_TO_PTR(src)),
				pkt, len);
		break;

	case NET_OP_PROXY_SUB_CONFIRM:
		if (ttl)
			return false;

		print_packet("Rx-NET_OP_PROXY_SUB_CONFIRM", pkt, len);
		break;

	case NET_OP_HEARTBEAT:
		if (net->heartbeat.sub_enabled &&
				src == net->heartbeat.sub_src) {
			uint8_t hops = pkt[0] - ttl + 1;

			print_packet("Rx-NET_OP_HEARTBEAT", pkt, len);

			if (net->heartbeat.sub_count != 0xffff)
				net->heartbeat.sub_count++;

			if (net->heartbeat.sub_min_hops > hops)
				net->heartbeat.sub_min_hops = hops;

			if (net->heartbeat.sub_max_hops < hops)
				net->heartbeat.sub_max_hops = hops;

			l_info("HB: cnt:%4.4x min:%2.2x max:%2.2x",
					net->heartbeat.sub_count,
					net->heartbeat.sub_min_hops,
					net->heartbeat.sub_max_hops);
		}
		break;
	}

	if (n) {
		mesh_net_transport_send(net, NULL, false,
				mesh_net_get_iv_index(net), rsp_ttl,
				0, dst & 0x8000 ? 0 : dst, src,
				msg, n);
	}

	return true;
}

static bool find_fast_hash(const void *a, const void *b)
{
	const uint64_t *entry = a;
	const uint64_t *test = b;

	return *entry == *test;
}

static void *check_fast_cache(struct mesh_net *net, uint64_t hash)
{
	void *found = l_queue_find(net->fast_cache, find_fast_hash, &hash);
	uint64_t *new_hash;

	if (found)
		return NULL;

	if (l_queue_length(net->fast_cache) >= 8)
		new_hash = l_queue_pop_head(net->fast_cache);
	else
		new_hash = l_malloc(sizeof(hash));

	*new_hash = hash;
	l_queue_push_tail(net->fast_cache, new_hash);

	return new_hash;
}

static bool match_keyset(const void *a, const void *b)
{
	const struct mesh_friend *frnd = a;
	const struct mesh_key_set *key_set = b;

	return (key_set == &frnd->key_set) || (key_set == &frnd->new_key_set);
}

static void try_decode(void *a, void *b)
{
	struct mesh_key_set *key_set = a;
	struct net_decode *decode = b;
	uint8_t tmp[29];
	bool status;

	if (decode->key_set || key_set->nid != decode->nid)
		return;

	status = mesh_crypto_packet_decode(decode->packet, decode->size,
					decode->proxy, tmp, decode->iv_index,
					key_set->enc_key, key_set->privacy_key);

	if (!status)
		return;

	memcpy(decode->packet, tmp, decode->size);
	decode->key_set = key_set;
	if (key_set->frnd)
		decode->frnd = l_queue_find(decode->net->friends,
						match_keyset, key_set);
	else
		decode->frnd = NULL;
}

static struct mesh_key_set *net_packet_decode(struct mesh_net *net,
				uint32_t iv_index, uint8_t nid,
				struct mesh_friend **frnd,
				bool proxy,
				uint8_t *packet, uint8_t size)
{
	struct net_decode decode = {
		.net = net,
		.key_set = NULL,
		.nid = nid,
		.iv_index = iv_index,
		.packet = packet,
		.size = size,
		.proxy = proxy,
	};

	l_queue_foreach(net->key_sets, try_decode, &decode);

	if (decode.key_set != NULL) {
		*frnd = decode.frnd;
		return decode.key_set;
	}
	return NULL;
}

static bool match_key_nid(const void *a, const void *b)
{
	const struct mesh_key_set *key_set = a;
	uint8_t nid = L_PTR_TO_UINT(b);

	return key_set->nid == nid;
}

static bool match_by_dst(const void *a, const void *b)
{
	const struct mesh_destination *dest = a;
	uint16_t dst = L_PTR_TO_UINT(b);

	return dest->dst == dst;
}

static void send_relay_pkt(struct mesh_net *net, uint8_t *packet, uint8_t size)
{
	struct mesh_io *io = net->io;
	struct mesh_io_send_info info = {
		.type = MESH_IO_TIMING_TYPE_GENERAL,
		.u.gen.interval = net->relay.interval,
		.u.gen.cnt = net->relay.count,
		.u.gen.min_delay = DEFAULT_MIN_DELAY,
		.u.gen.max_delay = DEFAULT_MAX_DELAY
	};

	packet[0] = MESH_AD_TYPE_NETWORK;

	mesh_io_send(io, &info, packet, size);
}

static void send_msg_pkt(struct mesh_net *net, uint8_t *packet, uint8_t size)
{
	struct mesh_io *io = net->io;
	struct mesh_io_send_info info = {
		.type = MESH_IO_TIMING_TYPE_GENERAL,
		.u.gen.interval = net->tx_interval,
		.u.gen.cnt = net->tx_cnt,
		.u.gen.min_delay = DEFAULT_MIN_DELAY,
		/* No extra randomization when sending regular mesh messages */
		.u.gen.max_delay = DEFAULT_MIN_DELAY
	};

	packet[0] = MESH_AD_TYPE_NETWORK;

	mesh_io_send(io, &info, packet, size);
}

static void packet_received(void *user_data, const void *data, uint8_t size,
								int8_t rssi)
{
	struct mesh_net *net = user_data;
	uint32_t iv_index;
	uint8_t iv_flag;
	uint8_t nid;
	const uint8_t *msg = data;
	uint8_t app_msg_len;
	uint8_t net_ttl, net_key_id, net_segO, net_segN, net_opcode;
	uint32_t net_seq, cache_cookie;
	uint16_t net_src, net_dst, net_seqZero;
	uint8_t packet[31];
	bool net_ctl, net_segmented, net_szmic, net_relay;
	struct mesh_friend *net_frnd;
	bool drop = false;
	uint64_t hash, *isNew = NULL;
	struct mesh_key_set *keys;

	nid = msg[0] & 0x7f;

	/* Ignore unrecognized NIDs */
	if (!(l_queue_find(net->key_sets, match_key_nid, L_UINT_TO_PTR(nid)))) {
		/* print_packet("Nope", data, size); */
		return;
	}

	iv_flag = msg[0] >> 7;
	iv_index = net->iv_index;
	l_debug("%s iv_index %d NID: %2.2x", __func__, iv_index, nid);

	if (sizeof(uint16_t) <= sizeof(void *)) {
		/* Add in additional cache to allow us to
		 * avoid decrypting duplicatesr
		 * Fast 64 bit Hash, Network MIC doesn't matter
		 * With 64 bit hash, false pos chance is 1 in 1.8 * 10^19
		 */
		hash = l_get_le64(msg + 1) ^ l_get_le64(msg + 9);
		isNew = check_fast_cache(net, hash);
		if (!isNew)
			return;

		l_debug("New");
	}

	memcpy(packet + 2, data, size);

	if (iv_index && (iv_index & 0x01) != iv_flag)
		iv_index--;

	/* Tester--Drop 90% of packets */
	/* l_getrandom(&iv_flag, 1); */
	/* if (iv_flag%10<9) drop = true; */

	if (!drop)
		print_packet("RX: Network [enc] :", data, size);

	keys = net_packet_decode(net, iv_index, nid, &net_frnd, false,
							packet + 2, size);
	if (keys == NULL) {
		l_debug("Failed to decode packet");
		/* Remove fast-cache-hash */
		l_queue_remove(net->fast_cache, isNew);
		l_free(isNew);
		return;
	}

	if (!drop)
		print_packet("RX: Network [clr] :", packet + 2, size);

	if (!mesh_crypto_packet_parse(packet + 2, size,
					&net_ctl, &net_ttl,
					&net_seq,
					&net_src, &net_dst,
					&cache_cookie,
					&net_opcode,
					&net_segmented,
					&net_key_id,
					&net_szmic, &net_relay, &net_seqZero,
					&net_segO, &net_segN,
					&msg, &app_msg_len)) {
		l_error("Failed to parse packet content");
		return;
	}

	/* Ignore incoming packets if we are LPN and frnd bit not set */
	if (net->friend_addr) {
		struct mesh_subnet *subnet;

		subnet = l_queue_find(net->subnets, match_key_set, keys);
		if (subnet)
			return;

		/* If the queue is empty, stop polling */
		if (net_ctl && net_opcode == NET_OP_FRND_UPDATE && !msg[5])
			frnd_poll_cancel(net);
		else
			frnd_poll(net, false);

	} else if (net_dst == 0) {
		l_error("illegal parms: DST: %4.4x Ctl: %d TTL: %2.2x",
						net_dst, net_ctl, net_ttl);
		return;
	}

	/* Ignore if we originally sent this */
	if (is_us(net, net_src, true))
		return;

	if (drop) {
		l_info("Dropping SEQ 0x%06x", net_seq);
		return;
	}

	l_debug("check %08x", cache_cookie);

	/* As a Relay, suppress repeats of last N packets that pass through */
	/* The "cache_cookie" should be unique part of App message */
	if (msg_in_cache(net, net_src, net_seq, cache_cookie))
		return;

	l_debug("RX: Network %04x -> %04x : TTL 0x%02x : IV : %8.8x SEQ 0x%06x",
			net_src, net_dst, net_ttl, iv_index, net_seq);

	if (is_us(net, net_dst, false) ||
			is_lpn_friend(net, net_src, !!(net_frnd)) ||
			(net_ctl && net_opcode == NET_OP_HEARTBEAT)) {

		l_info("RX: App 0x%04x -> 0x%04x : TTL 0x%02x : SEQ 0x%06x",
					net_src, net_dst, net_ttl, net_seq);

		l_debug("seq:%x seq0:%x", net_seq, net_seqZero);
		if (net_ctl) {
			l_debug("CTL - %4.4x RX", net_seqZero);
			if (net_opcode == NET_OP_SEG_ACKNOWLEDGE) {
				/* Illegal to send ACK to non-Unicast Addr */
				if (net_dst & 0x8000)
					return;

				/* print_packet("Got ACK", msg, app_msg_len); */
				/* Pedantic check for correct size */
				if (app_msg_len != 7)
					return;

				/* If this is an ACK to our friend queue-only */
				if (is_lpn_friend(net, net_dst, true))
					friend_ack_rxed(net, iv_index, net_seq,
							net_src, net_dst,
							msg);
				else
					ack_received(net, false,
							net_src, net_dst,
							net_seqZero,
							l_get_be32(msg + 3));
			} else {
				ctl_received(net, !!(net_frnd), iv_index,
						net_ttl, net_seq, net_src,
						net_dst, net_opcode, rssi,
						msg, app_msg_len);
			}
		} else if (net_segmented) {
			/* If we accept SAR packets to non-Unicast, then
			 * Friend Sar at least needs to be Unicast Only
			 */
			if (is_lpn_friend(net, net_dst, true) &&
							!(net_dst & 0x8000)) {
				/* Check TTL >= 2 before accepting segments
				 * for Friends
				 */
				if (net_ttl >= 2) {
					friend_seg_rxed(net, iv_index,
						net_ttl, net_seq,
						net_src, net_dst,
						l_get_be32(packet + 2 + 9),
						msg, app_msg_len);
				}
			} else {
				seg_rxed(net, net_frnd,
						iv_index,
						net_ttl,
						net_seq,
						net_src, net_dst,
						net_key_id,
						net_szmic, net_seqZero,
						net_segO, net_segN,
						msg, app_msg_len);
			}

		} else {
			msg_rxed(net, net_frnd,
						iv_index,
						net_ttl,
						net_seq,
						net_src, net_dst,
						net_key_id,
						false, net_seq & SEQ_ZERO_MASK,
						msg, app_msg_len);
		}

		if (!!(net_frnd))
			l_info("Ask for more data!");

		/* If this is one of our Unicast addresses, don't relay */
		if (net_dst <= 0x7fff)
			return;
	}

	if (!net->relay.enable || net_ttl < 0x02 || net_frnd)
		return;

	packet[2 + 1] = (packet[2 + 1] & ~TTL_MASK) | (net_ttl - 1);

	if (!mesh_crypto_packet_encode(packet + 2, size, keys->enc_key,
					iv_index, keys->privacy_key)) {
		l_error("Failed to encode relay packet");
		return;
	}

	if (net->relay.enable)
		send_relay_pkt(net, packet, size + 1);
}

static void net_msg_recv(void *user_data, struct mesh_io_recv_info *info,
					const uint8_t *data, uint16_t len)
{
	struct mesh_net *net = user_data;
	int8_t rssi = 0;

	if (len <= 2 || !net)
		return;

	if (info) {
		net->instant = info->instant;
		net->chan = info->chan;
		rssi = info->rssi;
	}

	packet_received(user_data, data + 1, len - 1, rssi);
}

static void set_network_beacon(void *a, void *b)
{
	struct mesh_subnet *subnet = a;
	struct mesh_net *net = b;
	uint8_t beacon_data[22];

	if (!create_secure_beacon(net, subnet, beacon_data,
							sizeof(beacon_data)))
		return;

	if (memcmp(&subnet->snb.beacon[1], beacon_data,
						sizeof(beacon_data)) == 0)
		return;

	memcpy(&subnet->snb.beacon[1], beacon_data, sizeof(beacon_data));

	if (net->beacon_enable && !net->friend_addr) {
		print_packet("Set My Beacon to",
			beacon_data, sizeof(beacon_data));
		start_network_beacon(subnet, net);
	}

	if (l_queue_length(net->friends)) {
		struct mesh_friend_msg update = {
			.src = net->src_addr,
			.iv_index = mesh_net_get_iv_index(net),
			.last_len = 7,
			.ctl = true,
		};

		update.u.one[0].hdr = NET_OP_FRND_UPDATE << OPCODE_HDR_SHIFT;
		update.u.one[0].seq = mesh_net_next_seq_num(net);
		update.u.one[0].data[0] = NET_OP_FRND_UPDATE;
		update.u.one[0].data[1] = beacon_data[3];
		l_put_be32(net->iv_index, update.u.one[0].data + 2);
		update.u.one[0].data[6] = 0x01; /* More Data */
		/* print_packet("Frnd-Beacon-SRC",
		 *			beacon_data, sizeof(beacon_data));
		 */
		/* print_packet("Frnd-Update", update.u.one[0].data, 6); */

		l_queue_foreach(net->friends, enqueue_update, &update);
	}
}

static void iv_upd_to(struct l_timeout *upd_timeout, void *user_data)
{
	struct mesh_net *net = user_data;

	switch (net->iv_upd_state) {
	case IV_UPD_UPDATING:
		if (l_queue_length(net->sar_out)) {
			l_info("don't leave IV Update until sar_out empty");
			l_timeout_modify(net->iv_update_timeout, 10);
			break;
		}

		l_info("iv_upd_state = IV_UPD_NORMAL_HOLD");
		net->iv_upd_state = IV_UPD_NORMAL_HOLD;
		l_timeout_modify(net->iv_update_timeout, IV_IDX_UPD_MIN);
		mesh_net_set_seq_num(net, 0);
		l_queue_foreach(net->subnets, set_network_beacon, net);
		mesh_net_flush_msg_queues(net);
		break;

	case IV_UPD_INIT:
	case IV_UPD_NORMAL_HOLD:
	case IV_UPD_NORMAL:
		l_timeout_remove(upd_timeout);
		net->iv_update_timeout = NULL;
		l_info("iv_upd_state = IV_UPD_NORMAL");
		net->iv_upd_state = IV_UPD_NORMAL;
		if (net->seq_num > IV_UPDATE_SEQ_TRIGGER)
			mesh_net_iv_index_update(net);
		break;
	}
}

static void update_iv_kr_state(struct mesh_subnet *subnet, uint32_t iv_index,
				bool iv_update, bool kr_transition,
				bool rxed_key_refresh, bool lpn)
{
	struct mesh_net *net = subnet->net;
	uint8_t local_kr;
	uint32_t local_iv_index;
	bool local_iv_update;

	/* Save original settings to avoid resetting same values,
	 * and secure beacon timer
	 */
	local_iv_index = net->iv_index;
	local_kr = subnet->key_refresh;
	local_iv_update = iv_is_updating(net);

	if (iv_index != local_iv_index || kr_transition)
		l_info("SNB-RX: %8.8x - Key Refresh: %d IV Update: %d",
					iv_index, rxed_key_refresh, iv_update);

	if (iv_update && (net->iv_upd_state > IV_UPD_UPDATING)) {
		if (iv_index != net->iv_index)
			l_error("Update attempted to0 soon (Normal < MIN)");

		return;
	}

	if (net->iv_upd_state == IV_UPD_INIT) {
		if (iv_index > net->iv_index)
			mesh_net_set_seq_num(net, 0);
		net->iv_index = iv_index;

		if (iv_update) {
			/* Other devices will be accepting old or new iv_index,
			 * but we don't know how far through update they are.
			 * Starting permissive state will allow us maximum
			 * (96 hours) to resync
			 */
			l_info("iv_upd_state = IV_UPD_UPDATING");
			net->iv_upd_state = IV_UPD_UPDATING;
			net->iv_update_timeout = l_timeout_create(
				IV_IDX_UPD_MIN, iv_upd_to, net, NULL);
		} else {
			l_info("iv_upd_state = IV_UPD_NORMAL");
			net->iv_upd_state = IV_UPD_NORMAL;
		}

		storage_local_set_iv_index(net, iv_index, net->iv_upd_state);

		/* Figure out the key refresh phase */
		if (kr_transition) {
			if (rxed_key_refresh)
				mesh_net_key_refresh_phase_two(net,
								subnet->idx);
			else
				mesh_net_key_refresh_finish(net, subnet->idx);
		}

		if (!lpn)
			set_network_beacon(subnet, net);

		return;
	}

	if (iv_update && !iv_is_updating(net)) {
		l_info("iv_upd_state = IV_UPD_UPDATING");
		net->iv_upd_state = IV_UPD_UPDATING;
		net->iv_update_timeout = l_timeout_create(IV_IDX_UPD_MIN,
							iv_upd_to, net, NULL);
		storage_local_set_iv_index(net, iv_index, net->iv_upd_state);
	} else if (iv_update && iv_index != net->iv_index) {
		l_error("Update attempted too soon (iv idx already updated)");
		return;
	}

	if (iv_index != local_iv_index || kr_transition)
		l_info("IVindex 0x%8.8x / Key Refresh update received",
								iv_index);

	if (iv_index > net->iv_index) {
		l_queue_clear(net->msg_cache, mesh_msg_free);
		net->iv_index = iv_index;
		storage_local_set_iv_index(net, iv_index, net->iv_upd_state);
	}

	/* Figure out the key refresh phase */
	if (kr_transition) {
		if (rxed_key_refresh)
			mesh_net_key_refresh_phase_two(net, subnet->idx);
		else
			mesh_net_key_refresh_finish(net, subnet->idx);
	}

	if (!lpn)
		return;

	if (local_kr != subnet->key_refresh ||
					local_iv_index != net->iv_index ||
					local_iv_update != iv_is_updating(net))
		set_network_beacon(subnet, net);
}

static void process_beacon(void *user_data, const void *data,
						uint8_t size, int8_t rssi)
{
	struct mesh_net *net = user_data;
	const uint8_t *buf = data;
	uint32_t iv_index;
	uint64_t cmac;
	bool iv_update, rxed_iv_update, rxed_key_refresh;
	struct mesh_subnet *subnet;
	struct net_key *keys;
	bool kr_transition = false;

	if (size != 22 || buf[0] != 0x01)
		return;

	/* print_packet("Secure Net Beacon RXed", data, size); */
	rxed_key_refresh = (buf[1] & 0x01) == 0x01;
	rxed_iv_update = iv_update = (buf[1] & 0x02) == 0x02;
	iv_index = l_get_be32(buf + 10);

	l_debug("KR: %d -- IVU: %d -- IV: %8.8x",
				rxed_key_refresh, rxed_iv_update, iv_index);

	/* Inhibit recognizing iv_update true-->false
	 * if we have outbound SAR messages in flight
	 */
	if (l_queue_length(net->sar_out)) {
		if (!iv_update && iv_update != iv_is_updating(net))
			iv_update = true;
	}

	subnet = l_queue_find(net->subnets, match_network_id, buf + 2);
	if (!subnet)
		return;

	/* Check if Key Refresh flag value is different from
	 * the locally stored one
	 */
	if (rxed_key_refresh != subnet->key_refresh)
		kr_transition = true;

	/* If the local node is a provisioner or there are no new keys,
	 * ignore KR beacon setting
	 */
	if (net->provisioner)
		kr_transition = false;
	else if (subnet->updated.key_set.nid == NET_NID_INVALID)
		kr_transition = false;
	/* If beacon's key refresh bit is not set and the beacon is encoded
	 * with the "new" network key, this signals transition from
	 * key refresh procedure to normal operation
	 */
	else if (!rxed_key_refresh &&
			!memcmp(subnet->updated.network_id, buf + 2, 8))
		kr_transition = true;

	if ((net->iv_index + IV_IDX_DIFF_RANGE < iv_index) ||
						(iv_index < net->iv_index)) {
		l_info("iv index outside range");
		return;
	}

	/* Don't bother going further if nothing has changed */
	if (!memcmp(&subnet->snb.beacon[1], buf, size)) {
		subnet->snb.observed++;
		return;
	}

	if (!rxed_key_refresh && !subnet->key_refresh && !kr_transition)
		keys = &subnet->current;
	else if (subnet->updated.key_set.nid != NET_NID_INVALID)
		keys = &subnet->updated;
	else
		return;

	if (memcmp(keys->network_id, buf + 2, 8))
		return;

	/* Any behavioral changes must pass CMAC test */
	if (!mesh_crypto_beacon_cmac(keys->beacon_key, keys->network_id,
						iv_index, rxed_key_refresh,
						rxed_iv_update, &cmac)) {
		l_error("mesh_crypto_beacon_cmac failed");
		return;
	}

	if (cmac != l_get_be64(buf + 14)) {
		l_error("cmac compare failed %16.16lx != %16.16lx",
						cmac, l_get_be64(buf + 14));
		return;
	}

	if (iv_index == net->iv_index &&
			iv_is_updating(net) == iv_update && !kr_transition) {
		l_info("No change: IV index %4.4x, rxed KR = %d ",
						iv_index, rxed_key_refresh);
		if (net->iv_upd_state == IV_UPD_INIT) {
			l_info("iv_upd_state = IV_UPD_NORMAL");
			net->iv_upd_state = IV_UPD_NORMAL;
		}

		subnet->snb.observed++;
		return;
	}

	subnet->snb.observed++;

	update_iv_kr_state(subnet, iv_index, iv_update, kr_transition,
						rxed_key_refresh, false);
}

static void lpn_process_beacon(void *user_data, const void *data,
						uint8_t size, int8_t rssi)
{
	struct mesh_net *net = user_data;
	const uint8_t *buf = data;
	uint32_t iv_index;
	bool iv_update, rxed_key_refresh;
	struct mesh_subnet *subnet;
	bool kr_transition = false;

	/* print_packet("lpn: Secure Net Beacon RXed", data, size); */
	rxed_key_refresh = (buf[0] & 0x01) == 0x01;
	iv_index = l_get_be32(buf + 1);

	l_debug("KR: %d -- IVU: %d -- IV: %8.8x",
				rxed_key_refresh, iv_index);

	/* Inhibit recognizing iv_update true-->false if we have outbound
	 * SAR messages in flight
	 */
	if (l_queue_length(net->sar_out)) {
		if (!iv_update && iv_update != iv_is_updating(net))
			iv_update = true;
	}

	/* TODO: figure out actual network index (i.e., friendship subnet) */
	subnet = get_primary_subnet(net);
	if (!subnet)
		return;

	/* Check if Key Refresh flag value is different from
	 * the locally stored one
	 */
	if (rxed_key_refresh != subnet->key_refresh)
		kr_transition = true;

	/* If the local node is a provisioner or there are no new keys,
	 * ignore KR beacon setting
	 */
	if (subnet->updated.key_set.nid == NET_NID_INVALID)
		kr_transition = false;

	if ((net->iv_index + IV_IDX_DIFF_RANGE < iv_index) ||
					(iv_index < net->iv_index)) {
		l_info("iv index outside range");
		return;
	}

	/* Don't bother going further if nothing has changed */
	if (!kr_transition && iv_index == net->iv_index &&
			iv_update == iv_is_updating(net) &&
			net->iv_upd_state != IV_UPD_INIT)
		return;

	if (iv_index == net->iv_index &&
			iv_is_updating(net) == iv_update && !kr_transition) {
		l_info("No change: IV index %4.4x, rxed KR = %d ",
						iv_index, rxed_key_refresh);
		if (net->iv_upd_state == IV_UPD_INIT) {
			l_info("iv_upd_state = IV_UPD_NORMAL");
			net->iv_upd_state = IV_UPD_NORMAL;
		}
		return;
	}

	update_iv_kr_state(subnet, iv_index, iv_update, kr_transition,
						rxed_key_refresh, true);
}

static void beacon_recv(void *user_data, struct mesh_io_recv_info *info,
					const uint8_t *data, uint16_t len)
{
	struct mesh_net *net = user_data;
	int8_t rssi = 0;

	if (len <= 2 || !net)
		return;

	if (info) {
		net->instant = info->instant;
		net->chan = info->chan;
		rssi = info->rssi;
	}

	process_beacon(user_data, data + 1, len - 1, rssi);
}

bool mesh_net_set_beacon_mode(struct mesh_net *net, bool enable)
{
	if (!net || !IS_UNASSIGNED(net->friend_addr))
		return false;

	if (net->beacon_enable != enable) {
		uint8_t type = MESH_AD_TYPE_BEACON;

		net->beacon_enable = enable;

		if (!enable)
			mesh_io_send_cancel(net->io, &type, 1);

		l_queue_foreach(net->subnets, start_network_beacon, net);
	}

	return true;
}


bool mesh_net_attach(struct mesh_net *net, struct mesh_io *io)
{
	if (!net)
		return false;

	net->io = io;

	return true;
}

struct mesh_io *mesh_net_detach(struct mesh_net *net)
{
	struct mesh_io *io;
	uint8_t type = 0;

	if (!net)
		return NULL;

	io  = net->io;

	mesh_io_send_cancel(net->io, &type, 1);
	mesh_io_deregister_recv_cb(io, MESH_IO_FILTER_BEACON);
	mesh_io_deregister_recv_cb(io, MESH_IO_FILTER_NET);

	net->io = NULL;

	return io;
}

bool mesh_net_iv_index_update(struct mesh_net *net)
{
	if (net->iv_upd_state != IV_UPD_NORMAL)
		return false;

	l_info("iv_upd_state = IV_UPD_UPDATING");
	mesh_net_flush_msg_queues(net);
	net->iv_upd_state = IV_UPD_UPDATING;
	net->iv_index++;
	if (!storage_local_set_iv_index(net, net->iv_index, IV_UPD_UPDATING))
		return false;

	l_queue_foreach(net->subnets, set_network_beacon, net);
	net->iv_update_timeout = l_timeout_create(
			IV_IDX_UPD_MIN,
			iv_upd_to, net, NULL);

	return true;
}



void mesh_net_sub_list_add(struct mesh_net *net, uint16_t addr)
{
	uint8_t msg[11] = { PROXY_OP_FILTER_ADD };
	uint8_t n = 1;

	l_put_be16(addr, msg + n);
	n += 2;

	mesh_net_transport_send(net, NULL, false,
			mesh_net_get_iv_index(net), 0,
			0, 0, 0, msg, n);
}

void mesh_net_sub_list_del(struct mesh_net *net, uint16_t addr)
{
	uint8_t msg[11] = { PROXY_OP_FILTER_DEL };
	uint8_t n = 1;

	l_put_be16(addr, msg + n);
	n += 2;

	mesh_net_transport_send(net, NULL, false,
			mesh_net_get_iv_index(net), 0,
			0, 0, 0, msg, n);
}

/* TODO: change to use net index */
bool mesh_net_set_friend(struct mesh_net *net, uint16_t friend_addr)
{
	if (!net)
		return false;

	net->bea_id = 0;

	l_info("Set Frnd addr: %4.4x", friend_addr);
	if (!friend_addr)
		trigger_heartbeat(net, FEATURE_LPN, false);
	else
		trigger_heartbeat(net, FEATURE_LPN, true);

	net->friend_addr = friend_addr;

	set_network_beacon(get_primary_subnet(net), net);
	return true;
}

uint16_t mesh_net_get_friend(struct mesh_net *net)
{
	if (!net)
		return 0;

	return net->friend_addr;
}

bool mesh_net_dst_reg(struct mesh_net *net, uint16_t dst)
{
	struct mesh_destination *dest = l_queue_find(net->destinations,
					match_by_dst, L_UINT_TO_PTR(dst));

	if (IS_UNASSIGNED(dst) || IS_ALL_NODES(dst))
		return false;

	if (!dest) {
		dest = l_new(struct mesh_destination, 1);

		if (dst < 0x8000)
			l_queue_push_head(net->destinations, dest);
		else
			l_queue_push_tail(net->destinations, dest);

		/* If LPN, and Group/Virtual, add to Subscription List */
		if (net->friend_addr) {
			/* TODO: Fix this garbage */
			uint32_t u32_dst[7] = {dst, 0xffffffff};

			frnd_sub_add(net, u32_dst);
		}
	}

	dest->dst = dst;
	dest->ref_cnt++;

	return true;
}

bool mesh_net_dst_unreg(struct mesh_net *net, uint16_t dst)
{
	struct mesh_destination *dest = l_queue_find(net->destinations,
					match_by_dst, L_UINT_TO_PTR(dst));

	if (!dest)
		return false;

	if (dest->ref_cnt)
		dest->ref_cnt--;

	if (dest->ref_cnt)
		return true;

	/* TODO: If LPN, and Group/Virtual, remove from Subscription List */
	if (net->friend_addr) {
		/* TODO: Fix this garbage */
		uint32_t u32_dst[7] = {dst, 0xffffffff};

		frnd_sub_del(net, u32_dst);
	}

	l_queue_remove(net->destinations, dest);

	l_free(dest);
	return true;
}

bool mesh_net_flush(struct mesh_net *net)
{
	if (!net)
		return false;

	/* TODO mesh-io Flush */
	return true;
}

/* TODO: add net key index */
static bool send_seg(struct mesh_net *net, struct mesh_sar *msg, uint8_t segO)
{
	uint8_t seg_len;
	uint8_t gatt_data[30];
	uint8_t *packet = gatt_data;
	uint8_t packet_len;
	uint8_t segN = SEG_MAX(msg->len);
	uint16_t seg_off = SEG_OFF(segO);
	struct mesh_key_set *key_set = NULL;
	uint32_t seq_num = mesh_net_next_seq_num(net);

	if (segN) {
		if (msg->len - seg_off > SEG_OFF(1))
			seg_len = SEG_OFF(1);
		else
			seg_len = msg->len - seg_off;
	} else {
		seg_len = msg->len;
	}

	/* Start IV Update procedure when we hit our trigger point */
	if (!msg->frnd && net->seq_num > IV_UPDATE_SEQ_TRIGGER)
		mesh_net_iv_index_update(net);

	l_debug("segN %d segment %d seg_off %d", segN, segO, seg_off);
	/* print_packet("Sending", msg->buf + seg_off, seg_len); */
	{
		/* TODO: Are we RXing on an LPN's behalf? Then set RLY bit */

		if (!mesh_crypto_packet_build(false, msg->ttl,
					seq_num,
					msg->src, msg->remote,
					0,
					segN ? true : false, msg->key_id,
					msg->szmic, false, msg->seqZero,
					segO, segN,
					msg->buf + seg_off, seg_len,
					packet + 1, &packet_len)) {
			l_error("Failed to build packet");
			return false;
		}
	}
	print_packet("Clr-Net Tx", packet + 1, packet_len);

	if (msg->frnd_cred && net->friend_addr)
		key_set = frnd_get_key(net);

	if (key_set == NULL) {
		struct mesh_subnet *subnet = get_primary_subnet(net);

		key_set = &subnet->tx->key_set;
	}

	if (!mesh_crypto_packet_encode(packet + 1, packet_len, key_set->enc_key,
					msg->iv_index, key_set->privacy_key)) {
		l_error("Failed to encode packet");
		return false;
	}

	print_packet("Step 3", packet + 1, packet_len);
	if (!mesh_crypto_packet_label(packet + 1, packet_len,
				msg->iv_index, key_set->nid)) {
		l_error("Failed to label packet");
		return false;
	}
	/* print_packet("Step 4", packet + 1, packet_len); */

	{
		char *str;

		send_msg_pkt(net, packet, packet_len + 1);

		str = l_util_hexstring(packet + 1, packet_len);
		l_info("TX: Network %04x -> %04x : %s (%u) : TTL %d : SEQ %06x",
				msg->src, msg->remote, str,
				packet_len, msg->ttl,
				msg->frnd ? msg->seqAuth + segO : seq_num);
		l_free(str);
	}

	msg->last_seg = segO;

	return true;
}

void mesh_net_send_seg(struct mesh_net *net, struct mesh_key_set *key_set,
				uint32_t iv_index,
				uint8_t ttl,
				uint32_t seq,
				uint16_t src, uint16_t dst,
				uint32_t hdr,
				const void *seg, uint16_t seg_len)
{
	char *str;
	uint8_t packet[30];
	uint8_t packet_len;
	bool segmented = !!((hdr >> SEG_HDR_SHIFT) & true);
	uint8_t key_id = (hdr >> KEY_HDR_SHIFT) & KEY_ID_MASK;
	bool szmic = !!((hdr >> SZMIC_HDR_SHIFT) & true);
	uint16_t seqZero = (hdr >> SEQ_ZERO_HDR_SHIFT) & SEQ_ZERO_MASK;
	uint8_t segO = (hdr >> SEGO_HDR_SHIFT) & SEG_MASK;
	uint8_t segN = (hdr >> SEGN_HDR_SHIFT) & SEG_MASK;

	/* TODO: Only used for current POLLed segments to LPNs */

	l_debug("SEQ: %6.6x", seq + segO);
	l_debug("SEQ0: %6.6x", seq);
	l_debug("segO: %d", segO);

	if (!mesh_crypto_packet_build(false, ttl,
				seq,
				src, dst,
				0,
				segmented, key_id,
				szmic, false, seqZero,
				segO, segN,
				seg, seg_len,
				packet + 1, &packet_len)) {
		l_error("Failed to build packet");
		return;
	}

	if (!mesh_crypto_packet_encode(packet + 1, packet_len, key_set->enc_key,
					iv_index, key_set->privacy_key)) {
		l_error("Failed to encode packet");
		return;
	}

	/* print_packet("Step 3", packet + 0, packet_len); */
	if (!mesh_crypto_packet_label(packet + 1, packet_len, iv_index,
							key_set->nid)) {
		l_error("Failed to label packet");
		return;
	}
	/* print_packet("Step 4", packet + 1, packet_len); */

	send_msg_pkt(net, packet, packet_len + 1);

	str = l_util_hexstring(packet + 1, packet_len);
	l_info("TX: Friend Seg-%d %04x -> %04x : %s (%u) : TTL %d : SEQ %06x",
			segO, src, dst, str, packet_len, ttl, seq);
	l_free(str);
}

unsigned int mesh_net_app_send(struct mesh_net *net, bool frnd_cred,
				uint16_t src, uint16_t dst,
				uint8_t key_id, uint8_t ttl,
				uint32_t seq, uint32_t iv_index,
				bool szmic,
				const void *msg, uint16_t msg_len,
				mesh_net_status_func_t status_func,
				void *user_data)
{
	struct mesh_sar *payload = NULL;
	uint8_t seg, seg_max;
	unsigned int ret = 0;
	bool result;

	if (!net || msg_len > 384)
		return 0;

	if (!src)
		src = net->src_addr;

	if (!src || !dst)
		return 0;

	if (ttl == 0xff)
		ttl = net->default_ttl;

	seg_max = SEG_MAX(msg_len);

	/* First enqueue to any Friends and internal models */
	result = msg_rxed(net, false,
				iv_index,
				ttl,
				seq + seg_max,
				src, dst,
				key_id,
				szmic, seq & SEQ_ZERO_MASK,
				msg, msg_len);

	/* If successfully enqued or delivered
	 * to Unicast address, we are done
	 */
	if (result || src == dst ||
			(dst >= net->src_addr && dst <= net->last_addr)) {
		/* Adjust our seq_num for "virtual" delivery */
		net->seq_num += seg_max;
		mesh_net_next_seq_num(net);
		return 0;
	}

	/* If Segmented, Cancel any OB segmented message to same DST */
	if (seg_max) {
		payload = l_queue_remove_if(net->sar_out, match_sar_remote,
							L_UINT_TO_PTR(dst));
		mesh_sar_free(payload);
	}

	/* Setup OTA Network send */
	payload = mesh_sar_new(msg_len);
	memcpy(payload->buf, msg, msg_len);
	payload->len = msg_len;
	payload->src = src;
	payload->remote = dst;
	payload->ttl = ttl;
	payload->szmic = szmic;
	payload->frnd_cred = frnd_cred;
	payload->key_id = key_id;
	if (seg_max) {
		payload->flags = 0xffffffff >> (31 - seg_max);
		payload->seqZero = seq & SEQ_ZERO_MASK;
	}

	payload->iv_index = mesh_net_get_iv_index(net);
	payload->seqAuth = net->seq_num;

	result = true;
	if (!IS_UNICAST(dst) && seg_max) {
		for (int i = 0; i < 4; i++) {
			for (seg = 0; seg <= seg_max && result; seg++)
				result = send_seg(net, payload, seg);
		}
	} else {
		for (seg = 0; seg <= seg_max && result; seg++)
			result = send_seg(net, payload, seg);
	}

	/* Reliable: Cache; Unreliable: Flush*/
	if (result && seg_max && IS_UNICAST(dst)) {
		l_queue_push_head(net->sar_out, payload);
		payload->seg_timeout =
			l_timeout_create(SEG_TO, outseg_to, net, NULL);
		payload->msg_timeout =
			l_timeout_create(MSG_TO, outmsg_to, net, NULL);
		payload->status_func = status_func;
		payload->user_data = user_data;
		ret = payload->id = ++net->sar_id_next;
	} else
		mesh_sar_free(payload);

	return ret;
}

void mesh_net_app_send_cancel(struct mesh_net *net, unsigned int id)
{
	struct mesh_sar *sar = l_queue_remove_if(net->sar_out, match_sar_id,
						L_UINT_TO_PTR(id));

	if (sar) {
		l_info("Canceling OB %d", id);
		if (sar->status_func)
			sar->status_func(sar->remote, 2,
				sar->buf, sar->len - 4,
				sar->user_data);
	}
	mesh_sar_free(sar);
}

/* TODO: add net key index */
void mesh_net_ack_send(struct mesh_net *net, struct mesh_key_set *key_set,
				uint32_t iv_index,
				uint8_t ttl,
				uint32_t seq,
				uint16_t src, uint16_t dst,
				bool rly, uint16_t seqZero,
				uint32_t ack_flags)
{
	uint32_t hdr;
	uint8_t data[7];
	uint8_t pkt_len;
	uint8_t pkt[30];
	char *str;

	hdr = NET_OP_SEG_ACKNOWLEDGE << OPCODE_HDR_SHIFT;
	hdr |= rly << RELAY_HDR_SHIFT;
	hdr |= (seqZero & SEQ_ZERO_MASK) << SEQ_ZERO_HDR_SHIFT;
	l_put_be32(hdr, data);
	l_put_be32(ack_flags, data + 3);
	if (!mesh_crypto_packet_build(true, ttl,
					seq,
					src, dst,
					NET_OP_SEG_ACKNOWLEDGE,
					false, /* Not Segmented */
					0,	/* No Key ID associated */
					false, rly, seqZero,
					0, 0,	/* no segO or segN */
					data + 1, 6,
					pkt + 1, &pkt_len)) {
		return;
	}

	if (key_set == NULL) {
		struct mesh_subnet *subnet = get_primary_subnet(net);

		key_set = &subnet->tx->key_set;
	}

	if (!mesh_crypto_packet_encode(pkt + 1, pkt_len, key_set->enc_key,
				iv_index, key_set->privacy_key)) {
		l_error("Failed to encode packet");
		return;
	}

	/* print_packet("Step 3", pkt, pkt_len); */
	if (!mesh_crypto_packet_label(pkt + 1, pkt_len,
				iv_index, key_set->nid)) {
		l_error("Failed to label packet");
		return;
	}

	/* print_packet("Step 4", pkt, pkt_len); */
	send_msg_pkt(net, pkt, pkt_len + 1);

	str = l_util_hexstring(pkt + 1, pkt_len);
	l_info("TX: Friend ACK %04x -> %04x : %s (%u) : TTL %d : SEQ %06x",
			src, dst, str, pkt_len,
			ttl, seq);
	l_free(str);
}

/* TODO: add net key index */
void mesh_net_transport_send(struct mesh_net *net, struct mesh_key_set *key_set,
				bool fast, uint32_t iv_index, uint8_t ttl,
				uint32_t seq, uint16_t src, uint16_t dst,
				const uint8_t *msg, uint16_t msg_len)
{
	uint32_t use_seq = seq;
	uint8_t pkt_len;
	uint8_t pkt[30];
	bool result = false;

	if (!net->src_addr)
		return;

	if (!src)
		src = net->src_addr;

	if (src == dst)
		return;

	if (ttl == 0xff)
		ttl = net->default_ttl;

	/* Range check the Opcode and msg length*/
	if (*msg & 0xc0 || (9 + msg_len + 8 > 29))
		return;

	/* Enqueue for Friend if forwardable and from us */
	if (!(key_set) && src >= net->src_addr && src <= net->last_addr) {
		uint32_t hdr = msg[0] << OPCODE_HDR_SHIFT;
		uint8_t frnd_ttl = ttl;

		if (friend_packet_queue(net, iv_index,
					true, frnd_ttl,
					mesh_net_next_seq_num(net),
					src, dst,
					hdr,
					msg + 1, msg_len - 1)) {
			return;
		}
	}

	/* Deliver to Local entities if applicable */
	if (!(dst & 0x8000) && src >= net->src_addr && src <= net->last_addr) {
		result = ctl_received(net, !!(key_set),
					iv_index, ttl,
					mesh_net_next_seq_num(net),
					src, dst,
					msg[0], 0, msg + 1, msg_len - 1);
	}

	if (key_set == NULL) {
		struct mesh_subnet *subnet = get_primary_subnet(net);

		key_set = &subnet->tx->key_set;
		use_seq = mesh_net_next_seq_num(net);

		if (result || (dst >= net->src_addr && dst <= net->last_addr))
			return;
	}

	if (!mesh_crypto_packet_build(true, ttl,
				use_seq,
				src, dst,
				msg[0],
				false, 0,
				false, false, 0,
				0, 0,
				msg + 1, msg_len - 1,
				pkt + 1, &pkt_len))
		return;

	/* print_packet("Step 2", pkt + 1, pkt_len); */

	if (!mesh_crypto_packet_encode(pkt + 1, pkt_len, key_set->enc_key,
					iv_index, key_set->privacy_key)) {
		l_error("Failed to encode pkt");
		return;
	}

	/* print_packet("Step 3", pkt + 1, pkt_len); */
	if (!mesh_crypto_packet_label(pkt, pkt_len, iv_index,
							key_set->nid)) {
		l_error("Failed to label pkt");
		return;
	}

	/* print_packet("Step 4", pkt + 1, pkt_len); */

	if (dst != 0) {
		char *str;

		send_msg_pkt(net, pkt, pkt_len + 1);

		str = l_util_hexstring(pkt + 1, pkt_len);
		l_info("TX: Network %04x -> %04x : %s (%u) : TTL %d : SEQ %06x",
				src, dst, str, pkt_len,
				ttl, use_seq);
		l_free(str);
	}
}

uint8_t mesh_net_key_refresh_phase_set(struct mesh_net *net, uint16_t idx,
							uint8_t transition)
{
	struct mesh_subnet *subnet;

	if (!net)
		return MESH_STATUS_UNSPECIFIED_ERROR;

	subnet = l_queue_find(net->subnets, match_key_index,
							L_UINT_TO_PTR(idx));
	if (!subnet)
		return MESH_STATUS_INVALID_NETKEY;

	if (transition == subnet->kr_phase)
		return MESH_STATUS_SUCCESS;

	if ((transition != 2 && transition != 3) ||
						transition < subnet->kr_phase)
		return MESH_STATUS_CANNOT_SET;

	switch (transition) {
	case 2:
		if (mesh_net_key_refresh_phase_two(net, idx)
							!= MESH_STATUS_SUCCESS)
			return MESH_STATUS_CANNOT_SET;
		break;
	case 3:
		if (mesh_net_key_refresh_finish(net, idx)
							!= MESH_STATUS_SUCCESS)
			return MESH_STATUS_CANNOT_SET;
		break;
	default:
		return MESH_STATUS_CANNOT_SET;
	}
	return MESH_STATUS_SUCCESS;
}

uint8_t mesh_net_key_refresh_phase_get(struct mesh_net *net, uint16_t idx,
								uint8_t *phase)
{
	struct mesh_subnet *subnet;

	if (!net)
		return MESH_STATUS_UNSPECIFIED_ERROR;

	subnet = l_queue_find(net->subnets, match_key_index,
							L_UINT_TO_PTR(idx));
	if (!subnet)
		return MESH_STATUS_INVALID_NETKEY;

	*phase = subnet->kr_phase;
	return MESH_STATUS_SUCCESS;
}

int mesh_net_kr_phase_one(struct mesh_net *net, uint16_t idx,
							const uint8_t *value)
{
	struct mesh_subnet *subnet;

	if (!net)
		return MESH_STATUS_UNSPECIFIED_ERROR;

	subnet = l_queue_find(net->subnets, match_key_index,
							L_UINT_TO_PTR(idx));
	if (!subnet)
		return MESH_STATUS_CANNOT_UPDATE;

	if (subnet->updated.key_set.nid != NET_NID_INVALID)
		l_info("Warning: overwriting new keys");

	/* Preserve starting data */
	subnet->updated = subnet->current;

	/* Generate new keys */
	if (!create_keys(net, &subnet->updated, value)) {
		subnet->updated.key_set.nid = NET_NID_INVALID;
		l_error("Failed to start key refresh phase one");
		return MESH_STATUS_CANNOT_UPDATE;
	}

	/* If we are an LPN, generate our keys here */
	if (net->friend_addr)
		frnd_key_refresh(net, 1);
	else
		/* If we are a Friend-Node, generate all our new keys */
		l_queue_foreach(net->friends, frnd_kr_phase1, (void *)value);

	l_info("key refresh phase 1: NID 0x%2x", subnet->updated.key_set.nid);

	mesh_net_add_keyset(net, &subnet->updated.key_set);
	subnet->kr_phase = KEY_REFRESH_PHASE_ONE;

	return MESH_STATUS_SUCCESS;
}

int mesh_net_key_refresh_phase_two(struct mesh_net *net, uint16_t idx)
{
	struct mesh_subnet *subnet;

	if (!net)
		return MESH_STATUS_UNSPECIFIED_ERROR;

	subnet = l_queue_find(net->subnets, match_key_index,
							L_UINT_TO_PTR(idx));

	if (!subnet || subnet->updated.key_set.nid == NET_NID_INVALID)
		return MESH_STATUS_INVALID_NETKEY;

	l_info("Key refresh procedure phase 2: start using new net TX keys");
	subnet->key_refresh = 1;
	subnet->tx = &subnet->updated;
	/* TODO: Provisioner may need to stay in phase three until
	 * it hears beacons from all the nodes
	 */
	subnet->kr_phase = KEY_REFRESH_PHASE_TWO;
	set_network_beacon(subnet, net);

	if (net->friend_addr)
		frnd_key_refresh(net, 2);
	else
		l_queue_foreach(net->friends, frnd_kr_phase2, net);

	return MESH_STATUS_SUCCESS;
}

int mesh_net_key_refresh_finish(struct mesh_net *net, uint16_t idx)
{
	struct mesh_subnet *subnet;

	if (!net)
		return MESH_STATUS_UNSPECIFIED_ERROR;

	subnet = l_queue_find(net->subnets, match_key_index,
							L_UINT_TO_PTR(idx));

	if (!subnet || subnet->updated.key_set.nid == NET_NID_INVALID)
		return MESH_STATUS_INVALID_NETKEY;

	if (subnet->kr_phase == KEY_REFRESH_PHASE_NONE)
		return MESH_STATUS_SUCCESS;

	l_info("Key refresh phase 3: use new keys only, discard old ones");

	/* Switch to using new keys, discard old ones */
	subnet->current = subnet->updated;
	subnet->tx = &subnet->current;
	subnet->updated.key_set.nid = NET_NID_INVALID;
	mesh_net_remove_keyset(net, &subnet->updated.key_set);
	subnet->key_refresh = 0;
	subnet->kr_phase = KEY_REFRESH_PHASE_NONE;
	set_network_beacon(subnet, net);

	if (net->friend_addr)
		frnd_key_refresh(net, 3);
	else
		l_queue_foreach(net->friends, frnd_kr_phase3, net);

	return MESH_STATUS_SUCCESS;
}

uint16_t mesh_net_get_features(struct mesh_net *net)
{
	uint16_t features = 0;

	if (net->relay.enable)
		features |= FEATURE_RELAY;
	if (net->proxy_enable)
		features |= FEATURE_PROXY;
	if (!l_queue_isempty(net->friends))
		features |= FEATURE_FRIEND;
	if (net->friend_addr != UNASSIGNED_ADDRESS)
		features |= FEATURE_LPN;

	return features;
}

struct mesh_net_heartbeat *mesh_net_heartbeat_get(struct mesh_net *net)
{
	return &net->heartbeat;
}

void mesh_net_heartbeat_send(struct mesh_net *net)
{
	struct mesh_net_heartbeat *hb = &net->heartbeat;
	uint8_t msg[4];
	int n = 0;

	if (hb->pub_dst == UNASSIGNED_ADDRESS)
		return;

	msg[n++] = NET_OP_HEARTBEAT;
	msg[n++] = hb->pub_ttl;
	l_put_be16(hb->features, msg + n);
	n += 2;

	mesh_net_transport_send(net, NULL, false, mesh_net_get_iv_index(net),
				hb->pub_ttl, 0, 0, hb->pub_dst, msg, n);
}

void mesh_net_heartbeat_init(struct mesh_net *net)
{
	struct mesh_net_heartbeat *hb = &net->heartbeat;

	memset(hb, 0, sizeof(struct mesh_net_heartbeat));
	hb->sub_min_hops = 0xff;
	hb->features = mesh_net_get_features(net);
}

void mesh_net_uni_range_set(struct mesh_net *net,
				struct mesh_net_addr_range *range)
{
	net->prov_uni_addr.low = range->low;
	net->prov_uni_addr.high = range->high;
	net->prov_uni_addr.next = range->next;
}

struct mesh_net_addr_range mesh_net_uni_range_get(struct mesh_net *net)
{
	return net->prov_uni_addr;
}

void mesh_net_set_iv_index(struct mesh_net *net, uint32_t index, bool update)
{
	net->iv_index = index;
	net->iv_update = update;
}

void mesh_net_provisioner_mode_set(struct mesh_net *net, bool mode)
{
	net->provisioner = mode;
}

bool mesh_net_provisioner_mode_get(struct mesh_net *net)
{
	return net->provisioner;
}

uint16_t mesh_net_get_primary_idx(struct mesh_net *net)
{
	struct mesh_subnet *subnet;

	if (!net)
		return NET_IDX_INVALID;

	subnet = get_primary_subnet(net);
	if (!subnet)
		return NET_IDX_INVALID;

	return subnet->idx;
}

uint32_t mesh_net_friend_timeout(struct mesh_net *net, uint16_t addr)
{
	struct mesh_friend *frnd = l_queue_find(net->friends, match_by_friend,
						L_UINT_TO_PTR(addr));

	if (!frnd)
		return 0;
	else
		return frnd->poll_timeout;
}

bool mesh_net_local_node_set(struct mesh_net *net, struct mesh_node *node,
							bool provisioner)
{
	if (net->local_node) {
		l_info("Local node already registered");
		return false;
	}

	net->local_node = node;
	net->provisioner = provisioner;

	return true;
}

struct mesh_node *mesh_net_local_node_get(struct mesh_net *net)
{
	return  net->local_node;
}

bool mesh_net_set_crpl(struct mesh_net *net, uint16_t crpl)
{
	if (!net)
		return false;

	net->crpl = crpl;
	return true;
}

uint16_t mesh_net_get_crpl(struct mesh_net *net)
{
	if (!net)
		return 0;

	return net->crpl;
}

struct l_queue *mesh_net_get_app_keys(struct mesh_net *net)
{
	if (!net)
		return NULL;

	if (!net->app_keys)
		net->app_keys = l_queue_new();

	return net->app_keys;
}

bool mesh_net_have_key(struct mesh_net *net, uint16_t idx)
{
	if (!net)
		return false;

	return (l_queue_find(net->subnets, match_key_index,
						L_UINT_TO_PTR(idx)) != NULL);
}

bool mesh_net_jconfig_set(struct mesh_net *net, void *jconfig)
{
	if (!net)
		return false;

	net->jconfig_local = jconfig;
	return true;
}

void *mesh_net_jconfig_get(struct mesh_net *net)
{
	if (!net)
		return NULL;

	return  net->jconfig_local;
}

bool mesh_net_cfg_file_set(struct mesh_net *net, const char *cfg)
{
	if (!net)
		return false;

	net->cfg_file = cfg;
	return true;
}

bool mesh_net_cfg_file_get(struct mesh_net *net, const char **cfg)
{
	if (!net)
		return false;

	*cfg = net->cfg_file;
	return true;
}

bool mesh_net_is_local_address(struct mesh_net *net, uint16_t addr)
{
	if (!net)
		return false;

	return (addr >= net->src_addr && addr <= net->last_addr);
}

void mesh_net_set_window_accuracy(struct mesh_net *net, uint8_t accuracy)
{
	if (!net)
		return;

	net->window_accuracy = accuracy;
}

void mesh_net_transmit_params_set(struct mesh_net *net, uint8_t count,
							uint16_t interval)
{
	if (!net)
		return;

	net->tx_interval = interval;
	net->tx_cnt = count;
}

void mesh_net_transmit_params_get(struct mesh_net *net, uint8_t *count,
							uint16_t *interval)
{
	if (!net)
		return;

	*interval = net->tx_interval;
	*count = net->tx_cnt;
}

struct mesh_io *mesh_net_get_io(struct mesh_net *net)
{
	if (!net)
		return NULL;

	return net->io;
}

struct mesh_prov *mesh_net_get_prov(struct mesh_net *net)
{
	if (!net)
		return NULL;

	return net->prov;
}

void mesh_net_set_prov(struct mesh_net *net, struct mesh_prov *prov)
{
	if (!net)
		return;

	net->prov = prov;
}

bool mesh_net_provisioned_new(struct mesh_net *net, uint8_t device_key[16],
				uint16_t net_idx,  uint8_t net_key[16],
				uint16_t unicast, uint16_t snb_flags,
				uint32_t iv_index, mesh_status_func_t cb,
				void *user_data)
{
	if (net->provisioned || !net->local_node)
		return false;

	if (!node_set_primary(net->local_node, unicast) ||
				!(mesh_net_register_unicast(net, unicast,
						mesh_net_get_num_ele(net))))
		return false;

	if (!node_set_device_key(net->local_node, device_key))
		return false;

	net->iv_index = iv_index;
	net->iv_update = ((snb_flags & 0x02) != 0);
	if (!storage_local_set_iv_index(net, iv_index, net->iv_update))
		return false;

	if (mesh_net_add_key(net, false, net_idx, net_key) !=
							MESH_STATUS_SUCCESS)
		return false;

	if ((snb_flags & 0x01) &&
			(mesh_net_add_key(net, true, net_idx, net_key) !=
							MESH_STATUS_SUCCESS)) {
		l_queue_clear(net->subnets, l_free);
		return false;
	}

	return storage_save_new_config(net, net->cfg_file, cb, user_data);

}

void mesh_net_provisioned_set(struct mesh_net *net, bool provisioned)
{
	struct mesh_io *io;

	if (!net)
		return;

	net->provisioned = provisioned;
	io = net->io;

	if (provisioned) {
		mesh_io_register_recv_cb(io, MESH_IO_FILTER_BEACON,
							beacon_recv, net);
		mesh_io_register_recv_cb(io, MESH_IO_FILTER_NET,
							net_msg_recv, net);
	} else {
		uint8_t *uuid = node_uuid_get(net->local_node);

		if (!uuid)
			return;

		mesh_io_deregister_recv_cb(io, MESH_IO_FILTER_BEACON);
		mesh_io_deregister_recv_cb(io, MESH_IO_FILTER_NET);

		mesh_prov_listen(net, uuid, (uint8_t *) &net->prov_caps,
					acceptor_prov_open,
					acceptor_prov_close,
					acceptor_prov_receive, net);
	}
}

bool mesh_net_provisioned_get(struct mesh_net *net)
{
	if (!net)
		return false;

	return net->provisioned;
}
