#include "tools/mesh/util.h"
#include "tools/mesh/model.h"
+#include "tools/mesh/keys.h"
+#include "tools/mesh/remote.h"
#include "tools/mesh/config-model.h"
#include "tools/mesh/cfgcli.h"
#define MIN_COMPOSITION_LEN 16
+#define NO_RESPONSE 0xFFFFFFFF
+
+struct cfg_cmd {
+ uint32_t opcode;
+ uint32_t resp;
+ const char *desc;
+};
static void *send_data;
static model_send_msg_func_t send_msg;
static uint16_t target = UNASSIGNED_ADDRESS;
static uint32_t parms[8];
+static struct cfg_cmd cmds[] = {
+ { OP_APPKEY_ADD, OP_APPKEY_STATUS, "AppKeyAdd" },
+ { OP_APPKEY_DELETE, OP_APPKEY_STATUS, "AppKeyDelete" },
+ { OP_APPKEY_GET, OP_APPKEY_LIST, "AppKeyGet"},
+ { OP_APPKEY_LIST, NO_RESPONSE, "AppKeyList"},
+ { OP_APPKEY_STATUS, NO_RESPONSE, "AppKeyStatus"},
+ { OP_APPKEY_UPDATE, OP_APPKEY_STATUS, "AppKeyUpdate" },
+ { OP_DEV_COMP_GET, OP_DEV_COMP_STATUS, "DeviceCompositionGet" },
+ { OP_DEV_COMP_STATUS, NO_RESPONSE, "DeviceCompositionStatus" },
+ { OP_CONFIG_BEACON_GET, OP_CONFIG_BEACON_STATUS, "BeaconGet" },
+ { OP_CONFIG_BEACON_SET, OP_CONFIG_BEACON_STATUS, "BeaconSet" },
+ { OP_CONFIG_BEACON_STATUS, NO_RESPONSE, "BeaconStatus" },
+ { OP_CONFIG_DEFAULT_TTL_GET, OP_CONFIG_DEFAULT_TTL_STATUS,
+ "DefaultTTLGet" },
+ { OP_CONFIG_DEFAULT_TTL_SET, OP_CONFIG_DEFAULT_TTL_STATUS,
+ "DefaultTTLSet" },
+ { OP_CONFIG_DEFAULT_TTL_STATUS, NO_RESPONSE, "DefaultTTLStatus" },
+ { OP_CONFIG_FRIEND_GET, OP_CONFIG_FRIEND_STATUS, "FriendGet" },
+ { OP_CONFIG_FRIEND_SET, OP_CONFIG_FRIEND_STATUS, "FrienSet" },
+ { OP_CONFIG_FRIEND_STATUS, NO_RESPONSE, "FriendStatus" },
+ { OP_CONFIG_PROXY_GET, OP_CONFIG_PROXY_STATUS, "ProxyGet" },
+ { OP_CONFIG_PROXY_SET, OP_CONFIG_PROXY_STATUS, "ProxySet" },
+ { OP_CONFIG_PROXY_STATUS, NO_RESPONSE, "ProxyStatus" },
+ { OP_CONFIG_KEY_REFRESH_PHASE_GET, OP_CONFIG_KEY_REFRESH_PHASE_STATUS,
+ "KeyRefreshPhaseGet" },
+ { OP_CONFIG_KEY_REFRESH_PHASE_SET, OP_CONFIG_KEY_REFRESH_PHASE_STATUS,
+ "KeyRefreshPhaseSet" },
+ { OP_CONFIG_KEY_REFRESH_PHASE_STATUS, NO_RESPONSE,
+ "KeyRefreshPhaseStatus" },
+ { OP_CONFIG_MODEL_PUB_GET, OP_CONFIG_MODEL_PUB_STATUS, "ModelPubGet" },
+ { OP_CONFIG_MODEL_PUB_SET, OP_CONFIG_MODEL_PUB_STATUS, "ModelPubSet" },
+ { OP_CONFIG_MODEL_PUB_STATUS, NO_RESPONSE, "ModelPubStatus" },
+ { OP_CONFIG_MODEL_PUB_VIRT_SET, OP_CONFIG_MODEL_PUB_STATUS,
+ "ModelPubVirtualSet" },
+ { OP_CONFIG_MODEL_SUB_ADD, OP_CONFIG_MODEL_SUB_STATUS, "ModelSubAdd" },
+ { OP_CONFIG_MODEL_SUB_DELETE, OP_CONFIG_MODEL_SUB_STATUS,
+ "ModelSubDelete" },
+ { OP_CONFIG_MODEL_SUB_DELETE_ALL, OP_CONFIG_MODEL_SUB_STATUS,
+ "ModelSubDeleteAll" },
+ { OP_CONFIG_MODEL_SUB_OVERWRITE, OP_CONFIG_MODEL_SUB_STATUS,
+ "ModelSubOverwrite" },
+ { OP_CONFIG_MODEL_SUB_STATUS, NO_RESPONSE, "ModelSubStatus" },
+ { OP_CONFIG_MODEL_SUB_VIRT_ADD, OP_CONFIG_MODEL_SUB_STATUS,
+ "ModelSubVirtAdd" },
+ { OP_CONFIG_MODEL_SUB_VIRT_DELETE, OP_CONFIG_MODEL_SUB_STATUS,
+ "ModelSubVirtDelete" },
+ { OP_CONFIG_MODEL_SUB_VIRT_OVERWRITE, OP_CONFIG_MODEL_SUB_STATUS,
+ "ModelSubVirtOverwrite" },
+ { OP_CONFIG_NETWORK_TRANSMIT_GET, OP_CONFIG_NETWORK_TRANSMIT_STATUS,
+ "NetworkTransmitGet" },
+ { OP_CONFIG_NETWORK_TRANSMIT_SET, OP_CONFIG_NETWORK_TRANSMIT_STATUS,
+ "NetworkTransmitSet" },
+ { OP_CONFIG_NETWORK_TRANSMIT_STATUS, NO_RESPONSE,
+ "NetworkTransmitStatus" },
+ { OP_CONFIG_RELAY_GET, OP_CONFIG_RELAY_STATUS, "RelayGet" },
+ { OP_CONFIG_RELAY_SET, OP_CONFIG_RELAY_STATUS, "RelaySet" },
+ { OP_CONFIG_RELAY_STATUS, NO_RESPONSE, "RelayStatus" },
+ { OP_CONFIG_MODEL_SUB_GET, OP_CONFIG_MODEL_SUB_LIST, "ModelSubGet" },
+ { OP_CONFIG_MODEL_SUB_LIST, NO_RESPONSE, "ModelSubList" },
+ { OP_CONFIG_VEND_MODEL_SUB_GET, OP_CONFIG_VEND_MODEL_SUB_LIST,
+ "VendorModelSubGet" },
+ { OP_CONFIG_VEND_MODEL_SUB_LIST, NO_RESPONSE, "VendorModelSubList" },
+ { OP_CONFIG_POLL_TIMEOUT_LIST, OP_CONFIG_POLL_TIMEOUT_STATUS,
+ "PollTimeoutList" },
+ { OP_CONFIG_POLL_TIMEOUT_STATUS, NO_RESPONSE, "PollTimeoutStatus" },
+ { OP_CONFIG_HEARTBEAT_PUB_GET, OP_CONFIG_HEARTBEAT_PUB_STATUS,
+ "HeartbeatPubGet" },
+ { OP_CONFIG_HEARTBEAT_PUB_SET, OP_CONFIG_HEARTBEAT_PUB_STATUS,
+ "HeartbeatPubSet" },
+ { OP_CONFIG_HEARTBEAT_PUB_STATUS, NO_RESPONSE, "HeartbeatPubStatus" },
+ { OP_CONFIG_HEARTBEAT_SUB_GET, OP_CONFIG_HEARTBEAT_SUB_GET,
+ "HeartbeatSubGet" },
+ { OP_CONFIG_HEARTBEAT_SUB_SET, OP_CONFIG_HEARTBEAT_SUB_GET,
+ "HeartbeatSubSet" },
+ { OP_CONFIG_HEARTBEAT_SUB_STATUS, NO_RESPONSE, "HeartbeatSubStatus" },
+ { OP_MODEL_APP_BIND, OP_MODEL_APP_STATUS, "ModelAppBind" },
+ { OP_MODEL_APP_STATUS, NO_RESPONSE, "ModelAppStatus" },
+ { OP_MODEL_APP_UNBIND, OP_MODEL_APP_STATUS, "ModelAppUnbind" },
+ { OP_NETKEY_ADD, OP_NETKEY_STATUS, "NetKeyAdd" },
+ { OP_NETKEY_DELETE, OP_NETKEY_STATUS, "NetKeyDelete" },
+ { OP_NETKEY_GET, OP_NETKEY_LIST, "NetKeyGet" },
+ { OP_NETKEY_LIST, NO_RESPONSE, "NetKeyList" },
+ { OP_NETKEY_STATUS, NO_RESPONSE, "NetKeyStatus" },
+ { OP_NETKEY_UPDATE, OP_NETKEY_STATUS, "NetKeyUpdate" },
+ { OP_NODE_IDENTITY_GET, OP_NODE_IDENTITY_STATUS, "NodeIdentityGet" },
+ { OP_NODE_IDENTITY_SET, OP_NODE_IDENTITY_STATUS, "NodeIdentitySet" },
+ { OP_NODE_IDENTITY_STATUS, NO_RESPONSE, "NodeIdentityStatus" },
+ { OP_NODE_RESET, OP_NODE_RESET_STATUS, "NodeReset" },
+ { OP_NODE_RESET_STATUS, NO_RESPONSE, "NodeResetStatus" },
+ { OP_MODEL_APP_GET, OP_MODEL_APP_LIST, "ModelAppGet" },
+ { OP_MODEL_APP_LIST, NO_RESPONSE, "ModelAppList" },
+ { OP_VEND_MODEL_APP_GET, OP_VEND_MODEL_APP_LIST, "VendorModelAppGet" },
+ { OP_VEND_MODEL_APP_LIST, NO_RESPONSE, "VendorModelAppList" }
+};
+
+static const char *opcode_str(uint32_t opcode)
+{
+ uint32_t n;
+
+ for (n = 0; n < L_ARRAY_SIZE(cmds); n++) {
+ if (opcode == cmds[n].opcode)
+ return cmds[n].desc;
+ }
+
+ return "Unknown";
+}
+
static uint32_t print_mod_id(uint8_t *data, bool vid, const char *offset)
{
uint32_t mod_id;
} else
return false;
+ bt_shell_printf("Received %s\n", opcode_str(opcode));
+
switch (opcode & ~OP_UNRELIABLE) {
default:
return false;
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static bool config_send(uint8_t *buf, uint16_t len)
+static bool config_send(uint8_t *buf, uint16_t len, uint32_t opcode)
{
+ bool res;
+
if (IS_UNASSIGNED(target)) {
bt_shell_printf("Destination not set\n");
return false;
}
- return send_msg(send_data, target, APP_IDX_DEV_REMOTE, buf, len);
+ res = send_msg(send_data, target, APP_IDX_DEV_REMOTE, buf, len);
+ if (!res)
+ bt_shell_printf("Failed to send \"%s\"\n", opcode_str(opcode));
+
+ return res;
}
static void cmd_default(uint32_t opcode)
n = mesh_opcode_set(opcode, msg);
- if (!config_send(msg, n)) {
- bt_shell_printf("Failed to send command (opcode 0x%x)\n",
- opcode);
+ if (!config_send(msg, n, opcode))
return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
/* By default, use page 0 */
msg[n++] = (read_input_parameters(argc, argv) == 1) ? parms[0] : 0;
- if (!config_send(msg, n)) {
- bt_shell_printf("Failed to send \"GET NODE COMPOSITION\"\n");
+ if (!config_send(msg, n, OP_DEV_COMP_GET))
return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
uint16_t n;
uint8_t msg[32];
+ if (IS_UNASSIGNED(target)) {
+ bt_shell_printf("Destination not set\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
n = mesh_opcode_set(OP_NETKEY_DELETE, msg);
if (read_input_parameters(argc, argv) != 1) {
return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
- put_le16(target + parms[0], msg + n);
+ put_le16(parms[0], msg + n);
n += 2;
- if (!config_send(msg, n)) {
- bt_shell_printf("Failed to send \"DEL_NET KEY\"\n");
+ if (!config_send(msg, n, OP_NETKEY_DELETE))
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+}
+
+static void cmd_appkey_del(int argc, char *argv[])
+{
+ uint16_t n;
+ uint8_t msg[32];
+ uint16_t app_idx, net_idx;
+
+ if (IS_UNASSIGNED(target)) {
+ bt_shell_printf("Destination not set\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ n = mesh_opcode_set(OP_APPKEY_DELETE, msg);
+
+ if (read_input_parameters(argc, argv) != 1) {
+ bt_shell_printf("Bad arguments %s\n", argv[1]);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ app_idx = (uint16_t) parms[0];
+ net_idx = keys_get_bound_key(app_idx);
+
+ /* Pack bound NetKey and AppKey into 3 octets */
+ msg[n] = net_idx;
+ msg[n + 1] = ((net_idx >> 8) & 0xf) | ((app_idx << 4) & 0xf0);
+ msg[n + 2] = app_idx >> 4;
+
+ n += 3;
+
+ if (!config_send(msg, n, OP_APPKEY_DELETE))
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+}
+
+static void cmd_key_add(uint32_t opcode, int argc, char *argv[])
+{
+ uint16_t key_idx;
+ bool is_appkey, update;
+
+ if (IS_UNASSIGNED(target)) {
+ bt_shell_printf("Destination not set\n");
return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
+ if (!send_key_msg) {
+ bt_shell_printf("Send key callback not set\n");
+ return;
+ }
+
+ if (read_input_parameters(argc, argv) != 1) {
+ bt_shell_printf("Bad arguments %s\n", argv[1]);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ key_idx = (uint16_t) parms[0];
+
+ update = (opcode == OP_NETKEY_UPDATE || opcode == OP_APPKEY_UPDATE);
+ is_appkey = (opcode == OP_APPKEY_ADD || opcode == OP_APPKEY_UPDATE);
+
+ if (!send_key_msg(key_data, target, key_idx, is_appkey, update))
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void cmd_netkey_add(int argc, char *argv[])
{
- /*TODO*/
- bt_shell_printf("Not implemented\n");
+ cmd_key_add(OP_NETKEY_ADD, argc, argv);
}
static void cmd_netkey_update(int argc, char *argv[])
{
- /*TODO*/
- bt_shell_printf("Not implemented\n");
+ cmd_key_add(OP_NETKEY_UPDATE, argc, argv);
}
static void cmd_appkey_add(int argc, char *argv[])
{
- /*TODO*/
- bt_shell_printf("Not implemented\n");
+ cmd_key_add(OP_APPKEY_ADD, argc, argv);
}
static void cmd_appkey_update(int argc, char *argv[])
{
- /*TODO*/
- bt_shell_printf("Not implemented\n");
-}
-
-static void cmd_appkey_del(int argc, char *argv[])
-{
- /*TODO*/
- bt_shell_printf("Not implemented\n");
+ cmd_key_add(OP_APPKEY_UPDATE, argc, argv);
}
static void cmd_bind(int argc, char *argv[])
n = mesh_opcode_set(OP_MODEL_APP_BIND, msg);
- put_le16(target + parms[0], msg + n);
+ put_le16(parms[0], msg + n);
n += 2;
put_le16(parms[1], msg + n);
n += 2;
n += 2;
}
- if (!config_send(msg, n)) {
- bt_shell_printf("Failed to send \"MODEL APP BIND\"\n");
+ if (!config_send(msg, n, OP_MODEL_APP_BIND))
return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
msg[n++] = parms[0];
- if (!config_send(msg, n)) {
- bt_shell_printf("Failed to send \"SET BEACON\"\n");
- return;
- }
+ if (!config_send(msg, n, OP_CONFIG_BEACON_SET))
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
n += 2;
msg[n++] = parms[1];
- if (!config_send(msg, n)) {
- bt_shell_printf("Failed to send \"SET IDENTITY\"\n");
- return;
- }
+ if (!config_send(msg, n, OP_NODE_IDENTITY_SET))
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
put_le16(parms[0], msg + n);
n += 2;
- if (!config_send(msg, n)) {
- bt_shell_printf("Failed to send \"GET IDENTITY\"\n");
+ if (!config_send(msg, n, OP_NODE_IDENTITY_GET))
return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
msg[n++] = parms[0];
- if (!config_send(msg, n)) {
- bt_shell_printf("Failed to send \"SET PROXY\"\n");
+ if (!config_send(msg, n, OP_CONFIG_PROXY_SET))
return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
msg[n++] = parms[0];
msg[n++] = (parms[1] << 5) | parms[2];
- if (!config_send(msg, n)) {
- bt_shell_printf("Failed to send \"SET RELAY\"\n");
+ if (!config_send(msg, n, OP_CONFIG_RELAY_SET))
return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
n = mesh_opcode_set(OP_CONFIG_DEFAULT_TTL_SET, msg);
msg[n++] = parms[0];
- if (!config_send(msg, n)) {
- bt_shell_printf("Failed to send \"SET_DEFAULT TTL\"\n");
+ if (!config_send(msg, n, OP_CONFIG_DEFAULT_TTL_SET))
return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
n += 2;
}
- if (!config_send(msg, n)) {
- bt_shell_printf("Failed to send \"SET MODEL PUBLICATION\"\n");
+ if (!config_send(msg, n, OP_CONFIG_MODEL_PUB_SET))
return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
n += 2;
}
- if (!config_send(msg, n)) {
- bt_shell_printf("Failed to send \"GET MODEL PUBLICATION\"\n");
+ if (!config_send(msg, n, OP_CONFIG_MODEL_PUB_GET))
return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
put_le16(parms[2], msg + n);
n += 2;
- if (!config_send(msg, n)) {
- bt_shell_printf("Failed to send \"ADD SUBSCRIPTION\"\n");
+ if (!config_send(msg, n, OP_CONFIG_MODEL_SUB_ADD))
return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
put_le16(parms[1], msg + n);
n += 2;
- if (!config_send(msg, n)) {
- bt_shell_printf("Failed to send \"GET SUB GET\"\n");
+ if (!config_send(msg, n, OP_CONFIG_MODEL_SUB_GET))
return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
put_le16(parms[1], msg + n);
n += 2;
- if (!config_send(msg, n)) {
- bt_shell_printf("Failed to send \"GET APP GET\"\n");
+ if (!config_send(msg, n, OP_MODEL_APP_GET))
return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
put_le16(parms[5], msg + n);
n += 2;
- if (!config_send(msg, n)) {
- bt_shell_printf("Failed to send \"SET HEARTBEAT PUBLISH\"\n");
+ if (!config_send(msg, n, OP_CONFIG_HEARTBEAT_PUB_SET))
return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
/* Period log */
msg[n++] = parms[2];
- if (!config_send(msg, n)) {
- bt_shell_printf("Failed to send \"SET HEARTBEAT SUBSCRIBE\"\n");
+ if (!config_send(msg, n, OP_CONFIG_HEARTBEAT_SUB_SET))
return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
"Add application key"},
{"appkey-del", "<app_idx>", cmd_appkey_del,
"Delete application key"},
- {"bind", "<ele_idx> <app_idx> <mod_id> [vendor_id]", cmd_bind,
+ {"bind", "<ele_addr> <app_idx> <mod_id> [vendor_id]", cmd_bind,
"Bind app key to a model"},
{"mod-appidx-get", "<ele_addr> <model id>", cmd_mod_appidx_get,
"Get model app_idx"},