Merge pull request #575 from angelos-oikonomopoulos/dynamic-shell-command-registration

Dynamic shell command registration
This commit is contained in:
Simon Duquennoy 2018-06-13 14:16:19 +02:00 committed by GitHub
commit f8d3d0f3c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 66 additions and 23 deletions

View File

@ -45,6 +45,7 @@
#include "contiki.h"
#include "shell.h"
#include "shell-commands.h"
#include "lib/list.h"
#include "sys/log.h"
#include "dev/watchdog.h"
#include "net/ipv6/uip.h"
@ -76,7 +77,8 @@ static uint16_t curr_ping_datalen;
#if TSCH_WITH_SIXTOP
static shell_command_6top_sub_cmd_t sixtop_sub_cmd = NULL;
#endif /* TSCH_WITH_SIXTOP */
static struct shell_command_set_t builtin_shell_command_set;
LIST(shell_command_sets);
/*---------------------------------------------------------------------------*/
static const char *
ds6_nbr_state_to_str(uint8_t state)
@ -345,15 +347,16 @@ PT_THREAD(cmd_log(struct pt *pt, shell_output_func output, char *args))
static
PT_THREAD(cmd_help(struct pt *pt, shell_output_func output, char *args))
{
struct shell_command_t *cmd_ptr;
struct shell_command_set_t *set;
const struct shell_command_t *cmd;
PT_BEGIN(pt);
SHELL_OUTPUT(output, "Available commands:\n");
cmd_ptr = shell_commands;
while(cmd_ptr->name != NULL) {
SHELL_OUTPUT(output, "%s\n", cmd_ptr->help);
cmd_ptr++;
/* Note: we explicitly don't expend any code space to deal with shadowing */
for(set = list_head(shell_command_sets); set != NULL; set = list_item_next(set)) {
for(cmd = set->commands; cmd->name != NULL; ++cmd) {
SHELL_OUTPUT(output, "%s\n", cmd->help);
}
}
PT_END(pt);
@ -729,12 +732,48 @@ PT_THREAD(cmd_6top(struct pt *pt, shell_output_func output, char *args))
void
shell_commands_init(void)
{
list_init(shell_command_sets);
list_add(shell_command_sets, &builtin_shell_command_set);
/* Set up Ping Reply callback */
uip_icmp6_echo_reply_callback_add(&echo_reply_notification,
echo_reply_handler);
}
/*---------------------------------------------------------------------------*/
struct shell_command_t shell_commands[] = {
void
shell_command_set_register(struct shell_command_set_t *set)
{
list_push(shell_command_sets, set);
}
/*---------------------------------------------------------------------------*/
int
shell_command_set_deregister(struct shell_command_set_t *set)
{
if(!list_contains(shell_command_sets, set)) {
return !0;
}
list_remove(shell_command_sets, set);
return 0;
}
/*---------------------------------------------------------------------------*/
const struct shell_command_t *
shell_command_lookup(const char *name)
{
struct shell_command_set_t *set;
const struct shell_command_t *cmd;
for(set = list_head(shell_command_sets);
set != NULL;
set = list_item_next(set)) {
for(cmd = set->commands; cmd->name != NULL; ++cmd) {
if(!strcmp(cmd->name, name)) {
return cmd;
}
}
}
return NULL;
}
/*---------------------------------------------------------------------------*/
const struct shell_command_t builtin_shell_commands[] = {
{ "help", cmd_help, "'> help': Shows this help" },
{ "reboot", cmd_reboot, "'> reboot': Reboot the board by watchdog_reboot()" },
{ "ip-addr", cmd_ipaddr, "'> ip-addr': Shows all IPv6 addresses" },
@ -765,4 +804,8 @@ struct shell_command_t shell_commands[] = {
{ NULL, NULL, NULL },
};
static struct shell_command_set_t builtin_shell_command_set = {
.next = NULL,
.commands = builtin_shell_commands,
};
/** @} */

View File

@ -53,8 +53,14 @@ struct shell_command_t {
const char *help;
};
/* The set of supported commands */
extern struct shell_command_t shell_commands[];
struct shell_command_set_t {
struct shell_command_set_t *next;
const struct shell_command_t *const commands;
};
void shell_command_set_register(struct shell_command_set_t *);
int shell_command_set_deregister(struct shell_command_set_t *);
const struct shell_command_t *shell_command_lookup(const char *);
/**
* Initializes Shell-commands module

View File

@ -89,7 +89,7 @@ output_prompt(shell_output_func output)
PT_THREAD(shell_input(struct pt *pt, shell_output_func output, const char *cmd))
{
static char *args;
static struct shell_command_t *cmd_ptr;
static const struct shell_command_t *cmd_descr = NULL;
PT_BEGIN(pt);
@ -105,20 +105,14 @@ PT_THREAD(shell_input(struct pt *pt, shell_output_func output, const char *cmd))
args++;
}
/* Lookup for command */
cmd_ptr = shell_commands;
while(cmd_ptr->name != NULL) {
if(strcmp(cmd, cmd_ptr->name) == 0) {
static struct pt cmd_pt;
PT_SPAWN(pt, &cmd_pt, cmd_ptr->func(&cmd_pt, output, args));
goto done;
}
cmd_ptr++;
cmd_descr = shell_command_lookup(cmd);
if(cmd_descr != NULL) {
static struct pt cmd_pt;
PT_SPAWN(pt, &cmd_pt, cmd_descr->func(&cmd_pt, output, args));
} else {
SHELL_OUTPUT(output, "Command not found. Type 'help' for a list of commands\n");
}
SHELL_OUTPUT(output, "Command not found. Type 'help' for a list of commands\n");
done:
output_prompt(output);
PT_END(pt);
}