/*  Bluetooth Mesh */

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

#include <zephyr.h>
#include <errno.h>
#include <atomic.h>
#include <misc/util.h>
#include <misc/byteorder.h>

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

#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_PROV)
#include "common/log.h"

#include "../ecc.h"

#include "crypto.h"
#include "adv.h"
#include "mesh.h"
#include "net.h"
#include "access.h"
#include "foundation.h"
#include "proxy.h"
#include "prov.h"

/* 3 transmissions, 20ms interval */
#define PROV_XMIT_COUNT        2
#define PROV_XMIT_INT          20

#define AUTH_METHOD_NO_OOB     0x00
#define AUTH_METHOD_STATIC     0x01
#define AUTH_METHOD_OUTPUT     0x02
#define AUTH_METHOD_INPUT      0x03

#define OUTPUT_OOB_BLINK       0x00
#define OUTPUT_OOB_BEEP        0x01
#define OUTPUT_OOB_VIBRATE     0x02
#define OUTPUT_OOB_NUMBER      0x03
#define OUTPUT_OOB_STRING      0x04

#define INPUT_OOB_PUSH         0x00
#define INPUT_OOB_TWIST        0x01
#define INPUT_OOB_NUMBER       0x02
#define INPUT_OOB_STRING       0x03

#define PROV_ERR_NONE          0x00
#define PROV_ERR_NVAL_PDU      0x01
#define PROV_ERR_NVAL_FMT      0x02
#define PROV_ERR_UNEXP_PDU     0x03
#define PROV_ERR_CFM_FAILED    0x04
#define PROV_ERR_RESOURCES     0x05
#define PROV_ERR_DECRYPT       0x06
#define PROV_ERR_UNEXP_ERR     0x07
#define PROV_ERR_ADDR          0x08

#define PROV_INVITE            0x00
#define PROV_CAPABILITIES      0x01
#define PROV_START             0x02
#define PROV_PUB_KEY           0x03
#define PROV_INPUT_COMPLETE    0x04
#define PROV_CONFIRM           0x05
#define PROV_RANDOM            0x06
#define PROV_DATA              0x07
#define PROV_COMPLETE          0x08
#define PROV_FAILED            0x09

#define PROV_ALG_P256          0x00

#define GPCF(gpc)              (gpc & 0x03)
#define GPC_START(last_seg)    (((last_seg) << 2) | 0x00)
#define GPC_ACK                0x01
#define GPC_CONT(seg_id)       (((seg_id) << 2) | 0x02)
#define GPC_CTL(op)            (((op) << 2) | 0x03)

#define START_PAYLOAD_MAX      20
#define CONT_PAYLOAD_MAX       23

#define START_LAST_SEG(gpc)    (gpc >> 2)
#define CONT_SEG_INDEX(gpc)    (gpc >> 2)

#define BEARER_CTL(gpc)        (gpc >> 2)
#define LINK_OPEN              0x00
#define LINK_ACK               0x01
#define LINK_CLOSE             0x02

#define CLOSE_REASON_SUCCESS   0x00
#define CLOSE_REASON_TIMEOUT   0x01
#define CLOSE_REASON_FAILED    0x02

#define XACT_SEG_DATA(_seg) (&link.rx.buf->data[20 + ((_seg - 1) * 23)])
#define XACT_SEG_RECV(_seg) (link.rx.seg &= ~(1 << (_seg)))

#define XACT_NVAL              0xff

enum {
	REMOTE_PUB_KEY,        /* Remote key has been received */
	LOCAL_PUB_KEY,         /* Local public key is available */
	LINK_ACTIVE,           /* Link has been opened */
	HAVE_DHKEY,            /* DHKey has been calcualted */
	SEND_CONFIRM,          /* Waiting to send Confirm value */
	WAIT_NUMBER,           /* Waiting for number input from user */
	WAIT_STRING,           /* Waiting for string input from user */

	NUM_FLAGS,
};

struct prov_link {
	ATOMIC_DEFINE(flags, NUM_FLAGS);
#if defined(CONFIG_BT_MESH_PB_GATT)
	struct bt_conn *conn;    /* GATT connection */
#endif
	u8_t  dhkey[32];         /* Calculated DHKey */
	u8_t  expect;            /* Next expected PDU */

	u8_t  oob_method;
	u8_t  oob_action;
	u8_t  oob_size;

	u8_t  conf[16];          /* Remote Confirmation */
	u8_t  rand[16];          /* Local Random */
	u8_t  auth[16];          /* Authentication Value */

	u8_t  conf_salt[16];     /* ConfirmationSalt */
	u8_t  conf_key[16];      /* ConfirmationKey */
	u8_t  conf_inputs[145];  /* ConfirmationInputs */
	u8_t  prov_salt[16];     /* Provisioning Salt */

#if defined(CONFIG_BT_MESH_PB_ADV)
	u32_t id;                /* Link ID */

	struct {
		u8_t  id;        /* Transaction ID */
		u8_t  prev_id;   /* Previous Transaction ID */
		u8_t  seg;       /* Bit-field of unreceived segments */
		u8_t  last_seg;  /* Last segment (to check length) */
		u8_t  fcs;       /* Expected FCS value */
		struct net_buf_simple *buf;
	} rx;

	struct {
		/* Start timestamp of the transaction */
		s64_t start;

		/* Transaction id*/
		u8_t id;

		/* Pending outgoing buffer(s) */
		struct net_buf *buf[3];

		/* Retransmit timer */
		struct k_delayed_work retransmit;
	} tx;
#endif
};

struct prov_rx {
	u32_t link_id;
	u8_t  xact_id;
	u8_t  gpc;
};

#define RETRANSMIT_TIMEOUT   K_MSEC(500)
#define BUF_TIMEOUT          K_MSEC(400)
#define TRANSACTION_TIMEOUT  K_SECONDS(30)

#if defined(CONFIG_BT_MESH_PB_GATT)
#define PROV_BUF_HEADROOM 5
#else
#define PROV_BUF_HEADROOM 0
static struct net_buf_simple *rx_buf = NET_BUF_SIMPLE(65);
#endif

#define PROV_BUF(len) NET_BUF_SIMPLE(PROV_BUF_HEADROOM + len)

static struct prov_link link;

static const struct bt_mesh_prov *prov;

static void close_link(u8_t err, u8_t reason);

#if defined(CONFIG_BT_MESH_PB_ADV)
static void buf_sent(struct net_buf *buf, int err)
{
	if (!link.tx.buf[0]) {
		return;
	}

	k_delayed_work_submit(&link.tx.retransmit, RETRANSMIT_TIMEOUT);
}

static void free_segments(void)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(link.tx.buf); i++) {
		struct net_buf *buf = link.tx.buf[i];

		if (!buf) {
			break;
		}

		link.tx.buf[i] = NULL;
		/* Mark as canceled */
		BT_MESH_ADV(buf)->busy = 0;
		net_buf_unref(buf);
	}
}

static void prov_clear_tx(void)
{
	BT_DBG("");

	k_delayed_work_cancel(&link.tx.retransmit);

	free_segments();
}

static void reset_link(void)
{
	prov_clear_tx();

	/* Clear everything except the retransmit delayed work config */
	memset(&link, 0, offsetof(struct prov_link, tx.retransmit));

	link.rx.prev_id = XACT_NVAL;

	if (bt_pub_key_get()) {
		atomic_set_bit(link.flags, LOCAL_PUB_KEY);
	}

#if defined(CONFIG_BT_MESH_PB_GATT)
	link.rx.buf = bt_mesh_proxy_get_buf();
#else
	net_buf_simple_init(rx_buf, 0);
	link.rx.buf = rx_buf;
#endif

	/* Disable Attention Timer if it was set */
	if (link.conf_inputs[0]) {
		bt_mesh_attention(NULL, 0);
	}
}

static struct net_buf *adv_buf_create(void)
{
	struct net_buf *buf;

	buf = bt_mesh_adv_create(BT_MESH_ADV_PROV, PROV_XMIT_COUNT,
				 PROV_XMIT_INT, BUF_TIMEOUT);
	if (!buf) {
		BT_ERR("Out of provisioning buffers");
		return NULL;
	}

	return buf;
}

static u8_t pending_ack = XACT_NVAL;

static void ack_complete(struct net_buf *buf, int err)
{
	BT_DBG("xact %u complete", (u8_t)pending_ack);
	pending_ack = XACT_NVAL;
}

static void gen_prov_ack_send(u8_t xact_id)
{
	bt_mesh_adv_func_t complete;
	struct net_buf *buf;

	BT_DBG("xact_id %u", xact_id);

	if (pending_ack == xact_id) {
		BT_DBG("Not sending duplicate ack");
		return;
	}

	buf = adv_buf_create();
	if (!buf) {
		return;
	}

	if (pending_ack == XACT_NVAL) {
		pending_ack = xact_id;
		complete = ack_complete;
	} else {
		complete = NULL;
	}

	net_buf_add_be32(buf, link.id);
	net_buf_add_u8(buf, xact_id);
	net_buf_add_u8(buf, GPC_ACK);

	bt_mesh_adv_send(buf, complete);
	net_buf_unref(buf);
}

static void send_reliable(void)
{
	int i;

	link.tx.start = k_uptime_get();

	for (i = 0; i < ARRAY_SIZE(link.tx.buf); i++) {
		struct net_buf *buf = link.tx.buf[i];

		if (!buf) {
			break;
		}

		if (i + 1 < ARRAY_SIZE(link.tx.buf) && link.tx.buf[i + 1]) {
			bt_mesh_adv_send(buf, NULL);
		} else {
			bt_mesh_adv_send(buf, buf_sent);
		}
	}
}

static int bearer_ctl_send(u8_t op, void *data, u8_t data_len)
{
	struct net_buf *buf;

	BT_DBG("op 0x%02x data_len %u", op, data_len);

	prov_clear_tx();

	buf = adv_buf_create();
	if (!buf) {
		return -ENOBUFS;
	}

	net_buf_add_be32(buf, link.id);
	/* Transaction ID, always 0 for Bearer messages */
	net_buf_add_u8(buf, 0x00);
	net_buf_add_u8(buf, GPC_CTL(op));
	net_buf_add_mem(buf, data, data_len);

	link.tx.buf[0] = buf;
	send_reliable();

	return 0;
}

static u8_t last_seg(u8_t len)
{
	if (len <= START_PAYLOAD_MAX) {
		return 0;
	}

	len -= START_PAYLOAD_MAX;

	return 1 + (len / CONT_PAYLOAD_MAX);
}

static inline u8_t next_transaction_id(void)
{
	if (link.tx.id != 0 && link.tx.id != 0xFF) {
		return ++link.tx.id;
	}

	link.tx.id = 0x80;
	return link.tx.id;
}

static int prov_send_adv(struct net_buf_simple *msg)
{
	struct net_buf *start, *buf;
	u8_t seg_len, seg_id;
	u8_t xact_id;

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

	prov_clear_tx();

	start = adv_buf_create();
	if (!start) {
		return -ENOBUFS;
	}

	xact_id = next_transaction_id();
	net_buf_add_be32(start, link.id);
	net_buf_add_u8(start, xact_id);

	net_buf_add_u8(start, GPC_START(last_seg(msg->len)));
	net_buf_add_be16(start, msg->len);
	net_buf_add_u8(start, bt_mesh_fcs_calc(msg->data, msg->len));

	link.tx.buf[0] = start;

	seg_len = min(msg->len, START_PAYLOAD_MAX);
	BT_DBG("seg 0 len %u: %s", seg_len, bt_hex(msg->data, seg_len));
	net_buf_add_mem(start, msg->data, seg_len);
	net_buf_simple_pull(msg, seg_len);

	buf = start;
	for (seg_id = 1; msg->len > 0; seg_id++) {
		if (seg_id >= ARRAY_SIZE(link.tx.buf)) {
			BT_ERR("Too big message");
			free_segments();
			return -E2BIG;
		}

		buf = adv_buf_create();
		if (!buf) {
			free_segments();
			return -ENOBUFS;
		}

		link.tx.buf[seg_id] = buf;

		seg_len = min(msg->len, CONT_PAYLOAD_MAX);

		BT_DBG("seg_id %u len %u: %s", seg_id, seg_len,
		       bt_hex(msg->data, seg_len));

		net_buf_add_be32(buf, link.id);
		net_buf_add_u8(buf, xact_id);
		net_buf_add_u8(buf, GPC_CONT(seg_id));
		net_buf_add_mem(buf, msg->data, seg_len);
		net_buf_simple_pull(msg, seg_len);
	}

	send_reliable();

	return 0;
}

#endif /* CONFIG_BT_MESH_PB_ADV */

#if defined(CONFIG_BT_MESH_PB_GATT)
static int prov_send_gatt(struct net_buf_simple *msg)
{
	if (!link.conn) {
		return -ENOTCONN;
	}

	return bt_mesh_proxy_send(link.conn, BT_MESH_PROXY_PROV, msg);
}
#endif /* CONFIG_BT_MESH_PB_GATT */

static inline int prov_send(struct net_buf_simple *buf)
{
#if defined(CONFIG_BT_MESH_PB_GATT)
	if (link.conn) {
		return prov_send_gatt(buf);
	}
#endif
#if defined(CONFIG_BT_MESH_PB_ADV)
	return prov_send_adv(buf);
#else
	return 0;
#endif
}

static void prov_buf_init(struct net_buf_simple *buf, u8_t type)
{
	net_buf_simple_init(buf, PROV_BUF_HEADROOM);
	net_buf_simple_add_u8(buf, type);
}

static void prov_send_fail_msg(u8_t err)
{
	struct net_buf_simple *buf = PROV_BUF(2);

	prov_buf_init(buf, PROV_FAILED);
	net_buf_simple_add_u8(buf, err);
	prov_send(buf);
}

static void prov_invite(const u8_t *data)
{
	struct net_buf_simple *buf = PROV_BUF(12);

	BT_DBG("Attention Duration: %u seconds", data[0]);

	if (data[0]) {
		bt_mesh_attention(NULL, data[0]);
	}

	link.conf_inputs[0] = data[0];

	prov_buf_init(buf, PROV_CAPABILITIES);

	/* Number of Elements supported */
	net_buf_simple_add_u8(buf, bt_mesh_elem_count());

	/* Supported algorithms - FIPS P-256 Eliptic Curve */
	net_buf_simple_add_be16(buf, BIT(PROV_ALG_P256));

	/* Public Key Type */
	net_buf_simple_add_u8(buf, 0x00);

	/* Static OOB Type */
	net_buf_simple_add_u8(buf, prov->static_val ? BIT(0) : 0x00);

	/* Output OOB Size */
	net_buf_simple_add_u8(buf, prov->output_size);

	/* Output OOB Action */
	net_buf_simple_add_be16(buf, prov->output_actions);

	/* Input OOB Size */
	net_buf_simple_add_u8(buf, prov->input_size);

	/* Input OOB Action */
	net_buf_simple_add_be16(buf, prov->input_actions);

	memcpy(&link.conf_inputs[1], &buf->data[1], 11);

	if (prov_send(buf)) {
		BT_ERR("Failed to send capabilities");
		close_link(PROV_ERR_RESOURCES, CLOSE_REASON_FAILED);
		return;
	}

	link.expect = PROV_START;
}

static void prov_capabilities(const u8_t *data)
{
	u16_t algorithms, output_action, input_action;

	BT_DBG("Elements: %u", data[0]);

	algorithms = sys_get_be16(&data[1]);
	BT_DBG("Algorithms:        %u", algorithms);

	BT_DBG("Public Key Type:   0x%02x", data[3]);
	BT_DBG("Static OOB Type:   0x%02x", data[4]);
	BT_DBG("Output OOB Size:   %u", data[5]);

	output_action = sys_get_be16(&data[6]);
	BT_DBG("Output OOB Action: 0x%04x", output_action);

	BT_DBG("Input OOB Size:    %u", data[8]);

	input_action = sys_get_be16(&data[9]);
	BT_DBG("Input OOB Action:  0x%04x", input_action);
}

static bt_mesh_output_action output_action(u8_t action)
{
	switch (action) {
	case OUTPUT_OOB_BLINK:
		return BT_MESH_BLINK;
	case OUTPUT_OOB_BEEP:
		return BT_MESH_BEEP;
	case OUTPUT_OOB_VIBRATE:
		return BT_MESH_VIBRATE;
	case OUTPUT_OOB_NUMBER:
		return BT_MESH_DISPLAY_NUMBER;
	case OUTPUT_OOB_STRING:
		return BT_MESH_DISPLAY_STRING;
	default:
		return BT_MESH_NO_OUTPUT;
	}
}

static bt_mesh_input_action input_action(u8_t action)
{
	switch (action) {
	case INPUT_OOB_PUSH:
		return BT_MESH_PUSH;
	case INPUT_OOB_TWIST:
		return BT_MESH_TWIST;
	case INPUT_OOB_NUMBER:
		return BT_MESH_ENTER_NUMBER;
	case INPUT_OOB_STRING:
		return BT_MESH_ENTER_STRING;
	default:
		return BT_MESH_NO_INPUT;
	}
}

static int prov_auth(u8_t method, u8_t action, u8_t size)
{
	bt_mesh_output_action output;
	bt_mesh_input_action input;

	switch (method) {
	case AUTH_METHOD_NO_OOB:
		if (action || size) {
			return -EINVAL;
		}

		memset(link.auth, 0, sizeof(link.auth));
		return 0;
	case AUTH_METHOD_STATIC:
		if (action || size) {
			return -EINVAL;
		}

		memcpy(link.auth, prov->static_val, prov->static_val_len);
		return 0;

	case AUTH_METHOD_OUTPUT:
		output = output_action(action);
		if (!output) {
			return -EINVAL;
		}

		if (!(prov->output_actions & output)) {
			return -EINVAL;
		}

		if (size > prov->output_size) {
			return -EINVAL;
		}

		if (output == BT_MESH_DISPLAY_STRING) {
			char str[9];
			u8_t i;

			bt_rand(str, size);

			/* Normalize to '0' .. '9' & 'A' .. 'Z' */
			for (i = 0; i < size; i++) {
				str[i] %= 36;
				if (str[i] < 10) {
					str[i] += '\0';
				} else {
					str[i] += 'A' - 10;
				}
			}
			str[size] = '\0';

			memcpy(link.auth, str, size);

			return prov->output_string(str);
		} else {
			u32_t div[8] = { 10, 100, 1000, 10000, 100000,
					    1000000, 10000000, 100000000 };
			u32_t num;

			bt_rand(&num, sizeof(num));
			num %= div[size - 1];

			sys_put_be32(num, &link.auth[12]);

			return prov->output_number(output, num);
		}

	case AUTH_METHOD_INPUT:
		input = input_action(action);
		if (!input) {
			return -EINVAL;
		}

		if (!(prov->input_actions & input)) {
			return -EINVAL;
		}

		if (size > prov->input_size) {
			return -EINVAL;
		}

		if (input == BT_MESH_ENTER_STRING) {
			atomic_set_bit(link.flags, WAIT_STRING);
		} else {
			atomic_set_bit(link.flags, WAIT_NUMBER);
		}

		return prov->input(input, size);

	default:
		return -EINVAL;
	}
}

static void prov_start(const u8_t *data)
{
	BT_DBG("Algorithm:   0x%02x", data[0]);
	BT_DBG("Public Key:  0x%02x", data[1]);
	BT_DBG("Auth Method: 0x%02x", data[2]);
	BT_DBG("Auth Action: 0x%02x", data[3]);
	BT_DBG("Auth Size:   0x%02x", data[4]);

	if (data[0] != PROV_ALG_P256) {
		BT_ERR("Unknown algorithm 0x%02x", data[0]);
		prov_send_fail_msg(PROV_ERR_NVAL_FMT);
		return;
	}

	if (data[1] > 0x01) {
		BT_ERR("Invalid public key value: 0x%02x", data[1]);
		prov_send_fail_msg(PROV_ERR_NVAL_FMT);
		return;
	}

	memcpy(&link.conf_inputs[12], data, 5);

	link.expect = PROV_PUB_KEY;

	if (prov_auth(data[2], data[3], data[4]) < 0) {
		BT_ERR("Invalid authentication method: 0x%02x; "
			"action: 0x%02x; size: 0x%02x", data[2], data[3], data[4]);
		prov_send_fail_msg(PROV_ERR_NVAL_FMT);
	}
}

static void send_confirm(void)
{
	struct net_buf_simple *cfm = PROV_BUF(17);

	BT_DBG("ConfInputs[0]   %s", bt_hex(link.conf_inputs, 64));
	BT_DBG("ConfInputs[64]  %s", bt_hex(&link.conf_inputs[64], 64));
	BT_DBG("ConfInputs[128] %s", bt_hex(&link.conf_inputs[128], 17));

	if (bt_mesh_prov_conf_salt(link.conf_inputs, link.conf_salt)) {
		BT_ERR("Unable to generate confirmation salt");
		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
		return;
	}

	BT_DBG("ConfirmationSalt: %s", bt_hex(link.conf_salt, 16));

	if (bt_mesh_prov_conf_key(link.dhkey, link.conf_salt, link.conf_key)) {
		BT_ERR("Unable to generate confirmation key");
		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
		return;
	}

	BT_DBG("ConfirmationKey: %s", bt_hex(link.conf_key, 16));

	if (bt_rand(link.rand, 16)) {
		BT_ERR("Unable to generate random number");
		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
		return;
	}

	BT_DBG("LocalRandom: %s", bt_hex(link.rand, 16));

	prov_buf_init(cfm, PROV_CONFIRM);

	if (bt_mesh_prov_conf(link.conf_key, link.rand, link.auth,
			      net_buf_simple_add(cfm, 16))) {
		BT_ERR("Unable to generate confirmation value");
		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
		return;
	}

	if (prov_send(cfm)) {
		BT_ERR("Failed to send Provisioning Confirm");
		close_link(PROV_ERR_RESOURCES, CLOSE_REASON_FAILED);
		return;
	}

	link.expect = PROV_RANDOM;
}

int bt_mesh_input_number(u32_t num)
{
	if (!atomic_test_and_clear_bit(link.flags, WAIT_NUMBER)) {
		return -EINVAL;
	}

	if (!atomic_test_bit(link.flags, HAVE_DHKEY)) {
		return 0;
	}

	sys_put_be32(num, &link.auth[12]);

	if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) {
		send_confirm();
	}

	return 0;
}

int bt_mesh_input_string(const char *str)
{
	if (!atomic_test_and_clear_bit(link.flags, WAIT_STRING)) {
		return -EINVAL;
	}

	if (!atomic_test_bit(link.flags, HAVE_DHKEY)) {
		return 0;
	}

	strncpy(link.auth, str, prov->input_size);

	if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) {
		send_confirm();
	}

	return 0;
}

static void prov_dh_key_cb(const u8_t key[32])
{
	BT_DBG("%p", key);

	if (!key) {
		BT_ERR("DHKey generation failed");
		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
		return;
	}

	sys_memcpy_swap(link.dhkey, key, 32);

	BT_DBG("DHkey: %s", bt_hex(link.dhkey, 32));

	atomic_set_bit(link.flags, HAVE_DHKEY);

	if (atomic_test_bit(link.flags, WAIT_NUMBER) ||
	    atomic_test_bit(link.flags, WAIT_STRING)) {
		return;
	}

	if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) {
		send_confirm();
	}
}

static void send_pub_key(void)
{
	struct net_buf_simple *buf = PROV_BUF(65);
	const u8_t *key;

	key = bt_pub_key_get();
	if (!key) {
		BT_ERR("No public key available");
		close_link(PROV_ERR_RESOURCES, CLOSE_REASON_FAILED);
		return;
	}

	BT_DBG("Local Public Key: %s", bt_hex(key, 64));

	prov_buf_init(buf, PROV_PUB_KEY);

	/* Swap X and Y halves independently to big-endian */
	sys_memcpy_swap(net_buf_simple_add(buf, 32), key, 32);
	sys_memcpy_swap(net_buf_simple_add(buf, 32), &key[32], 32);

	memcpy(&link.conf_inputs[81], &buf->data[1], 64);

	prov_send(buf);

	/* Copy remote key in little-endian for bt_dh_key_gen().
	 * X and Y halves are swapped independently.
	 */
	net_buf_simple_init(buf, 0);
	sys_memcpy_swap(buf->data, &link.conf_inputs[17], 32);
	sys_memcpy_swap(&buf->data[32], &link.conf_inputs[49], 32);

	if (bt_dh_key_gen(buf->data, prov_dh_key_cb)) {
		BT_ERR("Failed to generate DHKey");
		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
		return;
	}

	link.expect = PROV_CONFIRM;
}

static void prov_pub_key(const u8_t *data)
{
	BT_DBG("Remote Public Key: %s", bt_hex(data, 64));

	memcpy(&link.conf_inputs[17], data, 64);

	if (!atomic_test_bit(link.flags, LOCAL_PUB_KEY)) {
		/* Clear retransmit timer */
#if defined(CONFIG_BT_MESH_PB_ADV)
		prov_clear_tx();
#endif
		atomic_set_bit(link.flags, REMOTE_PUB_KEY);
		BT_WARN("Waiting for local public key");
		return;
	}

	send_pub_key();
}

static void pub_key_ready(const u8_t *pkey)
{
	if (!pkey) {
		BT_WARN("Public key not available");
		return;
	}

	BT_DBG("Local public key ready");

	atomic_set_bit(link.flags, LOCAL_PUB_KEY);

	if (atomic_test_and_clear_bit(link.flags, REMOTE_PUB_KEY)) {
		send_pub_key();
	}
}

static void prov_input_complete(const u8_t *data)
{
	BT_DBG("");
}

static void prov_confirm(const u8_t *data)
{
	BT_DBG("Remote Confirm: %s", bt_hex(data, 16));

	memcpy(link.conf, data, 16);

	if (!atomic_test_bit(link.flags, HAVE_DHKEY)) {
#if defined(CONFIG_BT_MESH_PB_ADV)
		prov_clear_tx();
#endif
		atomic_set_bit(link.flags, SEND_CONFIRM);
	} else {
		send_confirm();
	}
}

static void prov_random(const u8_t *data)
{
	struct net_buf_simple *rnd = PROV_BUF(16);
	u8_t conf_verify[16];

	BT_DBG("Remote Random: %s", bt_hex(data, 16));

	if (bt_mesh_prov_conf(link.conf_key, data, link.auth, conf_verify)) {
		BT_ERR("Unable to calculate confirmation verification");
		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
		return;
	}

	if (memcmp(conf_verify, link.conf, 16)) {
		BT_ERR("Invalid confirmation value");
		BT_DBG("Received:   %s", bt_hex(link.conf, 16));
		BT_DBG("Calculated: %s",  bt_hex(conf_verify, 16));
		close_link(PROV_ERR_CFM_FAILED, CLOSE_REASON_FAILED);
		return;
	}

	prov_buf_init(rnd, PROV_RANDOM);
	net_buf_simple_add_mem(rnd, link.rand, 16);

	if (prov_send(rnd)) {
		BT_ERR("Failed to send Provisioning Random");
		close_link(PROV_ERR_RESOURCES, CLOSE_REASON_FAILED);
		return;
	}

	if (bt_mesh_prov_salt(link.conf_salt, data, link.rand,
			      link.prov_salt)) {
		BT_ERR("Failed to generate provisioning salt");
		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
		return;
	}

	BT_DBG("ProvisioningSalt: %s", bt_hex(link.prov_salt, 16));

	link.expect = PROV_DATA;
}

static void prov_data(const u8_t *data)
{
	struct net_buf_simple *msg = PROV_BUF(1);
	u8_t session_key[16];
	u8_t nonce[13];
	u8_t dev_key[16];
	u8_t pdu[25];
	u8_t flags;
	u32_t iv_index;
	u16_t addr;
	u16_t net_idx;
	int err;

	BT_DBG("");

	err = bt_mesh_session_key(link.dhkey, link.prov_salt, session_key);
	if (err) {
		BT_ERR("Unable to generate session key");
		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
		return;
	}

	BT_DBG("SessionKey: %s", bt_hex(session_key, 16));

	err = bt_mesh_prov_nonce(link.dhkey, link.prov_salt, nonce);
	if (err) {
		BT_ERR("Unable to generate session nonce");
		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
		return;
	}

	BT_DBG("Nonce: %s", bt_hex(nonce, 13));

	err = bt_mesh_prov_decrypt(session_key, nonce, data, pdu);
	if (err) {
		BT_ERR("Unable to decrypt provisioning data");
		close_link(PROV_ERR_DECRYPT, CLOSE_REASON_FAILED);
		return;
	}

	err = bt_mesh_dev_key(link.dhkey, link.prov_salt, dev_key);
	if (err) {
		BT_ERR("Unable to generate device key");
		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
		return;
	}

	BT_DBG("DevKey: %s", bt_hex(dev_key, 16));

	net_idx = sys_get_be16(&pdu[16]);
	flags = pdu[18];
	iv_index = sys_get_be32(&pdu[19]);
	addr = sys_get_be16(&pdu[23]);

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

	prov_buf_init(msg, PROV_COMPLETE);
	prov_send(msg);

	/* Ignore any further PDUs on this link */
	link.expect = 0;

	bt_mesh_provision(pdu, net_idx, flags, iv_index, 0, addr, dev_key);

	if (prov->complete) {
		prov->complete();
	}
}

static void prov_complete(const u8_t *data)
{
	BT_DBG("");
}

static void prov_failed(const u8_t *data)
{
	BT_WARN("Error: 0x%02x", data[0]);
}

static const struct {
	void (*func)(const u8_t *data);
	u16_t len;
} prov_handlers[] = {
	{ prov_invite, 1 },
	{ prov_capabilities, 11 },
	{ prov_start, 5, },
	{ prov_pub_key, 64 },
	{ prov_input_complete, 0 },
	{ prov_confirm, 16 },
	{ prov_random, 16 },
	{ prov_data, 33 },
	{ prov_complete, 0 },
	{ prov_failed, 1 },
};

static void close_link(u8_t err, u8_t reason)
{
#if defined(CONFIG_BT_MESH_PB_GATT)
	if (link.conn) {
		bt_mesh_pb_gatt_close(link.conn);
		return;
	}
#endif

#if defined(CONFIG_BT_MESH_PB_ADV)
	if (err) {
		prov_send_fail_msg(err);
	}

	link.rx.seg = 0;
	bearer_ctl_send(LINK_CLOSE, &reason, sizeof(reason));
#endif

	atomic_clear_bit(link.flags, LINK_ACTIVE);

	/* Disable Attention Timer if it was set */
	if (link.conf_inputs[0]) {
		bt_mesh_attention(NULL, 0);
	}
}

#if defined(CONFIG_BT_MESH_PB_ADV)
static void prov_retransmit(struct k_work *work)
{
	int i;

	BT_DBG("");

	if (!atomic_test_bit(link.flags, LINK_ACTIVE)) {
		BT_WARN("Link not active");
		return;
	}

	if (k_uptime_get() - link.tx.start > TRANSACTION_TIMEOUT) {
		BT_WARN("Giving up transaction");
		reset_link();
		return;
	}

	for (i = 0; i < ARRAY_SIZE(link.tx.buf); i++) {
		struct net_buf *buf = link.tx.buf[i];

		if (!buf) {
			break;
		}

		if (BT_MESH_ADV(buf)->busy) {
			continue;
		}

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

		if (i + 1 < ARRAY_SIZE(link.tx.buf) && link.tx.buf[i + 1]) {
			bt_mesh_adv_send(buf, NULL);
		} else {
			bt_mesh_adv_send(buf, buf_sent);
		}

	}
}

static void link_open(struct prov_rx *rx, struct net_buf_simple *buf)
{
	BT_DBG("len %u", buf->len);

	if (buf->len < 16) {
		BT_ERR("Too short bearer open message (len %u)", buf->len);
		return;
	}

	if (atomic_test_bit(link.flags, LINK_ACTIVE)) {
		BT_WARN("Ignoring bearer open: link already active");
		return;
	}

	if (memcmp(buf->data, prov->uuid, 16)) {
		BT_DBG("Bearer open message not for us");
		return;
	}

	link.id = rx->link_id;
	atomic_set_bit(link.flags, LINK_ACTIVE);
	net_buf_simple_init(link.rx.buf, 0);

	bearer_ctl_send(LINK_ACK, NULL, 0);

	link.expect = PROV_INVITE;
}

static void link_ack(struct prov_rx *rx, struct net_buf_simple *buf)
{
	BT_DBG("len %u", buf->len);
}

static void link_close(struct prov_rx *rx, struct net_buf_simple *buf)
{
	BT_DBG("len %u", buf->len);

	reset_link();
}

static void gen_prov_ctl(struct prov_rx *rx, struct net_buf_simple *buf)
{
	BT_DBG("op 0x%02x len %u", BEARER_CTL(rx->gpc), buf->len);

	switch (BEARER_CTL(rx->gpc)) {
	case LINK_OPEN:
		link_open(rx, buf);
		break;
	case LINK_ACK:
		if (!atomic_test_bit(link.flags, LINK_ACTIVE)) {
			return;
		}

		link_ack(rx, buf);
		break;
	case LINK_CLOSE:
		if (!atomic_test_bit(link.flags, LINK_ACTIVE)) {
			return;
		}

		link_close(rx, buf);
		break;
	default:
		BT_ERR("Unknown bearer opcode: 0x%02x", BEARER_CTL(rx->gpc));
		return;
	}
}

static void prov_msg_recv(void)
{
	u8_t type = link.rx.buf->data[0];

	BT_DBG("type 0x%02x len %u", type, link.rx.buf->len);

	if (!bt_mesh_fcs_check(link.rx.buf, link.rx.fcs)) {
		BT_ERR("Incorrect FCS");
		return;
	}

	gen_prov_ack_send(link.rx.id);
	link.rx.prev_id = link.rx.id;
	link.rx.id = 0;

	if (type != PROV_FAILED && type != link.expect) {
		BT_WARN("Unexpected msg 0x%02x != 0x%02x", type, link.expect);
		prov_send_fail_msg(PROV_ERR_UNEXP_PDU);
		return;
	}

	if (type >= ARRAY_SIZE(prov_handlers)) {
		BT_ERR("Unknown provisioning PDU type 0x%02x", type);
		close_link(PROV_ERR_NVAL_PDU, CLOSE_REASON_FAILED);
		return;
	}

	if (1 + prov_handlers[type].len != link.rx.buf->len) {
		BT_ERR("Invalid length %u for type 0x%02x",
		       link.rx.buf->len, type);
		close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED);
		return;
	}

	prov_handlers[type].func(&link.rx.buf->data[1]);
}

static void gen_prov_cont(struct prov_rx *rx, struct net_buf_simple *buf)
{
	u8_t seg = CONT_SEG_INDEX(rx->gpc);

	BT_DBG("len %u, seg_index %u", buf->len, seg);

	if (!link.rx.seg && link.rx.prev_id == rx->xact_id) {
		BT_WARN("Resending ack");
		gen_prov_ack_send(rx->xact_id);
		return;
	}

	if (rx->xact_id != link.rx.id) {
		BT_WARN("Data for unknown transaction (%u != %u)",
			rx->xact_id, link.rx.id);
		return;
	}

	if (seg > link.rx.last_seg) {
		BT_ERR("Invalid segment index %u", seg);
		close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED);
		return;
	} else if (seg == link.rx.last_seg) {
		u8_t expect_len;

		expect_len = (link.rx.buf->len - 20 -
			      (23 * (link.rx.last_seg - 1)));
		if (expect_len != buf->len) {
			BT_ERR("Incorrect last seg len: %u != %u",
			       expect_len, buf->len);
			close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED);
			return;
		}
	}

	if (!(link.rx.seg & BIT(seg))) {
		BT_WARN("Ignoring already received segment");
		return;
	}

	memcpy(XACT_SEG_DATA(seg), buf->data, buf->len);
	XACT_SEG_RECV(seg);

	if (!link.rx.seg) {
		prov_msg_recv();
	}
}

static void gen_prov_ack(struct prov_rx *rx, struct net_buf_simple *buf)
{
	BT_DBG("len %u", buf->len);

	if (!link.tx.buf[0]) {
		return;
	}

	if (rx->xact_id == link.tx.id) {
		prov_clear_tx();
	}
}

static void gen_prov_start(struct prov_rx *rx, struct net_buf_simple *buf)
{
	if (link.rx.seg) {
		BT_WARN("Got Start while there are unreceived segments");
		return;
	}

	if (link.rx.prev_id == rx->xact_id) {
		BT_WARN("Resending ack");
		gen_prov_ack_send(rx->xact_id);
		return;
	}

	link.rx.buf->len = net_buf_simple_pull_be16(buf);
	link.rx.id  = rx->xact_id;
	link.rx.fcs = net_buf_simple_pull_u8(buf);

	BT_DBG("len %u last_seg %u total_len %u fcs 0x%02x", buf->len,
	       START_LAST_SEG(rx->gpc), link.rx.buf->len, link.rx.fcs);

	if (link.rx.buf->len < 1) {
		BT_ERR("Ignoring zero-length provisioning PDU");
		close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED);
		return;
	}

	if (link.rx.buf->len > link.rx.buf->size) {
		BT_ERR("Too large provisioning PDU (%u bytes)",
		       link.rx.buf->len);
		close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED);
		return;
	}

	if (START_LAST_SEG(rx->gpc) > 0 && link.rx.buf->len <= 20) {
		BT_ERR("Too small total length for multi-segment PDU");
		close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED);
		return;
	}

	link.rx.seg = (1 << (START_LAST_SEG(rx->gpc) + 1)) - 1;
	link.rx.last_seg = START_LAST_SEG(rx->gpc);
	memcpy(link.rx.buf->data, buf->data, buf->len);
	XACT_SEG_RECV(0);

	if (!link.rx.seg) {
		prov_msg_recv();
	}
}

static const struct {
	void (*const func)(struct prov_rx *rx, struct net_buf_simple *buf);
	const u8_t require_link;
	const u8_t min_len;
} gen_prov[] = {
	{ gen_prov_start, true, 3 },
	{ gen_prov_ack, true, 0 },
	{ gen_prov_cont, true, 0 },
	{ gen_prov_ctl, false, 0 },
};

static void gen_prov_recv(struct prov_rx *rx, struct net_buf_simple *buf)
{
	if (buf->len < gen_prov[GPCF(rx->gpc)].min_len) {
		BT_ERR("Too short GPC message type %u", GPCF(rx->gpc));
		return;
	}

	if (!atomic_test_bit(link.flags, LINK_ACTIVE) &&
	    gen_prov[GPCF(rx->gpc)].require_link) {
		BT_DBG("Ignoring message that requires active link");
		return;
	}

	gen_prov[GPCF(rx->gpc)].func(rx, buf);
}

void bt_mesh_pb_adv_recv(struct net_buf_simple *buf)
{
	struct prov_rx rx;

	if (!bt_prov_active() && bt_mesh_is_provisioned()) {
		BT_DBG("Ignoring provisioning PDU - already provisioned");
		return;
	}

	if (buf->len < 6) {
		BT_WARN("Too short provisioning packet (len %u)", buf->len);
		return;
	}

	rx.link_id = net_buf_simple_pull_be32(buf);
	rx.xact_id = net_buf_simple_pull_u8(buf);
	rx.gpc = net_buf_simple_pull_u8(buf);

	BT_DBG("link_id 0x%08x xact_id %u", rx.link_id, rx.xact_id);

	if (atomic_test_bit(link.flags, LINK_ACTIVE) && link.id != rx.link_id) {
		BT_DBG("Ignoring mesh beacon for unknown link");
		return;
	}

	gen_prov_recv(&rx, buf);
}
#endif /* CONFIG_BT_MESH_PB_ADV */

#if defined(CONFIG_BT_MESH_PB_GATT)
int bt_mesh_pb_gatt_recv(struct bt_conn *conn, struct net_buf_simple *buf)
{
	u8_t type;

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

	if (link.conn != conn) {
		BT_WARN("Data for unexpected connection");
		return -ENOTCONN;
	}

	if (buf->len < 1) {
		BT_WARN("Too short provisioning packet (len %u)", buf->len);
		return -EINVAL;
	}

	type = net_buf_simple_pull_u8(buf);
	if (type != PROV_FAILED && type != link.expect) {
		BT_WARN("Unexpected msg 0x%02x != 0x%02x", type, link.expect);
		return -EINVAL;
	}

	if (type >= ARRAY_SIZE(prov_handlers)) {
		BT_ERR("Unknown provisioning PDU type 0x%02x", type);
		return -EINVAL;
	}

	if (prov_handlers[type].len != buf->len) {
		BT_ERR("Invalid length %u for type 0x%02x", buf->len, type);
		return -EINVAL;
	}

	prov_handlers[type].func(buf->data);

	return 0;
}

int bt_mesh_pb_gatt_open(struct bt_conn *conn)
{
	BT_DBG("conn %p", conn);

	if (atomic_test_and_set_bit(link.flags, LINK_ACTIVE)) {
		return -EBUSY;
	}

	link.conn = bt_conn_ref(conn);
	link.expect = PROV_INVITE;

	return 0;
}

int bt_mesh_pb_gatt_close(struct bt_conn *conn)
{
	bool pub_key;

	BT_DBG("conn %p", conn);

	if (link.conn != conn) {
		BT_ERR("Not connected");
		return -ENOTCONN;
	}

	/* Disable Attention Timer if it was set */
	if (link.conf_inputs[0]) {
		bt_mesh_attention(NULL, 0);
	}

	bt_conn_unref(link.conn);

	pub_key = atomic_test_bit(link.flags, LOCAL_PUB_KEY);
	memset(&link, 0, sizeof(link));

	if (pub_key) {
		atomic_set_bit(link.flags, LOCAL_PUB_KEY);
	}

	return 0;
}
#endif /* CONFIG_BT_MESH_PB_GATT */

const u8_t *bt_mesh_prov_get_uuid(void)
{
	return prov->uuid;
}

bool bt_prov_active(void)
{
	return atomic_test_bit(link.flags, LINK_ACTIVE);
}

void bt_mesh_prov_init(const struct bt_mesh_prov *prov_info)
{
	static struct bt_pub_key_cb pub_key_cb = {
		.func = pub_key_ready,
	};

	if (bt_pub_key_gen(&pub_key_cb)) {
		BT_ERR("Failed to generate public key");
	}

	prov = prov_info;

#if defined(CONFIG_BT_MESH_PB_ADV)
	k_delayed_work_init(&link.tx.retransmit, prov_retransmit);
	link.rx.prev_id = XACT_NVAL;

#if defined(CONFIG_BT_MESH_PB_GATT)
	link.rx.buf = bt_mesh_proxy_get_buf();
#else
	net_buf_simple_init(rx_buf, 0);
	link.rx.buf = rx_buf;
#endif

#endif /* CONFIG_BT_MESH_PB_ADV */

	if (IS_ENABLED(CONFIG_BT_DEBUG)) {
		struct bt_uuid_128 uuid = { .uuid.type = BT_UUID_TYPE_128 };
		memcpy(uuid.val, prov->uuid, 16);
		BT_INFO("Device UUID: %s", bt_uuid_str(&uuid.uuid));
	}
}
