Merge branch 'refactor_esp_matter_console' into 'main'

console: refactor esp_matter_console

See merge request app-frameworks/esp-matter!170
This commit is contained in:
Shu Chen
2022-09-28 10:07:10 +08:00
12 changed files with 379 additions and 247 deletions
@@ -263,186 +263,213 @@ namespace attribute {
static esp_matter_val_type_t get_val_type_from_attribute_type(int attribute_type);
static callback_t attribute_callback = NULL;
#if CONFIG_ENABLE_CHIP_SHELL
static esp_matter::console::engine attribute_console;
static esp_err_t console_handler(int argc, char **argv)
static esp_err_t console_set_handler(int argc, char **argv)
{
if (argc == 5 && strncmp(argv[0], "set", sizeof("set")) == 0) {
uint16_t endpoint_id = strtol((const char *)&argv[1][2], NULL, 16);
uint32_t cluster_id = strtol((const char *)&argv[2][2], NULL, 16);
uint32_t attribute_id = strtol((const char *)&argv[3][2], NULL, 16);
uint16_t endpoint_id = strtol((const char *)&argv[0][2], NULL, 16);
uint32_t cluster_id = strtol((const char *)&argv[1][2], NULL, 16);
uint32_t attribute_id = strtol((const char *)&argv[2][2], NULL, 16);
/* Get type from matter_attribute */
const EmberAfAttributeMetadata *matter_attribute = emberAfLocateAttributeMetadata(endpoint_id, cluster_id,
attribute_id);
if (!matter_attribute) {
ESP_LOGE(TAG, "Matter attribute not found");
return ESP_ERR_INVALID_ARG;
}
/* Use the type to create the val and then update te attribute */
esp_matter_val_type_t type = get_val_type_from_attribute_type(matter_attribute->attributeType);
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
if (type == ESP_MATTER_VAL_TYPE_BOOLEAN) {
bool value = atoi(argv[4]);
val = esp_matter_bool(value);
} else if (type == ESP_MATTER_VAL_TYPE_INT8) {
int8_t value = atoi(argv[4]);
val = esp_matter_int8(value);
} else if (type == ESP_MATTER_VAL_TYPE_UINT8) {
uint8_t value = atoi(argv[4]);
val = esp_matter_uint8(value);
} else if (type == ESP_MATTER_VAL_TYPE_INT16) {
int16_t value = atoi(argv[4]);
val = esp_matter_int16(value);
} else if (type == ESP_MATTER_VAL_TYPE_UINT16) {
uint16_t value = atoi(argv[4]);
val = esp_matter_uint16(value);
} else if (type == ESP_MATTER_VAL_TYPE_INT32) {
int32_t value = atoi(argv[4]);
val = esp_matter_int32(value);
} else if (type == ESP_MATTER_VAL_TYPE_UINT32) {
uint32_t value = atoi(argv[4]);
val = esp_matter_uint32(value);
} else if (type == ESP_MATTER_VAL_TYPE_INT64) {
int64_t value = atoi(argv[4]);
val = esp_matter_int64(value);
} else if (type == ESP_MATTER_VAL_TYPE_UINT64) {
uint64_t value = atoi(argv[4]);
val = esp_matter_uint64(value);
} else if (type == ESP_MATTER_VAL_TYPE_CHAR_STRING) {
char *value = argv[4];
val = esp_matter_char_str(value, strlen(value));
} else if (type == ESP_MATTER_VAL_TYPE_BITMAP8) {
uint8_t value = atoi(argv[4]);
val = esp_matter_bitmap8(value);
} else if (type == ESP_MATTER_VAL_TYPE_BITMAP16) {
uint16_t value = atoi(argv[4]);
val = esp_matter_bitmap16(value);
} else if (type == ESP_MATTER_VAL_TYPE_BITMAP32) {
uint32_t value = atoi(argv[4]);
val = esp_matter_bitmap32(value);
} else if (type == ESP_MATTER_VAL_TYPE_ENUM8) {
uint8_t value = atoi(argv[4]);
val = esp_matter_enum8(value);
} else {
ESP_LOGE(TAG, "Type not handled: %d", type);
return ESP_ERR_INVALID_ARG;
}
update(endpoint_id, cluster_id, attribute_id, &val);
} else if (argc == 4 && strncmp(argv[0], "get", sizeof("get")) == 0) {
uint16_t endpoint_id = strtol((const char *)&argv[1][2], NULL, 16);
uint32_t cluster_id = strtol((const char *)&argv[2][2], NULL, 16);
uint32_t attribute_id = strtol((const char *)&argv[3][2], NULL, 16);
/* Get type from matter_attribute */
const EmberAfAttributeMetadata *matter_attribute = emberAfLocateAttributeMetadata(endpoint_id, cluster_id,
attribute_id);
if (!matter_attribute) {
ESP_LOGE(TAG, "Matter attribute not found");
return ESP_ERR_INVALID_ARG;
}
/* Use the type to read the raw value and then print */
esp_matter_val_type_t type = get_val_type_from_attribute_type(matter_attribute->attributeType);
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
if (type == ESP_MATTER_VAL_TYPE_BOOLEAN) {
bool value = false;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_bool(value);
} else if (type == ESP_MATTER_VAL_TYPE_INT8) {
int8_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_int8(value);
} else if (type == ESP_MATTER_VAL_TYPE_UINT8) {
uint8_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_uint8(value);
} else if (type == ESP_MATTER_VAL_TYPE_INT16) {
int16_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_int16(value);
} else if (type == ESP_MATTER_VAL_TYPE_UINT16) {
uint16_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_uint16(value);
} else if (type == ESP_MATTER_VAL_TYPE_INT32) {
int32_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_int32(value);
} else if (type == ESP_MATTER_VAL_TYPE_UINT32) {
uint32_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_uint32(value);
} else if (type == ESP_MATTER_VAL_TYPE_INT64) {
int64_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_int64(value);
} else if (type == ESP_MATTER_VAL_TYPE_UINT64) {
uint64_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_uint64(value);
} else if (type == ESP_MATTER_VAL_TYPE_CHAR_STRING) {
/* Get raw value */
char value[256] = {0}; /* It can go upto 256 since only 1 byte (first) is used for size */
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
/* Get val from raw value */
val = esp_matter_char_str(NULL, 0);
int data_size_len = val.val.a.t - val.val.a.s;
int data_count = 0;
memcpy(&data_count, &value[0], data_size_len);
val = esp_matter_char_str((char *)(value + data_size_len), data_count);
} else if (type == ESP_MATTER_VAL_TYPE_BITMAP8) {
uint8_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_bitmap8(value);
} else if (type == ESP_MATTER_VAL_TYPE_BITMAP16) {
uint16_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_bitmap16(value);
} else if (type == ESP_MATTER_VAL_TYPE_BITMAP32) {
uint32_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_bitmap32(value);
} else if (type == ESP_MATTER_VAL_TYPE_ENUM8) {
uint8_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_enum8(value);
} else {
ESP_LOGE(TAG, "Type not handled: %d", type);
return ESP_ERR_INVALID_ARG;
}
val_print(endpoint_id, cluster_id, attribute_id, &val);
} else {
ESP_LOGE(TAG, "Incorrect arguments");
/* Get type from matter_attribute */
const EmberAfAttributeMetadata *matter_attribute = emberAfLocateAttributeMetadata(endpoint_id, cluster_id,
attribute_id);
if (!matter_attribute) {
ESP_LOGE(TAG, "Matter attribute not found");
return ESP_ERR_INVALID_ARG;
}
/* Use the type to create the val and then update te attribute */
esp_matter_val_type_t type = get_val_type_from_attribute_type(matter_attribute->attributeType);
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
if (type == ESP_MATTER_VAL_TYPE_BOOLEAN) {
bool value = atoi(argv[3]);
val = esp_matter_bool(value);
} else if (type == ESP_MATTER_VAL_TYPE_INT8) {
int8_t value = atoi(argv[3]);
val = esp_matter_int8(value);
} else if (type == ESP_MATTER_VAL_TYPE_UINT8) {
uint8_t value = atoi(argv[3]);
val = esp_matter_uint8(value);
} else if (type == ESP_MATTER_VAL_TYPE_INT16) {
int16_t value = atoi(argv[3]);
val = esp_matter_int16(value);
} else if (type == ESP_MATTER_VAL_TYPE_UINT16) {
uint16_t value = atoi(argv[3]);
val = esp_matter_uint16(value);
} else if (type == ESP_MATTER_VAL_TYPE_INT32) {
int32_t value = atoi(argv[3]);
val = esp_matter_int32(value);
} else if (type == ESP_MATTER_VAL_TYPE_UINT32) {
uint32_t value = atoi(argv[3]);
val = esp_matter_uint32(value);
} else if (type == ESP_MATTER_VAL_TYPE_INT64) {
int64_t value = atoi(argv[3]);
val = esp_matter_int64(value);
} else if (type == ESP_MATTER_VAL_TYPE_UINT64) {
uint64_t value = atoi(argv[3]);
val = esp_matter_uint64(value);
} else if (type == ESP_MATTER_VAL_TYPE_CHAR_STRING) {
char *value = argv[3];
val = esp_matter_char_str(value, strlen(value));
} else if (type == ESP_MATTER_VAL_TYPE_BITMAP8) {
uint8_t value = atoi(argv[3]);
val = esp_matter_bitmap8(value);
} else if (type == ESP_MATTER_VAL_TYPE_BITMAP16) {
uint16_t value = atoi(argv[3]);
val = esp_matter_bitmap16(value);
} else if (type == ESP_MATTER_VAL_TYPE_BITMAP32) {
uint32_t value = atoi(argv[3]);
val = esp_matter_bitmap32(value);
} else if (type == ESP_MATTER_VAL_TYPE_ENUM8) {
uint8_t value = atoi(argv[3]);
val = esp_matter_enum8(value);
} else {
ESP_LOGE(TAG, "Type not handled: %d", type);
return ESP_ERR_INVALID_ARG;
}
return update(endpoint_id, cluster_id, attribute_id, &val);
}
static esp_err_t console_get_handler(int argc, char **argv)
{
uint16_t endpoint_id = strtol((const char *)&argv[0][2], NULL, 16);
uint32_t cluster_id = strtol((const char *)&argv[1][2], NULL, 16);
uint32_t attribute_id = strtol((const char *)&argv[2][2], NULL, 16);
/* Get type from matter_attribute */
const EmberAfAttributeMetadata *matter_attribute = emberAfLocateAttributeMetadata(endpoint_id, cluster_id,
attribute_id);
if (!matter_attribute) {
ESP_LOGE(TAG, "Matter attribute not found");
return ESP_ERR_INVALID_ARG;
}
/* Use the type to read the raw value and then print */
esp_matter_val_type_t type = get_val_type_from_attribute_type(matter_attribute->attributeType);
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
if (type == ESP_MATTER_VAL_TYPE_BOOLEAN) {
bool value = false;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_bool(value);
} else if (type == ESP_MATTER_VAL_TYPE_INT8) {
int8_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_int8(value);
} else if (type == ESP_MATTER_VAL_TYPE_UINT8) {
uint8_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_uint8(value);
} else if (type == ESP_MATTER_VAL_TYPE_INT16) {
int16_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_int16(value);
} else if (type == ESP_MATTER_VAL_TYPE_UINT16) {
uint16_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_uint16(value);
} else if (type == ESP_MATTER_VAL_TYPE_INT32) {
int32_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_int32(value);
} else if (type == ESP_MATTER_VAL_TYPE_UINT32) {
uint32_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_uint32(value);
} else if (type == ESP_MATTER_VAL_TYPE_INT64) {
int64_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_int64(value);
} else if (type == ESP_MATTER_VAL_TYPE_UINT64) {
uint64_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_uint64(value);
} else if (type == ESP_MATTER_VAL_TYPE_CHAR_STRING) {
/* Get raw value */
char value[256] = {0}; /* It can go upto 256 since only 1 byte (first) is used for size */
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
/* Get val from raw value */
val = esp_matter_char_str(NULL, 0);
int data_size_len = val.val.a.t - val.val.a.s;
int data_count = 0;
memcpy(&data_count, &value[0], data_size_len);
val = esp_matter_char_str((char *)(value + data_size_len), data_count);
} else if (type == ESP_MATTER_VAL_TYPE_BITMAP8) {
uint8_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_bitmap8(value);
} else if (type == ESP_MATTER_VAL_TYPE_BITMAP16) {
uint16_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_bitmap16(value);
} else if (type == ESP_MATTER_VAL_TYPE_BITMAP32) {
uint32_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_bitmap32(value);
} else if (type == ESP_MATTER_VAL_TYPE_ENUM8) {
uint8_t value = 0;
get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value));
val = esp_matter_enum8(value);
} else {
ESP_LOGE(TAG, "Type not handled: %d", type);
return ESP_ERR_INVALID_ARG;
}
val_print(endpoint_id, cluster_id, attribute_id, &val);
return ESP_OK;
}
static void register_commands()
static esp_err_t console_dispatch(int argc, char **argv)
{
if (argc <= 0) {
attribute_console.for_each_command(esp_matter::console::print_description, NULL);
return ESP_OK;
}
return attribute_console.exec_command(argc, argv);
}
static void register_console_commands()
{
static bool init_done = false;
if (init_done) {
return;
}
esp_matter_console_command_t command = {
static const esp_matter::console::command_t command = {
.name = "attribute",
.description = "This can be used to simulate on-device control. "
"Usage: matter esp attribute <set|get> <endpoint_id> <cluster_id> <attribute_id> [value]. "
"Example1: matter esp attribute set 0x0001 0x0006 0x0000 1. "
"Example2: matter esp attribute get 0x0001 0x0006 0x0000.",
.handler = console_handler,
.description = "This can be used to simulate on-device control. ",
.handler = console_dispatch,
};
esp_matter_console_add_command(&command);
static const esp_matter::console::command_t attribute_commands[] = {
{
.name = "set",
.description = "Set an attribute value of a cluster on an endpoint. "
"Usage: matter esp attribute set <endpoint_id> <cluster_id> <attribute_id> <value>. "
"Example: matter esp attribute set 0x0001 0x0006 0x0000 1.",
.handler = console_set_handler,
},
{
.name = "get",
.description = "Get an attribute value of a cluster on an endpoint. "
"Usage: matter esp attribute get <endpoint_id> <cluster_id> <attribute_id>. "
"Example: matter esp attribute get 0x0001 0x0006 0x0000.",
.handler = console_get_handler,
},
};
attribute_console.register_commands(attribute_commands, sizeof(attribute_commands)/sizeof(esp_matter::console::command_t));
esp_matter::console::add_commands(&command, 1);
init_done = true;
}
#endif // CONFIG_ENABLE_CHIP_SHELL
esp_err_t set_callback(callback_t callback)
{
attribute_callback = callback;
/* Other initialisations */
register_commands();
#if CONFIG_ENABLE_CHIP_SHELL
register_console_commands();
#endif
return ESP_OK;
}
+6 -2
View File
@@ -1,3 +1,7 @@
idf_component_register(SRCS esp_matter_console.cpp esp_matter_console_diagnostics.cpp
set(srcs_list )
if (CONFIG_ENABLE_CHIP_SHELL)
list(APPEND srcs_list esp_matter_console.cpp esp_matter_console_diagnostics.cpp)
endif()
idf_component_register(SRCS ${srcs_list}
INCLUDE_DIRS .
PRIV_REQUIRES chip esp32_mbedtls esp_timer)
PRIV_REQUIRES chip esp32_mbedtls esp_timer bt openthread)
@@ -19,80 +19,100 @@
#include <esp_matter_console.h>
#include <lib/shell/Engine.h>
#include <src/platform/ESP32/ESP32Utils.h>
#define MAX_CONSOLE_COMMANDS CONFIG_ESP_MATTER_CONSOLE_MAX_COMMANDS
namespace esp_matter {
namespace console {
static const char *TAG = "esp_matter_console";
static esp_matter_console_command_t commands[MAX_CONSOLE_COMMANDS];
static int total_added_commands = 0;
static engine base_engine;
esp_err_t esp_matter_console_add_command(esp_matter_console_command_t *command)
void engine::for_each_command(command_iterator_t *on_command, void *arg)
{
if (total_added_commands + 1 > MAX_CONSOLE_COMMANDS) {
ESP_LOGE(TAG, "Could not add command. Increase the max limit to add more.");
for (unsigned i = 0; i < _command_set_count; ++i) {
for (unsigned j = 0; j < _command_set_size[i]; ++j) {
if (on_command(&_command_set[i][j], arg) != ESP_OK) {
return;
}
}
}
}
esp_err_t engine::exec_command(int argc, char *argv[])
{
esp_err_t err = ESP_ERR_INVALID_ARG;
if (argc <= 0) {
return err;
}
// find the command from the command set
for (unsigned i = 0; i < _command_set_count; ++i) {
for (unsigned j = 0; j < _command_set_size[i]; ++j) {
if (strcmp(argv[0], _command_set[i][j].name) == 0 && _command_set[i][j].handler) {
err = _command_set[i][j].handler(argc - 1, &argv[1]);
break;
}
}
}
return err;
}
esp_err_t engine::register_commands(const command_t *command_set, unsigned count)
{
if (_command_set_count >= CONSOLE_MAX_COMMAND_SETS) {
ESP_LOGE(TAG, "Max number of command sets reached");
return ESP_FAIL;
}
/* Since the strings in esp_matter_console_command_t are constants, this will work */
commands[total_added_commands] = *command;
total_added_commands++;
_command_set[_command_set_count] = command_set;
_command_set_size[_command_set_count] = count;
++_command_set_count;
return ESP_OK;
}
static void esp_matter_console_print_help()
esp_err_t add_commands(const command_t *command_set, unsigned count)
{
ESP_LOGI(TAG, "Usage: matter esp <sub_command>");
ESP_LOGI(TAG, "Sub commands:");
for (int i = 0; i < total_added_commands; i++) {
ESP_LOGI(TAG, "\t%s: %s", commands[i].name, commands[i].description);
}
return base_engine.register_commands(command_set, count);
}
static esp_err_t esp_matter_console_help_handler(int argc, char **argv)
esp_err_t print_description(const command_t *command, void *arg)
{
esp_matter_console_print_help();
ESP_LOGI(TAG, "\t%s: %s", command->name, command->description);
return ESP_OK;
}
static esp_err_t esp_matter_console_register_default_commands()
static esp_err_t help_handler(int argc, char **argv)
{
esp_matter_console_command_t command = {
base_engine.for_each_command(print_description, NULL);
return ESP_OK;
}
static esp_err_t register_default_commands()
{
static const command_t command= {
.name = "help",
.description = "Print help",
.handler = esp_matter_console_help_handler,
.handler = help_handler,
};
return esp_matter_console_add_command(&command);
return add_commands(&command, 1);
}
static CHIP_ERROR esp_matter_console_common_handler(int argc, char **argv)
static CHIP_ERROR common_handler(int argc, char **argv)
{
/* This common handler is added to avoid adding `CHIP_ERROR` and its component requirements in other esp-matter
* components */
if (argc <= 0) {
esp_matter_console_print_help();
help_handler(argc, argv);
return CHIP_NO_ERROR;
}
for (int i = 0; i < total_added_commands; i++) {
if (strncmp(argv[0], commands[i].name, strlen(commands[i].name) + 1) == 0) {
if (commands[i].handler == NULL) {
ESP_LOGW(TAG, "No handler set for the command: %s", argv[0]);
return CHIP_NO_ERROR;
}
if (commands[i].handler(argc - 1, &argv[1]) == ESP_OK) { /* Removing the first argument from argv */
return CHIP_NO_ERROR;
}
/* The command handler returned error */
return CHIP_ERROR_INVALID_ARGUMENT;
}
}
ESP_LOGE(TAG, "Could not find the command: %s. Try the help command for more details: matter esp help", argv[0]);
return CHIP_ERROR_INVALID_ARGUMENT;
return chip::DeviceLayer::Internal::ESP32Utils::MapError(base_engine.exec_command(argc, argv));
}
static esp_err_t esp_matter_console_register_common_shell_handler()
static esp_err_t register_common_shell_handler()
{
static chip::Shell::shell_command_t cmds[] = {
static const chip::Shell::shell_command_t cmds[] = {
{
.cmd_func = esp_matter_console_common_handler,
.cmd_func = common_handler,
.cmd_name = "esp",
.cmd_help = "Usage: matter esp <sub_command>",
},
@@ -107,14 +127,14 @@ static void ChipShellTask(void *args)
chip::Shell::Engine::Root().RunMainLoop();
}
esp_err_t esp_matter_console_init()
esp_err_t init()
{
esp_err_t err = ESP_OK;
err = esp_matter_console_register_default_commands();
err = register_default_commands();
if (err != ESP_OK) {
ESP_LOGE(TAG, "Couldn't register default console commands");
}
err = esp_matter_console_register_common_shell_handler();
err = register_common_shell_handler();
if (err != ESP_OK) {
ESP_LOGE(TAG, "Couldn't register common handler");
return err;
@@ -126,3 +146,6 @@ esp_err_t esp_matter_console_init()
}
return err;
}
} // namespace console
} // namespace esp_matter
@@ -15,10 +15,12 @@
#pragma once
#include <esp_err.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
#define CONSOLE_MAX_COMMAND_SETS CONFIG_ESP_MATTER_CONSOLE_MAX_COMMANDS
namespace esp_matter {
namespace console {
/** Callback for console commands
*
@@ -27,7 +29,7 @@ extern "C" {
* @return ESP_OK on success.
* @return error in case of failure.
*/
typedef esp_err_t (*esp_matter_console_handler_t)(int argc, char **argv);
typedef esp_err_t (*command_handler_t)(int argc, char **argv);
/** ESP Matter Console Command */
typedef struct {
@@ -36,8 +38,64 @@ typedef struct {
/** Command Description/Help */
const char *description;
/** Command Handler */
esp_matter_console_handler_t handler;
} esp_matter_console_command_t;
command_handler_t handler;
} command_t;
/** Command iterator callback for the console commands
*
* @param command The console command being iterated.
* @param arg A context variable passed to the iterator function.
*
* @return ESP_OK to continue iteration; anything else to break iteration.
*/
typedef esp_err_t command_iterator_t(const command_t *command, void *arg);
class engine
{
protected:
const command_t *_command_set[CONSOLE_MAX_COMMAND_SETS];
unsigned _command_set_size[CONSOLE_MAX_COMMAND_SETS];
unsigned _command_set_count;
public:
engine(): _command_set_count(0) {}
/** Execution callback for a console command.
*
* @param[in] on_command An iterator callback to be called for each command.
* @param[in] arg A context variable to be passed to each command iterated.
*/
void for_each_command(command_iterator_t *on_command, void *arg);
/** Dispatch and execute the command for the given argument list.
*
* @param[in] argc Number of arguments in argv.
* @param[in] argv Array of arguments in the tokenized command line to execute.
*
* @return ESP_OK on success
* @return error in case of failure.
*/
esp_err_t exec_command(int argc, char *argv[]);
/** Registers a command set, or array of commands with the console.
*
* @param command_set[in] An array of commands to add to the console.
* @param count[in] The number of commands in the command set array.
*
* @return ESP_OK on success
* @return error in case of failure.
*/
esp_err_t register_commands(const command_t *command_set, unsigned count);
};
/** Print the description of a command
*
* @param command[in] The command which's description will be printed.
* @param arg[in] A context variable passed to the iterator function.
*
* @return ESP_OK on success
* @return error in case of failure.
*/
esp_err_t print_description(const command_t *command, void *arg);
/** Initialize Console
*
@@ -46,19 +104,20 @@ typedef struct {
* @return ESP_OK on success.
* @return error in case of failure.
*/
esp_err_t esp_matter_console_init(void);
esp_err_t init(void);
/** Add Console Command
/** Add Console Command Set
*
* Add a new console command.
* This can be done before calling `esp_matter_console_init()` but the commands will not work until initialized.
*
* @param[in] command Pointer to command struct
* @param[in] command_set Command struct set array pointer
* @param[in] count Command struct set array size
*
* @return ESP_OK on success.
* @return error in case of failure.
*/
esp_err_t esp_matter_console_add_command(esp_matter_console_command_t *command);
esp_err_t add_commands(const command_t *command_set, unsigned count);
/** Add Diagnostics Commands
*
@@ -67,8 +126,7 @@ esp_err_t esp_matter_console_add_command(esp_matter_console_command_t *command);
* @return ESP_OK on success.
* @return error in case of failure.
*/
esp_err_t esp_matter_console_diagnostics_register_commands();
esp_err_t diagnostics_register_commands();
#ifdef __cplusplus
}
#endif
} // namespace console
} // namespace esp_matter
@@ -18,7 +18,11 @@
#include <esp_timer.h>
#include <string.h>
namespace esp_matter {
namespace console {
static const char *TAG = "esp_matter_console_diagnostics";
static engine diagnostics_console;
static esp_err_t mem_dump_console_handler(int argc, char *argv[])
{
@@ -39,26 +43,38 @@ static esp_err_t up_time_console_handler(int argc, char *argv[])
return ESP_OK;
}
static esp_err_t esp_matter_console_diagnostics_handler(int argc, char **argv)
static esp_err_t diagnostics_dispatch(int argc, char **argv)
{
if (argc == 1 && strncmp(argv[0], "mem-dump", sizeof("mem-dump")) == 0) {
return mem_dump_console_handler(argc, argv);
} else if (argc == 1 && strncmp(argv[0], "up-time", sizeof("up-time")) == 0) {
return up_time_console_handler(argc, argv);
} else {
ESP_LOGE(TAG, "Incorrect arguments");
return ESP_FAIL;
if (argc <= 0) {
diagnostics_console.for_each_command(print_description, NULL);
return ESP_OK;
}
return ESP_OK;
return diagnostics_console.exec_command(argc, argv);
}
esp_err_t esp_matter_console_diagnostics_register_commands()
esp_err_t diagnostics_register_commands()
{
esp_matter_console_command_t command = {
static const command_t command = {
.name = "diagnostics",
.description = "Diagnostic commands. Usage matter esp diagnostics <diagnostic_command>. Diagnostics commands: "
"mem-dump, up-time",
.handler = esp_matter_console_diagnostics_handler,
.description = "Diagnostic commands. Usage matter esp diagnostics <diagnostic_command>.",
.handler = diagnostics_dispatch,
};
return esp_matter_console_add_command(&command);
static const command_t diagnostics_commands[] = {
{
.name = "mem-dump",
.description = "help for memory analysis",
.handler = mem_dump_console_handler,
},
{
.name = "up-time",
.description = "print the uptime of the device",
.handler = up_time_console_handler,
},
};
diagnostics_console.register_commands(diagnostics_commands, sizeof(diagnostics_commands)/sizeof(command_t));
return add_commands(&command, 1);
}
} // namespace console
} // namespace esp_matter
+1 -1
View File
@@ -1,4 +1,4 @@
set(PRIV_REQUIRES_LIST device esp_matter esp_matter_console route_hook app_bridge)
set(PRIV_REQUIRES_LIST device esp_matter route_hook app_bridge)
idf_component_register(SRC_DIRS "."
PRIV_INCLUDE_DIRS "."
+2 -2
View File
@@ -103,7 +103,7 @@ extern "C" void app_main()
}
#if CONFIG_ENABLE_CHIP_SHELL
esp_matter_console_diagnostics_register_commands();
esp_matter_console_init();
esp_matter::console::diagnostics_register_commands();
esp_matter::console::init();
#endif
}
+2 -2
View File
@@ -131,7 +131,7 @@ extern "C" void app_main()
app_driver_light_set_defaults(light_endpoint_id);
#if CONFIG_ENABLE_CHIP_SHELL
esp_matter_console_diagnostics_register_commands();
esp_matter_console_init();
esp_matter::console::diagnostics_register_commands();
esp_matter::console::init();
#endif
}
+8 -4
View File
@@ -28,6 +28,7 @@ using namespace esp_matter::cluster;
static const char *TAG = "app_driver";
extern uint16_t switch_endpoint_id;
#if CONFIG_ENABLE_CHIP_SHELL
static esp_err_t app_driver_bound_console_handler(int argc, char **argv)
{
if (argc == 1 && strncmp(argv[0], "help", sizeof("help")) == 0) {
@@ -87,25 +88,26 @@ static esp_err_t app_driver_client_console_handler(int argc, char **argv)
static void app_driver_register_commands()
{
/* Add console command for bound devices */
esp_matter_console_command_t bound_command = {
static const esp_matter::console::command_t bound_command = {
.name = "bound",
.description = "This can be used to simulate on-device control for bound devices."
"Usage: matter esp bound <bound_command>. "
"Bound commands: help, invoke",
.handler = app_driver_bound_console_handler,
};
esp_matter_console_add_command(&bound_command);
esp_matter::console::add_commands(&bound_command, 1);
/* Add console command for client to control non-bound devices */
esp_matter_console_command_t client_command = {
static const esp_matter::console::command_t client_command = {
.name = "client",
.description = "This can be used to simulate on-device control for client devices."
"Usage: matter esp client <client_command>. "
"Client commands: help, invoke",
.handler = app_driver_client_console_handler,
};
esp_matter_console_add_command(&client_command);
esp_matter::console::add_commands(&client_command, 1);
}
#endif // CONFIG_ENABLE_CHIP_SHELL
void app_driver_client_command_callback(client::peer_device_t *peer_device, uint16_t remote_endpoint_id,
client::command_handle_t *cmd_handle, void *priv_data)
@@ -163,8 +165,10 @@ app_driver_handle_t app_driver_switch_init()
iot_button_register_cb(handle, BUTTON_PRESS_DOWN, app_driver_button_toggle_cb);
/* Other initializations */
#if CONFIG_ENABLE_CHIP_SHELL
app_driver_register_commands();
client::set_command_callback(app_driver_client_command_callback, app_driver_client_group_command_callback, NULL);
#endif // CONFIG_ENABLE_CHIP_SHELL
return (app_driver_handle_t)handle;
}
+2 -2
View File
@@ -118,7 +118,7 @@ extern "C" void app_main()
}
#if CONFIG_ENABLE_CHIP_SHELL
esp_matter_console_diagnostics_register_commands();
esp_matter_console_init();
esp_matter::console::diagnostics_register_commands();
esp_matter::console::init();
#endif
}
+2 -2
View File
@@ -99,7 +99,7 @@ extern "C" void app_main()
app_driver_light_set_defaults(light_endpoint_id);
#if CONFIG_ENABLE_CHIP_SHELL
esp_matter_console_diagnostics_register_commands();
esp_matter_console_init();
esp_matter::console::diagnostics_register_commands();
esp_matter::console::init();
#endif
}
+2 -2
View File
@@ -102,8 +102,8 @@ extern "C" void app_main()
}
#if CONFIG_ENABLE_CHIP_SHELL
esp_matter_console_diagnostics_register_commands();
esp_matter_console_init();
esp_matter::console::diagnostics_register_commands();
esp_matter::console::init();
#endif
launch_app_zboss();
}