mirror of
https://dev.iopsys.eu/bbf/icwmp.git
synced 2025-12-10 07:44:41 +01:00
code cleanup
This commit is contained in:
parent
5d1317aac8
commit
c42b5ba366
17 changed files with 793 additions and 595 deletions
|
|
@ -17,7 +17,7 @@ icwmpd_SOURCES = \
|
|||
./event.c \
|
||||
./http.c \
|
||||
./netlink.c \
|
||||
./ubus.c \
|
||||
./ubus_utils.c \
|
||||
./datamodel_interface.c \
|
||||
./cwmp_cli.c \
|
||||
./notifications.c \
|
||||
|
|
|
|||
10
README.md
10
README.md
|
|
@ -205,16 +205,6 @@ root@iopsys:~# ubus call tr069 command '{"command":"reload"}'
|
|||
}
|
||||
root@iopsys:~#
|
||||
```
|
||||
- To exit the icwmpd daemon, use the `command` ubus method with `exit` argument:
|
||||
|
||||
```bash
|
||||
root@iopsys:~# ubus call tr069 command '{"command":"exit"}'
|
||||
{
|
||||
"status": 1,
|
||||
"info": "icwmpd daemon stopped"
|
||||
}
|
||||
root@iopsys:~#
|
||||
```
|
||||
## icwmpd command line
|
||||
|
||||
`icwmpd` command line options are described with `--help` option as below:
|
||||
|
|
|
|||
40
common.c
40
common.c
|
|
@ -19,7 +19,7 @@
|
|||
#include "common.h"
|
||||
#include "cwmp_cli.h"
|
||||
#include "cwmp_uci.h"
|
||||
#include "ubus.h"
|
||||
#include "ubus_utils.h"
|
||||
#include "log.h"
|
||||
|
||||
|
||||
|
|
@ -29,8 +29,6 @@
|
|||
|
||||
char *commandKey = NULL;
|
||||
bool thread_end = false;
|
||||
bool signal_exit = false;
|
||||
bool ubus_exit = false;
|
||||
long int flashsize = 256000000;
|
||||
struct cwmp cwmp_main = { 0 };
|
||||
static int nbre_services = 0;
|
||||
|
|
@ -302,7 +300,13 @@ void cwmp_reboot(char *command_key)
|
|||
cwmp_uci_set_varstate_value("cwmp", "cpe", "ParameterKey", command_key);
|
||||
cwmp_commit_package("cwmp", UCI_VARSTATE_CONFIG);
|
||||
|
||||
cwmp_ubus_call("rpc-sys", "reboot", CWMP_UBUS_ARGS{ {} }, 0, NULL, NULL);
|
||||
struct blob_buf b = { 0 };
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
|
||||
icwmp_ubus_invoke("rpc-sys", "reboot", b.head, NULL, NULL);
|
||||
|
||||
blob_buf_free(&b);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -310,7 +314,13 @@ void cwmp_reboot(char *command_key)
|
|||
*/
|
||||
void cwmp_factory_reset() //use the ubus rpc-sys factory
|
||||
{
|
||||
cwmp_ubus_call("rpc-sys", "factory", CWMP_UBUS_ARGS{ {} }, 0, NULL, NULL);
|
||||
struct blob_buf b = { 0 };
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
|
||||
icwmp_ubus_invoke("rpc-sys", "factory", b.head, NULL, NULL);
|
||||
|
||||
blob_buf_free(&b);
|
||||
}
|
||||
|
||||
long int get_file_size(char *file_name)
|
||||
|
|
@ -579,9 +589,14 @@ void icwmp_restart_services()
|
|||
if (list_services[i] == NULL)
|
||||
continue;
|
||||
|
||||
cwmp_ubus_call("uci", "commit",
|
||||
CWMP_UBUS_ARGS{ { "config", { .str_val = list_services[i] }, UBUS_String } }, 1, NULL,
|
||||
NULL);
|
||||
struct blob_buf b = { 0 };
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
bb_add_string(&b, "config", list_services[i]);
|
||||
|
||||
icwmp_ubus_invoke("uci", "commit",b.head, NULL, NULL);
|
||||
|
||||
blob_buf_free(&b);
|
||||
|
||||
if (strcmp(list_services[i], "firewall") == 0) {
|
||||
g_firewall_restart = true;
|
||||
|
|
@ -712,7 +727,14 @@ void ubus_network_interface_callback(struct ubus_request *req __attribute__((unu
|
|||
|
||||
int get_connection_interface()
|
||||
{
|
||||
int e = cwmp_ubus_call("network.interface", "status", CWMP_UBUS_ARGS{ { "interface", { .str_val = cwmp_main.conf.default_wan_iface }, UBUS_String } }, 1, ubus_network_interface_callback, NULL);
|
||||
struct blob_buf b = { 0 };
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
bb_add_string(&b, "interface", cwmp_main.conf.default_wan_iface);
|
||||
|
||||
int e = icwmp_ubus_invoke("network.interface", "status", b.head, ubus_network_interface_callback, NULL);
|
||||
blob_buf_free(&b);
|
||||
|
||||
if (e != 0) {
|
||||
CWMP_LOG(INFO, "Get network interface from network.interface ubus method failed. Ubus err code: %d", e);
|
||||
return -1;
|
||||
|
|
|
|||
102
cwmp.c
102
cwmp.c
|
|
@ -15,6 +15,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "ssl_utils.h"
|
||||
|
|
@ -29,13 +30,14 @@
|
|||
#include "rpc_soap.h"
|
||||
#include "config.h"
|
||||
#include "backupSession.h"
|
||||
#include "ubus.h"
|
||||
#include "ubus_utils.h"
|
||||
#include "digestauth.h"
|
||||
#include "upload.h"
|
||||
#include "download.h"
|
||||
#include "sched_inform.h"
|
||||
#include "datamodel_interface.h"
|
||||
#include "cwmp_du_state.h"
|
||||
#include "netlink.h"
|
||||
|
||||
static pthread_t periodic_event_thread;
|
||||
static pthread_t scheduleInform_thread;
|
||||
|
|
@ -47,8 +49,8 @@ static pthread_t upload_thread;
|
|||
static pthread_t ubus_thread;
|
||||
static pthread_t http_cr_server_thread;
|
||||
static pthread_t periodic_check_notify;
|
||||
static pthread_t signal_handler_thread;
|
||||
bool g_firewall_restart = false;
|
||||
static struct ubus_context *ctx = NULL;
|
||||
|
||||
static int cwmp_get_retry_interval(struct cwmp *cwmp)
|
||||
{
|
||||
|
|
@ -440,9 +442,46 @@ static void cwmp_schedule_session(struct cwmp *cwmp)
|
|||
}
|
||||
}
|
||||
|
||||
static void check_exit_timer_expiry(struct uloop_timeout *timeout)
|
||||
{
|
||||
if (thread_end == true) {
|
||||
uloop_end();
|
||||
}
|
||||
|
||||
uloop_timeout_set(timeout, 1);
|
||||
}
|
||||
|
||||
static void *thread_uloop_run(void *v __attribute__((unused)))
|
||||
{
|
||||
cwmp_ubus_init(&cwmp_main);
|
||||
uloop_init();
|
||||
|
||||
if (netlink_init()) {
|
||||
CWMP_LOG(ERROR, "netlink initialization failed");
|
||||
}
|
||||
|
||||
if (cwmp_main.conf.ipv6_enable) {
|
||||
if (netlink_init_v6()) {
|
||||
CWMP_LOG(ERROR, "netlink initialization failed");
|
||||
}
|
||||
}
|
||||
|
||||
ctx = ubus_connect(cwmp_main.conf.ubus_socket);
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
ubus_add_uloop(ctx);
|
||||
|
||||
if (icwmp_register_object(ctx))
|
||||
return NULL;
|
||||
|
||||
struct uloop_timeout tm;
|
||||
memset(&tm, 0, sizeof(tm));
|
||||
tm.cb = check_exit_timer_expiry;
|
||||
uloop_timeout_set(&tm, 1);
|
||||
|
||||
uloop_run();
|
||||
uloop_done();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -754,36 +793,37 @@ static void cwmp_free(struct cwmp *cwmp)
|
|||
FREE(nonce_privacy_key);
|
||||
clean_list_param_notify();
|
||||
bkp_tree_clean();
|
||||
cwmp_ubus_exit();
|
||||
|
||||
if (ctx) {
|
||||
icwmp_delete_object(ctx);
|
||||
ubus_free(ctx);
|
||||
}
|
||||
|
||||
clean_custom_inform_parameters();
|
||||
icwmp_cleanmem();
|
||||
cwmp_uci_exit();
|
||||
}
|
||||
|
||||
static void *thread_cwmp_signal_handler_thread(void *arg)
|
||||
static void icwmp_signal_handler(int signal_num)
|
||||
{
|
||||
sigset_t *set = (sigset_t *)arg;
|
||||
if (signal_num == SIGINT || signal_num == SIGTERM) {
|
||||
thread_end = true;
|
||||
|
||||
for (;;) {
|
||||
int s, signal_num;
|
||||
s = sigwait(set, &signal_num);
|
||||
if (s == -1) {
|
||||
CWMP_LOG(ERROR, "Error in sigwait");
|
||||
} else {
|
||||
CWMP_LOG(INFO, "Catch of Signal(%d)", signal_num);
|
||||
if (cwmp_main.session_status.last_status == SESSION_RUNNING)
|
||||
http_set_timeout();
|
||||
|
||||
if (signal_num == SIGINT || signal_num == SIGTERM) {
|
||||
signal_exit = true;
|
||||
pthread_cond_signal(&(cwmp_main.threshold_session_send));
|
||||
pthread_cond_signal(&(cwmp_main.threshold_periodic));
|
||||
pthread_cond_signal(&(cwmp_main.threshold_notify_periodic));
|
||||
pthread_cond_signal(&threshold_schedule_inform);
|
||||
pthread_cond_signal(&threshold_download);
|
||||
pthread_cond_signal(&threshold_change_du_state);
|
||||
pthread_cond_signal(&threshold_schedule_download);
|
||||
pthread_cond_signal(&threshold_apply_schedule_download);
|
||||
pthread_cond_signal(&threshold_upload);
|
||||
|
||||
if (!ubus_exit)
|
||||
cwmp_ubus_call("tr069", "command", CWMP_UBUS_ARGS{ { "command", { .str_val = "exit" }, UBUS_String } }, 1, NULL, NULL);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
shutdown(cwmp_main.cr_socket_desc, SHUT_RDWR);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void configure_var_state(struct cwmp *cwmp)
|
||||
|
|
@ -806,7 +846,7 @@ static void configure_var_state(struct cwmp *cwmp)
|
|||
int main(int argc, char **argv)
|
||||
{
|
||||
struct cwmp *cwmp = &cwmp_main;
|
||||
sigset_t set;
|
||||
struct sigaction act;
|
||||
int error;
|
||||
|
||||
openlog("cwmp", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
|
||||
|
|
@ -826,10 +866,10 @@ int main(int argc, char **argv)
|
|||
configure_var_state(cwmp);
|
||||
http_server_init();
|
||||
|
||||
sigemptyset(&set);
|
||||
sigaddset(&set, SIGINT);
|
||||
sigaddset(&set, SIGTERM);
|
||||
sigprocmask(SIG_BLOCK, &set, NULL);
|
||||
memset(&act, 0, sizeof(act));
|
||||
act.sa_handler = icwmp_signal_handler;
|
||||
sigaction(SIGINT, &act, 0);
|
||||
sigaction(SIGTERM, &act, 0);
|
||||
|
||||
error = pthread_create(&http_cr_server_thread, NULL, &thread_http_cr_server_listen, NULL);
|
||||
if (error < 0) {
|
||||
|
|
@ -880,11 +920,6 @@ int main(int argc, char **argv)
|
|||
CWMP_LOG(ERROR, "Error when creating the download thread!");
|
||||
}
|
||||
|
||||
error = pthread_create(&signal_handler_thread, NULL, &thread_cwmp_signal_handler_thread, (void *)&set);
|
||||
if (error < 0) {
|
||||
CWMP_LOG(ERROR, "Error when creating the signal handler thread!");
|
||||
}
|
||||
|
||||
cwmp_schedule_session(cwmp);
|
||||
|
||||
/* Join all threads */
|
||||
|
|
@ -898,7 +933,6 @@ int main(int argc, char **argv)
|
|||
pthread_join(change_du_state_thread, NULL);
|
||||
pthread_join(http_cr_server_thread, NULL);
|
||||
pthread_join(ubus_thread, NULL);
|
||||
pthread_join(signal_handler_thread, NULL);
|
||||
|
||||
/* Free all memory allocation */
|
||||
cwmp_free(cwmp);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#include <regex.h>
|
||||
|
||||
#include "cwmp_du_state.h"
|
||||
#include "ubus.h"
|
||||
#include "ubus_utils.h"
|
||||
#include "log.h"
|
||||
#include "datamodel_interface.h"
|
||||
#include "cwmp_time.h"
|
||||
|
|
@ -37,12 +37,30 @@ void ubus_du_state_callback(struct ubus_request *req, int type __attribute__((un
|
|||
}
|
||||
}
|
||||
|
||||
static void prepare_blob_msg(struct blob_buf *b, char *url, char *uuid, char *user, char *pass, char *env_name, int env_id)
|
||||
{
|
||||
if (b == NULL)
|
||||
return;
|
||||
|
||||
bb_add_string(b, "ee_name", env_name);
|
||||
blobmsg_add_u32(b, "eeid", env_id);
|
||||
bb_add_string(b, "url", url);
|
||||
bb_add_string(b, "uuid", uuid);
|
||||
bb_add_string(b, "username", user);
|
||||
bb_add_string(b, "password", pass);
|
||||
}
|
||||
|
||||
int cwmp_du_install(char *url, char *uuid, char *user, char *pass, char *env_name, int env_id, char **fault_code)
|
||||
{
|
||||
int e;
|
||||
e = cwmp_ubus_call("swmodules", "du_install",
|
||||
CWMP_UBUS_ARGS{ { "ee_name", {.str_val = env_name }, UBUS_String }, { "eeid", {.int_val = env_id }, UBUS_Integer }, { "url", {.str_val = url }, UBUS_String }, { "uuid", {.str_val = uuid ? uuid : "" }, UBUS_String }, { "username", {.str_val = user ? user : "" }, UBUS_String }, { "password", {.str_val = pass ? pass : ""}, UBUS_String } }, 6,
|
||||
ubus_du_state_callback, fault_code);
|
||||
struct blob_buf b = { 0 };
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
|
||||
prepare_blob_msg(&b, url, uuid, user, pass, env_name, env_id);
|
||||
e = icwmp_ubus_invoke("swmodules", "du_install", b.head, ubus_du_state_callback, fault_code);
|
||||
blob_buf_free(&b);
|
||||
|
||||
if (e < 0) {
|
||||
CWMP_LOG(INFO, "Change du state install failed: Ubus err code: %d", e);
|
||||
return FAULT_CPE_INTERNAL_ERROR;
|
||||
|
|
@ -53,8 +71,14 @@ int cwmp_du_install(char *url, char *uuid, char *user, char *pass, char *env_nam
|
|||
int cwmp_du_update(char *url, char *uuid, char *user, char *pass, char *env_name, int env_id, char **fault_code)
|
||||
{
|
||||
int e;
|
||||
e = cwmp_ubus_call("swmodules", "du_update", CWMP_UBUS_ARGS{ { "ee_name", {.str_val = env_name }, UBUS_String }, { "eeid", {.int_val = env_id }, UBUS_Integer }, { "url", {.str_val = url }, UBUS_String }, { "uuid", {.str_val = uuid ? uuid : "" }, UBUS_String }, { "username", {.str_val = user ? user : "" }, UBUS_String }, { "password", {.str_val = pass ? pass : "" }, UBUS_String } }, 6, ubus_du_state_callback,
|
||||
fault_code);
|
||||
struct blob_buf b = { 0 };
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
|
||||
prepare_blob_msg(&b, url, uuid, user, pass, env_name, env_id);
|
||||
e = icwmp_ubus_invoke("swmodules", "du_update", b.head, ubus_du_state_callback, fault_code);
|
||||
blob_buf_free(&b);
|
||||
|
||||
if (e < 0) {
|
||||
CWMP_LOG(INFO, "Change du state update failed: Ubus err code: %d", e);
|
||||
return FAULT_CPE_INTERNAL_ERROR;
|
||||
|
|
@ -65,7 +89,17 @@ int cwmp_du_update(char *url, char *uuid, char *user, char *pass, char *env_name
|
|||
int cwmp_du_uninstall(char *package_name, char *env_name, int env_id, char **fault_code)
|
||||
{
|
||||
int e;
|
||||
e = cwmp_ubus_call("swmodules", "du_uninstall", CWMP_UBUS_ARGS{ { "ee_name", {.str_val = env_name }, UBUS_String }, { "eeid", {.int_val = env_id }, UBUS_Integer }, { "du_name", {.str_val = package_name }, UBUS_String } }, 3, ubus_du_state_callback, fault_code);
|
||||
struct blob_buf b = { 0 };
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
|
||||
bb_add_string(&b, "ee_name", env_name);
|
||||
blobmsg_add_u32(&b, "eeid", env_id);
|
||||
bb_add_string(&b, "du_name", package_name);
|
||||
|
||||
e = icwmp_ubus_invoke("swmodules", "du_uninstall", b.head, ubus_du_state_callback, fault_code);
|
||||
blob_buf_free(&b);
|
||||
|
||||
if (e < 0) {
|
||||
CWMP_LOG(INFO, "Change du state uninstall failed: Ubus err code: %d", e);
|
||||
return FAULT_CPE_INTERNAL_ERROR;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include <libubox/blobmsg_json.h>
|
||||
|
||||
#include "datamodel_interface.h"
|
||||
#include "ubus.h"
|
||||
#include "ubus_utils.h"
|
||||
#include "log.h"
|
||||
|
||||
int transaction_id = 0;
|
||||
|
|
@ -200,7 +200,13 @@ bool cwmp_transaction_start(char *app)
|
|||
{
|
||||
CWMP_LOG(INFO, "Starting transaction ...");
|
||||
bool status = false;
|
||||
int e = cwmp_ubus_call(USP_OBJECT_NAME, "transaction_start", CWMP_UBUS_ARGS{ { "app", { .str_val = app }, UBUS_String } }, 1, ubus_transaction_callback, &status);
|
||||
struct blob_buf b = { 0 };
|
||||
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
bb_add_string(&b, "app", app);
|
||||
|
||||
int e = icwmp_ubus_invoke(USP_OBJECT_NAME, "transaction_start", b.head, ubus_transaction_callback, &status);
|
||||
if (e != 0) {
|
||||
CWMP_LOG(INFO, "Transaction start failed: Ubus err code: %d", e);
|
||||
status = false;
|
||||
|
|
@ -208,6 +214,8 @@ bool cwmp_transaction_start(char *app)
|
|||
if (!status) {
|
||||
CWMP_LOG(INFO, "Transaction Start doesn't success\n");
|
||||
}
|
||||
|
||||
blob_buf_free(&b);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
@ -215,7 +223,14 @@ bool cwmp_transaction_commit()
|
|||
{
|
||||
CWMP_LOG(INFO, "Transaction Commit ...");
|
||||
bool status = false;
|
||||
int e = cwmp_ubus_call(USP_OBJECT_NAME, "transaction_commit", CWMP_UBUS_ARGS{ { "transaction_id", { .int_val = transaction_id }, UBUS_Integer }, { "restart_services", { .bool_val = false }, UBUS_Bool } }, 2, ubus_transaction_commit_callback, &status);
|
||||
struct blob_buf b = { 0 };
|
||||
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
blobmsg_add_u32(&b, "transaction_id", transaction_id);
|
||||
blobmsg_add_u8(&b, "restart_service", false);
|
||||
|
||||
int e = icwmp_ubus_invoke(USP_OBJECT_NAME, "transaction_commit", b.head, ubus_transaction_commit_callback, &status);
|
||||
if (e != 0) {
|
||||
CWMP_LOG(INFO, "Transaction commit failed: Ubus err code: %d", e);
|
||||
status = false;
|
||||
|
|
@ -224,6 +239,7 @@ bool cwmp_transaction_commit()
|
|||
CWMP_LOG(INFO, "Transaction Commit with id: %d doesn't success\n", transaction_id);
|
||||
}
|
||||
|
||||
blob_buf_free(&b);
|
||||
transaction_id = 0;
|
||||
return status;
|
||||
}
|
||||
|
|
@ -232,7 +248,13 @@ bool cwmp_transaction_abort()
|
|||
{
|
||||
CWMP_LOG(INFO, "Transaction Abort ...");
|
||||
bool status = false;
|
||||
int e = cwmp_ubus_call(USP_OBJECT_NAME, "transaction_abort", CWMP_UBUS_ARGS{ { "transaction_id", { .int_val = transaction_id }, UBUS_Integer } }, 1, ubus_transaction_callback, &status);
|
||||
struct blob_buf b = { 0 };
|
||||
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
blobmsg_add_u32(&b, "transaction_id", transaction_id);
|
||||
|
||||
int e = icwmp_ubus_invoke(USP_OBJECT_NAME, "transaction_abort", b.head, ubus_transaction_callback, &status);
|
||||
if (e != 0) {
|
||||
CWMP_LOG(INFO, "Transaction abort failed: Ubus err code: %d", e);
|
||||
status = false;
|
||||
|
|
@ -240,6 +262,8 @@ bool cwmp_transaction_abort()
|
|||
if (!status) {
|
||||
CWMP_LOG(INFO, "Transaction Abort of transaction with id: %d failed\n", transaction_id);
|
||||
}
|
||||
|
||||
blob_buf_free(&b);
|
||||
transaction_id = 0;
|
||||
return status;
|
||||
}
|
||||
|
|
@ -248,7 +272,15 @@ bool cwmp_transaction_status()
|
|||
{
|
||||
CWMP_LOG(INFO, "Transaction Status");
|
||||
bool status = false;
|
||||
int e = cwmp_ubus_call(USP_OBJECT_NAME, "transaction_status", CWMP_UBUS_ARGS{ { "transaction_id", { .int_val = transaction_id }, UBUS_Integer } }, 1, ubus_transaction_status_callback, &status);
|
||||
struct blob_buf b = { 0 };
|
||||
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
blobmsg_add_u32(&b, "transaction_id", transaction_id);
|
||||
|
||||
int e = icwmp_ubus_invoke(USP_OBJECT_NAME, "transaction_status", b.head, ubus_transaction_status_callback, &status);
|
||||
blob_buf_free(&b);
|
||||
|
||||
if (e != 0) {
|
||||
CWMP_LOG(INFO, "Transaction status failed: Ubus err code: %d", e);
|
||||
return false;
|
||||
|
|
@ -293,7 +325,17 @@ char *cwmp_get_single_parameter_value(char *parameter_name, struct cwmp_dm_param
|
|||
{
|
||||
int e;
|
||||
struct cwmp *cwmp = &cwmp_main;
|
||||
e = cwmp_ubus_call(USP_OBJECT_NAME, "get", CWMP_UBUS_ARGS{ { "path", { .str_val = !parameter_name || parameter_name[0] == '\0' ? DM_ROOT_OBJ : parameter_name }, UBUS_String }, { "proto", { .str_val = "cwmp" }, UBUS_String }, { "instance_mode", { .int_val = cwmp->conf.instance_mode }, UBUS_Integer } }, 3, ubus_get_single_parameter_callback, dm_parameter);
|
||||
struct blob_buf b = { 0 };
|
||||
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
bb_add_string(&b, "path", !parameter_name || parameter_name[0] == '\0' ? DM_ROOT_OBJ : parameter_name);
|
||||
bb_add_string(&b, "proto", "cwmp");
|
||||
blobmsg_add_u32(&b, "instance_mode", cwmp->conf.instance_mode);
|
||||
|
||||
e = icwmp_ubus_invoke(USP_OBJECT_NAME, "get", b.head, ubus_get_single_parameter_callback, dm_parameter);
|
||||
blob_buf_free(&b);
|
||||
|
||||
if (e < 0) {
|
||||
CWMP_LOG(INFO, "get ubus method failed: Ubus err code: %d", e);
|
||||
return "9002";
|
||||
|
|
@ -370,7 +412,17 @@ char *cwmp_get_parameter_values(char *parameter_name, struct list_head *paramete
|
|||
int e;
|
||||
struct cwmp *cwmp = &cwmp_main;
|
||||
struct list_params_result get_result = { .parameters_list = parameters_list };
|
||||
e = cwmp_ubus_call(USP_OBJECT_NAME, "get", CWMP_UBUS_ARGS{ { "path", { .str_val = !parameter_name || parameter_name[0] == '\0' ? DM_ROOT_OBJ : parameter_name }, UBUS_String }, { "proto", { .str_val = "cwmp" }, UBUS_String }, { "instance_mode", { .int_val = cwmp->conf.instance_mode }, UBUS_Integer } }, 3, ubus_get_parameter_callback, &get_result);
|
||||
struct blob_buf b = { 0 };
|
||||
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
bb_add_string(&b, "path", !parameter_name || parameter_name[0] == '\0' ? DM_ROOT_OBJ : parameter_name);
|
||||
bb_add_string(&b, "proto", "cwmp");
|
||||
blobmsg_add_u32(&b, "instance_mode", cwmp->conf.instance_mode);
|
||||
|
||||
e = icwmp_ubus_invoke(USP_OBJECT_NAME, "get", b.head, ubus_get_parameter_callback, &get_result);
|
||||
blob_buf_free(&b);
|
||||
|
||||
if (e < 0) {
|
||||
CWMP_LOG(INFO, "get ubus method failed: Ubus err code: %d", e);
|
||||
return "9002";
|
||||
|
|
@ -387,8 +439,24 @@ char *cwmp_get_multiple_parameters_values(struct list_head *arg_params_list, str
|
|||
{
|
||||
int e;
|
||||
struct cwmp *cwmp = &cwmp_main;
|
||||
struct cwmp_dm_parameter *param_value;
|
||||
struct list_params_result get_result = { .parameters_list = parameters_list };
|
||||
e = cwmp_ubus_call(USP_OBJECT_NAME, "getm_values", CWMP_UBUS_ARGS{ { "paths", { .param_value_list = arg_params_list }, UBUS_List_Param_Get }, { "instance_mode", { .int_val = cwmp->conf.instance_mode }, UBUS_Integer } }, 2, ubus_get_parameter_callback, &get_result );
|
||||
struct blob_buf b = { 0 };
|
||||
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
void *arr = blobmsg_open_array(&b, "paths");
|
||||
list_for_each_entry (param_value, arg_params_list, list) {
|
||||
if (!param_value->name)
|
||||
break;
|
||||
blobmsg_add_string(&b, NULL, param_value->name);
|
||||
}
|
||||
blobmsg_close_array(&b, arr);
|
||||
blobmsg_add_u32(&b, "instance_mode", cwmp->conf.instance_mode);
|
||||
|
||||
e = icwmp_ubus_invoke(USP_OBJECT_NAME, "getm_values", b.head, ubus_get_parameter_callback, &get_result );
|
||||
blob_buf_free(&b);
|
||||
|
||||
if (e < 0) {
|
||||
CWMP_LOG(INFO, "getm_values ubus method failed: Ubus err code: %d", e);
|
||||
return "9002";
|
||||
|
|
@ -406,7 +474,18 @@ char *cwmp_get_parameter_names(char *object_name, bool next_level, struct list_h
|
|||
int e;
|
||||
struct list_params_result get_result = { .parameters_list = parameters_list };
|
||||
struct cwmp *cwmp = &cwmp_main;
|
||||
e = cwmp_ubus_call(USP_OBJECT_NAME, "object_names", CWMP_UBUS_ARGS{ { "path", { .str_val = object_name }, UBUS_String }, { "next-level", { .bool_val = next_level }, UBUS_Bool }, { "proto", { .str_val = "cwmp" }, UBUS_String }, { "instance_mode", { .int_val = cwmp->conf.instance_mode }, UBUS_Integer } }, 4, ubus_get_parameter_callback, &get_result);
|
||||
struct blob_buf b = { 0 };
|
||||
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
bb_add_string(&b, "path", object_name);
|
||||
blobmsg_add_u8(&b, "next-level", next_level);
|
||||
bb_add_string(&b, "proto", "cwmp");
|
||||
blobmsg_add_u32(&b, "instance_mode", cwmp->conf.instance_mode);
|
||||
|
||||
e = icwmp_ubus_invoke(USP_OBJECT_NAME, "object_names", b.head, ubus_get_parameter_callback, &get_result);
|
||||
blob_buf_free(&b);
|
||||
|
||||
if (e < 0) {
|
||||
CWMP_LOG(INFO, "object_names ubus method failed: Ubus err code: %d", e);
|
||||
return "9002";
|
||||
|
|
@ -456,11 +535,30 @@ void ubus_setm_values_callback(struct ubus_request *req, int type __attribute__(
|
|||
int cwmp_set_multiple_parameters_values(struct list_head *parameters_values_list, char *parameter_key, int *flag, struct list_head *faults_list)
|
||||
{
|
||||
int e;
|
||||
struct cwmp_dm_parameter *param_value;
|
||||
struct setm_values_res set_result = { .flag = flag, .faults_list = faults_list };
|
||||
struct cwmp *cwmp = &cwmp_main;
|
||||
e = cwmp_ubus_call(USP_OBJECT_NAME, "setm_values",
|
||||
CWMP_UBUS_ARGS{ { "pv_tuple", { .param_value_list = parameters_values_list }, UBUS_List_Param_Set }, { "key", { .str_val = parameter_key }, UBUS_String }, { "transaction_id", { .int_val = transaction_id }, UBUS_Integer }, { "proto", { .str_val = "cwmp" }, UBUS_String }, { "instance_mode", { .int_val = cwmp->conf.instance_mode }, UBUS_Integer } }, 5,
|
||||
ubus_setm_values_callback, &set_result);
|
||||
struct blob_buf b = { 0 };
|
||||
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
void *arr = blobmsg_open_array(&b, "pv_tuple");
|
||||
list_for_each_entry (param_value, parameters_values_list, list) {
|
||||
if (!param_value->name)
|
||||
break;
|
||||
void *tbl = blobmsg_open_table(&b, "");
|
||||
blobmsg_add_string(&b, "path", param_value->name);
|
||||
blobmsg_add_string(&b, "value", param_value->value);
|
||||
blobmsg_close_table(&b, tbl);
|
||||
}
|
||||
blobmsg_close_array(&b, arr);
|
||||
bb_add_string(&b, "key", parameter_key);
|
||||
blobmsg_add_u32(&b, "transaction_id", transaction_id);
|
||||
bb_add_string(&b, "proto", "cwmp");
|
||||
blobmsg_add_u32(&b, "instance_mode", cwmp->conf.instance_mode);
|
||||
|
||||
e = icwmp_ubus_invoke(USP_OBJECT_NAME, "setm_values", b.head, ubus_setm_values_callback, &set_result);
|
||||
blob_buf_free(&b);
|
||||
|
||||
if (e < 0) {
|
||||
CWMP_LOG(INFO, "setm_values ubus method failed: Ubus err code: %d", e);
|
||||
|
|
@ -506,13 +604,30 @@ void ubus_objects_callback(struct ubus_request *req, int type __attribute__((unu
|
|||
}
|
||||
}
|
||||
|
||||
static void prepare_add_delete_blobmsg(struct blob_buf *b, char *object_name, char *key)
|
||||
{
|
||||
if (b == NULL)
|
||||
return;
|
||||
|
||||
bb_add_string(b, "path", object_name);
|
||||
bb_add_string(b, "key", key);
|
||||
blobmsg_add_u32(b, "transaction_id", transaction_id);
|
||||
bb_add_string(b, "proto", "cwmp");
|
||||
blobmsg_add_u32(b, "instance_mode", cwmp_main.conf.instance_mode);
|
||||
}
|
||||
|
||||
char *cwmp_add_object(char *object_name, char *key, char **instance)
|
||||
{
|
||||
int e;
|
||||
struct cwmp *cwmp = &cwmp_main;
|
||||
struct object_result add_result = { .instance = instance };
|
||||
e = cwmp_ubus_call(USP_OBJECT_NAME, "add_object", CWMP_UBUS_ARGS{ { "path", { .str_val = object_name }, UBUS_String }, { "key", { .str_val = key }, UBUS_String }, { "transaction_id", { .int_val = transaction_id }, UBUS_Integer }, { "proto", { .str_val = "cwmp" }, UBUS_String }, { "instance_mode", { .int_val = cwmp->conf.instance_mode }, UBUS_Integer } }, 5,
|
||||
ubus_objects_callback, &add_result);
|
||||
struct blob_buf b = { 0 };
|
||||
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
prepare_add_delete_blobmsg(&b, object_name, key);
|
||||
|
||||
e = icwmp_ubus_invoke(USP_OBJECT_NAME, "add_object", b.head, ubus_objects_callback, &add_result);
|
||||
blob_buf_free(&b);
|
||||
|
||||
if (e < 0) {
|
||||
CWMP_LOG(INFO, "add_object ubus method failed: Ubus err code: %d", e);
|
||||
|
|
@ -529,9 +644,15 @@ char *cwmp_delete_object(char *object_name, char *key)
|
|||
{
|
||||
int e;
|
||||
struct object_result add_result = { .instance = NULL };
|
||||
struct cwmp *cwmp = &cwmp_main;
|
||||
e = cwmp_ubus_call(USP_OBJECT_NAME, "del_object", CWMP_UBUS_ARGS{ { "path", { .str_val = object_name }, UBUS_String }, { "key", { .str_val = key }, UBUS_String }, { "transaction_id", { .int_val = transaction_id }, UBUS_Integer }, { "proto", { .str_val = "cwmp" }, UBUS_String }, { "instance_mode", { .int_val = cwmp->conf.instance_mode }, UBUS_Integer } }, 5,
|
||||
ubus_objects_callback, &add_result);
|
||||
struct blob_buf b = { 0 };
|
||||
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
prepare_add_delete_blobmsg(&b, object_name, key);
|
||||
|
||||
e = icwmp_ubus_invoke(USP_OBJECT_NAME, "del_object", b.head, ubus_objects_callback, &add_result);
|
||||
blob_buf_free(&b);
|
||||
|
||||
if (e < 0) {
|
||||
CWMP_LOG(INFO, "del_object ubus method failed: Ubus err code: %d", e);
|
||||
return "9002";
|
||||
|
|
|
|||
17
diagnostic.c
17
diagnostic.c
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
#include "common.h"
|
||||
#include "diagnostic.h"
|
||||
#include "ubus.h"
|
||||
#include "ubus_utils.h"
|
||||
#include "log.h"
|
||||
#include "event.h"
|
||||
|
||||
|
|
@ -146,14 +146,23 @@ void empty_ubus_callback(struct ubus_request *req __attribute__((unused)), int t
|
|||
static int cwmp_diagnostics_operate(char *diagnostics_object, char *action_name, struct diagnostic_input diagnostics_array[], int number_inputs)
|
||||
{
|
||||
int e, i;
|
||||
struct blob_buf b = { 0 };
|
||||
|
||||
LIST_HEAD(diagnostics_param_value_list);
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
bb_add_string(&b, "path", diagnostics_object);
|
||||
bb_add_string(&b, "action", action_name);
|
||||
void *tbl = blobmsg_open_table(&b, "input");
|
||||
for (i = 0; i < number_inputs; i++) {
|
||||
if (diagnostics_array[i].value == NULL || diagnostics_array[i].value[0] == '\0')
|
||||
continue;
|
||||
add_dm_parameter_to_list(&diagnostics_param_value_list, diagnostics_array[i].input_name, diagnostics_array[i].value, NULL, 0, false);
|
||||
bb_add_string(&b, diagnostics_array[i].input_name, diagnostics_array[i].value);
|
||||
}
|
||||
e = cwmp_ubus_call(USP_OBJECT_NAME, "operate", CWMP_UBUS_ARGS{ { "path", {.str_val = diagnostics_object }, UBUS_String }, { "action", {.str_val = action_name }, UBUS_String }, { "input", {.param_value_list = &diagnostics_param_value_list }, UBUS_Obj_Obj } }, 3, empty_ubus_callback, NULL);
|
||||
blobmsg_close_table(&b, tbl);
|
||||
|
||||
e = icwmp_ubus_invoke(USP_OBJECT_NAME, "operate", b.head, empty_ubus_callback, NULL);
|
||||
blob_buf_free(&b);
|
||||
|
||||
if (e)
|
||||
return -1;
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -67,16 +67,12 @@ The value of this property **must** be equal to one of the [known values below](
|
|||
|
||||
| Value |
|
||||
| ------------------ |
|
||||
| reload_end_session |
|
||||
| reload |
|
||||
| reboot_end_session |
|
||||
| action_end_session |
|
||||
| exit |
|
||||
|
||||
### Ubus CLI Example
|
||||
|
||||
```
|
||||
ubus call tr069 command {"command":"reboot_end_session"}
|
||||
ubus call tr069 command {"command":"reload"}
|
||||
```
|
||||
|
||||
### JSONRPC Example
|
||||
|
|
@ -86,7 +82,7 @@ ubus call tr069 command {"command":"reboot_end_session"}
|
|||
"jsonrpc": "2.0",
|
||||
"id": 0,
|
||||
"method": "call",
|
||||
"params": ["<SID>", "tr069", "command", { "command": "reboot_end_session" }]
|
||||
"params": ["<SID>", "tr069", "command", { "command": "reload" }]
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
|||
37
download.c
37
download.c
|
|
@ -13,7 +13,7 @@
|
|||
#include <libubox/blobmsg_json.h>
|
||||
|
||||
#include "download.h"
|
||||
#include "ubus.h"
|
||||
#include "ubus_utils.h"
|
||||
#include "cwmp_uci.h"
|
||||
#include "backupSession.h"
|
||||
#include "cwmp_time.h"
|
||||
|
|
@ -86,12 +86,17 @@ void ubus_check_image_callback(struct ubus_request *req, int type __attribute__(
|
|||
int cwmp_check_image()
|
||||
{
|
||||
int code = 0, e;
|
||||
struct blob_buf b = { 0 };
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
|
||||
CWMP_LOG(INFO, "Check downloaded image ...");
|
||||
e = cwmp_ubus_call("rpc-sys", "upgrade_test", CWMP_UBUS_ARGS{ {} }, 0, ubus_check_image_callback, &code);
|
||||
e = icwmp_ubus_invoke("rpc-sys", "upgrade_test", b.head, ubus_check_image_callback, &code);
|
||||
if (e != 0) {
|
||||
CWMP_LOG(INFO, "rpc-sys upbrade_test ubus method failed: Ubus err code: %d", e);
|
||||
code = 1;
|
||||
}
|
||||
blob_buf_free(&b);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
@ -133,10 +138,16 @@ void ubus_get_available_bank_callback(struct ubus_request *req, int type __attri
|
|||
int get_available_bank_id()
|
||||
{
|
||||
int bank_id = 0, e;
|
||||
e = cwmp_ubus_call("fwbank", "dump", CWMP_UBUS_ARGS{ {} }, 0, ubus_get_available_bank_callback, &bank_id);
|
||||
struct blob_buf b = { 0 };
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
|
||||
e = icwmp_ubus_invoke("fwbank", "dump", b.head, ubus_get_available_bank_callback, &bank_id);
|
||||
if (e != 0) {
|
||||
CWMP_LOG(INFO, "fwbank dump ubus method failed: Ubus err code: %d", e);
|
||||
}
|
||||
|
||||
blob_buf_free(&b);
|
||||
return bank_id;
|
||||
}
|
||||
|
||||
|
|
@ -146,11 +157,18 @@ int get_available_bank_id()
|
|||
int cwmp_apply_firmware()
|
||||
{
|
||||
int e;
|
||||
struct blob_buf b = { 0 };
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
blobmsg_add_u8(&b, "keep", true);
|
||||
|
||||
CWMP_LOG(INFO, "Apply downloaded image ...");
|
||||
e = cwmp_ubus_call("rpc-sys", "upgrade_start", CWMP_UBUS_ARGS{ { "keep", { .bool_val = true }, UBUS_Bool } }, 1, NULL, NULL);
|
||||
e = icwmp_ubus_invoke("rpc-sys", "upgrade_start", b.head, NULL, NULL);
|
||||
if (e != 0) {
|
||||
CWMP_LOG(INFO, "rpc-sys upgrade_start ubus method failed: Ubus err code: %d", e);
|
||||
}
|
||||
|
||||
blob_buf_free(&b);
|
||||
return e;
|
||||
}
|
||||
|
||||
|
|
@ -161,7 +179,16 @@ int cwmp_apply_multiple_firmware()
|
|||
if (bank_id <= 0)
|
||||
return -1;
|
||||
|
||||
e = cwmp_ubus_call("fwbank", "upgrade", CWMP_UBUS_ARGS{ { "path", { .str_val = FIRMWARE_UPGRADE_IMAGE }, UBUS_String }, { "auto_activate", { .bool_val = false }, UBUS_Bool }, { "bank", { .int_val = bank_id }, UBUS_Integer } }, 3, NULL, NULL);
|
||||
struct blob_buf b = { 0 };
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
bb_add_string(&b, "path", FIRMWARE_UPGRADE_IMAGE);
|
||||
blobmsg_add_u8(&b, "auto_activate", false);
|
||||
blobmsg_add_u32(&b, "bank", bank_id);
|
||||
|
||||
e = icwmp_ubus_invoke("fwbank", "upgrade", b.head, NULL, NULL);
|
||||
blob_buf_free(&b);
|
||||
|
||||
if (e != 0) {
|
||||
CWMP_LOG(INFO, "fwbank upgrade ubus method failed: Ubus err code: %d", e);
|
||||
return -1;
|
||||
|
|
|
|||
9
http.c
9
http.c
|
|
@ -19,7 +19,7 @@
|
|||
#include "cwmp_uci.h"
|
||||
#include "log.h"
|
||||
#include "event.h"
|
||||
#include "ubus.h"
|
||||
#include "ubus_utils.h"
|
||||
#include "config.h"
|
||||
#include "digestauth.h"
|
||||
|
||||
|
|
@ -236,7 +236,12 @@ int http_send_message(struct cwmp *cwmp, char *msg_out, int msg_out_len, char **
|
|||
cwmp_commit_package("cwmp", UCI_VARSTATE_CONFIG);
|
||||
|
||||
// Trigger firewall to reload firewall.cwmp
|
||||
cwmp_ubus_call("uci", "commit", CWMP_UBUS_ARGS{ { "config", { .str_val = "firewall" }, UBUS_String } }, 1, NULL, NULL);
|
||||
struct blob_buf b = { 0 };
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
bb_add_string(&b, "config", "firewall");
|
||||
icwmp_ubus_invoke("uci", "commit", b.head, NULL, NULL);
|
||||
blob_buf_free(&b);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,8 +52,6 @@
|
|||
#define STRCMP(S1, S2) ((S1 != NULL && S2 != NULL) ? strcmp(S1, S2) : -1)
|
||||
extern char *commandKey;
|
||||
extern bool thread_end;
|
||||
extern bool signal_exit;
|
||||
extern bool ubus_exit;
|
||||
|
||||
typedef struct env {
|
||||
unsigned short boot;
|
||||
|
|
|
|||
67
inc/ubus.h
67
inc/ubus.h
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* 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) 2013-2020 iopsys Software Solutions AB
|
||||
* Author Omar Kallel <omar.kallel@pivasoftware.com>
|
||||
*
|
||||
* Copyright (C) 2012 Luka Perkov <freecwmp@lukaperkov.net>
|
||||
*/
|
||||
#ifndef _FREECWMP_UBUS_H__
|
||||
#define _FREECWMP_UBUS_H__
|
||||
#include <libubus.h>
|
||||
/*
|
||||
#include <json-c/json.h>
|
||||
#include <libubox/blobmsg_json.h>
|
||||
|
||||
#include "common.h"
|
||||
*/
|
||||
#include "common.h"
|
||||
|
||||
#define ARRAY_MAX 8
|
||||
|
||||
int cwmp_ubus_init(struct cwmp *cwmp);
|
||||
void cwmp_ubus_exit(void);
|
||||
|
||||
enum cwmp_ubus_arg_type
|
||||
{
|
||||
UBUS_String,
|
||||
UBUS_Integer,
|
||||
UBUS_Array_Obj,
|
||||
UBUS_Array_Str,
|
||||
UBUS_Obj_Obj,
|
||||
UBUS_List_Param_Set,
|
||||
UBUS_List_Param_Get,
|
||||
UBUS_Bool,
|
||||
};
|
||||
|
||||
struct key_value {
|
||||
char *key;
|
||||
char *value;
|
||||
};
|
||||
|
||||
union array_membre {
|
||||
char *str_value;
|
||||
struct key_value param_value;
|
||||
};
|
||||
|
||||
union ubus_value {
|
||||
char *str_val;
|
||||
int int_val;
|
||||
bool bool_val;
|
||||
union array_membre array_value[ARRAY_MAX];
|
||||
struct list_head *param_value_list;
|
||||
};
|
||||
|
||||
struct cwmp_ubus_arg {
|
||||
const char *key;
|
||||
const union ubus_value val;
|
||||
enum cwmp_ubus_arg_type type;
|
||||
};
|
||||
|
||||
#define CWMP_UBUS_ARGS (struct cwmp_ubus_arg[])
|
||||
int cwmp_ubus_call(const char *obj, const char *method, const struct cwmp_ubus_arg u_args[], int u_args_size, void (*ubus_callback)(struct ubus_request *req, int type, struct blob_attr *msg), void *callback_arg);
|
||||
|
||||
#endif /* UBUS_H_ */
|
||||
50
inc/ubus_utils.h
Normal file
50
inc/ubus_utils.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2022, IOPSYS Software Solutions AB.
|
||||
*
|
||||
* Author: suvendhu.hansa@iopsys.eu
|
||||
*
|
||||
* 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 the copyright holder 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 HOLDER 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ICWMP_UBUS_UTILS_H__
|
||||
#define __ICWMP_UBUS_UTILS_H__
|
||||
|
||||
#include <libubus.h>
|
||||
#include "common.h"
|
||||
|
||||
typedef void (*icwmp_ubus_cb)(struct ubus_request *req, int type, struct blob_attr *msg);
|
||||
|
||||
void bb_add_string(struct blob_buf *bb, const char *name, const char *value);
|
||||
int icwmp_register_object(struct ubus_context *ctx);
|
||||
int icwmp_delete_object(struct ubus_context *ctx);
|
||||
int icwmp_ubus_invoke(const char *obj, const char *method, struct blob_attr *msg,
|
||||
icwmp_ubus_cb icwmp_callback, void *callback_arg);
|
||||
|
||||
#endif /* __ICWMP_UBUS_UTILS_H__ */
|
||||
|
|
@ -4,11 +4,7 @@
|
|||
"type": "string",
|
||||
"description": "CWMP supported commands",
|
||||
"enum": [
|
||||
"reload_end_session",
|
||||
"reload",
|
||||
"reboot_end_session",
|
||||
"action_end_session",
|
||||
"exit"
|
||||
"reload"
|
||||
]
|
||||
},
|
||||
"event_t": {
|
||||
|
|
|
|||
|
|
@ -172,28 +172,6 @@
|
|||
"method": "status",
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "command",
|
||||
"args": {
|
||||
"command": "reload_end_session"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "status",
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "command",
|
||||
"args": {
|
||||
"command": "action_end_session"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "status",
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "command",
|
||||
"args": {
|
||||
|
|
|
|||
403
ubus.c
403
ubus.c
|
|
@ -1,403 +0,0 @@
|
|||
/*
|
||||
* 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) 2013-2021 iopsys Software Solutions AB
|
||||
* Author Mohamed Kallel <mohamed.kallel@pivasoftware.com>
|
||||
* Author Ahmed Zribi <ahmed.zribi@pivasoftware.com>
|
||||
* Author Omar Kallel <omar.kallel@pivasoftware.com>
|
||||
* Copyright (C) 2012 Luka Perkov <freecwmp@lukaperkov.net>
|
||||
*/
|
||||
|
||||
#include <json-c/json.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/socket.h>
|
||||
#include <libubox/blobmsg_json.h>
|
||||
|
||||
#include "ubus.h"
|
||||
#include "session.h"
|
||||
#include "log.h"
|
||||
#include "sched_inform.h"
|
||||
#include "http.h"
|
||||
#include "download.h"
|
||||
#include "upload.h"
|
||||
#include "cwmp_du_state.h"
|
||||
#include "netlink.h"
|
||||
#include "event.h"
|
||||
#include "cwmp_time.h"
|
||||
|
||||
static struct ubus_context *ctx = NULL;
|
||||
|
||||
static const char *arr_session_status[] = {
|
||||
[SESSION_WAITING] = "waiting",
|
||||
[SESSION_RUNNING] = "running",
|
||||
[SESSION_FAILURE] = "failure",
|
||||
[SESSION_SUCCESS] = "success",
|
||||
};
|
||||
|
||||
enum command
|
||||
{
|
||||
COMMAND_NAME,
|
||||
__COMMAND_MAX
|
||||
};
|
||||
|
||||
static const struct blobmsg_policy command_policy[] = {
|
||||
[COMMAND_NAME] = {.name = "command", .type = BLOBMSG_TYPE_STRING },
|
||||
};
|
||||
|
||||
static int cwmp_handle_command(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), struct ubus_request_data *req, const char *method __attribute__((unused)), struct blob_attr *msg)
|
||||
{
|
||||
struct blob_attr *tb[__COMMAND_MAX];
|
||||
struct blob_buf blob_command;
|
||||
|
||||
blobmsg_parse(command_policy, ARRAYSIZEOF(command_policy), tb, blob_data(msg), blob_len(msg));
|
||||
|
||||
if (!tb[COMMAND_NAME])
|
||||
return UBUS_STATUS_INVALID_ARGUMENT;
|
||||
|
||||
memset(&blob_command, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&blob_command, 0);
|
||||
|
||||
char *cmd = blobmsg_data(tb[COMMAND_NAME]);
|
||||
char info[128] = {0};
|
||||
|
||||
if (!strcmp("reload_end_session", cmd)) {
|
||||
CWMP_LOG(INFO, "triggered ubus reload_end_session");
|
||||
cwmp_set_end_session(END_SESSION_RELOAD);
|
||||
blobmsg_add_u32(&blob_command, "status", 0);
|
||||
if (snprintf(info, sizeof(info), "icwmpd config will reload at the end of the session") == -1)
|
||||
return -1;
|
||||
} else if (!strcmp("reload", cmd)) {
|
||||
CWMP_LOG(INFO, "triggered ubus reload");
|
||||
if (cwmp_main.session_status.last_status == SESSION_RUNNING) {
|
||||
cwmp_set_end_session(END_SESSION_RELOAD);
|
||||
blobmsg_add_u32(&blob_command, "status", 0);
|
||||
if (snprintf(info, sizeof(info), "Session running, reload at the end of the session") == -1)
|
||||
return -1;
|
||||
} else {
|
||||
pthread_mutex_lock(&(cwmp_main.mutex_session_queue));
|
||||
cwmp_apply_acs_changes();
|
||||
pthread_mutex_unlock(&(cwmp_main.mutex_session_queue));
|
||||
blobmsg_add_u32(&blob_command, "status", 0);
|
||||
if (snprintf(info, sizeof(info), "icwmpd config reloaded") == -1)
|
||||
return -1;
|
||||
}
|
||||
} else if (!strcmp("reboot_end_session", cmd)) {
|
||||
CWMP_LOG(INFO, "triggered ubus reboot_end_session");
|
||||
cwmp_set_end_session(END_SESSION_REBOOT);
|
||||
blobmsg_add_u32(&blob_command, "status", 0);
|
||||
if (snprintf(info, sizeof(info), "icwmpd will reboot at the end of the session") == -1)
|
||||
return -1;
|
||||
} else if (!strcmp("action_end_session", cmd)) {
|
||||
CWMP_LOG(INFO, "triggered ubus action_end_session");
|
||||
cwmp_set_end_session(END_SESSION_EXTERNAL_ACTION);
|
||||
blobmsg_add_u32(&blob_command, "status", 0);
|
||||
if (snprintf(info, sizeof(info), "icwmpd will execute the scheduled action commands at the end of the session") == -1)
|
||||
return -1;
|
||||
} else if (!strcmp("exit", cmd)) {
|
||||
ubus_exit = true;
|
||||
thread_end = true;
|
||||
|
||||
if (cwmp_main.session_status.last_status == SESSION_RUNNING)
|
||||
http_set_timeout();
|
||||
|
||||
pthread_cond_signal(&(cwmp_main.threshold_session_send));
|
||||
pthread_cond_signal(&(cwmp_main.threshold_periodic));
|
||||
pthread_cond_signal(&(cwmp_main.threshold_notify_periodic));
|
||||
pthread_cond_signal(&threshold_schedule_inform);
|
||||
pthread_cond_signal(&threshold_download);
|
||||
pthread_cond_signal(&threshold_change_du_state);
|
||||
pthread_cond_signal(&threshold_schedule_download);
|
||||
pthread_cond_signal(&threshold_apply_schedule_download);
|
||||
pthread_cond_signal(&threshold_upload);
|
||||
|
||||
uloop_end();
|
||||
|
||||
shutdown(cwmp_main.cr_socket_desc, SHUT_RDWR);
|
||||
|
||||
if (!signal_exit)
|
||||
kill(getpid(), SIGTERM);
|
||||
|
||||
if (snprintf(info, sizeof(info), "icwmpd daemon stopped") == -1)
|
||||
return -1;
|
||||
} else {
|
||||
blobmsg_add_u32(&blob_command, "status", -1);
|
||||
if (snprintf(info, sizeof(info), "%s command is not supported", cmd) == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
blobmsg_add_string(&blob_command, "info", info);
|
||||
ubus_send_reply(ctx, req, blob_command.head);
|
||||
blob_buf_free(&blob_command);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline time_t get_session_status_next_time()
|
||||
{
|
||||
time_t ntime = 0;
|
||||
if (list_schedule_inform.next != &(list_schedule_inform)) {
|
||||
struct schedule_inform *schedule_inform;
|
||||
schedule_inform = list_entry(list_schedule_inform.next, struct schedule_inform, list);
|
||||
ntime = schedule_inform->scheduled_time;
|
||||
}
|
||||
if (!ntime || (cwmp_main.session_status.next_retry && ntime > cwmp_main.session_status.next_retry)) {
|
||||
ntime = cwmp_main.session_status.next_retry;
|
||||
}
|
||||
if (!ntime || (cwmp_main.session_status.next_periodic && ntime > cwmp_main.session_status.next_periodic)) {
|
||||
ntime = cwmp_main.session_status.next_periodic;
|
||||
}
|
||||
return ntime;
|
||||
}
|
||||
|
||||
static int cwmp_handle_status(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), struct ubus_request_data *req, const char *method __attribute__((unused)), struct blob_attr *msg __attribute__((unused)))
|
||||
{
|
||||
void *c;
|
||||
time_t ntime = 0;
|
||||
struct blob_buf blob_status;
|
||||
|
||||
memset(&blob_status, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&blob_status, 0);
|
||||
|
||||
c = blobmsg_open_table(&blob_status, "cwmp");
|
||||
blobmsg_add_string(&blob_status, "status", "up");
|
||||
blobmsg_add_string(&blob_status, "start_time", mix_get_time_of(cwmp_main.start_time));
|
||||
blobmsg_add_string(&blob_status, "acs_url", cwmp_main.conf.acsurl);
|
||||
blobmsg_close_table(&blob_status, c);
|
||||
|
||||
c = blobmsg_open_table(&blob_status, "last_session");
|
||||
blobmsg_add_string(&blob_status, "status", cwmp_main.session_status.last_start_time ? arr_session_status[cwmp_main.session_status.last_status] : "N/A");
|
||||
blobmsg_add_string(&blob_status, "start_time", cwmp_main.session_status.last_start_time ? mix_get_time_of(cwmp_main.session_status.last_start_time) : "N/A");
|
||||
blobmsg_add_string(&blob_status, "end_time", cwmp_main.session_status.last_end_time ? mix_get_time_of(cwmp_main.session_status.last_end_time) : "N/A");
|
||||
blobmsg_close_table(&blob_status, c);
|
||||
|
||||
c = blobmsg_open_table(&blob_status, "next_session");
|
||||
blobmsg_add_string(&blob_status, "status", arr_session_status[SESSION_WAITING]);
|
||||
ntime = get_session_status_next_time();
|
||||
blobmsg_add_string(&blob_status, "start_time", ntime ? mix_get_time_of(ntime) : "N/A");
|
||||
blobmsg_add_string(&blob_status, "end_time", "N/A");
|
||||
blobmsg_close_table(&blob_status, c);
|
||||
|
||||
c = blobmsg_open_table(&blob_status, "statistics");
|
||||
blobmsg_add_u32(&blob_status, "success_sessions", cwmp_main.session_status.success_session);
|
||||
blobmsg_add_u32(&blob_status, "failure_sessions", cwmp_main.session_status.failure_session);
|
||||
blobmsg_add_u32(&blob_status, "total_sessions", cwmp_main.session_status.success_session + cwmp_main.session_status.failure_session);
|
||||
blobmsg_close_table(&blob_status, c);
|
||||
|
||||
ubus_send_reply(ctx, req, blob_status.head);
|
||||
blob_buf_free(&blob_status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum enum_inform
|
||||
{
|
||||
INFORM_GET_RPC_METHODS,
|
||||
INFORM_EVENT,
|
||||
__INFORM_MAX
|
||||
};
|
||||
|
||||
static const struct blobmsg_policy inform_policy[] = {
|
||||
[INFORM_GET_RPC_METHODS] = {.name = "GetRPCMethods", .type = BLOBMSG_TYPE_BOOL },
|
||||
[INFORM_EVENT] = {.name = "event", .type = BLOBMSG_TYPE_STRING },
|
||||
};
|
||||
|
||||
static int cwmp_handle_inform(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), struct ubus_request_data *req, const char *method __attribute__((unused)), struct blob_attr *msg)
|
||||
{
|
||||
struct blob_attr *tb[__INFORM_MAX];
|
||||
bool grm = false;
|
||||
char *event = "";
|
||||
struct blob_buf blob_inform;
|
||||
|
||||
memset(&blob_inform, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&blob_inform, 0);
|
||||
|
||||
blobmsg_parse(inform_policy, ARRAYSIZEOF(inform_policy), tb, blob_data(msg), blob_len(msg));
|
||||
|
||||
if (tb[INFORM_GET_RPC_METHODS]) {
|
||||
grm = blobmsg_data(tb[INFORM_GET_RPC_METHODS]);
|
||||
}
|
||||
if (tb[INFORM_EVENT]) {
|
||||
event = blobmsg_data(tb[INFORM_EVENT]);
|
||||
}
|
||||
if (grm) {
|
||||
struct event_container *event_container;
|
||||
struct session *session;
|
||||
|
||||
pthread_mutex_lock(&(cwmp_main.mutex_session_queue));
|
||||
event_container = cwmp_add_event_container(&cwmp_main, EVENT_IDX_2PERIODIC, "");
|
||||
if (event_container == NULL) {
|
||||
pthread_mutex_unlock(&(cwmp_main.mutex_session_queue));
|
||||
return 0;
|
||||
}
|
||||
cwmp_save_event_container(event_container);
|
||||
session = list_entry(cwmp_main.head_event_container, struct session, head_event_container);
|
||||
if (cwmp_add_session_rpc_acs(session, RPC_ACS_GET_RPC_METHODS) == NULL) {
|
||||
pthread_mutex_unlock(&(cwmp_main.mutex_session_queue));
|
||||
return 0;
|
||||
}
|
||||
pthread_mutex_unlock(&(cwmp_main.mutex_session_queue));
|
||||
pthread_cond_signal(&(cwmp_main.threshold_session_send));
|
||||
blobmsg_add_u32(&blob_inform, "status", 1);
|
||||
blobmsg_add_string(&blob_inform, "info", "Session with GetRPCMethods will start");
|
||||
} else {
|
||||
int event_code = cwmp_get_int_event_code(event);
|
||||
pthread_mutex_lock(&(cwmp_main.mutex_session_queue));
|
||||
cwmp_add_event_container(&cwmp_main, event_code, "");
|
||||
pthread_mutex_unlock(&(cwmp_main.mutex_session_queue));
|
||||
pthread_cond_signal(&(cwmp_main.threshold_session_send));
|
||||
if (cwmp_main.session_status.last_status == SESSION_RUNNING) {
|
||||
blobmsg_add_u32(&blob_inform, "status", -1);
|
||||
blobmsg_add_string(&blob_inform, "info", "Session already running, event will be sent at the end of the session");
|
||||
} else {
|
||||
blobmsg_add_u32(&blob_inform, "status", 1);
|
||||
blobmsg_add_string(&blob_inform, "info", "Session started");
|
||||
}
|
||||
}
|
||||
ubus_send_reply(ctx, req, blob_inform.head);
|
||||
blob_buf_free(&blob_inform);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ubus_method freecwmp_methods[] = {
|
||||
UBUS_METHOD("command", cwmp_handle_command, command_policy),
|
||||
UBUS_METHOD_NOARG("status", cwmp_handle_status),
|
||||
UBUS_METHOD("inform", cwmp_handle_inform, inform_policy),
|
||||
};
|
||||
|
||||
static struct ubus_object_type main_object_type = UBUS_OBJECT_TYPE("freecwmpd", freecwmp_methods);
|
||||
|
||||
static struct ubus_object main_object = {
|
||||
.name = "tr069",
|
||||
.type = &main_object_type,
|
||||
.methods = freecwmp_methods,
|
||||
.n_methods = ARRAYSIZEOF(freecwmp_methods),
|
||||
};
|
||||
|
||||
int cwmp_ubus_init(struct cwmp *cwmp)
|
||||
{
|
||||
uloop_init();
|
||||
|
||||
if (netlink_init()) {
|
||||
CWMP_LOG(ERROR, "netlink initialization failed");
|
||||
}
|
||||
|
||||
if (cwmp->conf.ipv6_enable) {
|
||||
if (netlink_init_v6()) {
|
||||
CWMP_LOG(ERROR, "netlink initialization failed");
|
||||
}
|
||||
}
|
||||
ctx = ubus_connect(cwmp->conf.ubus_socket);
|
||||
if (!ctx)
|
||||
return -1;
|
||||
|
||||
ubus_add_uloop(ctx);
|
||||
|
||||
if (ubus_add_object(ctx, &main_object))
|
||||
return -1;
|
||||
|
||||
uloop_run();
|
||||
uloop_done();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cwmp_ubus_exit(void)
|
||||
{
|
||||
if (ctx) {
|
||||
ubus_remove_object(ctx, &main_object);
|
||||
ubus_free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
int cwmp_ubus_call(const char *obj, const char *method, const struct cwmp_ubus_arg u_args[], int u_args_size, void (*ubus_callback)(struct ubus_request *req, int type, struct blob_attr *msg), void *callback_arg)
|
||||
{
|
||||
uint32_t id;
|
||||
int i = 0;
|
||||
int rc = 0;
|
||||
struct blob_buf b = { 0 };
|
||||
|
||||
struct ubus_context *ubus_ctx = NULL;
|
||||
|
||||
ubus_ctx = ubus_connect(NULL);
|
||||
if (ubus_ctx == NULL)
|
||||
return -1;
|
||||
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
for (i = 0; i < u_args_size; i++) {
|
||||
if (u_args[i].type == UBUS_String)
|
||||
blobmsg_add_string(&b, u_args[i].key, u_args[i].val.str_val);
|
||||
else if (u_args[i].type == UBUS_Integer) {
|
||||
blobmsg_add_u32(&b, u_args[i].key, u_args[i].val.int_val);
|
||||
} else if (u_args[i].type == UBUS_Array_Obj || u_args[i].type == UBUS_Array_Str) {
|
||||
void *a;
|
||||
int j;
|
||||
a = blobmsg_open_array(&b, u_args[i].key);
|
||||
if (u_args[i].type == UBUS_Array_Obj) {
|
||||
void *t;
|
||||
t = blobmsg_open_table(&b, "");
|
||||
for (j = 0; j < ARRAY_MAX; j++) {
|
||||
if (u_args[i].val.array_value[j].param_value.key == NULL || strlen(u_args[i].val.array_value[j].param_value.key) == 0)
|
||||
break;
|
||||
blobmsg_add_string(&b, u_args[i].val.array_value[j].param_value.key, u_args[i].val.array_value[j].param_value.value);
|
||||
}
|
||||
blobmsg_close_table(&b, t);
|
||||
}
|
||||
if (u_args[i].type == UBUS_Array_Str) {
|
||||
for (j = 0; j < ARRAY_MAX; j++) {
|
||||
if (u_args[i].val.array_value[j].str_value == NULL || strlen(u_args[i].val.array_value[j].str_value) == 0)
|
||||
break;
|
||||
blobmsg_add_string(&b, NULL, u_args[i].val.array_value[j].str_value);
|
||||
}
|
||||
}
|
||||
blobmsg_close_array(&b, a);
|
||||
} else if (u_args[i].type == UBUS_List_Param_Set) {
|
||||
struct cwmp_dm_parameter *param_value;
|
||||
void *a;
|
||||
a = blobmsg_open_array(&b, u_args[i].key);
|
||||
list_for_each_entry (param_value, u_args[i].val.param_value_list, list) {
|
||||
void *t;
|
||||
if (!param_value->name)
|
||||
break;
|
||||
t = blobmsg_open_table(&b, "");
|
||||
blobmsg_add_string(&b, "path", param_value->name);
|
||||
blobmsg_add_string(&b, "value", param_value->value);
|
||||
blobmsg_close_table(&b, t);
|
||||
}
|
||||
blobmsg_close_array(&b, a);
|
||||
} else if (u_args[i].type == UBUS_List_Param_Get) {
|
||||
struct cwmp_dm_parameter *param_value;
|
||||
void *a;
|
||||
a = blobmsg_open_array(&b, u_args[i].key);
|
||||
list_for_each_entry (param_value, u_args[i].val.param_value_list, list) {
|
||||
if (!param_value->name)
|
||||
break;
|
||||
blobmsg_add_string(&b, NULL, param_value->name);
|
||||
}
|
||||
blobmsg_close_array(&b, a);
|
||||
} else if (u_args[i].type == UBUS_Obj_Obj) {
|
||||
struct cwmp_dm_parameter *param_value;
|
||||
json_object *input_json_obj = json_object_new_object();
|
||||
list_for_each_entry (param_value, u_args[i].val.param_value_list, list) {
|
||||
if (!param_value->name)
|
||||
break;
|
||||
json_object_object_add(input_json_obj, param_value->name, json_object_new_string(param_value->value));
|
||||
}
|
||||
blobmsg_add_json_element(&b, u_args[i].key, input_json_obj);
|
||||
} else if (u_args[i].type == UBUS_Bool)
|
||||
blobmsg_add_u8(&b, u_args[i].key, u_args[i].val.bool_val);
|
||||
}
|
||||
if (!ubus_lookup_id(ubus_ctx, obj, &id))
|
||||
rc = ubus_invoke(ubus_ctx, id, method, b.head, ubus_callback, callback_arg, 20000);
|
||||
else
|
||||
rc = -1;
|
||||
blob_buf_free(&b);
|
||||
if (ubus_ctx) {
|
||||
ubus_free(ubus_ctx);
|
||||
ubus_ctx = NULL;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
408
ubus_utils.c
Normal file
408
ubus_utils.c
Normal file
|
|
@ -0,0 +1,408 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2022, IOPSYS Software Solutions AB.
|
||||
*
|
||||
* Author: suvendhu.hansa@iopsys.eu
|
||||
*
|
||||
* 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 the copyright holder 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 HOLDER 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 "ubus_utils.h"
|
||||
#include "log.h"
|
||||
#include "sched_inform.h"
|
||||
#include "event.h"
|
||||
#include "cwmp_time.h"
|
||||
|
||||
typedef int (*callback)(struct blob_buf *b);
|
||||
|
||||
struct command_cb {
|
||||
char *str;
|
||||
callback cb;
|
||||
char *help;
|
||||
};
|
||||
|
||||
static const char *arr_session_status[] = {
|
||||
[SESSION_WAITING] = "waiting",
|
||||
[SESSION_RUNNING] = "running",
|
||||
[SESSION_FAILURE] = "failure",
|
||||
[SESSION_SUCCESS] = "success",
|
||||
};
|
||||
|
||||
static int reload_cmd(struct blob_buf *b)
|
||||
{
|
||||
CWMP_LOG(INFO, "triggered ubus reload");
|
||||
if (cwmp_main.session_status.last_status == SESSION_RUNNING) {
|
||||
cwmp_set_end_session(END_SESSION_RELOAD);
|
||||
blobmsg_add_u32(b, "status", 0);
|
||||
blobmsg_add_string(b, "info", "Session running, reload at the end of the session");
|
||||
} else {
|
||||
pthread_mutex_lock(&(cwmp_main.mutex_session_queue));
|
||||
cwmp_apply_acs_changes();
|
||||
pthread_mutex_unlock(&(cwmp_main.mutex_session_queue));
|
||||
blobmsg_add_u32(b, "status", 0);
|
||||
blobmsg_add_string(b, "info", "icwmpd config reloaded");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct command_cb cmd_cb[] ={
|
||||
{ "reload", reload_cmd, "Reload icwmpd with new configuration" }
|
||||
};
|
||||
|
||||
static int call_command_cb(char *cmd, struct blob_buf *b)
|
||||
{
|
||||
int cmd_num, i;
|
||||
callback cb = NULL;
|
||||
|
||||
if (cmd == NULL || b == NULL)
|
||||
return -1;
|
||||
|
||||
cmd_num = sizeof(cmd_cb)/sizeof(struct command_cb);
|
||||
for (i = 0; i < cmd_num; i++) {
|
||||
if (strcmp(cmd, cmd_cb[i].str) == 0) {
|
||||
cb = cmd_cb[i].cb;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cb == NULL) {
|
||||
char info[128] = {0};
|
||||
if (snprintf(info, sizeof(info), "\'%s\' is not supported. Check the supported commands.", cmd) == -1)
|
||||
return -1;
|
||||
|
||||
blobmsg_add_u32(b, "status", -1);
|
||||
blobmsg_add_string(b, "info", info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cb(b);
|
||||
}
|
||||
|
||||
enum command
|
||||
{
|
||||
COMMAND_NAME,
|
||||
__COMMAND_MAX
|
||||
};
|
||||
|
||||
static const struct blobmsg_policy icwmp_cmd_policy[] = {
|
||||
[COMMAND_NAME] = {.name = "command", .type = BLOBMSG_TYPE_STRING },
|
||||
};
|
||||
|
||||
static int icwmp_command_handler(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), struct ubus_request_data *req, const char *method __attribute__((unused)), struct blob_attr *msg)
|
||||
{
|
||||
struct blob_attr *tb[__COMMAND_MAX];
|
||||
struct blob_buf blob_command;
|
||||
|
||||
memset(&blob_command, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&blob_command, 0);
|
||||
|
||||
blobmsg_parse(icwmp_cmd_policy, ARRAYSIZEOF(icwmp_cmd_policy), tb, blob_data(msg), blob_len(msg));
|
||||
|
||||
if (!tb[COMMAND_NAME]) {
|
||||
int i;
|
||||
int cmd_num = sizeof(cmd_cb)/sizeof(struct command_cb);
|
||||
void *tbl = blobmsg_open_table(&blob_command, "SupportedCommands");
|
||||
for (i = 0; i < cmd_num; i++) {
|
||||
void *tbl_in = blobmsg_open_table(&blob_command, "");
|
||||
bb_add_string(&blob_command, "command", cmd_cb[i].str);
|
||||
bb_add_string(&blob_command, "description", cmd_cb[i].help);
|
||||
blobmsg_close_table(&blob_command, tbl_in);
|
||||
}
|
||||
blobmsg_close_table(&blob_command, tbl);
|
||||
goto send_reply;
|
||||
}
|
||||
|
||||
char *cmd = blobmsg_data(tb[COMMAND_NAME]);
|
||||
|
||||
if (call_command_cb(cmd, &blob_command) != 0) {
|
||||
blob_buf_free(&blob_command);
|
||||
return -1;
|
||||
}
|
||||
|
||||
send_reply:
|
||||
ubus_send_reply(ctx, req, blob_command.head);
|
||||
blob_buf_free(&blob_command);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static time_t get_nonzero_min_time(time_t time1, time_t time2, time_t time3)
|
||||
{
|
||||
time_t arr[] = { time1, time2, time3 };
|
||||
time_t min = 0;
|
||||
int i;
|
||||
int size = sizeof(arr)/sizeof(time_t);
|
||||
|
||||
for (i = 0; i < size && arr[i] == 0; i++); // find the first non zero element
|
||||
|
||||
if (i == size) {
|
||||
return min; // array has no non-zero values
|
||||
}
|
||||
|
||||
min = arr[i];
|
||||
for (; i < size; i++) {
|
||||
if (arr[i] != 0 && arr[i] < min)
|
||||
min = arr[i];
|
||||
}
|
||||
|
||||
return min;
|
||||
}
|
||||
|
||||
static time_t get_next_session_time()
|
||||
{
|
||||
time_t sched_time = 0;
|
||||
if (list_schedule_inform.next != &(list_schedule_inform)) {
|
||||
struct schedule_inform *schedule_inform;
|
||||
schedule_inform = list_entry(list_schedule_inform.next, struct schedule_inform, list);
|
||||
sched_time = schedule_inform->scheduled_time;
|
||||
}
|
||||
|
||||
time_t next_time = get_nonzero_min_time(sched_time, cwmp_main.session_status.next_retry, cwmp_main.session_status.next_periodic);
|
||||
|
||||
return next_time;
|
||||
}
|
||||
|
||||
static void bb_add_icwmp_status(struct blob_buf *bb)
|
||||
{
|
||||
void *tbl = blobmsg_open_table(bb, "cwmp");
|
||||
bb_add_string(bb, "status", "up");
|
||||
bb_add_string(bb, "start_time", mix_get_time_of(cwmp_main.start_time));
|
||||
bb_add_string(bb, "acs_url", cwmp_main.conf.acsurl);
|
||||
blobmsg_close_table(bb, tbl);
|
||||
}
|
||||
|
||||
static void bb_add_icwmp_last_session(struct blob_buf *bb)
|
||||
{
|
||||
void *tbl = blobmsg_open_table(bb, "last_session");
|
||||
const char *status = cwmp_main.session_status.last_start_time ? arr_session_status[cwmp_main.session_status.last_status] : "N/A";
|
||||
bb_add_string(bb, "status", status);
|
||||
char *start_time = cwmp_main.session_status.last_start_time ? mix_get_time_of(cwmp_main.session_status.last_start_time) : "N/A";
|
||||
bb_add_string(bb, "start_time", start_time);
|
||||
char *end_time = cwmp_main.session_status.last_end_time ? mix_get_time_of(cwmp_main.session_status.last_end_time) : "N/A";
|
||||
bb_add_string(bb, "end_time", end_time);
|
||||
blobmsg_close_table(bb, tbl);
|
||||
}
|
||||
|
||||
static void bb_add_icwmp_next_session(struct blob_buf *bb)
|
||||
{
|
||||
void *tbl = blobmsg_open_table(bb, "next_session");
|
||||
bb_add_string(bb, "status", arr_session_status[SESSION_WAITING]);
|
||||
time_t ntime = get_next_session_time();
|
||||
char *start_time = ntime ? mix_get_time_of(ntime) : "N/A";
|
||||
bb_add_string(bb, "start_time", start_time);
|
||||
bb_add_string(bb, "end_time", "N/A");
|
||||
blobmsg_close_table(bb, tbl);
|
||||
}
|
||||
|
||||
static void bb_add_icwmp_statistics(struct blob_buf *bb)
|
||||
{
|
||||
void *tbl = blobmsg_open_table(bb, "statistics");
|
||||
blobmsg_add_u32(bb, "success_sessions", cwmp_main.session_status.success_session);
|
||||
blobmsg_add_u32(bb, "failure_sessions", cwmp_main.session_status.failure_session);
|
||||
blobmsg_add_u32(bb, "total_sessions", cwmp_main.session_status.success_session + cwmp_main.session_status.failure_session);
|
||||
blobmsg_close_table(bb, tbl);
|
||||
|
||||
}
|
||||
|
||||
static int icwmp_status_handler(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), struct ubus_request_data *req, const char *method __attribute__((unused)), struct blob_attr *msg __attribute__((unused)))
|
||||
{
|
||||
struct blob_buf bb;
|
||||
|
||||
memset(&bb, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&bb, 0);
|
||||
|
||||
bb_add_icwmp_status(&bb);
|
||||
bb_add_icwmp_last_session(&bb);
|
||||
bb_add_icwmp_next_session(&bb);
|
||||
bb_add_icwmp_statistics(&bb);
|
||||
|
||||
ubus_send_reply(ctx, req, bb.head);
|
||||
blob_buf_free(&bb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum enum_inform
|
||||
{
|
||||
INFORM_GET_RPC_METHODS,
|
||||
INFORM_EVENT,
|
||||
__INFORM_MAX
|
||||
};
|
||||
|
||||
static const struct blobmsg_policy icwmp_inform_policy[] = {
|
||||
[INFORM_GET_RPC_METHODS] = {.name = "GetRPCMethods", .type = BLOBMSG_TYPE_BOOL },
|
||||
[INFORM_EVENT] = {.name = "event", .type = BLOBMSG_TYPE_STRING },
|
||||
};
|
||||
|
||||
static void icwmp_inform_get_rpc_method(struct ubus_context *ctx, struct ubus_request_data *req)
|
||||
{
|
||||
struct event_container *event_container;
|
||||
struct session *session;
|
||||
struct blob_buf bb;
|
||||
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
memset(&bb, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&bb, 0);
|
||||
|
||||
pthread_mutex_lock(&(cwmp_main.mutex_session_queue));
|
||||
event_container = cwmp_add_event_container(&cwmp_main, EVENT_IDX_2PERIODIC, "");
|
||||
if (event_container == NULL) {
|
||||
pthread_mutex_unlock(&(cwmp_main.mutex_session_queue));
|
||||
return;
|
||||
}
|
||||
|
||||
cwmp_save_event_container(event_container);
|
||||
session = list_entry(cwmp_main.head_event_container, struct session, head_event_container);
|
||||
if (cwmp_add_session_rpc_acs(session, RPC_ACS_GET_RPC_METHODS) == NULL) {
|
||||
pthread_mutex_unlock(&(cwmp_main.mutex_session_queue));
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&(cwmp_main.mutex_session_queue));
|
||||
pthread_cond_signal(&(cwmp_main.threshold_session_send));
|
||||
blobmsg_add_u32(&bb, "status", 1);
|
||||
blobmsg_add_string(&bb, "info", "Session with GetRPCMethods will start");
|
||||
|
||||
ubus_send_reply(ctx, req, bb.head);
|
||||
blob_buf_free(&bb);
|
||||
}
|
||||
|
||||
static void icwmp_inform_event(struct ubus_context *ctx, struct ubus_request_data *req, char *event)
|
||||
{
|
||||
struct blob_buf bb;
|
||||
|
||||
if (ctx == NULL || event == NULL)
|
||||
return;
|
||||
|
||||
memset(&bb, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&bb, 0);
|
||||
|
||||
int event_code = cwmp_get_int_event_code(event);
|
||||
pthread_mutex_lock(&(cwmp_main.mutex_session_queue));
|
||||
cwmp_add_event_container(&cwmp_main, event_code, "");
|
||||
pthread_mutex_unlock(&(cwmp_main.mutex_session_queue));
|
||||
pthread_cond_signal(&(cwmp_main.threshold_session_send));
|
||||
if (cwmp_main.session_status.last_status == SESSION_RUNNING) {
|
||||
blobmsg_add_u32(&bb, "status", -1);
|
||||
blobmsg_add_string(&bb, "info", "Session already running, event will be sent at the end of the session");
|
||||
} else {
|
||||
blobmsg_add_u32(&bb, "status", 1);
|
||||
blobmsg_add_string(&bb, "info", "Session started");
|
||||
}
|
||||
|
||||
ubus_send_reply(ctx, req, bb.head);
|
||||
blob_buf_free(&bb);
|
||||
}
|
||||
|
||||
static int icwmp_inform_handler(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), struct ubus_request_data *req, const char *method __attribute__((unused)), struct blob_attr *msg)
|
||||
{
|
||||
struct blob_attr *tb[__INFORM_MAX];
|
||||
bool is_get_rpc = false;
|
||||
char *event = "";
|
||||
|
||||
blobmsg_parse(icwmp_inform_policy, ARRAYSIZEOF(icwmp_inform_policy), tb, blob_data(msg), blob_len(msg));
|
||||
|
||||
if (tb[INFORM_GET_RPC_METHODS]) {
|
||||
is_get_rpc = blobmsg_data(tb[INFORM_GET_RPC_METHODS]);
|
||||
}
|
||||
if (tb[INFORM_EVENT]) {
|
||||
event = blobmsg_data(tb[INFORM_EVENT]);
|
||||
}
|
||||
|
||||
if (is_get_rpc) {
|
||||
icwmp_inform_get_rpc_method(ctx, req);
|
||||
} else {
|
||||
icwmp_inform_event(ctx, req, event);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ubus_method icwmp_methods[] = {
|
||||
UBUS_METHOD("command", icwmp_command_handler, icwmp_cmd_policy),
|
||||
UBUS_METHOD_NOARG("status", icwmp_status_handler),
|
||||
UBUS_METHOD("inform", icwmp_inform_handler, icwmp_inform_policy),
|
||||
};
|
||||
|
||||
static struct ubus_object_type tr069_object_type = UBUS_OBJECT_TYPE("icwmpd", icwmp_methods);
|
||||
|
||||
static struct ubus_object tr069_object = {
|
||||
.name = "tr069",
|
||||
.type = &tr069_object_type,
|
||||
.methods = icwmp_methods,
|
||||
.n_methods = ARRAYSIZEOF(icwmp_methods),
|
||||
};
|
||||
|
||||
int icwmp_register_object(struct ubus_context *ctx)
|
||||
{
|
||||
return ubus_add_object(ctx, &tr069_object);
|
||||
}
|
||||
|
||||
int icwmp_delete_object(struct ubus_context *ctx)
|
||||
{
|
||||
return ubus_remove_object(ctx, &tr069_object);
|
||||
}
|
||||
|
||||
void bb_add_string(struct blob_buf *bb, const char *name, const char *value)
|
||||
{
|
||||
if (bb == NULL)
|
||||
return;
|
||||
|
||||
if (value)
|
||||
blobmsg_add_string(bb, name, value);
|
||||
else
|
||||
blobmsg_add_string(bb, name, "");
|
||||
}
|
||||
|
||||
int icwmp_ubus_invoke(const char *obj, const char *method, struct blob_attr *msg, icwmp_ubus_cb icwmp_callback, void *callback_arg)
|
||||
{
|
||||
uint32_t id;
|
||||
int rc = 0;
|
||||
|
||||
struct ubus_context *ubus_ctx = NULL;
|
||||
|
||||
ubus_ctx = ubus_connect(NULL);
|
||||
if (ubus_ctx == NULL)
|
||||
return -1;
|
||||
|
||||
if (!ubus_lookup_id(ubus_ctx, obj, &id))
|
||||
rc = ubus_invoke(ubus_ctx, id, method, msg, icwmp_callback, callback_arg, 20000);
|
||||
else
|
||||
rc = -1;
|
||||
|
||||
if (ubus_ctx) {
|
||||
ubus_free(ubus_ctx);
|
||||
ubus_ctx = NULL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue