/** @file
 * @brief Bluetooth BR/EDR shell module
 *
 * Provide some Bluetooth shell commands that can be useful to applications.
 */

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

#include <errno.h>
#include <zephyr/types.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <sys/byteorder.h>
#include <zephyr.h>

#include <settings/settings.h>

#include <bluetooth/hci.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/conn.h>
#include <bluetooth/l2cap.h>
#include <bluetooth/rfcomm.h>
#include <bluetooth/sdp.h>

#include <shell/shell.h>

#include "bt.h"

#if defined(CONFIG_BT_CONN)
/* Connection context for BR/EDR legacy pairing in sec mode 3 */
static struct bt_conn *pairing_conn;
#endif /* CONFIG_BT_CONN */

#define DATA_BREDR_MTU		48

NET_BUF_POOL_FIXED_DEFINE(data_pool, 1, DATA_BREDR_MTU, NULL);

#define SDP_CLIENT_USER_BUF_LEN		512
NET_BUF_POOL_FIXED_DEFINE(sdp_client_pool, CONFIG_BT_MAX_CONN,
			  SDP_CLIENT_USER_BUF_LEN, NULL);

static int cmd_auth_pincode(const struct shell *shell,
			    size_t argc, char *argv[])
{
	struct bt_conn *conn;
	u8_t max = 16U;

	if (default_conn) {
		conn = default_conn;
	} else if (pairing_conn) {
		conn = pairing_conn;
	} else {
		conn = NULL;
	}

	if (!conn) {
		shell_print(shell, "Not connected");
		return 0;
	}

	if (strlen(argv[1]) > max) {
		shell_print(shell, "PIN code value invalid - enter max %u "
			    "digits", max);
		return 0;
	}

	shell_print(shell, "PIN code \"%s\" applied", argv[1]);

	bt_conn_auth_pincode_entry(conn, argv[1]);

	return 0;
}

static int cmd_connect(const struct shell *shell, size_t argc, char *argv[])
{
	struct bt_conn *conn;
	bt_addr_t addr;
	int err;

	err = bt_addr_from_str(argv[1], &addr);
	if (err) {
		shell_print(shell, "Invalid peer address (err %d)", err);
		return -ENOEXEC;
	}

	conn = bt_conn_create_br(&addr, BT_BR_CONN_PARAM_DEFAULT);
	if (!conn) {
		shell_print(shell, "Connection failed");
	} else {

		shell_print(shell, "Connection pending");

		/* unref connection obj in advance as app user */
		bt_conn_unref(conn);
	}

	return 0;
}

static void br_device_found(const bt_addr_t *addr, s8_t rssi,
				  const u8_t cod[3], const u8_t eir[240])
{
	char br_addr[BT_ADDR_STR_LEN];
	char name[239];
	int len = 240;

	(void)memset(name, 0, sizeof(name));

	while (len) {
		if (len < 2) {
			break;
		};

		/* Look for early termination */
		if (!eir[0]) {
			break;
		}

		/* Check if field length is correct */
		if (eir[0] > len - 1) {
			break;
		}

		switch (eir[1]) {
		case BT_DATA_NAME_SHORTENED:
		case BT_DATA_NAME_COMPLETE:
			if (eir[0] > sizeof(name) - 1) {
				memcpy(name, &eir[2], sizeof(name) - 1);
			} else {
				memcpy(name, &eir[2], eir[0] - 1);
			}
			break;
		default:
			break;
		}

		/* Parse next AD Structure */
		len -= eir[0] + 1;
		eir += eir[0] + 1;
	}

	bt_addr_to_str(addr, br_addr, sizeof(br_addr));

	shell_print(ctx_shell, "[DEVICE]: %s, RSSI %i %s", br_addr, rssi, name);
}

static struct bt_br_discovery_result br_discovery_results[5];

static void br_discovery_complete(struct bt_br_discovery_result *results,
				  size_t count)
{
	size_t i;

	shell_print(ctx_shell, "BR/EDR discovery complete");

	for (i = 0; i < count; i++) {
		br_device_found(&results[i].addr, results[i].rssi,
				results[i].cod, results[i].eir);
	}
}

static int cmd_discovery(const struct shell *shell, size_t argc, char *argv[])
{
	const char *action;

	action = argv[1];
	if (!strcmp(action, "on")) {
		struct bt_br_discovery_param param;

		param.limited = false;
		param.length = 8U;

		if (argc > 2) {
			param.length = atoi(argv[2]);
		}

		if (argc > 3 && !strcmp(argv[3], "limited")) {
			param.limited = true;
		}

		if (bt_br_discovery_start(&param, br_discovery_results,
					  ARRAY_SIZE(br_discovery_results),
					  br_discovery_complete) < 0) {
			shell_print(shell, "Failed to start discovery");
			return 0;
		}

		shell_print(shell, "Discovery started");
	} else if (!strcmp(action, "off")) {
		if (bt_br_discovery_stop()) {
			shell_print(shell, "Failed to stop discovery");
			return 0;
		}

		shell_print(shell, "Discovery stopped");
	} else {
		shell_help(shell);
	}

	return 0;
}

static int l2cap_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
{
	shell_print(ctx_shell, "Incoming data channel %p len %u", chan,
		    buf->len);

	return 0;
}

static void l2cap_connected(struct bt_l2cap_chan *chan)
{
	shell_print(ctx_shell, "Channel %p connected", chan);
}

static void l2cap_disconnected(struct bt_l2cap_chan *chan)
{
	shell_print(ctx_shell, "Channel %p disconnected", chan);
}

static struct net_buf *l2cap_alloc_buf(struct bt_l2cap_chan *chan)
{
	shell_print(ctx_shell, "Channel %p requires buffer", chan);

	return net_buf_alloc(&data_pool, K_FOREVER);
}

static struct bt_l2cap_chan_ops l2cap_ops = {
	.alloc_buf	= l2cap_alloc_buf,
	.recv		= l2cap_recv,
	.connected	= l2cap_connected,
	.disconnected	= l2cap_disconnected,
};

static struct bt_l2cap_br_chan l2cap_chan = {
	.chan.ops	= &l2cap_ops,
	 /* Set for now min. MTU */
	.rx.mtu		= 48,
};

static int l2cap_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan)
{
	shell_print(ctx_shell, "Incoming BR/EDR conn %p", conn);

	if (l2cap_chan.chan.conn) {
		shell_error(ctx_shell, "No channels available");
		return -ENOMEM;
	}

	*chan = &l2cap_chan.chan;

	return 0;
}

static struct bt_l2cap_server br_server = {
	.accept = l2cap_accept,
};

static int cmd_l2cap_register(const struct shell *shell,
			      size_t argc, char *argv[])
{
	if (br_server.psm) {
		shell_print(shell, "Already registered");
		return 0;
	}

	br_server.psm = strtoul(argv[1], NULL, 16);

	if (bt_l2cap_br_server_register(&br_server) < 0) {
		shell_error(shell, "Unable to register psm");
		br_server.psm = 0U;
		return -ENOEXEC;
	} else {
		shell_print(shell, "L2CAP psm %u registered", br_server.psm);
	}

	return 0;
}

static int cmd_discoverable(const struct shell *shell,
			    size_t argc, char *argv[])
{
	int err;
	const char *action;

	action = argv[1];

	if (!strcmp(action, "on")) {
		err = bt_br_set_discoverable(true);
	} else if (!strcmp(action, "off")) {
		err = bt_br_set_discoverable(false);
	} else {
		shell_help(shell);
		return 0;
	}

	if (err) {
		shell_print(shell, "BR/EDR set/reset discoverable failed "
			    "(err %d)", err);
		return -ENOEXEC;
	} else {
		shell_print(shell, "BR/EDR set/reset discoverable done");
	}

	return 0;
}

static int cmd_connectable(const struct shell *shell,
			   size_t argc, char *argv[])
{
	int err;
	const char *action;

	action = argv[1];

	if (!strcmp(action, "on")) {
		err = bt_br_set_connectable(true);
	} else if (!strcmp(action, "off")) {
		err = bt_br_set_connectable(false);
	} else {
		shell_help(shell);
		return 0;
	}

	if (err) {
		shell_print(shell, "BR/EDR set/rest connectable failed "
			    "(err %d)", err);
		return -ENOEXEC;
	} else {
		shell_print(shell, "BR/EDR set/reset connectable done");
	}

	return 0;
}

static int cmd_oob(const struct shell *shell, size_t argc, char *argv[])
{
	char addr[BT_ADDR_STR_LEN];
	struct bt_br_oob oob;
	int err;

	err = bt_br_oob_get_local(&oob);
	if (err) {
		shell_print(shell, "BR/EDR OOB data failed");
		return -ENOEXEC;
	}

	bt_addr_to_str(&oob.addr, addr, sizeof(addr));

	shell_print(shell, "BR/EDR OOB data:");
	shell_print(shell, "  addr %s", addr);
	return 0;
}

static u8_t sdp_hfp_ag_user(struct bt_conn *conn,
			       struct bt_sdp_client_result *result)
{
	char addr[BT_ADDR_STR_LEN];
	u16_t param, version;
	u16_t features;
	int res;

	conn_addr_str(conn, addr, sizeof(addr));

	if (result) {
		shell_print(ctx_shell, "SDP HFPAG data@%p (len %u) hint %u from"
			    " remote %s", result->resp_buf,
			    result->resp_buf->len, result->next_record_hint,
			    addr);

		/*
		 * Focus to get BT_SDP_ATTR_PROTO_DESC_LIST attribute item to
		 * get HFPAG Server Channel Number operating on RFCOMM protocol.
		 */
		res = bt_sdp_get_proto_param(result->resp_buf,
					     BT_SDP_PROTO_RFCOMM, &param);
		if (res < 0) {
			shell_error(ctx_shell, "Error getting Server CN, "
				    "err %d", res);
			goto done;
		}
		shell_print(ctx_shell, "HFPAG Server CN param 0x%04x", param);

		res = bt_sdp_get_profile_version(result->resp_buf,
						 BT_SDP_HANDSFREE_SVCLASS,
						 &version);
		if (res < 0) {
			shell_error(ctx_shell, "Error getting profile version, "
				    "err %d", res);
			goto done;
		}
		shell_print(ctx_shell, "HFP version param 0x%04x", version);

		/*
		 * Focus to get BT_SDP_ATTR_SUPPORTED_FEATURES attribute item to
		 * get profile Supported Features mask.
		 */
		res = bt_sdp_get_features(result->resp_buf, &features);
		if (res < 0) {
			shell_error(ctx_shell, "Error getting HFPAG Features, "
				    "err %d", res);
			goto done;
		}
		shell_print(ctx_shell, "HFPAG Supported Features param 0x%04x",
		      features);
	} else {
		shell_print(ctx_shell, "No SDP HFPAG data from remote %s",
			    addr);
	}
done:
	return BT_SDP_DISCOVER_UUID_CONTINUE;
}

static u8_t sdp_a2src_user(struct bt_conn *conn,
			   struct bt_sdp_client_result *result)
{
	char addr[BT_ADDR_STR_LEN];
	u16_t param, version;
	u16_t features;
	int res;

	conn_addr_str(conn, addr, sizeof(addr));

	if (result) {
		shell_print(ctx_shell, "SDP A2SRC data@%p (len %u) hint %u from"
			    " remote %s", result->resp_buf,
			    result->resp_buf->len, result->next_record_hint,
			    addr);

		/*
		 * Focus to get BT_SDP_ATTR_PROTO_DESC_LIST attribute item to
		 * get A2SRC Server PSM Number.
		 */
		res = bt_sdp_get_proto_param(result->resp_buf,
					     BT_SDP_PROTO_L2CAP, &param);
		if (res < 0) {
			shell_error(ctx_shell, "A2SRC PSM Number not found, "
				    "err %d", res);
			goto done;
		}

		shell_print(ctx_shell, "A2SRC Server PSM Number param 0x%04x",
			    param);

		/*
		 * Focus to get BT_SDP_ATTR_PROFILE_DESC_LIST attribute item to
		 * get profile version number.
		 */
		res = bt_sdp_get_profile_version(result->resp_buf,
						 BT_SDP_ADVANCED_AUDIO_SVCLASS,
						 &version);
		if (res < 0) {
			shell_error(ctx_shell, "A2SRC version not found, "
				    "err %d", res);
			goto done;
		}
		shell_print(ctx_shell, "A2SRC version param 0x%04x", version);

		/*
		 * Focus to get BT_SDP_ATTR_SUPPORTED_FEATURES attribute item to
		 * get profile supported features mask.
		 */
		res = bt_sdp_get_features(result->resp_buf, &features);
		if (res < 0) {
			shell_error(ctx_shell, "A2SRC Features not found, "
				    "err %d", res);
			goto done;
		}
		shell_print(ctx_shell, "A2SRC Supported Features param 0x%04x",
		      features);
	} else {
		shell_print(ctx_shell, "No SDP A2SRC data from remote %s",
			    addr);
	}
done:
	return BT_SDP_DISCOVER_UUID_CONTINUE;
}

static struct bt_sdp_discover_params discov_hfpag = {
	.uuid = BT_UUID_DECLARE_16(BT_SDP_HANDSFREE_AGW_SVCLASS),
	.func = sdp_hfp_ag_user,
	.pool = &sdp_client_pool,
};

static struct bt_sdp_discover_params discov_a2src = {
	.uuid = BT_UUID_DECLARE_16(BT_SDP_AUDIO_SOURCE_SVCLASS),
	.func = sdp_a2src_user,
	.pool = &sdp_client_pool,
};

static struct bt_sdp_discover_params discov;

static int cmd_sdp_find_record(const struct shell *shell,
			       size_t argc, char *argv[])
{
	int res;
	const char *action;

	if (!default_conn) {
		shell_print(shell, "Not connected");
		return 0;
	}

	action = argv[1];

	if (!strcmp(action, "HFPAG")) {
		discov = discov_hfpag;
	} else if (!strcmp(action, "A2SRC")) {
		discov = discov_a2src;
	} else {
		shell_help(shell);
		return 0;
	}

	shell_print(shell, "SDP UUID \'%s\' gets applied", action);

	res = bt_sdp_discover(default_conn, &discov);
	if (res) {
		shell_error(shell, "SDP discovery failed: result %d", res);
		return -ENOEXEC;
	} else {
		shell_print(shell, "SDP discovery started");
	}

	return 0;
}

#define HELP_NONE "[none]"
#define HELP_ADDR_LE "<address: XX:XX:XX:XX:XX:XX> <type: (public|random)>"

SHELL_STATIC_SUBCMD_SET_CREATE(br_cmds,
	SHELL_CMD_ARG(auth-pincode, NULL, "<pincode>", cmd_auth_pincode, 2, 0),
	SHELL_CMD_ARG(connect, NULL, "<address>", cmd_connect, 2, 0),
	SHELL_CMD_ARG(discovery, NULL,
		      "<value: on, off> [length: 1-48] [mode: limited]",
		      cmd_discovery, 2, 2),
	SHELL_CMD_ARG(iscan, NULL, "<value: on, off>", cmd_discoverable, 2, 0),
	SHELL_CMD_ARG(l2cap-register, NULL, "<psm>", cmd_l2cap_register, 2, 0),
	SHELL_CMD_ARG(oob, NULL, NULL, cmd_oob, 1, 0),
	SHELL_CMD_ARG(pscan, NULL, "<value: on, off>", cmd_connectable, 2, 0),
	SHELL_CMD_ARG(sdp-find, NULL, "<HFPAG>", cmd_sdp_find_record, 2, 0),
	SHELL_SUBCMD_SET_END
);

static int cmd_br(const struct shell *shell, size_t argc, char **argv)
{
	if (argc == 1) {
		shell_help(shell);
		/* shell returns 1 when help is printed */
		return 1;
	}

	shell_error(shell, "%s unknown parameter: %s", argv[0], argv[1]);

	return -ENOEXEC;
}

SHELL_CMD_ARG_REGISTER(br, &br_cmds, "Bluetooth BR/EDR shell commands", cmd_br,
		       1, 1);
