icwmp/src/cwmp_cli.c
2025-08-29 16:47:10 +05:30

364 lines
10 KiB
C

/*
* cwmp_cli.c - icwmp CLI
*
* Copyright (C) 2021-2022, IOPSYS Software Solutions AB.
*
* Author Omar Kallel <omar.kallel@pivasoftware.com>
*
* See LICENSE file for license related information.
*
*/
#include <string.h>
#include "common.h"
#include "cwmp_cli.h"
#include "notifications.h"
LIST_HEAD(parameters_list);
struct fault_resp {
int fault_index;
char *fault_code;
char *fault_message;
};
struct cwmp_cli_command_struct {
char *command_name;
char *(*cmd_exec_func)(struct cmd_input in, union cmd_result *out);
void (*display_cmd_result)(struct cmd_input in, union cmd_result res, char *fault);
};
const struct fault_resp faults_array[] = {
{ FAULT_CPE_INTERNAL_ERROR, "9002", "Internal error" }, //Internal error
{ FAULT_CPE_INVALID_PARAMETER_NAME, "9003", "Invalid arguments" }, //Invalid arguments
{ FAULT_CPE_INVALID_PARAMETER_NAME, "9005", "Invalid parameter name" }, //Invalid parameter name
{ FAULT_CPE_INVALID_PARAMETER_VALUE, "9007", "Invalid parameter value" }, //Invalid Parameter value
{ FAULT_CPE_NON_WRITABLE_PARAMETER, "9008", "Attempt to set a non-writable parameter" }, //Non writable parameter
{ FAULT_CPE_NOTIFICATION_REJECTED, "9009", "Notification request rejected" }
};
static char *get_fault_message_by_fault_code(char *fault_code)
{
for (size_t i = 0; i < ARRAY_SIZE(faults_array); i++) {
if (CWMP_STRCMP(faults_array[i].fault_code, fault_code) == 0)
return faults_array[i].fault_message;
}
return NULL;
}
/*
* Get_Values
*/
char *cmd_get_exec_func(struct cmd_input in, union cmd_result *res)
{
res->param_list = &parameters_list;
char *fault = cwmp_get_parameter_values(in.first_input, res->param_list);
return fault;
}
static void display_get_cmd_result(struct cmd_input in __attribute__((unused)), union cmd_result res, char *fault)
{
if (fault != NULL) {
fprintf(stderr, "Fault %s: %s\n", fault, get_fault_message_by_fault_code(fault));
return;
}
struct cwmp_dm_parameter *param_value = NULL;
list_for_each_entry (param_value, res.param_list, list) {
fprintf(stdout, "%s => %s\n", param_value->name, param_value->value);
}
cwmp_free_all_dm_parameter_list(&parameters_list);
}
/*
* Set_Values
*/
char *cmd_set_exec_func(struct cmd_input in, union cmd_result *res)
{
if (CWMP_STRLEN(in.first_input) == 0)
return "9003";
LIST_HEAD(faults_list);
modified_uci_list = (struct list_head *)malloc(sizeof(struct list_head));
INIT_LIST_HEAD(modified_uci_list);
int fault_idx = cwmp_set_parameter_value(in.first_input, in.second_input, NULL, &faults_list);
if (fault_idx != FAULT_CPE_NO_FAULT) {
struct cwmp_param_fault *param_fault = NULL;
char *fault = NULL;
list_for_each_entry (param_fault, &faults_list, list) {
res->obj_res.fault_code = param_fault->fault_code;
snprintf(res->obj_res.fault_msg, sizeof(res->obj_res.fault_msg), "%s", param_fault->fault_msg);
break;
}
cwmp_free_all_list_param_fault(&faults_list);
icwmp_asprintf(&fault, "%d", res->obj_res.fault_code);
icwmp_restart_services(RELOAD_END_SESSION, false, false);
cwmp_free_modified_uci_list();
return fault;
}
set_rpc_parameter_key(in.third_input);
icwmp_restart_services(RELOAD_END_SESSION, true, false);
cwmp_free_modified_uci_list();
return NULL;
}
static void display_set_cmd_result(struct cmd_input in, union cmd_result res, char *fault)
{
if (fault == NULL) {
fprintf(stdout, "Set value is successfully done\n");
fprintf(stdout, "%s => %s\n", in.first_input, in.second_input);
return;
}
fprintf(stderr, "Fault %s: %s\n", fault, res.obj_res.fault_msg);
}
/*
* Add_Object
*/
char *cmd_add_exec_func(struct cmd_input in, union cmd_result *res)
{
if (in.first_input == NULL)
return "9003";
modified_uci_list = (struct list_head *)malloc(sizeof(struct list_head));
INIT_LIST_HEAD(modified_uci_list);
bool status = cwmp_add_object(in.first_input, &res->obj_res);
if (!status) {
char *fault = NULL;
icwmp_asprintf(&fault, "%d", res->obj_res.fault_code);
icwmp_restart_services(RELOAD_END_SESSION, false, false);
cwmp_free_modified_uci_list();
return fault;
}
set_rpc_parameter_key(in.second_input);
icwmp_restart_services(RELOAD_END_SESSION, true, false);
cwmp_free_modified_uci_list();
return NULL;
}
static void display_add_cmd_result(struct cmd_input in, union cmd_result res, char *fault)
{
char ob_path[1024] = {0};
if (fault != NULL) {
fprintf(stderr, "Fault %s: %s\n", fault, strlen(res.obj_res.fault_msg) ? res.obj_res.fault_msg : get_fault_message_by_fault_code(fault));
return;
}
snprintf(ob_path, sizeof(ob_path), "%s", in.first_input);
if (in.first_input[strlen(in.first_input) - 2] == ']') {
char *tmp = NULL;
tmp = strrchr(ob_path, '[');
if (tmp) {
*tmp = '\0';
}
}
fprintf(stdout, "Added %s%s.\n", ob_path, res.obj_res.instance);
FREE(res.obj_res.instance);
}
/*
* Delete_Object
*/
char *cmd_del_exec_func(struct cmd_input in, union cmd_result *res)
{
if (in.first_input == NULL)
return "9003";
modified_uci_list = (struct list_head *)malloc(sizeof(struct list_head));
INIT_LIST_HEAD(modified_uci_list);
bool status = cwmp_delete_object(in.first_input, &res->obj_res);
if (!status) {
char *fault = NULL;
icwmp_asprintf(&fault, "%d", res->obj_res.fault_code);
icwmp_restart_services(RELOAD_END_SESSION, false, false);
cwmp_free_modified_uci_list();
return fault;
}
set_rpc_parameter_key(in.second_input);
icwmp_restart_services(RELOAD_END_SESSION, true, false);
cwmp_free_modified_uci_list();
return NULL;
}
static void display_del_cmd_result(struct cmd_input in, union cmd_result res, char *fault)
{
if (fault != NULL) {
fprintf(stderr, "Fault %s: %s\n", fault, strlen(res.obj_res.fault_msg) ? res.obj_res.fault_msg : get_fault_message_by_fault_code(fault));
return;
}
fprintf(stdout, "Deleted %s\n", in.first_input);
}
/*
* Get_Notifications
*/
char *cmd_get_notif_exec_func(struct cmd_input in, union cmd_result *res)
{
if (in.first_input == NULL)
in.first_input = "";
res->param_list = &parameters_list;
return cwmp_get_parameter_attributes(in.first_input, res->param_list);
}
static void display_get_notif_cmd_result(struct cmd_input in __attribute__((unused)), union cmd_result res, char *fault)
{
if (fault != NULL) {
fprintf(stderr, "Fault %s: %s\n", fault, get_fault_message_by_fault_code(fault));
return;
}
struct cwmp_dm_parameter *param_value = NULL;
list_for_each_entry (param_value, res.param_list, list) {
fprintf(stdout, "%s => %s\n", param_value->name, param_value->notification == 2 ? "active" : param_value->notification == 1 ? "passive" : "off");
}
cwmp_free_all_dm_parameter_list(&parameters_list);
}
/*
* Set_Notifications
*/
char *cmd_set_notif_exec_func(struct cmd_input in, union cmd_result *res __attribute__((unused)))
{
if (in.first_input == NULL || CWMP_STRLEN(in.second_input) == 0)
return "9003";
if (!icwmp_validate_int_in_range(in.second_input, 0, 6))
return "9003";
char *fault = cwmp_set_parameter_attributes(in.first_input, (int)strtol(in.second_input, NULL, 10));
if (fault != NULL)
return fault;
return NULL;
}
static void display_set_notif_cmd_result(struct cmd_input in, union cmd_result res __attribute__((unused)), char *fault)
{
if (fault != NULL) {
fprintf(stderr, "Fault %s: %s\n", fault, get_fault_message_by_fault_code(fault));
return;
}
fprintf(stdout, "%s => %s\n", in.first_input, in.second_input);
}
/*
* Get_Names
*/
char *cmd_get_names_exec_func(struct cmd_input in, union cmd_result *res)
{
if (in.first_input == NULL)
in.first_input = "";
res->param_list = &parameters_list;
bool next_level = (CWMP_STRCMP(in.second_input, "1") == 0 || CWMP_LSTRCASECMP(in.second_input, "true") == 0) ? true : false;
char *fault = cwmp_get_parameter_names(in.first_input, next_level, res->param_list, NULL);
return fault;
}
static void display_get_names_cmd_result(struct cmd_input in __attribute__((unused)), union cmd_result res, char *fault)
{
if (fault != NULL) {
fprintf(stderr, "Fault %s: %s\n", fault, get_fault_message_by_fault_code(fault));
return;
}
struct cwmp_dm_parameter *param_value = NULL;
list_for_each_entry (param_value, res.param_list, list) {
fprintf(stdout, "%s => %s\n", param_value->name, param_value->writable ? "writable" : "not-writable");
}
cwmp_free_all_dm_parameter_list(&parameters_list);
}
/*
* Main
*/
static void cwmp_cli_help()
{
printf("Valid commands:\n");
printf(" help => show this help\n");
printf(" get [path-expr] => get parameter values\n");
printf(" get_names [path-expr] [next-level] => get parameter names\n");
printf(" set [path-expr] [value] [pkey] => set parameter value\n");
printf(" add [object] [pkey] => add object\n");
printf(" del [object] [pkey] => delete object\n");
printf(" get_notif [path-expr] => get parameter notifications\n");
printf(" set_notif [path-expr] [notification] => set parameter notifications\n");
}
const struct cwmp_cli_command_struct icwmp_commands[] = {
{ "get", cmd_get_exec_func, display_get_cmd_result }, //get_values
{ "get_names", cmd_get_names_exec_func, display_get_names_cmd_result }, //get_names
{ "set", cmd_set_exec_func, display_set_cmd_result }, //set_values
{ "add", cmd_add_exec_func, display_add_cmd_result }, //add_object
{ "del", cmd_del_exec_func, display_del_cmd_result }, //delete_object
{ "get_notif", cmd_get_notif_exec_func, display_get_notif_cmd_result }, //get_notifications
{ "set_notif", cmd_set_notif_exec_func, display_set_notif_cmd_result }, //set_notifications
};
char *execute_cwmp_cli_command(char *cmd, char *args[])
{
char *fault = NULL, *fault_ret = NULL;
union cmd_result cmd_out = {0};
if (CWMP_STRLEN(cmd) == 0) {
printf("You must add a command as input: \n\n");
goto cli_help;
}
if (CWMP_STRCMP(cmd, "help") == 0)
goto cli_help;
struct cmd_input cmd_in = {
args[0] ? args[0] : NULL,
args[0] && args[1] ? args[1] : "",
args[0] && args[1] && args[2] ? args[2] : NULL
};
for (size_t i = 0; i < ARRAY_SIZE(icwmp_commands); i++) {
if (CWMP_STRCMP(icwmp_commands[i].command_name, cmd) == 0) {
fault = icwmp_commands[i].cmd_exec_func(cmd_in, &cmd_out);
if (fault)
fault_ret = strdup(fault);
icwmp_commands[i].display_cmd_result(cmd_in, cmd_out, fault);
goto cli_end;
}
}
printf("Wrong cwmp cli command: %s\n", cmd);
cli_help:
cwmp_cli_help();
cli_end:
icwmp_cleanmem();
return fault_ret;
}