Merge branch 'task/matter_console' into 'main'

esp_matter_console: Separating console/shell into another component

See merge request app-frameworks/esp-matter!33
This commit is contained in:
Hrishikesh Dhayagude
2021-10-13 09:54:48 +00:00
13 changed files with 244 additions and 105 deletions
@@ -0,0 +1,3 @@
idf_component_register(SRCS esp_matter_console.cpp
INCLUDE_DIRS .
PRIV_REQUIRES chip esp32_mbedtls)
+15
View File
@@ -0,0 +1,15 @@
menu "ESP Matter Console"
config ESP_MATTER_CONSOLE_TASK_STACK
int "Task stack size"
default 2048
help
Stack size of the console task.
config ESP_MATTER_CONSOLE_MAX_COMMANDS
int "Max commands supported"
default 10
help
Maximum number of commands that can be added for the 'chip esp <sub_command>' command.
endmenu
@@ -0,0 +1,127 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include <esp_log.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <lib/shell/Engine.h>
#include <esp_matter_console.h>
#define MAX_CONSOLE_COMMANDS CONFIG_ESP_MATTER_CONSOLE_MAX_COMMANDS
static const char *TAG = "esp_matter_console";
static esp_matter_console_command_t commands[MAX_CONSOLE_COMMANDS];
static int total_added_commands = 0;
esp_err_t esp_matter_console_add_command(esp_matter_console_command_t *command)
{
if (total_added_commands + 1 > MAX_CONSOLE_COMMANDS) {
ESP_LOGE(TAG, "Could not add command. Increase the max limit to add more.");
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++;
return ESP_OK;
}
static void esp_matter_console_print_help()
{
ESP_LOGI(TAG, "Usage: chip 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);
}
}
static esp_err_t esp_matter_console_help_handler(int argc, char** argv)
{
esp_matter_console_print_help();
return ESP_OK;
}
static esp_err_t esp_matter_console_register_default_commands()
{
esp_matter_console_command_t command= {
.name = "help",
.description = "Print help",
.handler = esp_matter_console_help_handler,
};
return esp_matter_console_add_command(&command);
}
static CHIP_ERROR esp_matter_console_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();
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: chip esp help", argv[0]);
return CHIP_ERROR_INVALID_ARGUMENT;
}
static esp_err_t esp_matter_console_register_common_shell_handler()
{
static chip::Shell::shell_command_t cmds[] = {
{
.cmd_func = esp_matter_console_common_handler,
.cmd_name = "esp",
.cmd_help = "Usage: chip esp <sub_command>",
},
};
int cmds_num = sizeof(cmds) / sizeof(chip::Shell::shell_command_t);
chip::Shell::Engine::Root().RegisterCommands(cmds, cmds_num);
return ESP_OK;
}
static void ChipShellTask(void *args)
{
chip::Shell::Engine::Root().RunMainLoop();
}
esp_err_t esp_matter_console_init()
{
esp_err_t err = ESP_OK;
err = esp_matter_console_register_default_commands();
if (err != ESP_OK) {
ESP_LOGE(TAG, "Couldn't register default console commands");
}
err = esp_matter_console_register_common_shell_handler();
if (err != ESP_OK) {
ESP_LOGE(TAG, "Couldn't register common handler");
return err;
}
if (xTaskCreate(&ChipShellTask, "console", CONFIG_ESP_MATTER_CONSOLE_TASK_STACK, NULL, 5, NULL) != pdPASS) {
ESP_LOGE(TAG, "Couldn't create console task");
err = ESP_FAIL;
}
return err;
}
@@ -0,0 +1,66 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <esp_err.h>
#ifdef __cplusplus
extern "C"
{
#endif
/** Callback for console commands
*
* This callback handler will be called when console command is triggered.
*
* @return ESP_OK on success.
* @return error in case of failure.
*/
typedef esp_err_t (*esp_matter_console_handler_t)(int argc, char** argv);
/** ESP Matter Console Command */
typedef struct {
/** Command Name */
const char *name;
/** Command Description/Help */
const char *description;
/** Command Handler */
esp_matter_console_handler_t handler;
} esp_matter_console_command_t;
/** Initialize Console
*
* This API internally initializes the matter shell.
*
* @return ESP_OK on success.
* @return error in case of failure.
*/
esp_err_t esp_matter_console_init(void);
/** Add Console Command
*
* 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
*
* @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);
#ifdef __cplusplus
}
#endif
+1 -1
View File
@@ -1,4 +1,4 @@
include($ENV{ESP_MATTER_DEVICE_PATH}/esp_matter_device.cmake)
idf_component_register(SRCS app_driver.c
INCLUDE_DIRS .
PRIV_REQUIRES device ${used_driver} esp_matter)
PRIV_REQUIRES device ${used_driver} esp_matter esp_matter_console)
+13 -1
View File
@@ -11,6 +11,7 @@
#include <esp_matter.h>
#include <esp_matter_standard.h>
#include <esp_matter_console.h>
#include <app_driver.h>
#include <device.h>
#include <light_driver.h>
@@ -48,7 +49,7 @@ static void app_driver_print_attr_val(const char *endpoint, const char *attribut
}
}
int app_driver_cli_handler(int argc, char** argv)
static esp_err_t app_driver_console_handler(int argc, char** argv)
{
if (argc == 4 && strncmp(argv[0], "set", sizeof("set")) == 0) {
char *endpoint_name = argv[1];
@@ -74,6 +75,16 @@ int app_driver_cli_handler(int argc, char** argv)
return 0;
}
static void app_driver_register_commands()
{
esp_matter_console_command_t command= {
.name = "driver",
.description = "This can be used to simulate on-device control. Usage: chip esp driver <set|get> <endpoint_name> <attribute_name> [value]. Example1: chip esp driver set Light Power 1. Example2: chip esp driver get Light Power.",
.handler = app_driver_console_handler,
};
esp_matter_console_add_command(&command);
}
static esp_matter_attr_val_t app_driver_attribute_get(const char *endpoint, const char *attribute)
{
if (strncmp(endpoint, ESP_MATTER_ENDPOINT_LIGHT, sizeof(ESP_MATTER_ENDPOINT_LIGHT)) == 0) {
@@ -135,5 +146,6 @@ esp_err_t app_driver_init()
{
device_init();
esp_matter_attribute_callback_add(APP_DRIVER_NAME, app_driver_attribute_update, NULL);
app_driver_register_commands();
return ESP_OK;
}
-9
View File
@@ -24,15 +24,6 @@ extern "C"
*/
esp_err_t app_driver_init(void);
/** CLI handler for driver
*
* This API can be added as the callback for shell commands
*
* @return 0 on success.
* @return -1 in case of failure.
*/
int app_driver_cli_handler(int argc, char** argv);
#ifdef __cplusplus
}
#endif
+1 -1
View File
@@ -18,7 +18,7 @@ set(SRC_DIRS_LIST "${CMAKE_CURRENT_LIST_DIR}"
set(PRIV_INCLUDE_DIRS_LIST "${CMAKE_CURRENT_LIST_DIR}"
"${MATTER_SDK_PATH}/src")
set(PRIV_REQUIRES_LIST chip bt esp32_mbedtls esp_matter app_driver app_qrcode)
set(PRIV_REQUIRES_LIST chip bt esp32_mbedtls esp_matter esp_matter_console app_driver app_qrcode)
if ("${IDF_TARGET}" STREQUAL "esp32h2")
list(APPEND PRIV_REQUIRES_LIST openthread mynewt_nimble)
+2 -40
View File
@@ -6,10 +6,9 @@
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include "esp_matter.h"
#include "esp_matter_standard.h"
#include "esp_matter_console.h"
#include "app_driver.h"
#include "app_qrcode.h"
#include "app_matter.h"
@@ -25,42 +24,6 @@
#define APP_MAIN_NAME "Main"
static const char *TAG = "app_main";
#if CONFIG_ENABLE_CHIP_SHELL
void ChipShellTask(void *args)
{
chip::Shell::Engine::Root().RunMainLoop();
}
CHIP_ERROR app_cli_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_LOGE(TAG, "Incorrect arguments");
return CHIP_ERROR_INVALID_ARGUMENT;
}
if (strncmp(argv[0], "driver", sizeof("driver")) == 0) {
app_driver_cli_handler(argc - 1, &argv[1]);
} else {
ESP_LOGE(TAG, "Incorrect arguments");
return CHIP_ERROR_INVALID_ARGUMENT;
}
return CHIP_NO_ERROR;
}
static void app_cli_register_commands()
{
static chip::Shell::shell_command_t cmds[] = {
{
.cmd_func = &app_cli_common_handler,
.cmd_name = "esp",
.cmd_help = "driver: This can be used to simulate on-device control. Usage: chip esp driver <set|get> <endpoint_name> <attribute_name> [value]. Example1: chip esp driver set Light Power 1. Example2: chip esp driver get Light Power.",
},
};
int cmds_num = sizeof(cmds) / sizeof(chip::Shell::shell_command_t);
chip::Shell::Engine::Root().RegisterCommands(cmds, cmds_num);
}
#endif // CONFIG_ENABLE_CHIP_SHELL
static esp_err_t app_main_attribute_update(const char *endpoint, const char *attribute, esp_matter_attr_val_t val, void *priv_data)
{
/* Just adding this callback to notify the application */
@@ -113,7 +76,6 @@ extern "C" void app_main()
esp_matter_attribute_notify(APP_MAIN_NAME, ESP_MATTER_ENDPOINT_LIGHT, ESP_MATTER_ATTR_SATURATION, esp_matter_int(DEFAULT_SATURATION));
#if CONFIG_ENABLE_CHIP_SHELL
xTaskCreate(&ChipShellTask, "chip_shell", 2048, NULL, 5, NULL);
app_cli_register_commands();
esp_matter_console_init();
#endif
}
+1 -1
View File
@@ -18,7 +18,7 @@ set(SRC_DIRS_LIST "${CMAKE_CURRENT_LIST_DIR}"
set(PRIV_INCLUDE_DIRS_LIST "${CMAKE_CURRENT_LIST_DIR}"
"${MATTER_SDK_PATH}/src")
set(PRIV_REQUIRES_LIST chip bt esp32_mbedtls esp_matter app_driver app_qrcode esp_rainmaker)
set(PRIV_REQUIRES_LIST chip bt esp32_mbedtls esp_matter esp_matter_console app_driver app_qrcode esp_rainmaker)
idf_component_register(SRC_DIRS ${SRC_DIRS_LIST}
PRIV_INCLUDE_DIRS ${PRIV_INCLUDE_DIRS_LIST}
+2 -42
View File
@@ -6,10 +6,9 @@
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include "esp_matter.h"
#include "esp_matter_standard.h"
#include "esp_matter_console.h"
#include "app_driver.h"
#include "app_qrcode.h"
#include "app_matter.h"
@@ -26,44 +25,6 @@
#define APP_MAIN_NAME "Main"
static const char *TAG = "app_main";
#if CONFIG_ENABLE_CHIP_SHELL
void ChipShellTask(void *args)
{
chip::Shell::Engine::Root().RunMainLoop();
}
CHIP_ERROR app_cli_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_LOGE(TAG, "Incorrect arguments");
return CHIP_ERROR_INVALID_ARGUMENT;
}
if (strncmp(argv[0], "driver", sizeof("driver")) == 0) {
app_driver_cli_handler(argc - 1, &argv[1]);
} else if (strncmp(argv[0], "rainmaker", sizeof("rainmaker")) == 0) {
app_rainmaker_cli_handler(argc - 1, &argv[1]);
} else {
ESP_LOGE(TAG, "Incorrect arguments");
return CHIP_ERROR_INVALID_ARGUMENT;
}
return CHIP_NO_ERROR;
}
static void app_cli_register_commands()
{
static chip::Shell::shell_command_t cmds[] = {
{
.cmd_func = &app_cli_common_handler,
.cmd_name = "esp",
.cmd_help = "command1: driver: This can be used to simulate on-device control. Usage: chip esp driver <set|get> <endpoint_name> <attribute_name> [value]. Example1: chip esp driver set Light Power 1. Example2: chip esp driver get Light Power. command2: rainmaker: Initiate ESP RainMaker User-Node mapping from the node. Usage: chip esp rainmaker add-user <user_id> <secret_key>",
},
};
int cmds_num = sizeof(cmds) / sizeof(chip::Shell::shell_command_t);
chip::Shell::Engine::Root().RegisterCommands(cmds, cmds_num);
}
#endif // CONFIG_ENABLE_CHIP_SHELL
static esp_err_t app_main_attribute_update(const char *endpoint, const char *attribute, esp_matter_attr_val_t val, void *priv_data)
{
/* Just adding this callback to notify the application */
@@ -119,7 +80,6 @@ extern "C" void app_main()
esp_matter_attribute_notify(APP_MAIN_NAME, ESP_MATTER_ENDPOINT_LIGHT, ESP_MATTER_ATTR_SATURATION, esp_matter_int(DEFAULT_SATURATION));
#if CONFIG_ENABLE_CHIP_SHELL
xTaskCreate(&ChipShellTask, "chip_shell", 2048, NULL, 5, NULL);
app_cli_register_commands();
esp_matter_console_init();
#endif
}
+13 -1
View File
@@ -22,6 +22,7 @@
#include <esp_matter.h>
#include <esp_matter_standard.h>
#include <esp_matter_console.h>
#include <app_rainmaker.h>
#include "app_constants.h"
@@ -30,7 +31,7 @@ static const char *TAG = "app_rainmaker";
esp_rmaker_device_t *light_device;
int app_rainmaker_cli_handler(int argc, char** argv)
static esp_err_t app_rainmaker_console_handler(int argc, char** argv)
{
if (argc == 3 && strncmp(argv[0], "add-user", sizeof("add-user")) == 0) {
printf("%s: Starting user-node mapping\n", TAG);
@@ -44,6 +45,16 @@ int app_rainmaker_cli_handler(int argc, char** argv)
return 0;
}
static void app_rainmaker_register_commands()
{
esp_matter_console_command_t command= {
.name = "rainmaker",
.description = "Initiate ESP RainMaker User-Node mapping from the node. Usage: chip esp rainmaker add-user <user_id> <secret_key>",
.handler = app_rainmaker_console_handler,
};
esp_matter_console_add_command(&command);
}
static esp_rmaker_param_val_t esp_rmaker_get_rmaker_val(esp_matter_attr_val_t val)
{
if (val.type == ESP_MATTER_VAL_TYPE_BOOLEAN) {
@@ -167,5 +178,6 @@ esp_err_t app_rainmaker_init()
esp_rmaker_start();
esp_matter_attribute_callback_add(APP_RAINMAKER_NAME, app_rainmaker_attribute_update, NULL);
app_rainmaker_register_commands();
return ESP_OK;
}
@@ -24,15 +24,6 @@ extern "C"
*/
esp_err_t app_rainmaker_init(void);
/** CLI handler for RainMaker
*
* This API can be added as the callback for shell commands
*
* @return 0 on success.
* @return -1 in case of failure.
*/
int app_rainmaker_cli_handler(int argc, char** argv);
#ifdef __cplusplus
}
#endif