/** @file
 * @brief Bluetooth Link Layer functions
 *
 */

/*
 * Copyright (c) 2017-2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdlib.h>
#include <string.h>
#include <zephyr.h>

#include <bluetooth/hci.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/conn.h>

#include <shell/shell.h>

#include "../controller/util/memq.h"
#include "../controller/include/ll.h"

#include "bt.h"

int cmd_ll_addr_read(const struct shell *sh, size_t argc, char *argv[])
{
	uint8_t addr_type;
	const char *str_type;
	bt_addr_t addr;
	char str_addr[BT_ADDR_STR_LEN];

	if (argc < 2) {
		return -EINVAL;
	}

	str_type = argv[1];
	if (!strcmp(str_type, "random")) {
		addr_type = 1U;
	} else if (!strcmp(str_type, "public")) {
		addr_type = 0U;
	} else {
		return -EINVAL;
	}

	(void)ll_addr_read(addr_type, addr.val);
	bt_addr_to_str(&addr, str_addr, sizeof(str_addr));

	shell_print(sh, "Current %s address: %s", str_type, str_addr);

	return 0;
}

#if defined(CONFIG_BT_CTLR_DTM)
#include "../controller/ll_sw/ll_test.h"

int cmd_test_tx(const struct shell *sh, size_t  argc, char *argv[])
{
	uint8_t chan, len, type, phy;
	uint32_t err;

	if (argc < 5) {
		return -EINVAL;
	}

	chan = strtoul(argv[1], NULL, 16);
	len  = strtoul(argv[2], NULL, 16);
	type = strtoul(argv[3], NULL, 16);
	phy  = strtoul(argv[4], NULL, 16);

	err = ll_test_tx(chan, len, type, phy);
	if (err) {
		return -EINVAL;
	}

	shell_print(sh, "test_tx...");

	return 0;
}

int cmd_test_rx(const struct shell *sh, size_t  argc, char *argv[])
{
	uint8_t chan, phy, mod_idx;
	uint32_t err;

	if (argc < 4) {
		return -EINVAL;
	}

	chan    = strtoul(argv[1], NULL, 16);
	phy     = strtoul(argv[2], NULL, 16);
	mod_idx = strtoul(argv[3], NULL, 16);

	err = ll_test_rx(chan, phy, mod_idx);
	if (err) {
		return -EINVAL;
	}

	shell_print(sh, "test_rx...");

	return 0;
}

int cmd_test_end(const struct shell *sh, size_t  argc, char *argv[])
{
	uint16_t num_rx;
	uint32_t err;

	err = ll_test_end(&num_rx);
	if (err) {
		return -EINVAL;
	}

	shell_print(sh, "num_rx= %u.", num_rx);

	return 0;
}
#endif /* CONFIG_BT_CTLR_DTM */

#if defined(CONFIG_BT_CTLR_ADV_EXT)
#include "../controller/ll_sw/lll.h"

#if defined(CONFIG_BT_BROADCASTER)
#define OWN_ADDR_TYPE 1
#define PEER_ADDR_TYPE 0
#define PEER_ADDR NULL
#define ADV_CHAN_MAP 0x07
#define FILTER_POLICY 0x00
#define ADV_TX_PWR NULL
#define ADV_SEC_SKIP 0
#define ADV_PHY_S 0x01
#define ADV_SID 0
#define SCAN_REQ_NOT 0

#define AD_OP 0x03
#define AD_FRAG_PREF 0x00

static const struct bt_data adv_data[] = {
	BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_NO_BREDR),
	};

int cmd_advx(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t adv_interval = 0x20;
	uint16_t handle = 0U;
	uint16_t evt_prop = 0U;
	uint8_t adv_type;
	uint8_t enable;
	uint8_t ad = 0;
	uint8_t phy_p;
	int32_t err;

	if (argc < 2) {
		return -EINVAL;
	}

	if (argc > 1) {
		if (!strcmp(argv[1], "on")) {
			adv_type = 0x05; /* Adv. Ext. */
			enable = 1U;
		} else if (!strcmp(argv[1], "hdcd")) {
			adv_type = 0x01; /* Directed */
			adv_interval = 0U; /* High Duty Cycle */
			phy_p = BIT(0);
			enable = 1U;
			goto do_enable;
		} else if (!strcmp(argv[1], "ldcd")) {
			adv_type = 0x04; /* Directed */
			enable = 1U;
		} else if (!strcmp(argv[1], "off")) {
			enable = 0U;
		} else {
			return -EINVAL;
		}
	}

	phy_p = BIT(0);

	if (argc > 2) {
		if (!strcmp(argv[2], "coded")) {
			phy_p = BIT(2);
		} else if (!strcmp(argv[2], "anon")) {
			evt_prop |= BIT(5);
		} else if (!strcmp(argv[2], "txp")) {
			evt_prop |= BIT(6);
		} else if (!strcmp(argv[2], "ad")) {
			ad = 1;
		} else {
			handle = strtoul(argv[2], NULL, 16);
			if (handle >= CONFIG_BT_CTLR_ADV_SET) {
				return -EINVAL;
			}
		}
	}

	if (argc > 3) {
		if (!strcmp(argv[3], "anon")) {
			evt_prop |= BIT(5);
		} else if (!strcmp(argv[3], "txp")) {
			evt_prop |= BIT(6);
		} else if (!strcmp(argv[3], "ad")) {
			ad = 1;
		} else {
			handle = strtoul(argv[3], NULL, 16);
			if (handle >= CONFIG_BT_CTLR_ADV_SET) {
				return -EINVAL;
			}
		}
	}

	if (argc > 4) {
		if (!strcmp(argv[4], "txp")) {
			evt_prop |= BIT(6);
		} else if (!strcmp(argv[4], "ad")) {
			ad = 1;
		} else {
			handle = strtoul(argv[4], NULL, 16);
			if (handle >= CONFIG_BT_CTLR_ADV_SET) {
				return -EINVAL;
			}
		}
	}

	if (argc > 5) {
		if (!strcmp(argv[5], "ad")) {
			ad = 1;
		} else {
			handle = strtoul(argv[5], NULL, 16);
			if (handle >= CONFIG_BT_CTLR_ADV_SET) {
				return -EINVAL;
			}
		}
	}

	if (argc > 6) {
		handle = strtoul(argv[6], NULL, 16);
		if (handle >= CONFIG_BT_CTLR_ADV_SET) {
			return -EINVAL;
		}
	}

	if (!enable) {
		goto disable;
	}

do_enable:
	shell_print(sh, "adv param set...");
	err = ll_adv_params_set(handle, evt_prop, adv_interval, adv_type,
				OWN_ADDR_TYPE, PEER_ADDR_TYPE, PEER_ADDR,
				ADV_CHAN_MAP, FILTER_POLICY, ADV_TX_PWR,
				phy_p, ADV_SEC_SKIP, ADV_PHY_S, ADV_SID,
				SCAN_REQ_NOT);
	if (err) {
		goto exit;
	}

	if (ad) {
		shell_print(sh, "ad data set...");
		err = ll_adv_aux_ad_data_set(handle, AD_OP, AD_FRAG_PREF,
					     ARRAY_SIZE(adv_data),
					     (void *)adv_data);
		if (err) {
			goto exit;
		}
	}

disable:
	shell_print(sh, "adv enable (%u)...", enable);
#if defined(CONFIG_BT_HCI_MESH_EXT)
	err = ll_adv_enable(handle, enable, 0, 0, 0, 0, 0);
#else /* !CONFIG_BT_HCI_MESH_EXT */
	err = ll_adv_enable(handle, enable, 0, 0);
#endif /* !CONFIG_BT_HCI_MESH_EXT */
	if (err) {
		goto exit;
	}

	if (!enable) {
		err = ll_adv_aux_set_remove(handle);
		if (err) {
			goto exit;
		}
	}

exit:
	shell_print(sh, "done (err= %d).", err);

	return 0;
}
#endif /* CONFIG_BT_BROADCASTER */

#if defined(CONFIG_BT_OBSERVER)
#define SCAN_INTERVAL 0x0004
#define SCAN_WINDOW 0x0004
#define SCAN_OWN_ADDR_TYPE 1
#define SCAN_FILTER_POLICY 0

int cmd_scanx(const struct shell *sh, size_t  argc, char *argv[])
{
	uint8_t type = 0U;
	uint8_t enable;
	int32_t err;

	if (argc < 2) {
		return -EINVAL;
	}

	if (argc > 1) {
		if (!strcmp(argv[1], "on")) {
			enable = 1U;
			type = 1U;
		} else if (!strcmp(argv[1], "passive")) {
			enable = 1U;
			type = 0U;
		} else if (!strcmp(argv[1], "off")) {
			enable = 0U;
			goto disable;
		} else {
			return -EINVAL;
		}
	}

	type |= BIT(1);

	if (argc > 2) {
		if (!strcmp(argv[2], "coded")) {
			type &= BIT(0);
			type |= BIT(3);
		} else {
			return -EINVAL;
		}
	}

	shell_print(sh, "scan param set...");
	err = ll_scan_params_set(type, SCAN_INTERVAL, SCAN_WINDOW,
				 SCAN_OWN_ADDR_TYPE, SCAN_FILTER_POLICY);
	if (err) {
		goto exit;
	}

disable:
	shell_print(sh, "scan enable (%u)...", enable);
	err = ll_scan_enable(enable, 0, 0);
	if (err) {
		goto exit;
	}

exit:
	shell_print(sh, "done (err= %d).", err);

	return err;
}
#endif /* CONFIG_BT_OBSERVER */
#endif /* CONFIG_BT_CTLR_ADV_EXT */
