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

#include <stdlib.h>
#include <zephyr/shell/shell.h>
#include <zephyr/bluetooth/mesh.h>

#include "../net.h"
#include "../access.h"
#include "utils.h"
#include <zephyr/bluetooth/mesh/shell.h>

#define CID_NVAL 0xffff

/* Default net & app key values, unless otherwise specified */
static const uint8_t default_key[16] = {
	0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
	0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
};

static int cmd_reset(const struct shell *sh, size_t argc, char *argv[])
{
	int err;
	bool reset = false;

	err = bt_mesh_cfg_cli_node_reset(bt_mesh_shell_target_ctx.net_idx,
					 bt_mesh_shell_target_ctx.dst, &reset);
	if (err) {
		shell_error(sh, "Unable to send Remote Node Reset (err %d)", err);
		return 0;
	}

	shell_print(sh, "Remote node reset complete");

	return 0;
}

static int cmd_timeout(const struct shell *sh, size_t argc, char *argv[])
{
	int32_t timeout_ms;
	int err = 0;

	if (argc == 2) {
		int32_t timeout_s = shell_strtol(argv[1], 0, &err);

		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		if (timeout_s < 0 || timeout_s > (INT32_MAX / 1000)) {
			timeout_ms = SYS_FOREVER_MS;
		} else {
			timeout_ms = timeout_s * MSEC_PER_SEC;
		}

		bt_mesh_cfg_cli_timeout_set(timeout_ms);
	}

	timeout_ms = bt_mesh_cfg_cli_timeout_get();
	if (timeout_ms == SYS_FOREVER_MS) {
		shell_print(sh, "Message timeout: forever");
	} else {
		shell_print(sh, "Message timeout: %u seconds", timeout_ms / 1000);
	}

	return 0;
}

static int cmd_get_comp(const struct shell *sh, size_t argc, char *argv[])
{
	NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_RX_SDU_MAX);
	struct bt_mesh_comp_p0_elem elem;
	struct bt_mesh_comp_p0 comp;
	uint8_t page = 0x00;
	int err = 0;

	if (argc > 1) {
		page = shell_strtoul(argv[1], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}
	}

	err = bt_mesh_cfg_cli_comp_data_get(bt_mesh_shell_target_ctx.net_idx,
					bt_mesh_shell_target_ctx.dst, page, &page, &buf);
	if (err) {
		shell_error(sh, "Getting composition failed (err %d)", err);
		return 0;
	}

	if (page != 0x00) {
		shell_print(sh, "Got page 0x%02x. No parser available.", page);
		return 0;
	}

	err = bt_mesh_comp_p0_get(&comp, &buf);
	if (err) {
		shell_error(sh, "Couldn't parse Composition data (err %d)", err);
		return 0;
	}

	shell_print(sh, "Got Composition Data for 0x%04x:", bt_mesh_shell_target_ctx.dst);
	shell_print(sh, "\tCID      0x%04x", comp.cid);
	shell_print(sh, "\tPID      0x%04x", comp.pid);
	shell_print(sh, "\tVID      0x%04x", comp.vid);
	shell_print(sh, "\tCRPL     0x%04x", comp.crpl);
	shell_print(sh, "\tFeatures 0x%04x", comp.feat);

	while (bt_mesh_comp_p0_elem_pull(&comp, &elem)) {
		int i;

		shell_print(sh, "\tElement @ 0x%04x:", elem.loc);

		if (elem.nsig) {
			shell_print(sh, "\t\tSIG Models:");
		} else {
			shell_print(sh, "\t\tNo SIG Models");
		}

		for (i = 0; i < elem.nsig; i++) {
			uint16_t mod_id = bt_mesh_comp_p0_elem_mod(&elem, i);

			shell_print(sh, "\t\t\t0x%04x", mod_id);
		}

		if (elem.nvnd) {
			shell_print(sh, "\t\tVendor Models:");
		} else {
			shell_print(sh, "\t\tNo Vendor Models");
		}

		for (i = 0; i < elem.nvnd; i++) {
			struct bt_mesh_mod_id_vnd mod = bt_mesh_comp_p0_elem_mod_vnd(&elem, i);

			shell_print(sh, "\t\t\tCompany 0x%04x: 0x%04x", mod.company, mod.id);
		}
	}

	if (buf.len) {
		shell_print(sh, "\t\t...truncated data!");
	}

	return 0;
}

static int cmd_beacon(const struct shell *sh, size_t argc, char *argv[])
{
	uint8_t status;
	int err = 0;

	if (argc < 2) {
		err = bt_mesh_cfg_cli_beacon_get(bt_mesh_shell_target_ctx.net_idx,
					     bt_mesh_shell_target_ctx.dst, &status);
	} else {
		uint8_t val = shell_strtobool(argv[1], 0, &err);

		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_beacon_set(bt_mesh_shell_target_ctx.net_idx,
					     bt_mesh_shell_target_ctx.dst, val, &status);
	}

	if (err) {
		shell_error(sh, "Unable to send Beacon Get/Set message (err %d)", err);
		return 0;
	}

	shell_print(sh, "Beacon state is 0x%02x", status);

	return 0;
}

static int cmd_ttl(const struct shell *sh, size_t argc, char *argv[])
{
	uint8_t ttl;
	int err = 0;

	if (argc < 2) {
		err = bt_mesh_cfg_cli_ttl_get(bt_mesh_shell_target_ctx.net_idx,
					  bt_mesh_shell_target_ctx.dst, &ttl);
	} else {
		uint8_t val = shell_strtoul(argv[1], 0, &err);

		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_ttl_set(bt_mesh_shell_target_ctx.net_idx,
					  bt_mesh_shell_target_ctx.dst, val, &ttl);
	}

	if (err) {
		shell_error(sh, "Unable to send Default TTL Get/Set (err %d)", err);
		return 0;
	}

	shell_print(sh, "Default TTL is 0x%02x", ttl);

	return 0;
}

static int cmd_friend(const struct shell *sh, size_t argc, char *argv[])
{
	uint8_t frnd;
	int err = 0;

	if (argc < 2) {
		err = bt_mesh_cfg_cli_friend_get(bt_mesh_shell_target_ctx.net_idx,
					     bt_mesh_shell_target_ctx.dst, &frnd);
	} else {
		uint8_t val = shell_strtobool(argv[1], 0, &err);

		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_friend_set(bt_mesh_shell_target_ctx.net_idx,
					     bt_mesh_shell_target_ctx.dst, val, &frnd);
	}

	if (err) {
		shell_error(sh, "Unable to send Friend Get/Set (err %d)", err);
		return 0;
	}

	shell_print(sh, "Friend is set to 0x%02x", frnd);

	return 0;
}

static int cmd_gatt_proxy(const struct shell *sh, size_t argc, char *argv[])
{
	uint8_t proxy;
	int err = 0;

	if (argc < 2) {
		err = bt_mesh_cfg_cli_gatt_proxy_get(bt_mesh_shell_target_ctx.net_idx,
						 bt_mesh_shell_target_ctx.dst, &proxy);
	} else {
		uint8_t val = shell_strtobool(argv[1], 0, &err);

		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_gatt_proxy_set(bt_mesh_shell_target_ctx.net_idx,
						 bt_mesh_shell_target_ctx.dst, val, &proxy);
	}

	if (err) {
		shell_print(sh, "Unable to send GATT Proxy Get/Set (err %d)", err);
		return 0;
	}

	shell_print(sh, "GATT Proxy is set to 0x%02x", proxy);

	return 0;
}

static int cmd_polltimeout_get(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t lpn_address;
	int32_t poll_timeout;
	int err = 0;

	lpn_address = shell_strtoul(argv[1], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	err = bt_mesh_cfg_cli_lpn_timeout_get(bt_mesh_shell_target_ctx.net_idx,
					  bt_mesh_shell_target_ctx.dst, lpn_address, &poll_timeout);
	if (err) {
		shell_error(sh, "Unable to send LPN PollTimeout Get (err %d)", err);
		return 0;
	}

	shell_print(sh, "PollTimeout value %d", poll_timeout);

	return 0;
}

static int cmd_net_transmit(const struct shell *sh, size_t argc, char *argv[])
{
	uint8_t transmit;
	int err = 0;

	if (argc < 2) {
		err = bt_mesh_cfg_cli_net_transmit_get(bt_mesh_shell_target_ctx.net_idx,
						   bt_mesh_shell_target_ctx.dst, &transmit);
	} else {
		if (argc != 3) {
			shell_warn(sh, "Wrong number of input arguments"
					"(2 arguments are required)");
			return -EINVAL;
		}

		uint8_t count, interval, new_transmit;

		count = shell_strtoul(argv[1], 0, &err);
		interval = shell_strtoul(argv[2], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		new_transmit = BT_MESH_TRANSMIT(count, interval);

		err = bt_mesh_cfg_cli_net_transmit_set(bt_mesh_shell_target_ctx.net_idx,
						   bt_mesh_shell_target_ctx.dst, new_transmit,
						   &transmit);
	}

	if (err) {
		shell_error(sh, "Unable to send network transmit Get/Set (err %d)", err);
		return 0;
	}

	shell_print(sh, "Transmit 0x%02x (count %u interval %ums)", transmit,
		    BT_MESH_TRANSMIT_COUNT(transmit), BT_MESH_TRANSMIT_INT(transmit));

	return 0;
}

static int cmd_relay(const struct shell *sh, size_t argc, char *argv[])
{
	uint8_t relay, transmit;
	int err = 0;

	if (argc < 2) {
		err = bt_mesh_cfg_cli_relay_get(bt_mesh_shell_target_ctx.net_idx,
					    bt_mesh_shell_target_ctx.dst, &relay, &transmit);
	} else {
		uint8_t count, interval, new_transmit;
		uint8_t val = shell_strtobool(argv[1], 0, &err);

		if (val) {
			if (argc > 2) {
				count = shell_strtoul(argv[2], 0, &err);
			} else {
				count = 2U;
			}

			if (argc > 3) {
				interval = shell_strtoul(argv[3], 0, &err);
			} else {
				interval = 20U;
			}

			new_transmit = BT_MESH_TRANSMIT(count, interval);
		} else {
			new_transmit = 0U;
		}

		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_relay_set(bt_mesh_shell_target_ctx.net_idx,
					    bt_mesh_shell_target_ctx.dst, val, new_transmit, &relay,
					    &transmit);
	}

	if (err) {
		shell_error(sh, "Unable to send Relay Get/Set (err %d)", err);
		return 0;
	}

	shell_print(sh, "Relay is 0x%02x, Transmit 0x%02x (count %u interval %ums)", relay,
		    transmit, BT_MESH_TRANSMIT_COUNT(transmit), BT_MESH_TRANSMIT_INT(transmit));

	return 0;
}

static int cmd_net_key_add(const struct shell *sh, size_t argc, char *argv[])
{
	bool has_key_val = (argc > 2);
	uint8_t key_val[16];
	uint16_t key_net_idx;
	uint8_t status;
	int err = 0;

	key_net_idx = shell_strtoul(argv[1], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (has_key_val) {
		size_t len;

		len = hex2bin(argv[3], strlen(argv[3]), key_val, sizeof(key_val));
		(void)memset(key_val, 0, sizeof(key_val) - len);
	} else {
		memcpy(key_val, default_key, sizeof(key_val));
	}

	if (IS_ENABLED(CONFIG_BT_MESH_CDB)) {
		struct bt_mesh_cdb_subnet *subnet;

		subnet = bt_mesh_cdb_subnet_get(key_net_idx);
		if (subnet) {
			if (has_key_val) {
				shell_error(sh, "Subnet 0x%03x already has a value", key_net_idx);
				return 0;
			}

			memcpy(key_val, subnet->keys[0].net_key, 16);
		} else {
			subnet = bt_mesh_cdb_subnet_alloc(key_net_idx);
			if (!subnet) {
				shell_error(sh, "No space for subnet in cdb");
				return 0;
			}

			memcpy(subnet->keys[0].net_key, key_val, 16);
			bt_mesh_cdb_subnet_store(subnet);
		}
	}

	err = bt_mesh_cfg_cli_net_key_add(bt_mesh_shell_target_ctx.net_idx,
				      bt_mesh_shell_target_ctx.dst, key_net_idx, key_val, &status);
	if (err) {
		shell_print(sh, "Unable to send NetKey Add (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "NetKeyAdd failed with status 0x%02x", status);
	} else {
		shell_print(sh, "NetKey added with NetKey Index 0x%03x", key_net_idx);
	}

	return 0;
}

static int cmd_net_key_update(const struct shell *sh, size_t argc, char *argv[])
{
	bool has_key_val = (argc > 2);
	uint8_t key_val[16];
	uint16_t key_net_idx;
	uint8_t status;
	int err = 0;

	key_net_idx = shell_strtoul(argv[1], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (has_key_val) {
		size_t len;

		len = hex2bin(argv[2], strlen(argv[2]), key_val, sizeof(key_val));
		(void)memset(key_val, 0, sizeof(key_val) - len);
	} else {
		memcpy(key_val, default_key, sizeof(key_val));
	}

	err = bt_mesh_cfg_cli_net_key_update(bt_mesh_shell_target_ctx.net_idx,
					 bt_mesh_shell_target_ctx.dst, key_net_idx, key_val,
					 &status);
	if (err) {
		shell_print(sh, "Unable to send NetKey Update (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "NetKeyUpdate failed with status 0x%02x", status);
	} else {
		shell_print(sh, "NetKey updated with NetKey Index 0x%03x", key_net_idx);
	}

	return 0;
}

static int cmd_net_key_get(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t keys[16];
	size_t cnt;
	int err, i;

	cnt = ARRAY_SIZE(keys);

	err = bt_mesh_cfg_cli_net_key_get(bt_mesh_shell_target_ctx.net_idx,
				      bt_mesh_shell_target_ctx.dst, keys, &cnt);
	if (err) {
		shell_print(sh, "Unable to send NetKeyGet (err %d)", err);
		return 0;
	}

	shell_print(sh, "NetKeys known by 0x%04x:", bt_mesh_shell_target_ctx.dst);
	for (i = 0; i < cnt; i++) {
		shell_print(sh, "\t0x%03x", keys[i]);
	}

	return 0;
}

static int cmd_net_key_del(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t key_net_idx;
	uint8_t status;
	int err = 0;

	key_net_idx = shell_strtoul(argv[1], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	err = bt_mesh_cfg_cli_net_key_del(bt_mesh_shell_target_ctx.net_idx,
				      bt_mesh_shell_target_ctx.dst, key_net_idx, &status);
	if (err) {
		shell_print(sh, "Unable to send NetKeyDel (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "NetKeyDel failed with status 0x%02x", status);
	} else {
		shell_print(sh, "NetKey 0x%03x deleted", key_net_idx);
	}

	return 0;
}

static int cmd_app_key_add(const struct shell *sh, size_t argc, char *argv[])
{
	uint8_t key_val[16];
	uint16_t key_net_idx, key_app_idx;
	bool has_key_val = (argc > 3);
	uint8_t status;
	int err = 0;

	key_net_idx = shell_strtoul(argv[1], 0, &err);
	key_app_idx = shell_strtoul(argv[2], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (has_key_val) {
		size_t len;

		len = hex2bin(argv[3], strlen(argv[3]), key_val, sizeof(key_val));
		(void)memset(key_val + len, 0, sizeof(key_val) - len);
	} else {
		memcpy(key_val, default_key, sizeof(key_val));
	}

	if (IS_ENABLED(CONFIG_BT_MESH_CDB)) {
		struct bt_mesh_cdb_app_key *app_key;

		app_key = bt_mesh_cdb_app_key_get(key_app_idx);
		if (app_key) {
			if (has_key_val) {
				shell_error(sh, "App key 0x%03x already has a value", key_app_idx);
				return 0;
			}

			memcpy(key_val, app_key->keys[0].app_key, 16);
		} else {
			app_key = bt_mesh_cdb_app_key_alloc(key_net_idx, key_app_idx);
			if (!app_key) {
				shell_error(sh, "No space for app key in cdb");
				return 0;
			}

			memcpy(app_key->keys[0].app_key, key_val, 16);
			bt_mesh_cdb_app_key_store(app_key);
		}
	}

	err = bt_mesh_cfg_cli_app_key_add(bt_mesh_shell_target_ctx.net_idx,
				      bt_mesh_shell_target_ctx.dst, key_net_idx, key_app_idx,
				      key_val, &status);
	if (err) {
		shell_error(sh, "Unable to send App Key Add (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "AppKeyAdd failed with status 0x%02x", status);
	} else {
		shell_print(sh, "AppKey added, NetKeyIndex 0x%04x AppKeyIndex 0x%04x", key_net_idx,
			    key_app_idx);
	}

	return 0;
}

static int cmd_app_key_upd(const struct shell *sh, size_t argc, char *argv[])
{
	uint8_t key_val[16];
	uint16_t key_net_idx, key_app_idx;
	bool has_key_val = (argc > 3);
	uint8_t status;
	int err = 0;

	key_net_idx = shell_strtoul(argv[1], 0, &err);
	key_app_idx = shell_strtoul(argv[2], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (has_key_val) {
		size_t len;

		len = hex2bin(argv[3], strlen(argv[3]), key_val, sizeof(key_val));
		(void)memset(key_val, 0, sizeof(key_val) - len);
	} else {
		memcpy(key_val, default_key, sizeof(key_val));
	}

	err = bt_mesh_cfg_cli_app_key_update(bt_mesh_shell_target_ctx.net_idx,
					 bt_mesh_shell_target_ctx.dst, key_net_idx, key_app_idx,
					 key_val, &status);
	if (err) {
		shell_error(sh, "Unable to send App Key Update (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "AppKey update failed with status 0x%02x", status);
	} else {
		shell_print(sh, "AppKey updated, NetKeyIndex 0x%04x AppKeyIndex 0x%04x",
			    key_net_idx, key_app_idx);
	}

	return 0;
}

static int cmd_app_key_get(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t net_idx;
	uint16_t keys[16];
	size_t cnt;
	uint8_t status;
	int err = 0;
	int i;

	cnt = ARRAY_SIZE(keys);
	net_idx = shell_strtoul(argv[1], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	err = bt_mesh_cfg_cli_app_key_get(bt_mesh_shell_target_ctx.net_idx,
				      bt_mesh_shell_target_ctx.dst, net_idx, &status, keys, &cnt);
	if (err) {
		shell_print(sh, "Unable to send AppKeyGet (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "AppKeyGet failed with status 0x%02x", status);
		return 0;
	}

	shell_print(sh, "AppKeys for NetKey 0x%03x known by 0x%04x:", net_idx,
		    bt_mesh_shell_target_ctx.dst);
	for (i = 0; i < cnt; i++) {
		shell_print(sh, "\t0x%03x", keys[i]);
	}

	return 0;
}

static int cmd_node_id(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t net_idx;
	uint8_t status, identify;
	int err = 0;

	net_idx = shell_strtoul(argv[1], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc <= 2) {
		printk("ANders\n");
		err = bt_mesh_cfg_cli_node_identity_get(bt_mesh_shell_target_ctx.net_idx,
						    bt_mesh_shell_target_ctx.dst, net_idx, &status,
						    &identify);
		if (err) {
			shell_print(sh, "Unable to send Node Identify Get (err %d)", err);
			return 0;
		}
	} else {
		uint8_t new_identify = shell_strtoul(argv[2], 0, &err);

		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_node_identity_set(bt_mesh_shell_target_ctx.net_idx,
						    bt_mesh_shell_target_ctx.dst, net_idx,
						    new_identify, &status, &identify);
		if (err) {
			shell_print(sh, "Unable to send Node Identify Set (err %d)", err);
			return 0;
		}
	}

	if (status) {
		shell_print(sh, "Node Identify Get/Set failed with status 0x%02x", status);
	} else {
		shell_print(sh, "Node Identify Get/Set successful with identify 0x%02x", identify);
	}

	return 0;
}

static int cmd_app_key_del(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t key_net_idx, key_app_idx;
	uint8_t status;
	int err = 0;

	key_net_idx = shell_strtoul(argv[1], 0, &err);
	key_app_idx = shell_strtoul(argv[2], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	err = bt_mesh_cfg_cli_app_key_del(bt_mesh_shell_target_ctx.net_idx,
				      bt_mesh_shell_target_ctx.dst, key_net_idx, key_app_idx,
				      &status);
	if (err) {
		shell_error(sh, "Unable to send App Key del(err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "AppKeyDel failed with status 0x%02x", status);
	} else {
		shell_print(sh, "AppKey deleted, NetKeyIndex 0x%04x AppKeyIndex 0x%04x",
			    key_net_idx, key_app_idx);
	}

	return 0;
}

static int cmd_mod_app_bind(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, mod_app_idx, mod_id, cid;
	uint8_t status;
	int err = 0;

	elem_addr = shell_strtoul(argv[1], 0, &err);
	mod_app_idx = shell_strtoul(argv[2], 0, &err);
	mod_id = shell_strtoul(argv[3], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 4) {
		cid = shell_strtoul(argv[4], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_app_bind_vnd(bt_mesh_shell_target_ctx.net_idx,
						   bt_mesh_shell_target_ctx.dst, elem_addr,
						   mod_app_idx, mod_id, cid, &status);
	} else {
		err = bt_mesh_cfg_cli_mod_app_bind(bt_mesh_shell_target_ctx.net_idx,
					       bt_mesh_shell_target_ctx.dst, elem_addr, mod_app_idx,
					       mod_id, &status);
	}

	if (err) {
		shell_error(sh, "Unable to send Model App Bind (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model App Bind failed with status 0x%02x", status);
	} else {
		shell_print(sh, "AppKey successfully bound");
	}

	return 0;
}

static int cmd_mod_app_unbind(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, mod_app_idx, mod_id, cid;
	uint8_t status;
	int err = 0;

	elem_addr = shell_strtoul(argv[1], 0, &err);
	mod_app_idx = shell_strtoul(argv[2], 0, &err);
	mod_id = shell_strtoul(argv[3], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 4) {
		cid = shell_strtoul(argv[4], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_app_unbind_vnd(bt_mesh_shell_target_ctx.net_idx,
						     bt_mesh_shell_target_ctx.dst, elem_addr,
						     mod_app_idx, mod_id, cid, &status);
	} else {
		err = bt_mesh_cfg_cli_mod_app_unbind(bt_mesh_shell_target_ctx.net_idx,
						 bt_mesh_shell_target_ctx.dst, elem_addr,
						 mod_app_idx, mod_id, &status);
	}

	if (err) {
		shell_error(sh, "Unable to send Model App Unbind (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model App Unbind failed with status 0x%02x", status);
	} else {
		shell_print(sh, "AppKey successfully unbound");
	}

	return 0;
}

static int cmd_mod_app_get(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, mod_id, cid;
	uint16_t apps[16];
	uint8_t status;
	size_t cnt;
	int err = 0;
	int i;

	cnt = ARRAY_SIZE(apps);
	elem_addr = shell_strtoul(argv[1], 0, &err);
	mod_id = shell_strtoul(argv[2], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 3) {
		cid = shell_strtoul(argv[3], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_app_get_vnd(bt_mesh_shell_target_ctx.net_idx,
						  bt_mesh_shell_target_ctx.dst, elem_addr, mod_id,
						  cid, &status, apps, &cnt);
	} else {
		err = bt_mesh_cfg_cli_mod_app_get(bt_mesh_shell_target_ctx.net_idx,
					      bt_mesh_shell_target_ctx.dst, elem_addr, mod_id,
					      &status, apps, &cnt);
	}

	if (err) {
		shell_error(sh, "Unable to send Model App Get (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model App Get failed with status 0x%02x", status);
	} else {
		shell_print(sh, "Apps bound to Element 0x%04x, Model 0x%04x %s:", elem_addr, mod_id,
			    argc > 3 ? argv[3] : "(SIG)");

		if (!cnt) {
			shell_print(sh, "\tNone.");
		}

		for (i = 0; i < cnt; i++) {
			shell_print(sh, "\t0x%04x", apps[i]);
		}
	}

	return 0;
}

static int cmd_mod_sub_add(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, sub_addr, mod_id, cid;
	uint8_t status;
	int err = 0;

	elem_addr = shell_strtoul(argv[1], 0, &err);
	sub_addr = shell_strtoul(argv[2], 0, &err);
	mod_id = shell_strtoul(argv[3], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 4) {
		cid = shell_strtoul(argv[4], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_sub_add_vnd(bt_mesh_shell_target_ctx.net_idx,
						  bt_mesh_shell_target_ctx.dst, elem_addr, sub_addr,
						  mod_id, cid, &status);
	} else {
		err = bt_mesh_cfg_cli_mod_sub_add(bt_mesh_shell_target_ctx.net_idx,
					      bt_mesh_shell_target_ctx.dst, elem_addr, sub_addr,
					      mod_id, &status);
	}

	if (err) {
		shell_error(sh, "Unable to send Model Subscription Add (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model Subscription Add failed with status 0x%02x", status);
	} else {
		shell_print(sh, "Model subscription was successful");
	}

	return 0;
}

static int cmd_mod_sub_del(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, sub_addr, mod_id, cid;
	uint8_t status;
	int err = 0;

	elem_addr = shell_strtoul(argv[1], 0, &err);
	sub_addr = shell_strtoul(argv[2], 0, &err);
	mod_id = shell_strtoul(argv[3], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 4) {
		cid = shell_strtoul(argv[4], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_sub_del_vnd(bt_mesh_shell_target_ctx.net_idx,
						  bt_mesh_shell_target_ctx.dst, elem_addr, sub_addr,
						  mod_id, cid, &status);
	} else {
		err = bt_mesh_cfg_cli_mod_sub_del(bt_mesh_shell_target_ctx.net_idx,
					      bt_mesh_shell_target_ctx.dst, elem_addr, sub_addr,
					      mod_id, &status);
	}

	if (err) {
		shell_error(sh, "Unable to send Model Subscription Delete (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model Subscription Delete failed with status 0x%02x", status);
	} else {
		shell_print(sh, "Model subscription deltion was successful");
	}

	return 0;
}

static int cmd_mod_sub_add_va(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, sub_addr, mod_id, cid;
	uint8_t label[16];
	uint8_t status;
	size_t len;
	int err = 0;

	elem_addr = shell_strtoul(argv[1], 0, &err);

	len = hex2bin(argv[2], strlen(argv[2]), label, sizeof(label));
	(void)memset(label + len, 0, sizeof(label) - len);

	mod_id = shell_strtoul(argv[3], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 4) {
		cid = shell_strtoul(argv[4], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_sub_va_add_vnd(bt_mesh_shell_target_ctx.net_idx,
						     bt_mesh_shell_target_ctx.dst, elem_addr, label,
						     mod_id, cid, &sub_addr, &status);
	} else {
		err = bt_mesh_cfg_cli_mod_sub_va_add(bt_mesh_shell_target_ctx.net_idx,
						 bt_mesh_shell_target_ctx.dst, elem_addr, label,
						 mod_id, &sub_addr, &status);
	}

	if (err) {
		shell_error(sh, "Unable to send Mod Sub VA Add (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Mod Sub VA Add failed with status 0x%02x", status);
	} else {
		shell_print(sh, "0x%04x subscribed to Label UUID %s (va 0x%04x)", elem_addr,
			    argv[2], sub_addr);
	}

	return 0;
}

static int cmd_mod_sub_del_va(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, sub_addr, mod_id, cid;
	uint8_t label[16];
	uint8_t status;
	size_t len;
	int err = 0;

	elem_addr = shell_strtoul(argv[1], 0, &err);

	len = hex2bin(argv[2], strlen(argv[2]), label, sizeof(label));
	(void)memset(label + len, 0, sizeof(label) - len);

	mod_id = shell_strtoul(argv[3], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 4) {
		cid = shell_strtoul(argv[4], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_sub_va_del_vnd(bt_mesh_shell_target_ctx.net_idx,
						     bt_mesh_shell_target_ctx.dst, elem_addr, label,
						     mod_id, cid, &sub_addr, &status);
	} else {
		err = bt_mesh_cfg_cli_mod_sub_va_del(bt_mesh_shell_target_ctx.net_idx,
						 bt_mesh_shell_target_ctx.dst, elem_addr, label,
						 mod_id, &sub_addr, &status);
	}

	if (err) {
		shell_error(sh, "Unable to send Model Subscription Delete (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model Subscription Delete failed with status 0x%02x", status);
	} else {
		shell_print(sh, "0x%04x unsubscribed from Label UUID %s (va 0x%04x)", elem_addr,
			    argv[2], sub_addr);
	}

	return 0;
}

static int cmd_mod_sub_ow(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, sub_addr, mod_id, cid;
	uint8_t status;
	int err = 0;

	elem_addr = shell_strtoul(argv[1], 0, &err);
	sub_addr = shell_strtoul(argv[2], 0, &err);
	mod_id = shell_strtoul(argv[3], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 4) {
		cid = shell_strtoul(argv[4], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_sub_overwrite_vnd(bt_mesh_shell_target_ctx.net_idx,
							bt_mesh_shell_target_ctx.dst, elem_addr,
							sub_addr, mod_id, cid, &status);
	} else {
		err = bt_mesh_cfg_cli_mod_sub_overwrite(bt_mesh_shell_target_ctx.net_idx,
						    bt_mesh_shell_target_ctx.dst, elem_addr,
						    sub_addr, mod_id, &status);
	}

	if (err) {
		shell_error(sh, "Unable to send Model Subscription Overwrite (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model Subscription Overwrite failed with status 0x%02x", status);
	} else {
		shell_print(sh, "Model subscription overwrite was successful");
	}

	return 0;
}

static int cmd_mod_sub_ow_va(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, sub_addr, mod_id, cid;
	uint8_t label[16];
	uint8_t status;
	size_t len;
	int err = 0;

	elem_addr = shell_strtoul(argv[1], 0, &err);

	len = hex2bin(argv[2], strlen(argv[2]), label, sizeof(label));
	(void)memset(label + len, 0, sizeof(label) - len);

	mod_id = shell_strtoul(argv[3], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 4) {
		cid = shell_strtoul(argv[4], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_sub_va_overwrite_vnd(bt_mesh_shell_target_ctx.net_idx,
							   bt_mesh_shell_target_ctx.dst, elem_addr,
							   label, mod_id, cid, &sub_addr, &status);
	} else {
		err = bt_mesh_cfg_cli_mod_sub_va_overwrite(bt_mesh_shell_target_ctx.net_idx,
						       bt_mesh_shell_target_ctx.dst, elem_addr,
						       label, mod_id, &sub_addr, &status);
	}

	if (err) {
		shell_error(sh, "Unable to send Mod Sub VA Overwrite (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Mod Sub VA Overwrite failed with status 0x%02x", status);
	} else {
		shell_print(sh, "0x%04x overwrite to Label UUID %s (va 0x%04x)", elem_addr, argv[2],
			    sub_addr);
	}

	return 0;
}

static int cmd_mod_sub_del_all(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, mod_id, cid;
	uint8_t status;
	int err = 0;

	elem_addr = shell_strtoul(argv[1], 0, &err);
	mod_id = shell_strtoul(argv[2], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 3) {
		cid = shell_strtoul(argv[3], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_sub_del_all_vnd(bt_mesh_shell_target_ctx.net_idx,
						      bt_mesh_shell_target_ctx.dst, elem_addr,
						      mod_id, cid, &status);
	} else {
		err = bt_mesh_cfg_cli_mod_sub_del_all(bt_mesh_shell_target_ctx.net_idx,
						  bt_mesh_shell_target_ctx.dst, elem_addr, mod_id,
						  &status);
	}

	if (err) {
		shell_error(sh, "Unable to send Model Subscription Delete All (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model Subscription Delete All failed with status 0x%02x", status);
	} else {
		shell_print(sh, "Model subscription deltion all was successful");
	}

	return 0;
}

static int cmd_mod_sub_get(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, mod_id, cid;
	uint16_t subs[16];
	uint8_t status;
	size_t cnt;
	int err = 0;
	int i;

	cnt = ARRAY_SIZE(subs);
	elem_addr = shell_strtoul(argv[1], 0, &err);
	mod_id = shell_strtoul(argv[2], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 3) {
		cid = shell_strtoul(argv[3], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_sub_get_vnd(bt_mesh_shell_target_ctx.net_idx,
						  bt_mesh_shell_target_ctx.dst, elem_addr, mod_id,
						  cid, &status, subs, &cnt);
	} else {
		err = bt_mesh_cfg_cli_mod_sub_get(bt_mesh_shell_target_ctx.net_idx,
					      bt_mesh_shell_target_ctx.dst, elem_addr, mod_id,
					      &status, subs, &cnt);
	}

	if (err) {
		shell_error(sh, "Unable to send Model Subscription Get (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model Subscription Get failed with status 0x%02x", status);
	} else {
		shell_print(sh,
			    "Model Subscriptions for Element 0x%04x, Model 0x%04x %s:", elem_addr,
			    mod_id, argc > 3 ? argv[3] : "(SIG)");

		if (!cnt) {
			shell_print(sh, "\tNone.");
		}

		for (i = 0; i < cnt; i++) {
			shell_print(sh, "\t0x%04x", subs[i]);
		}
	}

	return 0;
}

static int cmd_krp(const struct shell *sh, size_t argc, char *argv[])
{
	uint8_t status, phase;
	uint16_t key_net_idx;
	int err = 0;

	key_net_idx = shell_strtoul(argv[1], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc < 3) {
		err = bt_mesh_cfg_cli_krp_get(bt_mesh_shell_target_ctx.net_idx,
					  bt_mesh_shell_target_ctx.dst, key_net_idx, &status,
					  &phase);
	} else {
		uint16_t trans = shell_strtoul(argv[2], 0, &err);

		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_krp_set(bt_mesh_shell_target_ctx.net_idx,
					  bt_mesh_shell_target_ctx.dst, key_net_idx, trans, &status,
					  &phase);
	}

	if (err) {
		shell_error(sh, "Unable to send key refresh phase Get/Set (err %d)", err);
		return 0;
	}

	shell_print(sh, "Key refresh phase Get/Set with status 0x%02x and phase 0x%02x", status,
		    phase);

	return 0;
}

static int mod_pub_get(const struct shell *sh, uint16_t addr, uint16_t mod_id, uint16_t cid)
{
	struct bt_mesh_cfg_cli_mod_pub pub;
	uint8_t status;
	int err;

	if (cid == CID_NVAL) {
		err = bt_mesh_cfg_cli_mod_pub_get(bt_mesh_shell_target_ctx.net_idx,
					      bt_mesh_shell_target_ctx.dst, addr, mod_id, &pub,
					      &status);
	} else {
		err = bt_mesh_cfg_cli_mod_pub_get_vnd(bt_mesh_shell_target_ctx.net_idx,
						  bt_mesh_shell_target_ctx.dst, addr, mod_id, cid,
						  &pub, &status);
	}

	if (err) {
		shell_error(sh, "Model Publication Get failed (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model Publication Get failed (status 0x%02x)", status);
		return 0;
	}

	shell_print(sh,
		    "Model Publication for Element 0x%04x, Model 0x%04x:\n"
		    "\tPublish Address:                0x%04x\n"
		    "\tAppKeyIndex:                    0x%04x\n"
		    "\tCredential Flag:                %u\n"
		    "\tPublishTTL:                     %u\n"
		    "\tPublishPeriod:                  0x%02x\n"
		    "\tPublishRetransmitCount:         %u\n"
		    "\tPublishRetransmitInterval:      %ums",
		    addr, mod_id, pub.addr, pub.app_idx, pub.cred_flag, pub.ttl, pub.period,
		    BT_MESH_PUB_TRANSMIT_COUNT(pub.transmit),
		    BT_MESH_PUB_TRANSMIT_INT(pub.transmit));

	return 0;
}

static int mod_pub_set(const struct shell *sh, uint16_t addr, bool is_va, uint16_t mod_id,
		       uint16_t cid, char *argv[])
{
	struct bt_mesh_cfg_cli_mod_pub pub;
	uint8_t status, count;
	uint16_t interval;
	uint8_t uuid[16];
	uint8_t len;
	int err = 0;

	if (!is_va) {
		pub.addr = shell_strtoul(argv[0], 0, &err);
		pub.uuid = NULL;
	} else {
		len = hex2bin(argv[0], strlen(argv[0]), uuid, sizeof(uuid));
		memset(uuid + len, 0, sizeof(uuid) - len);
		pub.uuid = (const uint8_t *)&uuid;
	}

	pub.app_idx = shell_strtoul(argv[1], 0, &err);
	pub.cred_flag = shell_strtobool(argv[2], 0, &err);
	pub.ttl = shell_strtoul(argv[3], 0, &err);
	pub.period = shell_strtoul(argv[4], 0, &err);

	count = shell_strtoul(argv[5], 0, &err);
	if (count > 7) {
		shell_print(sh, "Invalid retransmit count");
		return -EINVAL;
	}

	interval = shell_strtoul(argv[6], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (interval > (31 * 50) || (interval % 50)) {
		shell_print(sh, "Invalid retransmit interval %u", interval);
		return -EINVAL;
	}

	pub.transmit = BT_MESH_PUB_TRANSMIT(count, interval);

	if (cid == CID_NVAL) {
		err = bt_mesh_cfg_cli_mod_pub_set(bt_mesh_shell_target_ctx.net_idx,
					      bt_mesh_shell_target_ctx.dst, addr, mod_id, &pub,
					      &status);
	} else {
		err = bt_mesh_cfg_cli_mod_pub_set_vnd(bt_mesh_shell_target_ctx.net_idx,
						  bt_mesh_shell_target_ctx.dst, addr, mod_id, cid,
						  &pub, &status);
	}

	if (err) {
		shell_error(sh, "Model Publication Set failed (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model Publication Set failed (status 0x%02x)", status);
	} else {
		shell_print(sh, "Model Publication successfully set");
	}

	return 0;
}

static int cmd_mod_pub(const struct shell *sh, size_t argc, char *argv[])
{
	int err = 0;
	uint16_t addr, mod_id, cid;

	addr = shell_strtoul(argv[1], 0, &err);
	mod_id = shell_strtoul(argv[2], 0, &err);

	argc -= 3;
	argv += 3;

	if (argc == 1 || argc == 8) {
		cid = shell_strtoul(argv[0], 0, &err);
		argc--;
		argv++;
	} else {
		cid = CID_NVAL;
	}

	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 0) {
		if (argc < 7) {
			shell_warn(sh, "Invalid number of argument");
			return -EINVAL;
		}

		return mod_pub_set(sh, addr, false, mod_id, cid, argv);
	} else {
		return mod_pub_get(sh, addr, mod_id, cid);
	}
}

static int cmd_mod_pub_va(const struct shell *sh, size_t argc, char *argv[])
{
	int err = 0;
	uint16_t addr, mod_id, cid = CID_NVAL;

	addr = shell_strtoul(argv[1], 0, &err);
	mod_id = shell_strtoul(argv[9], 0, &err);

	if (argc > 10) {
		cid = shell_strtoul(argv[10], 0, &err);
	}

	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	argv += 2;

	return mod_pub_set(sh, addr, true, mod_id, cid, argv);
}

static void hb_sub_print(const struct shell *sh, struct bt_mesh_cfg_cli_hb_sub *sub)
{
	shell_print(sh,
		    "Heartbeat Subscription:\n"
		    "\tSource:      0x%04x\n"
		    "\tDestination: 0x%04x\n"
		    "\tPeriodLog:   0x%02x\n"
		    "\tCountLog:    0x%02x\n"
		    "\tMinHops:     %u\n"
		    "\tMaxHops:     %u",
		    sub->src, sub->dst, sub->period, sub->count, sub->min, sub->max);
}

static int hb_sub_get(const struct shell *sh, size_t argc, char *argv[])
{
	struct bt_mesh_cfg_cli_hb_sub sub;
	uint8_t status;
	int err;

	err = bt_mesh_cfg_cli_hb_sub_get(bt_mesh_shell_target_ctx.net_idx,
					 bt_mesh_shell_target_ctx.dst, &sub, &status);
	if (err) {
		shell_error(sh, "Heartbeat Subscription Get failed (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Heartbeat Subscription Get failed (status 0x%02x)", status);
	} else {
		hb_sub_print(sh, &sub);
	}

	return 0;
}

static int hb_sub_set(const struct shell *sh, size_t argc, char *argv[])
{
	struct bt_mesh_cfg_cli_hb_sub sub;
	uint8_t status;
	int err = 0;

	sub.src = shell_strtoul(argv[1], 0, &err);
	sub.dst = shell_strtoul(argv[2], 0, &err);
	sub.period = shell_strtoul(argv[3], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	err = bt_mesh_cfg_cli_hb_sub_set(bt_mesh_shell_target_ctx.net_idx,
					 bt_mesh_shell_target_ctx.dst, &sub, &status);
	if (err) {
		shell_error(sh, "Heartbeat Subscription Set failed (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Heartbeat Subscription Set failed (status 0x%02x)", status);
	} else {
		hb_sub_print(sh, &sub);
	}

	return 0;
}

static int cmd_hb_sub(const struct shell *sh, size_t argc, char *argv[])
{
	if (argc > 1) {
		if (argc < 4) {
			shell_warn(sh, "Invalid number of argument");
			return -EINVAL;
		}

		return hb_sub_set(sh, argc, argv);
	} else {
		return hb_sub_get(sh, argc, argv);
	}
}

static int hb_pub_get(const struct shell *sh, size_t argc, char *argv[])
{
	struct bt_mesh_cfg_cli_hb_pub pub;
	uint8_t status;
	int err;

	err = bt_mesh_cfg_cli_hb_pub_get(bt_mesh_shell_target_ctx.net_idx,
					 bt_mesh_shell_target_ctx.dst, &pub, &status);
	if (err) {
		shell_error(sh, "Heartbeat Publication Get failed (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Heartbeat Publication Get failed (status 0x%02x)", status);
		return 0;
	}

	shell_print(sh, "Heartbeat publication:");
	shell_print(sh, "\tdst 0x%04x count 0x%02x period 0x%02x", pub.dst, pub.count, pub.period);
	shell_print(sh, "\tttl 0x%02x feat 0x%04x net_idx 0x%04x", pub.ttl, pub.feat, pub.net_idx);

	return 0;
}

static int hb_pub_set(const struct shell *sh, size_t argc, char *argv[])
{
	struct bt_mesh_cfg_cli_hb_pub pub;
	uint8_t status;
	int err = 0;

	pub.dst = shell_strtoul(argv[1], 0, &err);
	pub.count = shell_strtoul(argv[2], 0, &err);
	pub.period = shell_strtoul(argv[3], 0, &err);
	pub.ttl = shell_strtoul(argv[4], 0, &err);
	pub.feat = shell_strtoul(argv[5], 0, &err);
	pub.net_idx = shell_strtoul(argv[6], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	err = bt_mesh_cfg_cli_hb_pub_set(bt_mesh_shell_target_ctx.net_idx,
					 bt_mesh_shell_target_ctx.dst, &pub, &status);
	if (err) {
		shell_error(sh, "Heartbeat Publication Set failed (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Heartbeat Publication Set failed (status 0x%02x)", status);
	} else {
		shell_print(sh, "Heartbeat publication successfully set");
	}

	return 0;
}

static int cmd_hb_pub(const struct shell *sh, size_t argc, char *argv[])
{
	if (argc > 1) {
		if (argc < 7) {
			shell_warn(sh, "Invalid number of argument");
			return -EINVAL;
		}

		return hb_pub_set(sh, argc, argv);
	} else {
		return hb_pub_get(sh, argc, argv);
	}
}

SHELL_STATIC_SUBCMD_SET_CREATE(model_cmds,
	SHELL_CMD_ARG(app-bind, NULL, "<Addr> <AppIndex> <Model ID> [Company ID]",
		      cmd_mod_app_bind, 4, 1),
	SHELL_CMD_ARG(app-get, NULL, "<Elem addr> <Model ID> [Company ID]", cmd_mod_app_get,
		      3, 1),
	SHELL_CMD_ARG(app-unbind, NULL, "<Addr> <AppIndex> <Model ID> [Company ID]",
		      cmd_mod_app_unbind, 4, 1),
	SHELL_CMD_ARG(pub, NULL,
		      "<Addr> <Model ID> [Company ID] [<PubAddr> "
		      "<AppKeyIndex> <Cred: off, on> <TTL> <Period> <Count> <Interval>]",
		      cmd_mod_pub, 3, 1 + 7),
	SHELL_CMD_ARG(pub-va, NULL,
		      "<Addr> <UUID: 16 hex values> "
		      "<AppKeyIndex> <Cred: off, on> <TTL> <Period> <Count> <Interval> "
		      "<Model ID> [Company ID]",
		      cmd_mod_pub_va, 10, 1),
	SHELL_CMD_ARG(sub-add, NULL, "<Elem addr> <Sub addr> <Model ID> [Company ID]",
		      cmd_mod_sub_add, 4, 1),
	SHELL_CMD_ARG(sub-del, NULL, "<Elem addr> <Sub addr> <Model ID> [Company ID]",
		      cmd_mod_sub_del, 4, 1),
	SHELL_CMD_ARG(sub-add-va, NULL,
		      "<Elem addr> <Label UUID> <Model ID> [Company ID]", cmd_mod_sub_add_va, 4, 1),
	SHELL_CMD_ARG(sub-del-va, NULL,
		      "<Elem addr> <Label UUID> <Model ID> [Company ID]", cmd_mod_sub_del_va, 4, 1),
	SHELL_CMD_ARG(sub-ow, NULL, "<Elem addr> <Sub addr> <Model ID> [Company ID]",
		      cmd_mod_sub_ow, 4, 1),
	SHELL_CMD_ARG(sub-ow-va, NULL, "<Elem addr> <Label UUID> <Model ID> [Company ID]",
		      cmd_mod_sub_ow_va, 4, 1),
	SHELL_CMD_ARG(sub-del-all, NULL, "<Elem addr> <Model ID> [Company ID]",
		      cmd_mod_sub_del_all, 3, 1),
	SHELL_CMD_ARG(sub-get, NULL, "<Elem addr> <Model ID> [Company ID]", cmd_mod_sub_get,
		      3, 1),
	SHELL_SUBCMD_SET_END);

SHELL_STATIC_SUBCMD_SET_CREATE(netkey_cmds,
	SHELL_CMD_ARG(add, NULL, "<NetKeyIndex> [Val]", cmd_net_key_add, 2, 1),
	SHELL_CMD_ARG(upd, NULL, "<NetKeyIndex> [Val]", cmd_net_key_update, 2, 1),
	SHELL_CMD_ARG(get, NULL, NULL, cmd_net_key_get, 1, 0),
	SHELL_CMD_ARG(del, NULL, "<NetKeyIndex>", cmd_net_key_del, 2, 0),
	SHELL_SUBCMD_SET_END);

SHELL_STATIC_SUBCMD_SET_CREATE(appkey_cmds,
	SHELL_CMD_ARG(add, NULL, "<NetKeyIndex> <AppKeyIndex> [Val]", cmd_app_key_add,
		      3, 1),
	SHELL_CMD_ARG(upd, NULL, "<NetKeyIndex> <AppKeyIndex> [Val]", cmd_app_key_upd,
		      3, 1),
	SHELL_CMD_ARG(del, NULL, "<NetKeyIndex> <AppKeyIndex>", cmd_app_key_del, 3, 0),
	SHELL_CMD_ARG(get, NULL, "<NetKeyIndex>", cmd_app_key_get, 2, 0),
	SHELL_SUBCMD_SET_END);


SHELL_STATIC_SUBCMD_SET_CREATE(
	cfg_cli_cmds,
	/* Configuration Client Model operations */
	SHELL_CMD_ARG(reset, NULL, NULL, cmd_reset, 1, 0),
	SHELL_CMD_ARG(timeout, NULL, "[Timeout in seconds]", cmd_timeout, 1, 1),
	SHELL_CMD_ARG(get-comp, NULL, "[Page]", cmd_get_comp, 1, 1),
	SHELL_CMD_ARG(beacon, NULL, "[Val: off, on]", cmd_beacon, 1, 1),
	SHELL_CMD_ARG(ttl, NULL, "[TTL: 0x00, 0x02-0x7f]", cmd_ttl, 1, 1),
	SHELL_CMD_ARG(friend, NULL, "[Val: off, on]", cmd_friend, 1, 1),
	SHELL_CMD_ARG(gatt-proxy, NULL, "[Val: off, on]", cmd_gatt_proxy, 1, 1),
	SHELL_CMD_ARG(relay, NULL, "[<Val: off, on> [<Count: 0-7> [Interval: 10-320]]]", cmd_relay,
		      1, 3),
	SHELL_CMD_ARG(node-id, NULL, "<NetKeyIndex> [Identify]", cmd_node_id, 2, 1),
	SHELL_CMD_ARG(polltimeout-get, NULL, "<LPN Address>", cmd_polltimeout_get, 2, 0),
	SHELL_CMD_ARG(net-transmit-param, NULL,
		      "[<Count: 0-7>"
		      " <Interval: 10-320>]",
		      cmd_net_transmit, 1, 2),
	SHELL_CMD_ARG(krp, NULL, "<NetKeyIndex> [Phase]", cmd_krp, 2, 1),
	SHELL_CMD_ARG(hb-sub, NULL, "[<Src> <Dst> <Period>]", cmd_hb_sub, 1, 3),
	SHELL_CMD_ARG(hb-pub, NULL, "[<Dst> <Count> <Period> <TTL> <Features> <NetKeyIndex>]",
		      cmd_hb_pub, 1, 6),
	SHELL_CMD(appkey, &appkey_cmds, "Appkey config commands", bt_mesh_shell_mdl_cmds_help),
	SHELL_CMD(netkey, &netkey_cmds, "Netkey config commands", bt_mesh_shell_mdl_cmds_help),
	SHELL_CMD(model, &model_cmds, "Model config commands", bt_mesh_shell_mdl_cmds_help),
	SHELL_SUBCMD_SET_END);

SHELL_SUBCMD_ADD((mesh, models), cfg, &cfg_cli_cmds, "Config Cli commands",
		 bt_mesh_shell_mdl_cmds_help, 1, 1);
