cli.c 9.42 KiB
/*
* cli.c: Cli command for bbfdmd
*
* Copyright (C) 2023 IOPSYS Software Solutions AB. All rights reserved.
*
* Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
* Author: Iryna Antsyferova <iryna.antsyferova@iopsys.eu>
*
* See LICENSE file for license related information.
*/
#include <stdlib.h>
#include <stdio.h>
#include "common.h"
#include "libdmtree/dmapi.h"
#include "libdmtree/dmjson.h"
#include "libdmtree/dmentry.h"
#define UNUSED __attribute__((unused))
extern DMOBJ *DEAMON_DM_ROOT_OBJ;
extern DM_MAP_VENDOR *DEAMON_DM_VENDOR_EXTENSION[2];
extern DM_MAP_VENDOR_EXCLUDE *DEAMON_DM_VENDOR_EXTENSION_EXCLUDE;
extern int bbfdm_load_deamon_config(void);
typedef struct {
struct dmctx bbf_ctx;
unsigned int instance_mode;
unsigned int proto;
char in_name[128];
char in_type[8];
char out_type[8];
char *cmd;
} cli_data_t;
typedef struct {
char *name;
int num_args;
int (*exec_cmd)(cli_data_t *cli_data, char *argv[]);
char *usage;
} cli_cmd_t;
static int cli_exec_help(cli_data_t *cli_data UNUSED, char *argv[] UNUSED);
static int cli_exec_get(cli_data_t *cli_data, char *argv[]);
static int cli_exec_set(cli_data_t *cli_data, char *argv[]);
static int cli_exec_add(cli_data_t *cli_data, char *argv[]);
static int cli_exec_del(cli_data_t *cli_data, char *argv[]);
static int cli_exec_instances(cli_data_t *cli_data, char *argv[]);
static int cli_exec_schema(cli_data_t *cli_data, char *argv[]);
cli_cmd_t cli_commands[] = {
// Name NumArgs Exec callback Usage String
{ "help", 0, cli_exec_help, "help" },
{ "get", 1, cli_exec_get, "get [path-expr]" },
{ "set", 2, cli_exec_set, "set [path-expr] [value]"},
{ "add", 1, cli_exec_add, "add [object]"},
{ "del", 1, cli_exec_del, "del [path-expr]"},
{ "instances", 1, cli_exec_instances, "instances [path-expr]" },
{ "schema", 1, cli_exec_schema, "schema [path-expr]"},
};
static int bbfdm_load_cli_config(cli_data_t *cli_data)
{
cli_data->proto = BBFDM_BOTH;
cli_data->instance_mode = INSTANCE_MODE_NUMBER;
snprintf(cli_data->out_type, 8, "%s", "CLI");
snprintf(cli_data->in_type, 8, "%s", "DotSO");
return 0;
}
static int cli_exec_help(cli_data_t *cli_data UNUSED, char *argv[] UNUSED)
{
printf("Valid commands:\n");
// Print out the help usage of all commands
for (size_t i = 0; i < ARRAY_SIZE(cli_commands); i++) {
printf(" %s\n", cli_commands[i].usage);
}
return EXIT_SUCCESS;
}
static int in_dotso_out_cli_exec_get(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
cli_data->bbf_ctx.in_param = argv[0];
err = bbf_entry_method(&cli_data->bbf_ctx, BBF_GET_VALUE);
if (!err) {
struct dm_parameter *n;
list_for_each_entry(n, &cli_data->bbf_ctx.list_parameter, list) {
printf("%s => %s\n", n->name, n->data);
}
} else {
printf("ERROR: %d retrieving %s\n", err, cli_data->bbf_ctx.in_param);
err = EXIT_FAILURE;
}
return err;
}
static int cli_exec_get(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
if (strcasecmp(cli_data->in_type, "DotSO") == 0 || strcasecmp(cli_data->in_type, "JSON") == 0)
err = in_dotso_out_cli_exec_get(cli_data, argv);
else
err = EXIT_FAILURE;
return err;
}
static int in_dotso_out_cli_exec_set(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
cli_data->bbf_ctx.in_param = argv[0];
cli_data->bbf_ctx.in_value = argv[1];
err = bbf_entry_method(&cli_data->bbf_ctx, BBF_SET_VALUE);
if (!err) {
printf("%s => Set value is successfully done\n", cli_data->bbf_ctx.in_param);
bbf_entry_restart_services(NULL, true);
} else {
printf("ERROR: %d retrieving %s => %s\n", err, cli_data->bbf_ctx.in_param, cli_data->bbf_ctx.in_value);
bbf_entry_revert_changes(NULL);
err = EXIT_FAILURE;
}
return err;
}
static int cli_exec_set(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
if (strcasecmp(cli_data->in_type, "DotSO") == 0 || strcasecmp(cli_data->in_type, "JSON") == 0)
err = in_dotso_out_cli_exec_set(cli_data, argv);
else
err = EXIT_FAILURE;
return err;
}
static int in_dotso_out_cli_exec_add(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
cli_data->bbf_ctx.in_param = argv[0];
err = bbf_entry_method(&cli_data->bbf_ctx, BBF_ADD_OBJECT);
if (!err) {
printf("Added %s%s.\n", cli_data->bbf_ctx.in_param, cli_data->bbf_ctx.addobj_instance);
bbf_entry_restart_services(NULL, true);
} else {
printf("ERROR: %d retrieving %s\n", err, cli_data->bbf_ctx.in_param);
bbf_entry_revert_changes(NULL);
err = EXIT_FAILURE;
}
return err;
}
static int cli_exec_add(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
if (strcasecmp(cli_data->in_type, "DotSO") == 0 || strcasecmp(cli_data->in_type, "JSON") == 0)
err = in_dotso_out_cli_exec_add(cli_data, argv);
else
err = EXIT_FAILURE;
return err;
}
static int in_dotso_out_cli_exec_del(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
cli_data->bbf_ctx.in_param = argv[0];
err = bbf_entry_method(&cli_data->bbf_ctx, BBF_DEL_OBJECT);
if (!err) {
printf("Deleted %s\n", cli_data->bbf_ctx.in_param);
bbf_entry_restart_services(NULL, true);
} else {
printf("ERROR: %d retrieving %s\n", err, cli_data->bbf_ctx.in_param);
bbf_entry_revert_changes(NULL);
err = EXIT_FAILURE;
}
return err;
}
static int cli_exec_del(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
if (strcasecmp(cli_data->in_type, "DotSO") == 0 || strcasecmp(cli_data->in_type, "JSON") == 0)
err = in_dotso_out_cli_exec_del(cli_data, argv);
else
err = EXIT_FAILURE;
return err;
}
static int in_dotso_out_cli_exec_instances(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
cli_data->bbf_ctx.in_param = argv[0];
cli_data->bbf_ctx.nextlevel = false;
err = bbf_entry_method(&cli_data->bbf_ctx, BBF_INSTANCES);
if (!err) {
struct dm_parameter *n;
list_for_each_entry(n, &cli_data->bbf_ctx.list_parameter, list) {
printf("%s\n", n->name);
}
} else {
printf("ERROR: %d retrieving %s\n", err, cli_data->bbf_ctx.in_param);
err = EXIT_FAILURE;
}
return err;
}
static int cli_exec_instances(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
if (strcasecmp(cli_data->in_type, "DotSO") == 0 || strcasecmp(cli_data->in_type, "JSON") == 0)
err = in_dotso_out_cli_exec_instances(cli_data, argv);
else
err = EXIT_FAILURE;
return err;
}
static int in_dotso_out_cli_exec_schema(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
cli_data->bbf_ctx.in_param = argv[0];
cli_data->bbf_ctx.nextlevel = false;
cli_data->bbf_ctx.iscommand = true;
cli_data->bbf_ctx.isevent = true;
cli_data->bbf_ctx.isinfo = true;
err = bbf_entry_method(&cli_data->bbf_ctx, BBF_SCHEMA);
if (!err) {
struct dm_parameter *n;
printf("\nDumping %s Schema...\n\n", cli_data->bbf_ctx.in_param);
list_for_each_entry(n, &cli_data->bbf_ctx.list_parameter, list) {
int cmd = get_dm_type(n->type);
printf("%s\n", n->name);
if (cmd == DMT_COMMAND) {
if (n->data) {
const char **in, **out;
operation_args *args;
int i;
args = (operation_args *) n->data;
in = args->in;
if (in) {
for (i = 0; in[i] != NULL; i++)
printf("%s input:%s\n", n->name, in[i]);
}
out = args->out;
if (out) {
for (i = 0; out[i] != NULL; i++)
printf("%s output:%s\n", n->name, out[i]);
}
}
} else if (cmd == DMT_EVENT) {
if (n->data) {
event_args *ev;
ev = (event_args *)n->data;
if (ev->param) {
const char **in = ev->param;
for (int i = 0; in[i] != NULL; i++)
printf("%s event_arg:%s\n", n->name, in[i]);
}
}
}
}
} else {
printf("ERROR: %d retrieving %s\n", err, cli_data->bbf_ctx.in_param);
err = EXIT_FAILURE;
}
return err;
}
static int cli_exec_schema(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
if (strcasecmp(cli_data->in_type, "DotSO") == 0 || strcasecmp(cli_data->in_type, "JSON") == 0)
err = in_dotso_out_cli_exec_schema(cli_data, argv);
else
err = EXIT_FAILURE;
return err;
}
static int cli_exec_command(cli_data_t *cli_data, int argc, char *argv[])
{
cli_cmd_t *cli_cmd = NULL;
int err = EXIT_SUCCESS;
cli_data->cmd = argv[0];
if (!cli_data->cmd || strlen(cli_data->cmd) == 0) {
return EXIT_FAILURE;
}
bbfdm_load_deamon_config();
bbf_ctx_init(&cli_data->bbf_ctx, DEAMON_DM_ROOT_OBJ, DEAMON_DM_VENDOR_EXTENSION, DEAMON_DM_VENDOR_EXTENSION_EXCLUDE);
if (DEAMON_DM_ROOT_OBJ == NULL) {
return EXIT_FAILURE;
}
cli_data->bbf_ctx.dm_type = cli_data->proto;
cli_data->bbf_ctx.instance_mode = cli_data->instance_mode;
for (size_t i = 0; i < ARRAY_SIZE(cli_commands); i++) {
cli_cmd = &cli_commands[i];
if (strcmp(cli_data->cmd, cli_cmd->name) == 0) {
if (argc-1 < cli_cmd->num_args) {
printf("ERROR: Number of arguments for %s method is wrong(%d), it should be %d\n", cli_cmd->name, argc-1, cli_cmd->num_args);
cli_commands[0].exec_cmd(cli_data, NULL);
err = EXIT_FAILURE;
goto end;
}
err = cli_cmd->exec_cmd(cli_data, &argv[1]);
break;
}
}
end:
bbf_ctx_clean(&cli_data->bbf_ctx);
bbf_global_clean(DEAMON_DM_ROOT_OBJ);
return err;
}
int bbfdm_cli_exec_command(int argc, char *argv[])
{
cli_data_t cli_data = {0};
int err = EXIT_SUCCESS;
// Exit if no command specified
if (argc < 1) {
printf("ERROR: command name not specified\n");
return EXIT_FAILURE;
}
memset(&cli_data, 0, sizeof(cli_data_t));
err = bbfdm_load_cli_config(&cli_data);
if (err) {
return EXIT_FAILURE;
}
err = cli_exec_command(&cli_data, argc, argv);
return err;
}