mirror of
https://github.com/espressif/esp-matter.git
synced 2026-04-27 19:13:13 +00:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,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 "."
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user