mirror of
https://dev.iopsys.eu/bbf/icwmp.git
synced 2026-03-11 03:28:31 +01:00
461 lines
11 KiB
C
461 lines
11 KiB
C
/*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Copyright (C) 2015 Inteno Broadband Technology AB
|
|
* Author MOHAMED Kallel <mohamed.kallel@pivasoftware.com>
|
|
* Author Imen Bhiri <imen.bhiri@pivasoftware.com>
|
|
* Author Feten Besbes <feten.besbes@pivasoftware.com>
|
|
*
|
|
*/
|
|
|
|
#include "dmcwmp.h"
|
|
#include "dmubus.h"
|
|
#include "dmuci.h"
|
|
#include "dmentry.h"
|
|
|
|
LIST_HEAD(head_package_change);
|
|
|
|
int dm_global_init(void)
|
|
{
|
|
dm_entry_set_prefix_methods_enable();
|
|
return 0;
|
|
}
|
|
|
|
static int dm_ctx_init_custom(struct dmctx *ctx, int custom)
|
|
{
|
|
if (custom == CTX_INIT_ALL) {
|
|
memset(&dmubus_ctx, 0, sizeof(struct dmubus_ctx));
|
|
INIT_LIST_HEAD(&dmubus_ctx.obj_head);
|
|
uci_ctx = uci_alloc_context();
|
|
uci_varstate_ctx = uci_alloc_context();
|
|
}
|
|
INIT_LIST_HEAD(&ctx->list_parameter);
|
|
INIT_LIST_HEAD(&ctx->set_list_tmp);
|
|
INIT_LIST_HEAD(&ctx->list_fault_param);
|
|
return 0;
|
|
}
|
|
|
|
static int dm_ctx_clean_custom(struct dmctx *ctx, int custom)
|
|
{
|
|
free_all_list_parameter(ctx);
|
|
free_all_set_list_tmp(ctx);
|
|
free_all_list_fault_param(ctx);
|
|
DMFREE(ctx->addobj_instance);
|
|
if (custom == CTX_INIT_ALL) {
|
|
if (uci_ctx) uci_free_context(uci_ctx);
|
|
uci_ctx = NULL;
|
|
if (uci_varstate_ctx) uci_free_context(uci_varstate_ctx);
|
|
uci_varstate_ctx = NULL;
|
|
dmubus_ctx_free(&dmubus_ctx);
|
|
dmcleanmem();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int dm_ctx_init(struct dmctx *ctx)
|
|
{
|
|
dm_ctx_init_custom(ctx, CTX_INIT_ALL);
|
|
return 0;
|
|
}
|
|
|
|
int dm_ctx_clean(struct dmctx *ctx)
|
|
{
|
|
dm_ctx_clean_custom(ctx, CTX_INIT_ALL);
|
|
return 0;
|
|
}
|
|
|
|
int dm_ctx_init_sub(struct dmctx *ctx)
|
|
{
|
|
dm_ctx_init_custom(ctx, CTX_INIT_SUB);
|
|
return 0;
|
|
}
|
|
|
|
int dm_ctx_clean_sub(struct dmctx *ctx)
|
|
{
|
|
dm_ctx_clean_custom(ctx, CTX_INIT_SUB);
|
|
return 0;
|
|
}
|
|
|
|
|
|
int dm_entry_param_method(struct dmctx *ctx, int cmd, char *inparam, char *arg1, char *arg2)
|
|
{
|
|
int fault = 0;
|
|
bool setnotif = true;
|
|
|
|
if (!inparam) inparam = "";
|
|
ctx->in_param = inparam;
|
|
|
|
if (ctx->in_param[0] == '\0' || strcmp(ctx->in_param, DMROOT) == 0) {
|
|
ctx->tree = true;
|
|
} else {
|
|
ctx->tree = false;
|
|
}
|
|
|
|
switch(cmd) {
|
|
case CMD_GET_VALUE:
|
|
fault = dm_entry_get_value(ctx);
|
|
break;
|
|
case CMD_GET_NAME:
|
|
if (arg1 && string_to_bool(arg1, &ctx->nextlevel) == 0){
|
|
fault = dm_entry_get_name(ctx);
|
|
} else {
|
|
fault = FAULT_9003;
|
|
}
|
|
break;
|
|
case CMD_GET_NOTIFICATION:
|
|
fault = dm_entry_get_notification(ctx);
|
|
break;
|
|
case CMD_SET_VALUE:
|
|
ctx->in_value = arg1 ? arg1 : "";
|
|
ctx->setaction = VALUECHECK;
|
|
fault = dm_entry_set_value(ctx);
|
|
if (fault)
|
|
add_list_fault_param(ctx, ctx->in_param, fault);
|
|
break;
|
|
case CMD_SET_NOTIFICATION:
|
|
if (arg2)
|
|
string_to_bool(arg2, &setnotif);
|
|
if (setnotif && arg1 &&
|
|
(strcmp(arg1, "0") == 0 ||
|
|
strcmp(arg1, "1") == 0 ||
|
|
strcmp(arg1, "2") == 0)) {
|
|
ctx->in_notification = arg1;
|
|
ctx->setaction = VALUECHECK;
|
|
fault = dm_entry_set_notification(ctx);
|
|
} else {
|
|
fault = FAULT_9003;
|
|
}
|
|
break;
|
|
case CMD_INFORM:
|
|
dm_entry_inform(ctx);
|
|
break;
|
|
case CMD_ADD_OBJECT:
|
|
fault = dm_entry_add_object(ctx);
|
|
if (!fault) {
|
|
dmuci_set_value("cwmp", "acs", "ParameterKey", arg1 ? arg1 : "");
|
|
}
|
|
break;
|
|
case CMD_DEL_OBJECT:
|
|
fault = dm_entry_delete_object(ctx);
|
|
if (!fault) {
|
|
dmuci_set_value("cwmp", "acs", "ParameterKey", arg1 ? arg1 : "");
|
|
}
|
|
break;
|
|
}
|
|
dmuci_commit();
|
|
return fault;
|
|
}
|
|
|
|
int dm_entry_apply(struct dmctx *ctx, int cmd, char *arg1, char *arg2)
|
|
{
|
|
int fault = 0;
|
|
struct set_tmp *n, *p;
|
|
|
|
switch(cmd) {
|
|
case CMD_SET_VALUE:
|
|
ctx->setaction = VALUESET;
|
|
ctx->tree = false;
|
|
list_for_each_entry_safe(n, p, &ctx->set_list_tmp, list) {
|
|
ctx->in_param = n->name;
|
|
ctx->in_value = n->value ? n->value : "";
|
|
ctx->stop = false;
|
|
fault = dm_entry_set_value(ctx);
|
|
if (fault) break;
|
|
}
|
|
if (fault) {
|
|
//Should not happen
|
|
dmuci_revert();
|
|
add_list_fault_param(ctx, ctx->in_param, fault);
|
|
} else {
|
|
dmuci_set_value("cwmp", "acs", "ParameterKey", arg1 ? arg1 : "");
|
|
dmuci_change_packages(&head_package_change);
|
|
dmuci_commit();
|
|
}
|
|
free_all_set_list_tmp(ctx);
|
|
break;
|
|
case CMD_SET_NOTIFICATION:
|
|
ctx->setaction = VALUESET;
|
|
ctx->tree = false;
|
|
list_for_each_entry_safe(n, p, &ctx->set_list_tmp, list) {
|
|
ctx->in_param = n->name;
|
|
ctx->in_notification = n->value ? n->value : "0";
|
|
ctx->stop = false;
|
|
fault = dm_entry_set_notification(ctx);
|
|
if (fault) break;
|
|
}
|
|
if (fault) {
|
|
//Should not happen
|
|
dmuci_revert();
|
|
} else {
|
|
dmuci_commit();
|
|
}
|
|
free_all_set_list_tmp(ctx);
|
|
break;
|
|
}
|
|
return fault;
|
|
}
|
|
|
|
int dm_entry_load_enabled_notify()
|
|
{
|
|
struct dmctx dmctx = {0};
|
|
|
|
dm_ctx_init(&dmctx);
|
|
dmctx.in_param = "";
|
|
dmctx.tree = true;
|
|
|
|
free_all_list_enabled_notify();
|
|
dm_entry_enabled_notify(&dmctx);
|
|
|
|
dm_ctx_clean(&dmctx);
|
|
return 0;
|
|
}
|
|
|
|
int adm_entry_get_linker_param(char *param, char *linker, char **value)
|
|
{
|
|
struct dmctx dmctx = {0};
|
|
|
|
dm_ctx_init_sub(&dmctx);
|
|
dmctx.in_param = param ? param : "";
|
|
dmctx.linker = linker;
|
|
|
|
|
|
if (dmctx.in_param[0] == '\0') {
|
|
dmctx.tree = true;
|
|
} else {
|
|
dmctx.tree = false;
|
|
}
|
|
|
|
dm_entry_get_linker(&dmctx);
|
|
*value = dmctx.linker_param;
|
|
|
|
dm_ctx_clean_sub(&dmctx);
|
|
return 0;
|
|
}
|
|
|
|
int adm_entry_get_linker_value(char *param, char **value)
|
|
{
|
|
struct dmctx dmctx = {0};
|
|
*value = NULL;
|
|
|
|
if (!param || param[0] == '\0') {
|
|
return 0;
|
|
}
|
|
|
|
dm_ctx_init_sub(&dmctx);
|
|
dmctx.in_param = param;
|
|
dmctx.tree = false;
|
|
|
|
dm_entry_get_linker_value(&dmctx);
|
|
*value = dmctx.linker;
|
|
|
|
dm_ctx_clean_sub(&dmctx);
|
|
return 0;
|
|
}
|
|
|
|
int dm_entry_restart_services()
|
|
{
|
|
struct package_change *pc;
|
|
json_object *res;
|
|
|
|
list_for_each_entry(pc, &head_package_change, list) {
|
|
dmubus_call("uci", "commit", UBUS_ARGS{{"config", pc->package}}, 1, &res);
|
|
}
|
|
free_all_list_package_change(&head_package_change);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int cli_output_dm_result(struct dmctx *dmctx, int fault, int cmd, int out)
|
|
{
|
|
if (!out) return 0;
|
|
|
|
if (dmctx->list_fault_param.next != &dmctx->list_fault_param) {
|
|
struct param_fault *p;
|
|
list_for_each_entry(p, &dmctx->list_fault_param, list) {
|
|
fprintf (stdout, "{ \"parameter\": \"%s\", \"fault\": \"%d\" }\n", p->name, p->fault);
|
|
}
|
|
goto end;
|
|
}
|
|
if (fault) {
|
|
fprintf (stdout, "{ \"fault\": \"%d\" }\n", fault);
|
|
goto end;
|
|
}
|
|
|
|
if (cmd == CMD_ADD_OBJECT) {
|
|
if (dmctx->addobj_instance) {
|
|
fprintf (stdout, "{ \"status\": \"1\", \"instance\": \"%s\" }\n", dmctx->addobj_instance);
|
|
goto end;
|
|
} else {
|
|
fprintf (stdout, "{ \"fault\": \"%d\" }\n", FAULT_9002);
|
|
goto end;
|
|
}
|
|
}
|
|
|
|
if (cmd == CMD_DEL_OBJECT || cmd == CMD_SET_VALUE) {
|
|
fprintf (stdout, "{ \"status\": \"1\" }\n");
|
|
goto end;
|
|
}
|
|
|
|
if (cmd == CMD_SET_NOTIFICATION) {
|
|
fprintf (stdout, "{ \"status\": \"0\" }\n");
|
|
goto end;
|
|
}
|
|
|
|
struct dm_parameter *n;
|
|
if (cmd == CMD_GET_NAME) {
|
|
list_for_each_entry(n, &dmctx->list_parameter, list) {
|
|
fprintf (stdout, "{ \"parameter\": \"%s\", \"writable\": \"%s\" }\n", n->name, n->data);
|
|
}
|
|
}
|
|
else if (cmd == CMD_GET_NOTIFICATION) {
|
|
list_for_each_entry(n, &dmctx->list_parameter, list) {
|
|
fprintf (stdout, "{ \"parameter\": \"%s\", \"notification\": \"%s\" }\n", n->name, n->data);
|
|
}
|
|
}
|
|
else if (cmd == CMD_GET_VALUE || cmd == CMD_INFORM) {
|
|
list_for_each_entry(n, &dmctx->list_parameter, list) {
|
|
fprintf (stdout, "{ \"parameter\": \"%s\", \"value\": \"%s\", \"type\": \"%s\" }\n", n->name, n->data, n->type);
|
|
}
|
|
}
|
|
end:
|
|
return 0;
|
|
}
|
|
|
|
void dm_entry_cli(int argc, char** argv)
|
|
{
|
|
struct dmctx cli_dmctx = {0};
|
|
int output = 1;
|
|
|
|
dm_global_init();
|
|
dm_ctx_init(&cli_dmctx);
|
|
|
|
if (argc < 4) goto invalid_arguments;
|
|
|
|
output = atoi(argv[2]);
|
|
char *cmd = argv[3];
|
|
|
|
char *param, *next_level, *parameter_key, *value;
|
|
int fault = 0, status = -1;
|
|
|
|
/* GET NAME */
|
|
if (strcmp(cmd, "get_name") == 0) {
|
|
if (argc < 6) goto invalid_arguments;
|
|
param =argv[4];
|
|
next_level =argv[5];
|
|
fault = dm_entry_param_method(&cli_dmctx, CMD_GET_NAME, param, next_level, NULL);
|
|
cli_output_dm_result(&cli_dmctx, fault, CMD_GET_NAME, output);
|
|
}
|
|
/* GET VALUE */
|
|
else if (strcmp(cmd, "get_value") == 0) {
|
|
if (argc < 5) goto invalid_arguments;
|
|
param =argv[4];
|
|
fault = dm_entry_param_method(&cli_dmctx, CMD_GET_VALUE, param, NULL, NULL);
|
|
cli_output_dm_result(&cli_dmctx, fault, CMD_GET_VALUE, output);
|
|
}
|
|
/* GET NOTIFICATION */
|
|
else if (strcmp(cmd, "get_notification") == 0) {
|
|
if (argc < 5) goto invalid_arguments;
|
|
param =argv[4];
|
|
fault = dm_entry_param_method(&cli_dmctx, CMD_GET_NOTIFICATION, param, NULL, NULL);
|
|
cli_output_dm_result(&cli_dmctx, fault, CMD_GET_NOTIFICATION, output);
|
|
}
|
|
/* SET VALUE */
|
|
else if (strcmp(cmd, "set_value") == 0) {
|
|
if (argc < 7 || (argc % 2) == 0) goto invalid_arguments;
|
|
int i;
|
|
for (i = 5; i < argc; i+=2) {
|
|
param = argv[i];
|
|
value = argv[i+1];
|
|
dm_entry_param_method(&cli_dmctx, CMD_SET_VALUE, param, value, NULL);
|
|
}
|
|
parameter_key = argv[4];
|
|
fault = dm_entry_apply(&cli_dmctx, CMD_SET_VALUE, parameter_key, NULL);
|
|
cli_output_dm_result(&cli_dmctx, fault, CMD_SET_VALUE, output);
|
|
}
|
|
/* SET NOTIFICATION */
|
|
else if (strcmp(cmd, "set_notification") == 0) {
|
|
if (argc < 6 || (argc % 2) != 0) goto invalid_arguments;
|
|
int i;
|
|
for (i = 4; i < argc; i+=2) {
|
|
param = argv[i];
|
|
value = argv[i+1];
|
|
dm_entry_param_method(&cli_dmctx, CMD_SET_NOTIFICATION, param, value, "1");
|
|
}
|
|
fault = dm_entry_apply(&cli_dmctx, CMD_SET_NOTIFICATION, NULL, NULL);
|
|
cli_output_dm_result(&cli_dmctx, fault, CMD_SET_NOTIFICATION, output);
|
|
}
|
|
/* ADD OBJECT */
|
|
else if (strcmp(cmd, "add_object") == 0) {
|
|
if (argc < 6) goto invalid_arguments;
|
|
param =argv[5];
|
|
parameter_key =argv[4];
|
|
fault = dm_entry_param_method(&cli_dmctx, CMD_ADD_OBJECT, param, parameter_key, NULL);
|
|
cli_output_dm_result(&cli_dmctx, fault, CMD_ADD_OBJECT, output);
|
|
}
|
|
/* DEL OBJECT */
|
|
else if (strcmp(cmd, "delete_object") == 0) {
|
|
if (argc < 6) goto invalid_arguments;
|
|
param =argv[5];
|
|
parameter_key =argv[4];
|
|
fault = dm_entry_param_method(&cli_dmctx, CMD_DEL_OBJECT, param, parameter_key, NULL);
|
|
cli_output_dm_result(&cli_dmctx, fault, CMD_DEL_OBJECT, output);
|
|
}
|
|
/* INFORM */
|
|
else if (strcmp(cmd, "inform") == 0) {
|
|
fault = dm_entry_param_method(&cli_dmctx, CMD_INFORM, "", NULL, NULL);
|
|
cli_output_dm_result(&cli_dmctx, fault, CMD_INFORM, output);
|
|
}
|
|
else {
|
|
goto invalid_arguments;
|
|
}
|
|
dm_ctx_clean(&cli_dmctx);
|
|
return;
|
|
|
|
invalid_arguments:
|
|
dm_ctx_clean(&cli_dmctx);
|
|
fprintf(stdout, "Invalid arguments!\n");;
|
|
}
|
|
|
|
int cli_output_wepkey64(char strk64[4][11])
|
|
{
|
|
fprintf(stdout, "%s\n%s\n%s\n%s\n", strk64[0], strk64[1], strk64[2], strk64[3]);
|
|
return 0;
|
|
}
|
|
|
|
int cli_output_wepkey128(char strk128[27])
|
|
{
|
|
fprintf(stdout, "%s\n", strk128);
|
|
return 0;
|
|
}
|
|
|
|
void wepkey_cli(int argc, char** argv)
|
|
{
|
|
if (argc < 4) goto invalid_arguments;
|
|
|
|
char *strength = argv[2];
|
|
char *passphrase = argv[3];
|
|
|
|
if (!strength || !passphrase || passphrase[0] == '\0')
|
|
goto invalid_arguments;
|
|
|
|
if (strcmp(strength, "64") == 0) {
|
|
char strk64[4][11];
|
|
wepkey64(passphrase, strk64);
|
|
cli_output_wepkey64(strk64);
|
|
}
|
|
else if (strcmp(strength, "128") == 0) {
|
|
char strk128[27];
|
|
wepkey128(passphrase, strk128);
|
|
cli_output_wepkey128(strk128);
|
|
}
|
|
else {
|
|
goto invalid_arguments;
|
|
}
|
|
return;
|
|
|
|
invalid_arguments:
|
|
fprintf(stdout, "Invalid arguments!\n");;
|
|
}
|