sdk-hwV1.3/lichee/xr806/appos/project/common/cmd/cmd_util.c

277 lines
7.0 KiB
C
Executable File

/*
* Copyright (C) 2017 XRADIO TECHNOLOGY CO., LTD. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* 3. Neither the name of XRADIO TECHNOLOGY CO., LTD. nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "cmd_util.h"
#include <stdarg.h>
/* cmd format: <command-name> <arg>... */
enum cmd_status cmd_exec(char *cmd, const struct cmd_data *cdata, int count)
{
int i;
char *args;
args = cmd_strchr(cmd, ' ');
if (args) {
*args++ = '\0'; /* has arguments */
}
for (i = 0; i < count; ++i, ++cdata) {
if (cmd_strcmp(cmd, cdata->name) == 0) {
return cdata->exec(args ? args : "");
}
}
CMD_ERR("unknown cmd '%s'\n", cmd);
return CMD_STATUS_UNKNOWN_CMD;
}
/* cmd2 format: <command-name>[ <arg>...] */
enum cmd_status cmd2_exec(char *cmd, const struct cmd2_data *cdata, int count)
{
int i;
for (i = 0; i < count; ++i, ++cdata) {
if (cmd_strncmp(cmd, cdata->name, cdata->name_len) == 0) {
return cdata->exec(cmd + cdata->name_len);
}
}
CMD_ERR("unknown cmd '%s'\n", cmd);
return CMD_STATUS_UNKNOWN_CMD;
}
enum cmd_status cmd_help_exec(const struct cmd_data *cdata, int count, int align)
{
for (int i = 0; i < count; ++i, ++cdata) {
#if CMD_DESCRIBE
if (cdata->desc)
CMD_LOG(1, "[*] %-*.*s : %s\n", align, cmd_strlen(cdata->name), cdata->name, cdata->desc);
else
#endif
CMD_LOG(1, "[*] %s\n", cdata->name);
}
CMD_LOG(1, "\nFor detail please use xxx help\n");
return CMD_STATUS_ACKED;
}
enum cmd_status cmd2_help_exec(const struct cmd2_data *cdata, int count, int align)
{
for (int i = 0; i < count; ++i, ++cdata) {
#if CMD_DESCRIBE
if (cdata->desc)
CMD_LOG(1, "[*] %-*.*s : %s\n", align, cmd_strlen(cdata->name), cdata->name, cdata->desc);
else
#endif
CMD_LOG(1, "[*] %s\n", cdata->name);
}
CMD_LOG(1, "\nFor detail please use xxx help\n");
return CMD_STATUS_ACKED;
}
enum cmd_status cmd_main_exec(char *cmd, const struct cmd_data *cdata, int count)
{
enum cmd_status status = CMD_STATUS_OK;
if (cmd[0] != '\0') {
#if (!CONSOLE_ECHO_EN)
if (cmd_strcmp(cmd, "efpg"))
CMD_LOG(CMD_DBG_ON, "$ %s\n", cmd);
#endif
status = cmd_exec(cmd, cdata, count);
if (status != CMD_STATUS_ACKED) {
cmd_write_respond(status, cmd_get_status_desc(status));
if (status == CMD_STATUS_INVALID_ARG ||
status == CMD_STATUS_UNKNOWN_CMD) {
CMD_LOG(1, "Use 'help' to list available subcommands\n");
}
}
}
#if (!CONSOLE_ECHO_EN)
else { /* empty command */
CMD_LOG(1, "$\n");
}
#endif
#if CONSOLE_ECHO_EN
console_write((uint8_t *)"$ ", 2);
#endif
return status;
}
/* parse all argument vectors from a command string, return argument count */
int cmd_parse_argv(char *cmd, char *argv[], int size)
{
int last, argc;
char *start, *end;
argc = 0;
start = cmd;
while (argc < size && *start != '\0') {
while (*start == ' ' || *start == '\t')
start++;
if (*start == '\0')
break;
end = start;
while (*end != ' ' && *end != '\t' && *end != '\0')
end++;
last = *end == '\0';
*end = '\0';
argv[argc++] = start;
if (last)
break;
start = end + 1;
}
if (argc > 0 && argc < size) {
argv[argc] = NULL; /* ANSI-C requirement */
}
return argc;
}
static const char *cmd_status_success_desc[CMD_STATUS_SUCCESS_MAX + 1 -
CMD_STATUS_SUCCESS_MIN] = {
"OK",
};
static const char *cmd_status_error_desc[CMD_STATUS_ERROR_MAX + 1 -
CMD_STATUS_ERROR_MIN] = {
"Unknown command",
"Invalid argument",
"Fail",
};
static const char *cmd_empty_desc = "";
const char *cmd_get_status_desc(enum cmd_status status)
{
if (status >= CMD_STATUS_SUCCESS_MIN &&
status <= CMD_STATUS_SUCCESS_MAX) {
return cmd_status_success_desc[status - CMD_STATUS_SUCCESS_MIN];
} else if (status >= CMD_STATUS_ERROR_MIN &&
status <= CMD_STATUS_ERROR_MAX) {
return cmd_status_error_desc[status - CMD_STATUS_ERROR_MIN];
}
return cmd_empty_desc;
}
#if 0
static const char *cmd_event_desc[CMD_EVENT_MAX + 1 - CMD_EVENT_MIN] = {
"Test finish",
"timer notify"
};
const char *cmd_get_event_desc(enum cmd_event event)
{
if (event >= CMD_EVENT_MIN && event <= CMD_EVENT_MAX) {
return cmd_event_desc[event - CMD_EVENT_MIN];
}
return cmd_empty_desc;
}
#endif
int cmd_write(enum cmd_code_type type, int code, const char *fmt, ...)
{
static char str_buf[400];
va_list ap;
int len, left;
char *ptr;
ptr = str_buf;
left = sizeof(str_buf) - 1; /* reserve 1 byte for '\n' */
len = cmd_snprintf(ptr, left, "<%s> %d ",
type == CMD_CODE_TYEP_STATUS ? "ACK" : "EVT", code);
ptr += len;
left -= len;
va_start(ap, fmt);
len = vsnprintf(ptr, left, fmt, ap);
va_end(ap);
ptr += len;
left -= len;
left += 1;
len = cmd_snprintf(ptr, left, "\n");
left -= len;
len = sizeof(str_buf) - left;
return console_write((uint8_t *)str_buf, len);
}
int32_t cmd_raw_mode_read(uint8_t *buf, int32_t size, uint32_t msec)
{
UART_ID uart_id = console_get_uart_id();
if (uart_id < UART_NUM) {
return HAL_UART_Receive_Poll(uart_id, buf, size, msec);
} else {
return -1;
}
}
int32_t cmd_raw_mode_write(uint8_t *buf, int32_t size)
{
UART_ID uart_id = console_get_uart_id();
if (uart_id < UART_NUM) {
return HAL_UART_Transmit_Poll(uart_id, buf, size);
} else {
return -1;
}
}
void cmd_print_uint8_array(uint8_t *buf, int32_t size)
{
for (int i = 0; i < size; i++) {
if (i % 8 == 0)
printf(" ");
if (i % 32 == 0)
printf("\n");
printf("%02x ", buf[i]);
}
printf("\n");
}
void cmd_print_uint32_array(uint32_t *buf, int32_t size)
{
for (int i = 0; i < size; i++) {
if (i % 4 == 0)
printf("\n0x%08x: ", (uint32_t)&buf[i]);
printf("%08x ", buf[i]);
}
printf("\n");
}