Ticket #4712: icwmp: convert icwmp.sh script to a C code

This commit is contained in:
Omar Kallel 2021-04-15 10:36:24 +01:00
parent 8a6c212c0b
commit 5b24edae8f
30 changed files with 1321 additions and 2049 deletions

View file

@ -41,6 +41,7 @@ config lwn 'lwn'
It defines **acs configuration** (like acs url, acs username, etc...). The possible options for **acs** section are listed in the table below.
| Name | Type | Description |
| --------------------------- | ------- | ------------------------------- |
| `url` | string | the **url** of ACS server. |
@ -62,6 +63,7 @@ It defines **acs configuration** (like acs url, acs username, etc...). The possi
| `dhcp_url` | string | the **url** of ACS server received from the DHCP server Option 43 when **'dhcp_discovery'** option is enabled. This option is updated automatically by the daemon. |
| `ip_version` | string | ip_version of ConnectionRequestURL
### cwmp cpe section
It defines **device configuration** (such as interface, manufacturer, etc...). The possible options for **cpe** section are listed in the table below.
@ -216,16 +218,6 @@ root@iopsys:~# ubus call tr069 status
root@iopsys:~#
```
- To trigger a new session of notify when a parameter is changed, then use the `notify` ubus method:
```
root@iopsys:~# ubus call tr069 notify
{
"status": 1
}
root@iopsys:~#
```
- To trigger a new session to ACS with the event `'6 CONNECTION REQUEST'` or `'8 DIAGNOSTICS COMPLETE'`, etc.., use the `inform` ubus method with the appropriate `event` argument:
```
@ -269,85 +261,38 @@ root@iopsys:~# ubus call tr069 command '{"command":"exit"}'
}
root@iopsys:~#
```
## icwmpd command line
## icwmp CLI
icwmpd offers a cli tool which its options are described with `--help` option as below:
icwmpd command line options are described with `--help` option as below:
```
root@iopsys:~# icwmpd --help
Usage: icwmpd [OPTIONS]
-b, --boot-event (CWMP daemon) Start CWMP with BOOT event
-g, --get-rpc-methods (CWMP daemon) Start CWMP with GetRPCMethods request to ACS
-c, --cli CWMP CLI
-h, --help Display this help text
-v, --version Display the version
root@iopsys:~#
```
There's an icwmp cli that can be called via the script `'icwmp'` as follow:
## icwmpd CLI
The icwmpd CLI is the -c (--cli) option of the icwmpd command line.
Different options of this CLI are described with help command as below:
```
root@iopsys:~# icwmp get Device.Time.
{
"parameters": [
{
"parameter": "Device.Time.CurrentLocalTime",
"value": "2021-03-14T00:19:45Z",
"type": "xsd:dateTime"
},
{
"parameter": "Device.Time.Enable",
"value": "1",
"type": "xsd:boolean"
},
{
"parameter": "Device.Time.LocalTimeZone",
"value": "CET-1CEST,M3.5.0,M10.5.0/3",
"type": "xsd:string"
},
{
"parameter": "Device.Time.NTPServer1",
"value": "ntp1.sth.netnod.se",
"type": "xsd:string"
},
{
"parameter": "Device.Time.NTPServer2",
"value": "ntp1.gbg.netnod.se",
"type": "xsd:string"
},
{
"parameter": "Device.Time.NTPServer3",
"value": "",
"type": "xsd:string"
},
{
"parameter": "Device.Time.NTPServer4",
"value": "",
"type": "xsd:string"
},
{
"parameter": "Device.Time.NTPServer5",
"value": "",
"type": "xsd:string"
},
{
"parameter": "Device.Time.Status",
"value": "Synchronized",
"type": "xsd:string"
},
{
"parameter": "Device.Time.X_IOPSYS_EU_LocalTimeZoneName",
"value": "Europe/Stockholm",
"type": "xsd:string"
},
{
"parameter": "Device.Time.X_IOPSYS_EU_SourceInterface",
"value": "",
"type": "xsd:string"
}
]
}
root@iopsys:~#
root@iopsys:~# icwmpd -c help
Valid commands:
help => show this help
get [path-expr] => get parameter values
get_names [path-expr] [next-level] => get parameter names
set [path-expr] [value] => set parameter value
add [object] => add object
del [object] => delete object
get_notif [path-expr] => get parameter notifications
set_notif [path-expr] [notification] => set parameter notifications
```
## Dependencies

View file

@ -12,14 +12,14 @@ icwmpd_SOURCES = \
../md5.c \
../digestauth.c \
../event.c \
../external.c \
../http.c \
../cwmp_json.c \
../netlink.c \
../ubus.c \
../datamodel_interface.c \
../cwmp_cli.c \
../notifications.c \
../cwmp_zlib.c \
../cwmp_du_state.c \
../xml.c \
../diagnostic.c \
../cwmp.c

341
common.c
View file

@ -8,36 +8,32 @@
* Author Omar Kallel <omar.kallel@pivasoftware.com>
*
*/
#include <stdio.h>
#include <getopt.h>
#include <sys/stat.h>
#include <curl/curl.h>
#include <unistd.h>
#include <sys/reboot.h>
#include <fcntl.h>
#include "common.h"
#include "cwmp_uci.h"
#include "ubus.h"
#include "log.h"
#include "cwmp_cli.h"
#define CURL_TIMEOUT 20
char *commandKey = NULL;
long int flashsize = 256000000;
struct option cwmp_long_options[] = { { "boot-event", no_argument, NULL, 'b' },
{ "get-rpc-methods", no_argument, NULL, 'g' },
{ "command-input", no_argument, NULL, 'c' },
{ "shell-cli", required_argument, NULL, 'm' },
{ "alias-based-addressing", no_argument, NULL, 'a' },
{ "instance-mode-number", no_argument, NULL, 'N' },
{ "instance-mode-alias", no_argument, NULL, 'A' },
{ "upnp", no_argument, NULL, 'U' },
{ "user-acl", required_argument, NULL, 'u' },
{ "amendment", required_argument, NULL, 'M' },
{ "time-tracking", no_argument, NULL, 't' },
{ "evaluating-test", no_argument, NULL, 'E' },
{ "file", required_argument, NULL, 'f' },
{ "wep", required_argument, NULL, 'w' },
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'v' },
{ NULL, 0, NULL, 0 } };
struct option cwmp_long_options[] = { { "boot-event", no_argument, NULL, 'b' }, { "get-rpc-methods", no_argument, NULL, 'g' }, { "command-input", no_argument, NULL, 'c' }, { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' }, { NULL, 0, NULL, 0 } };
static void show_help(void)
{
printf("Usage: icwmpd [OPTIONS]\n");
printf(" -b, --boot-event (CWMP daemon) Start CWMP with BOOT event\n");
printf(" -g, --get-rpc-methods (CWMP daemon) Start CWMP with GetRPCMethods request to ACS\n");
printf(" -c, --cli CWMP CLI\n");
printf(" -h, --help Display this help text\n");
printf(" -v, --version Display the version\n");
}
@ -55,7 +51,7 @@ int global_env_init(int argc, char **argv, struct env *env)
{
int c, option_index = 0;
while ((c = getopt_long(argc, argv, "bghv", cwmp_long_options, &option_index)) != -1) {
while ((c = getopt_long(argc, argv, "bgchv", cwmp_long_options, &option_index)) != -1) {
switch (c) {
case 'b':
env->boot = CWMP_START_BOOT;
@ -64,7 +60,9 @@ int global_env_init(int argc, char **argv, struct env *env)
case 'g':
env->periodic = CWMP_START_PERIODIC;
break;
case 'c':
execute_cwmp_cli_command(argv[2], argv + 3);
exit(0);
case 'h':
show_help();
exit(0);
@ -159,27 +157,27 @@ void cwmp_free_all_list_param_fault(struct list_head *list_param_fault)
cwmp_del_list_fault_param(param_fault);
}
}
///////////////////////////////////////////////////////////
int cwmp_asprintf(char **s, const char *format, ...)
{
int size;
char *str = NULL;
va_list arg, argcopy;
va_start(arg, format);
va_copy(argcopy, arg);
size = vsnprintf(NULL, 0, format, argcopy);
if (size < 0)
if (size < 0) {
return -1;
}
va_end(argcopy);
str = (char *)calloc(sizeof(char), size + 1);
vsnprintf(str, size + 1, format, arg);
va_end(arg);
*s = strdup(str);
FREE(str);
if (*s == NULL)
if (*s == NULL) {
return -1;
}
return 0;
}
@ -189,3 +187,300 @@ bool folder_exists(const char *path)
return (stat(path, &folder_stat) == 0 && S_ISDIR(folder_stat.st_mode));
}
size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
size_t written = fwrite(ptr, size, nmemb, stream);
return written;
}
int download_file(const char *file_path, const char *url, const char *username, const char *password)
{
int res_code = 0;
CURL *curl = curl_easy_init();
if (curl) {
char *userpass = NULL;
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
if (username != NULL && strlen(username) > 0) {
cwmp_asprintf(&userpass, "%s:%s", username, password);
curl_easy_setopt(curl, CURLOPT_USERPWD, userpass);
}
if (strncmp(url, "https://", 8) == 0)
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L);
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_ANY);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, 10000L);
curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
curl_easy_setopt(curl, CURLOPT_FTP_SKIP_PASV_IP, 1L);
FILE *fp = fopen(file_path, "wb");
if (fp) {
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
curl_easy_perform(curl);
fclose(fp);
}
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &res_code);
curl_easy_cleanup(curl);
FREE(userpass);
}
return res_code;
}
struct transfer_status {
CURL *easy;
int halted;
int counter; /* count write callback invokes */
int please; /* number of times xferinfo is called while halted */
};
int upload_file(const char *file_path, const char *url, const char *username, const char *password)
{
int res_code = 0;
CURL *curl = curl_easy_init();
if (curl) {
char *userpass = NULL;
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_ANY);
cwmp_asprintf(&userpass, "%s:%s", username, password);
curl_easy_setopt(curl, CURLOPT_USERPWD, userpass);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, CURL_TIMEOUT);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
FILE *fp = fopen(file_path, "rb");
if (fp) {
curl_easy_setopt(curl, CURLOPT_READDATA, fp);
curl_easy_perform(curl);
fclose(fp);
}
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &res_code);
curl_easy_cleanup(curl);
FREE(userpass);
}
return res_code;
}
void get_firewall_zone_name_by_wan_iface(char *if_wan, char **zone_name)
{
struct uci_section *s;
char *network = NULL;
cwmp_uci_init(UCI_STANDARD_CONFIG);
cwmp_uci_foreach_sections("firewall", "zone", s)
{
cwmp_uci_get_value_by_section_string(s, "network", &network);
char *net = strtok(network, " ");
while (net != NULL) {
if (strcmp(net, if_wan) == 0) {
cwmp_uci_get_value_by_section_string(s, "name", zone_name);
FREE(network);
goto end;
}
net = strtok(NULL, " ");
}
FREE(network);
}
end:
cwmp_uci_exit();
}
/*
* updated firewall.cwmp file
*/
int update_firewall_cwmp_file(int port, char *zone_name, char *ip_addr, int ip_type)
{
FILE *fp;
remove(FIREWALL_CWMP);
fp = fopen(FIREWALL_CWMP, "a");
if (fp == NULL)
return -1;
fprintf(fp, "zone_name=%s\n", zone_name);
fprintf(fp, "port=%d\n", port);
fprintf(fp, "if [ \"$zone_name\" = \"\" ]; then\n");
fprintf(fp, " exit 0\n");
fprintf(fp, "elif [ \"$zone_name\" = \"icwmp\" ]; then\n");
fprintf(fp, " iptables -nL zone_icwmp_input 2> /dev/null\n");
fprintf(fp, " if [ $? != 0 ]; then\n");
fprintf(fp, " iptables -N zone_icwmp_input\n");
fprintf(fp, " iptables -t filter -A INPUT -j zone_icwmp_input\n");
fprintf(fp, " iptables -I zone_icwmp_input -p tcp --dport $port -j REJECT\n");
fprintf(fp, " else\n");
fprintf(fp, " iptables -F zone_icwmp_input\n");
fprintf(fp, " iptables -I zone_icwmp_input -p tcp --dport $port -j REJECT\n");
fprintf(fp, " fi\n");
fprintf(fp, "else\n");
fprintf(fp, " iptables -F zone_icwmp_input 2> /dev/null\n");
fprintf(fp, " iptables -t filter -D INPUT -j zone_icwmp_input 2> /dev/null\n");
fprintf(fp, " iptables -X zone_icwmp_input 2> /dev/null\n");
fprintf(fp, "fi\n");
if (ip_type == 0)
fprintf(fp, "iptables -I zone_%s_input -p tcp -s %s --dport %d -j ACCEPT -m comment --comment=\"Open ACS port\"\n", zone_name, ip_addr, port);
else
fprintf(fp, "ip6tables -I zone_%s_input -p tcp -s %s --dport %d -j ACCEPT -m comment --comment=\"Open ACS port\"\n", zone_name, ip_addr, port);
fclose(fp);
return 0;
}
/*
* Reboot
*/
void cwmp_reboot(char *command_key)
{
uci_set_value(UCI_ACS_PARAMETERKEY_PATH, command_key, CWMP_CMD_SET);
cwmp_commit_package("cwmp");
sync();
reboot(RB_AUTOBOOT);
}
/*
* FactoryReset
*/
void cwmp_factory_reset() //use the ubus rpc-sys factory
{
cwmp_ubus_call("rpc-sys", "factory", CWMP_UBUS_ARGS{ {} }, 0, NULL, NULL);
}
long int get_file_size(char *file_name)
{
FILE *fp = fopen(file_name, "r");
if (fp == NULL) {
CWMP_LOG(INFO, "File Not Found!");
return -1;
}
fseek(fp, 0L, SEEK_END);
long int res = ftell(fp);
fclose(fp);
return res;
}
void ubus_check_image_callback(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg)
{
int *code = (int *)req->priv;
const struct blobmsg_policy p[2] = { { "code", BLOBMSG_TYPE_INT32 }, { "stdout", BLOBMSG_TYPE_STRING } };
struct blob_attr *tb[2] = { NULL, NULL };
blobmsg_parse(p, 2, tb, blobmsg_data(msg), blobmsg_len(msg));
*code = tb[0] ? blobmsg_get_u32(tb[0]) : 1;
}
/*
* Check if the downloaded image can be applied
*/
int cwmp_check_image()
{
int code, e;
e = cwmp_ubus_call("rpc-sys", "upgrade_test", CWMP_UBUS_ARGS{ {} }, 0, 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;
}
return code;
}
/*
* Apply the new firmware
*/
void cwmp_apply_firmware()
{
int e;
e = cwmp_ubus_call("rpc-sys", "upgrade_start", CWMP_UBUS_ARGS{ { "keep", {.bool_val = true }, UBUS_Bool } }, 1, NULL, NULL);
if (e != 0) {
CWMP_LOG(INFO, "rpc-sys upgrade_start ubus method failed: Ubus err code: %d", e);
}
}
int opkg_install_package(char *package_path)
{
FILE *fp;
char path[1035];
char *cmd = NULL;
cwmp_asprintf(&cmd, "opkg --force-depends --force-maintainer install %s", package_path);
if (cmd == NULL)
return -1;
fp = popen(cmd, "r");
if (fp == NULL) {
FREE(cmd);
CWMP_LOG(INFO, "Failed to run command");
return -1;
}
/* Read the output a line at a time - output it. */
while (fgets(path, sizeof(path), fp) != NULL) {
if (strstr(path, "Installing") != NULL) {
FREE(cmd);
return 0;
}
}
/* close */
pclose(fp);
FREE(cmd);
return -1;
}
int copy(const char *from, const char *to)
{
int fd_to, fd_from;
char buf[4096];
ssize_t nread;
int saved_errno;
fd_from = open(from, O_RDONLY);
if (fd_from < 0)
return -1;
fd_to = open(to, O_WRONLY | O_CREAT | O_EXCL, 0666);
if (fd_to < 0)
goto out_error;
while ((nread = read(fd_from, buf, sizeof buf)) > 0) {
char *out_ptr = buf;
ssize_t nwritten;
do {
nwritten = write(fd_to, out_ptr, nread);
if (nwritten >= 0) {
nread -= nwritten;
out_ptr += nwritten;
} else if (errno != EINTR) {
goto out_error;
}
} while (nread > 0);
}
if (nread == 0) {
if (close(fd_to) < 0) {
fd_to = -1;
goto out_error;
}
close(fd_from);
/* Success! */
return 0;
}
out_error:
saved_errno = errno;
close(fd_from);
if (fd_to >= 0)
close(fd_to);
errno = saved_errno;
return -1;
}

View file

@ -307,6 +307,14 @@ int get_global_config(struct config *conf)
} else {
return error;
}
if ((error = uci_get_value(UCI_CPE_DEFAULT_WAN_IFACE, &value)) == CWMP_OK) {
if (value != NULL)
conf->default_wan_iface = strdup(value);
else
conf->default_wan_iface = strdup("wan");
} else {
return error;
}
if ((error = uci_get_value(UCI_CPE_CRPATH_PATH, &value)) == CWMP_OK) {
if (conf->connection_request_path != NULL) {
free(conf->connection_request_path);

21
cwmp.c
View file

@ -253,13 +253,6 @@ end:
int run_session_end_func()
{
if (end_session_flag & END_SESSION_EXTERNAL_ACTION) {
CWMP_LOG(INFO, "Executing external commands: end session request");
external_init();
external_simple("end_session", NULL, 0);
external_exit();
}
if (end_session_flag & END_SESSION_RELOAD) {
CWMP_LOG(INFO, "Config reload: end session request");
cwmp_apply_acs_changes();
@ -311,26 +304,20 @@ int run_session_end_func()
if (end_session_flag & END_SESSION_REBOOT) {
CWMP_LOG(INFO, "Executing Reboot: end session request");
external_init();
external_simple("reboot", commandKey, 0);
cwmp_reboot(commandKey);
FREE(commandKey);
external_exit();
exit(EXIT_SUCCESS);
}
if (end_session_flag & END_SESSION_X_FACTORY_RESET_SOFT) {
CWMP_LOG(INFO, "Executing factory reset soft: end session request");
external_init();
external_simple("factory_reset_soft", NULL, 0);
external_exit();
cwmp_factory_reset();
exit(EXIT_SUCCESS);
}
if (end_session_flag & END_SESSION_FACTORY_RESET) {
CWMP_LOG(INFO, "Executing factory reset: end session request");
external_init();
external_simple("factory_reset", NULL, 0);
external_exit();
cwmp_factory_reset();
exit(EXIT_SUCCESS);
}
@ -386,7 +373,7 @@ void cwmp_schedule_session(struct cwmp *cwmp)
uci_get_value(UCI_CPE_EXEC_DOWNLOAD, &exec_download);
if (strcmp(exec_download, "1") == 0) {
CWMP_LOG(INFO, "Firmware downloaded and applied successfully");
uci_set_value("cwmp.cpe.exec_download=0");
uci_set_value(UCI_CPE_EXEC_DOWNLOAD, "0", CWMP_CMD_SET);
}
error = cwmp_schedule_rpc(cwmp, session);
CWMP_LOG(INFO, "End session");

327
cwmp_cli.c Normal file
View file

@ -0,0 +1,327 @@
#include <stdio.h>
#include "common.h"
#include "datamodel_interface.h"
LIST_HEAD(parameters_list);
struct fault_resp {
int fault_index;
char *fault_code;
char *fault_message;
};
const struct fault_resp faults_array[] = { { FAULT_CPE_INTERNAL_ERROR, "9002", "Internal error" }, //Internal error
{ 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" } };
char *get_fault_message_by_fault_code(char *fault_code)
{
size_t i;
size_t faults_array_size = sizeof(faults_array) / sizeof(struct fault_resp);
for (i = 0; i < faults_array_size; i++) {
if (strcmp(faults_array[i].fault_code, fault_code) == 0)
return faults_array[i].fault_message;
}
return NULL;
}
union cmd_result {
struct list_head *param_list;
char *instance;
};
struct cmd_input {
char *first_input;
char *second_input;
};
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);
};
/*
* 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;
}
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));
FREE(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 __attribute__((unused)))
{
int flag;
if (!transaction_started) {
if (!cwmp_transaction_start("cwmp"))
return strdup(get_fault_message_by_fault_code("9002"));
transaction_started = true;
}
LIST_HEAD(list_set_param_value);
LIST_HEAD(faults_list);
add_dm_parameter_to_list(&list_set_param_value, in.first_input, in.second_input, NULL, 0, false);
int fault_idx = cwmp_set_multiple_parameters_values(&list_set_param_value, "set_key", &flag, &faults_list);
if (fault_idx != FAULT_CPE_NO_FAULT) {
struct cwmp_param_fault *param_fault = NULL;
list_for_each_entry (param_fault, &faults_list, list) {
char fault[5];
snprintf(fault, 5, "%d", param_fault->fault);
if (transaction_started) {
cwmp_transaction_abort();
transaction_started = false;
}
return strdup(fault);
}
}
if (transaction_started) {
cwmp_transaction_commit();
transaction_started = false;
}
return NULL;
}
void display_set_cmd_result(struct cmd_input in, union cmd_result res __attribute__((unused)), 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, get_fault_message_by_fault_code(fault));
FREE(fault);
}
/*
* Add_Object
*/
char *cmd_add_exec_func(struct cmd_input in, union cmd_result *res)
{
if (!transaction_started) {
if (!cwmp_transaction_start("cwmp"))
return strdup(get_fault_message_by_fault_code("9002"));
transaction_started = true;
}
char *fault = cwmp_add_object(in.first_input, in.second_input ? in.second_input : "add_obj", &(res->instance));
if (fault != NULL) {
if (transaction_started) {
cwmp_transaction_abort();
transaction_started = false;
}
return strdup(fault);
}
if (transaction_started) {
cwmp_transaction_commit();
transaction_started = false;
}
return NULL;
}
void display_add_cmd_result(struct cmd_input in, union cmd_result res, char *fault)
{
if (fault != NULL) {
fprintf(stderr, "Fault %s: %s\n", fault, get_fault_message_by_fault_code(fault));
FREE(fault);
return;
}
if (in.first_input[strlen(in.first_input) - 1] == '.')
fprintf(stdout, "Added %s%s.\n", in.first_input, res.instance);
else
fprintf(stdout, "Added %s.%s.\n", in.first_input, res.instance);
}
/*
* Delete_Object
*/
char *cmd_del_exec_func(struct cmd_input in, union cmd_result *res __attribute__((unused)))
{
if (!transaction_started) {
if (!cwmp_transaction_start("cwmp"))
return strdup(get_fault_message_by_fault_code("9002"));
transaction_started = true;
}
char *fault = cwmp_delete_object(in.first_input, in.second_input ? in.second_input : "del_obj");
if (fault != NULL) {
if (transaction_started) {
cwmp_transaction_abort();
transaction_started = false;
}
return strdup(fault);
}
if (transaction_started) {
cwmp_transaction_commit();
transaction_started = false;
}
return NULL;
}
void display_del_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));
FREE(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)
{
res->param_list = &parameters_list;
char *fault = cwmp_get_parameter_attributes(in.first_input, res->param_list);
return fault;
}
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));
FREE(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 (!transaction_started) {
if (!cwmp_transaction_start("cwmp"))
return strdup(get_fault_message_by_fault_code("9002"));
transaction_started = true;
}
char *fault = cwmp_set_parameter_attributes(in.first_input, in.second_input);
if (fault != NULL) {
if (transaction_started) {
cwmp_transaction_abort();
transaction_started = false;
}
return strdup(fault);
}
if (transaction_started) {
cwmp_transaction_commit();
transaction_started = false;
}
return NULL;
}
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));
FREE(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)
{
res->param_list = &parameters_list;
bool next_level = in.second_input && (strcmp(in.second_input, "1") == 0 || strcasecmp(in.second_input, "true") == 0) ? true : false;
char *fault = cwmp_get_parameter_names(in.first_input, next_level, res->param_list);
return fault;
}
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));
FREE(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
*/
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] => set parameter value\n");
printf(" add [object] => add object\n");
printf(" del [object] => 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
};
void execute_cwmp_cli_command(char *cmd, char *args[])
{
if (!cmd || strlen(cmd) <= 0) {
printf("You must add a command as input: \n\n");
goto cli_help;
}
if (strcmp(cmd, "help") == 0)
goto cli_help;
struct cmd_input cmd_in = { args[0] ? args[0] : NULL, args[0] && args[1] ? args[1] : NULL };
union cmd_result cmd_out = { 0 };
size_t i;
size_t commands_array_size = sizeof(icwmp_commands) / sizeof(struct cwmp_cli_command_struct);
for (i = 0; i < commands_array_size; i++) {
if (strcmp(icwmp_commands[i].command_name, cmd) == 0) {
char *fault = icwmp_commands[i].cmd_exec_func(cmd_in, &cmd_out);
icwmp_commands[i].display_cmd_result(cmd_in, cmd_out, fault);
return;
}
}
printf("Wrong cwmp cli command: %s\n", cmd);
cli_help:
cwmp_cli_help();
}

96
cwmp_du_state.c Normal file
View file

@ -0,0 +1,96 @@
/*
* 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 Omar Kallel <omar.kallel@pivasoftware.com>
*/
#include <stdio.h>
#include <libubox/blobmsg_json.h>
#include "common.h"
#include "ubus.h"
#include "cwmp_du_state.h"
#include "log.h"
struct change_du_state_res {
char **pack_name;
char **pack_version;
char **pack_uuid;
char **pack_env;
char **fault;
enum dustate_type type;
};
void ubus_du_install_update_callback(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg)
{
struct change_du_state_res *result = (struct change_du_state_res *)req->priv;
const struct blobmsg_policy p[6] = { { "status", BLOBMSG_TYPE_STRING }, { "error", BLOBMSG_TYPE_STRING }, { "name", BLOBMSG_TYPE_STRING }, { "uuid", BLOBMSG_TYPE_STRING }, { "version", BLOBMSG_TYPE_STRING }, { "environment", BLOBMSG_TYPE_STRING } };
struct blob_attr *tb[6] = { NULL, NULL, NULL, NULL, NULL, NULL };
blobmsg_parse(p, 6, tb, blobmsg_data(msg), blobmsg_len(msg));
if (tb[0] && strcmp(blobmsg_get_string(tb[0]), "1") == 0) {
*(result->fault) = NULL;
*(result->pack_name) = strdup(tb[2] ? blobmsg_get_string(tb[2]) : "");
*(result->pack_uuid) = strdup(tb[3] ? blobmsg_get_string(tb[3]) : "");
*(result->pack_version) = strdup(tb[4] ? blobmsg_get_string(tb[4]) : "");
*(result->pack_env) = strdup(tb[5] ? blobmsg_get_string(tb[5]) : "");
} else {
if (result->type == DU_INSTALL)
*(result->fault) = strdup(tb[1] && strcmp(blobmsg_get_string(tb[1]), "Download") ? "9010" : "9018");
else
*(result->fault) = strdup("9010");
}
}
int cwmp_du_install(char *url, char *uuid, char *user, char *pass, char *env, char **package_version, char **package_name, char **package_uuid, char **package_env, char **fault_code)
{
int e;
struct change_du_state_res cds_install = {.pack_name = package_name, .pack_version = package_version, .pack_uuid = package_uuid, .pack_env = package_env, .fault = fault_code, .type = DU_INSTALL };
e = cwmp_ubus_call("swmodules", "du_install",
CWMP_UBUS_ARGS{ { "url", {.str_val = url }, UBUS_String }, { "uuid", {.str_val = uuid }, UBUS_String }, { "username", {.str_val = user }, UBUS_String }, { "password", {.str_val = pass }, UBUS_String }, { "environment", {.str_val = env }, UBUS_String } }, 5,
ubus_du_install_update_callback, &cds_install);
if (e < 0) {
CWMP_LOG(INFO, "Change du state install failed: Ubus err code: %d", e);
return FAULT_CPE_INTERNAL_ERROR;
}
return FAULT_CPE_NO_FAULT;
}
int cwmp_du_update(char *url, char *uuid, char *user, char *pass, char **package_version, char **package_name, char **package_uuid, char **package_env, char **fault_code)
{
int e;
struct change_du_state_res cds_update = {.pack_name = package_name, .pack_version = package_version, .pack_uuid = package_uuid, .pack_env = package_env, .fault = fault_code, .type = DU_UPDATE };
e = cwmp_ubus_call("swmodules", "du_install", CWMP_UBUS_ARGS{ { "url", {.str_val = url }, UBUS_String }, { "uuid", {.str_val = uuid }, UBUS_String }, { "username", {.str_val = user }, UBUS_String }, { "password", {.str_val = pass }, UBUS_String } }, 4, ubus_du_install_update_callback,
&cds_update);
if (e < 0) {
CWMP_LOG(INFO, "Change du state update failed: Ubus err code: %d", e);
return FAULT_CPE_INTERNAL_ERROR;
}
return FAULT_CPE_NO_FAULT;
}
void ubus_du_uninstall_callback(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg)
{
char **fault = (char **)req->priv;
const struct blobmsg_policy p[2] = { { "status", BLOBMSG_TYPE_STRING } };
struct blob_attr *tb[1] = { NULL };
blobmsg_parse(p, 1, tb, blobmsg_data(msg), blobmsg_len(msg));
if (tb[0] && strcmp(blobmsg_get_string(tb[0]), "1") == 0)
*fault = NULL;
else
*fault = strdup("9010");
}
int cwmp_du_uninstall(char *package_name, char *package_env, char **fault_code)
{
int e;
e = cwmp_ubus_call("swmodules", "du_uninstall", CWMP_UBUS_ARGS{ { "name", {.str_val = package_name }, UBUS_String }, { "environment", {.str_val = package_env }, UBUS_String } }, 2, ubus_du_uninstall_callback, fault_code);
if (e < 0) {
CWMP_LOG(INFO, "Change du state uninstall failed: Ubus err code: %d", e);
return FAULT_CPE_INTERNAL_ERROR;
}
return FAULT_CPE_NO_FAULT;
}

View file

@ -1,193 +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-2019 iopsys Software Solutions AB
* Author Mohamed Kallel <mohamed.kallel@pivasoftware.com>
* Author Ahmed Zribi <ahmed.zribi@pivasoftware.com>
* Copyright (C) 2012 Luka Perkov <freecwmp@lukaperkov.net>
*/
#include <unistd.h>
#include <libubus.h>
#include <json-c/json.h>
#include "external.h"
#include "cwmp_json.h"
#include "log.h"
static json_object *jshn_obj = NULL;
static int cwmp_json_message_parse(char **policy, int size, char **tb, char *msg)
{
int i;
json_object *obj;
jshn_obj = json_tokener_parse(msg);
if (jshn_obj == NULL || json_object_get_type(jshn_obj) != json_type_object) {
jshn_obj = NULL;
return -1;
}
for (i = 0; i < size; i++) {
json_object_object_get_ex(jshn_obj, policy[i], &obj);
if (obj == NULL || json_object_get_type(obj) != json_type_string)
continue;
tb[i] = (char *)json_object_get_string(obj);
}
return 0;
}
static inline void cwmp_json_message_delete()
{
if (jshn_obj != NULL)
json_object_put(jshn_obj);
}
enum download_fault
{
DOWNLOAD_FAULT,
__DOWNLOAD_MAX
};
char *download_fault_policy[] = {[DOWNLOAD_FAULT] = "fault_code" };
int cwmp_handle_download_fault(char *msg)
{
char *tb[__DOWNLOAD_MAX] = { 0 };
cwmp_json_message_parse(download_fault_policy, ARRAYSIZEOF(download_fault_policy), tb, msg);
if (!tb[DOWNLOAD_FAULT])
goto error;
DD(INFO, "triggered handle download fault %s", tb[DOWNLOAD_FAULT]);
external_download_fault_resp(tb[DOWNLOAD_FAULT]);
cwmp_json_message_delete();
return 0;
error:
cwmp_json_message_delete();
return -1;
}
enum upload_fault
{
UPLOAD_FAULT,
__UPLOAD_MAX
};
char *upload_fault_policy[] = {[UPLOAD_FAULT] = "fault_code" };
int cwmp_handle_upload_fault(char *msg)
{
char *tb[__UPLOAD_MAX] = { 0 };
cwmp_json_message_parse(upload_fault_policy, ARRAYSIZEOF(upload_fault_policy), tb, msg);
if (!tb[UPLOAD_FAULT])
goto error;
DD(INFO, "triggered handle upload fault %s", tb[UPLOAD_FAULT]);
external_upload_fault_resp(tb[UPLOAD_FAULT]);
cwmp_json_message_delete();
return 0;
error:
cwmp_json_message_delete();
return -1;
}
enum dustatechange_fault
{
DUState_Change_FAULT,
DUState_Change_VERSION,
DUState_Change_NAME,
DUState_Change_UUID,
DUState_Change_ENV,
__DUSTATE_MAX
};
char *dustatechange_fault_policy[] = {[DUState_Change_FAULT] = "fault_code", [DUState_Change_VERSION] = "package_version", [DUState_Change_NAME] = "package_name", [DUState_Change_UUID] = "package_uuid", [DUState_Change_ENV] = "package_env" };
int cwmp_handle_dustate_change_fault(char *msg)
{
char *tb[__DUSTATE_MAX] = { 0 };
cwmp_json_message_parse(dustatechange_fault_policy, ARRAYSIZEOF(dustatechange_fault_policy), tb, msg);
if (!tb[DUState_Change_FAULT])
goto error;
DD(INFO, "triggered handle dustate_change fault:%s version:%s name:%s", tb[DUState_Change_FAULT], tb[DUState_Change_VERSION], tb[DUState_Change_NAME], tb[DUState_Change_UUID], tb[DUState_Change_ENV]);
external_du_change_state_fault_resp(tb[DUState_Change_FAULT], tb[DUState_Change_VERSION], tb[DUState_Change_NAME], tb[DUState_Change_UUID], tb[DUState_Change_ENV]);
cwmp_json_message_delete();
return 0;
error:
cwmp_json_message_delete();
return -1;
}
enum uninstall_fault
{
UNINSTALL_FAULT,
__UNINSTALL_MAX
};
char *uninstall_fault_policy[] = {[UNINSTALL_FAULT] = "fault_code" };
int cwmp_handle_uninstall_fault(char *msg)
{
char *tb[__UNINSTALL_MAX] = { 0 };
cwmp_json_message_parse(uninstall_fault_policy, ARRAYSIZEOF(uninstall_fault_policy), tb, msg);
if (!tb[UNINSTALL_FAULT])
goto error;
DD(INFO, "triggered handle upload fault %s", tb[UNINSTALL_FAULT]);
external_uninstall_fault_resp(tb[UNINSTALL_FAULT]);
cwmp_json_message_delete();
return 0;
error:
cwmp_json_message_delete();
return -1;
}
void cwmp_add_json_obj(json_object *json_obj_out, char *object, char *string)
{
if (object != NULL && string != NULL) {
json_object *json_obj_tmp = json_object_new_string(string);
json_object_object_add(json_obj_out, object, json_obj_tmp);
}
}
void cwmp_json_fprintf(FILE *fp, int argc, struct cwmp_json_arg cwmp_arg[])
{
int i;
char *arg;
json_object *json_obj_out = json_object_new_object();
if (json_obj_out == NULL)
return;
if (argc) {
for (i = 0; i < argc; i++) {
cwmp_add_json_obj(json_obj_out, cwmp_arg[i].key, cwmp_arg[i].val);
}
arg = (char *)json_object_to_json_string(json_obj_out);
fprintf(fp, "%s\n", arg);
}
json_object_put(json_obj_out);
}

View file

@ -93,23 +93,24 @@ lookup:
char *cwmp_uci_list_to_string(struct uci_list *list, char *delimitor)
{
struct uci_element *e = NULL;
char val[512] = { 0 };
int del_len = strlen(delimitor);
if (list) {
struct uci_element *e = NULL;
char list_val[512] = { 0 };
unsigned pos = 0;
list_val[0] = 0;
uci_foreach_element(list, e)
{
int len = strlen(val);
if (len != 0) {
memcpy(val + len, delimitor, del_len);
strcpy(val + len + del_len, e->name);
} else
strcpy(val, e->name);
if (e->name)
pos += snprintf(&list_val[pos], sizeof(list_val) - pos, "%s%s", e->name, delimitor);
}
return (strdup(val));
if (pos)
list_val[pos - 1] = 0;
return strdup(list_val);
} else {
return "";
return strdup("");
}
}
@ -310,12 +311,38 @@ int uci_get_value(char *cmd, char **value)
return error;
}
static int uci_action_value_common(char *cmd, uci_config_action action)
int uci_delete_value(char *cmd)
{
int ret = UCI_OK;
char *s, *t;
struct uci_context *c = uci_alloc_context();
struct uci_ptr ptr;
int ret = UCI_OK;
if (!c) {
CWMP_LOG(ERROR, "Out of memory");
return CWMP_GEN_ERR;
}
if (uci_lookup_ptr(c, &ptr, cmd, true) != UCI_OK) {
uci_free_context(c);
return CWMP_GEN_ERR;
}
ret = uci_delete(c, &ptr);
if (ret == UCI_OK) {
ret = uci_save(c, ptr.p);
} else {
CWMP_LOG(ERROR, "UCI delete not succeed %s", cmd);
return CWMP_GEN_ERR;
}
uci_free_context(c);
return CWMP_OK;
}
int uci_set_value(char *path, char *value, uci_config_action action)
{
struct uci_context *c = uci_alloc_context();
struct uci_ptr ptr;
int ret = UCI_OK;
char state_path[32];
if (!c) {
@ -329,62 +356,54 @@ static int uci_action_value_common(char *cmd, uci_config_action action)
uci_set_savedir(c, state_path);
}
s = strdup(cmd);
t = s;
char *cmd = NULL;
cwmp_asprintf(&cmd, "%s=%s", path, value);
if (uci_lookup_ptr(c, &ptr, s, true) != UCI_OK) {
free(t);
if (uci_lookup_ptr(c, &ptr, cmd, true) != UCI_OK) {
uci_free_context(c);
FREE(cmd);
return CWMP_GEN_ERR;
}
switch (action) {
case CWMP_CMD_SET:
case CWMP_CMD_SET_STATE:
ret = uci_set(c, &ptr);
break;
case CWMP_CMD_DEL:
ret = uci_delete(c, &ptr);
break;
case CWMP_CMD_ADD_LIST:
ret = uci_add_list(c, &ptr);
break;
}
ret = uci_set(c, &ptr);
if (ret == UCI_OK) {
ret = uci_save(c, ptr.p);
} else {
CWMP_LOG(ERROR, "UCI %s %s not succeed %s", action == CWMP_CMD_SET_STATE ? "state" : "config", action == CWMP_CMD_DEL ? "delete" : "set", cmd);
CWMP_LOG(ERROR, "UCI delete not succeed %s", cmd);
FREE(cmd);
return CWMP_GEN_ERR;
}
free(t);
uci_free_context(c);
FREE(cmd);
return CWMP_OK;
}
int uci_delete_value(char *cmd)
{
int error;
error = uci_action_value_common(cmd, CWMP_CMD_DEL);
return error;
}
int uci_set_value(char *cmd)
{
int error;
error = uci_action_value_common(cmd, CWMP_CMD_SET);
return error;
}
int uci_set_state_value(char *cmd)
{
int error;
error = uci_action_value_common(cmd, CWMP_CMD_SET_STATE);
return error;
}
int uci_add_list_value(char *cmd)
{
int error;
error = uci_action_value_common(cmd, CWMP_CMD_ADD_LIST);
return error;
struct uci_context *c = uci_alloc_context();
struct uci_ptr ptr;
int ret = UCI_OK;
if (!c) {
CWMP_LOG(ERROR, "Out of memory");
return CWMP_GEN_ERR;
}
if (uci_lookup_ptr(c, &ptr, cmd, true) != UCI_OK) {
uci_free_context(c);
return CWMP_GEN_ERR;
}
ret = uci_add_list(c, &ptr);
if (ret == UCI_OK) {
ret = uci_save(c, ptr.p);
} else {
CWMP_LOG(ERROR, "UCI delete not succeed %s", cmd);
return CWMP_GEN_ERR;
}
uci_free_context(c);
return CWMP_OK;
}
static inline void cwmp_uci_list_insert(struct uci_list *list, struct uci_list *ptr)
@ -411,14 +430,14 @@ int cwmp_uci_get_value_by_section_string(struct uci_section *s, char *option, ch
if (o->type == UCI_TYPE_LIST) {
*value = cwmp_uci_list_to_string(&o->v.list, " ");
} else {
*value = o->v.string ? strdup(o->v.string) : "";
*value = o->v.string ? strdup(o->v.string) : strdup("");
}
return 0;
}
}
not_found:
*value = "";
*value = strdup("");
return -1;
}
@ -470,11 +489,12 @@ int cwmp_uci_get_value_by_section_list(struct uci_section *s, char *option, stru
}
return -1;
}
struct uci_section *cwmp_uci_walk_section(char *package, char *stype, void *arg1, void *arg2, int cmp, int (*filter)(struct uci_section *s, void *value), struct uci_section *prev_section, int walk)
{
struct uci_section *s = NULL;
struct uci_element *e, *m;
char *value, *dup, *pch, *spch;
char *value = NULL, *dup = NULL, *pch = NULL, *spch = NULL;
struct uci_list *list_value, *list_section;
struct uci_ptr ptr = { 0 };
@ -491,7 +511,7 @@ struct uci_section *cwmp_uci_walk_section(char *package, char *stype, void *arg1
while (&e->list != list_section) {
s = uci_to_section(e);
if (strcmp(s->type, stype) == 0) {
if (s && s->type && strcmp(s->type, stype) == 0) {
switch (cmp) {
case CWMP_CMP_SECTION:
goto end;
@ -543,3 +563,90 @@ end:
FREE(value);
return s;
}
int cwmp_commit_package(char *package)
{
struct uci_ptr ptr = { 0 };
struct uci_context *c = uci_alloc_context();
if (uci_lookup_ptr(c, &ptr, package, true) != UCI_OK)
return -1;
if (uci_commit(c, &ptr.p, false) != UCI_OK)
return -1;
uci_free_context(c);
return 0;
}
int cwmp_uci_import(char *package_name, const char *input_path)
{
struct uci_package *package = NULL;
struct uci_element *e = NULL;
int ret = CWMP_OK;
struct uci_context *c = uci_alloc_context();
FILE *input = fopen(input_path, "r");
if (!input) {
uci_free_context(c);
return -1;
}
if (uci_import(c, input, package_name, &package, (package_name != NULL)) != UCI_OK) {
ret = -1;
goto end;
}
uci_foreach_element(&c->root, e)
{
struct uci_package *p = uci_to_package(e);
if (uci_commit(c, &p, true) != UCI_OK)
ret = CWMP_GEN_ERR;
}
end:
fclose(input);
uci_free_context(c);
return ret;
}
int cwmp_uci_export_package(char *package, const char *output_path)
{
struct uci_ptr ptr = { 0 };
int ret = 0;
struct uci_context *c = uci_alloc_context();
FILE *out = fopen(output_path, "a");
if (!out) {
uci_free_context(c);
return -1;
}
if (uci_lookup_ptr(c, &ptr, package, true) != UCI_OK) {
ret = -1;
goto end;
}
if (uci_export(c, out, ptr.p, true) != UCI_OK)
ret = -1;
end:
fclose(out);
uci_free_context(c);
return ret;
}
int cwmp_uci_export(const char *output_path)
{
char **configs = NULL;
char **p;
struct uci_context *c = uci_alloc_context();
if ((uci_list_configs(c, &configs) != UCI_OK) || !configs) {
uci_free_context(c);
return -1;
}
for (p = configs; *p; p++)
cwmp_uci_export_package(*p, output_path);
free(configs);
uci_free_context(c);
return 0;
}

View file

@ -93,9 +93,9 @@ void get_parameters_list_from_parameters_blob_array(struct blob_attr *parameters
continue;
int notification = 0;
bool writable = 0;
if (tb[3] && strncmp(blobmsg_get_string(tb[3]), "1", 1) == 0)
if (tb[1] && strncmp(blobmsg_get_string(tb[1]), "1", 1) == 0)
notification = 1;
if (tb[3] && strncmp(blobmsg_get_string(tb[3]), "2", 1) == 0)
else if (tb[1] && strncmp(blobmsg_get_string(tb[1]), "2", 1) == 0)
notification = 2;
if (tb[4] && (strncmp(blobmsg_get_string(tb[4]), "1", 1) == 0 || strcasecmp(blobmsg_get_string(tb[4]), "true") == 0))
writable = true;
@ -332,12 +332,12 @@ 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 cwmp_set_multiple_parameters_values(struct list_head *parameters_values_list, char *parameter_key, int *flag, struct list_head *faults_list)
{
int e;
struct setm_values_res set_result = {.flag = flag, .faults_list = faults_list };
e = cwmp_ubus_call("usp.raw", "setm_values",
CWMP_UBUS_ARGS{ { "pv_tuple", {.param_value_list = &parameters_values_list }, UBUS_List_Param }, { "key", {.str_val = parameter_key }, UBUS_String }, { "transaction_id", {.int_val = transaction_id }, UBUS_Integer }, { "proto", {.str_val = "cwmp" }, UBUS_String } }, 4,
CWMP_UBUS_ARGS{ { "pv_tuple", {.param_value_list = parameters_values_list }, UBUS_List_Param }, { "key", {.str_val = parameter_key }, UBUS_String }, { "transaction_id", {.int_val = transaction_id }, UBUS_Integer }, { "proto", {.str_val = "cwmp" }, UBUS_String } }, 4,
ubus_setm_values_callback, &set_result);
if (e < 0) {

View file

@ -20,7 +20,6 @@
#include <pthread.h>
#include "backupSession.h"
#include "log.h"
#include "external.h"
#include "event.h"
#include "session.h"
#include "xml.h"

View file

@ -1,435 +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-2019 iopsys Software Solutions AB
* Author Mohamed Kallel <mohamed.kallel@pivasoftware.com>
* Author Ahmed Zribi <ahmed.zribi@pivasoftware.com>
* Copyright (C) 2011 Luka Perkov <freecwmp@lukaperkov.net>
*/
#include <poll.h>
#include <json-c/json.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include "external.h"
#include "xml.h"
#include "log.h"
static int pid;
static int pfds_in[2], pfds_out[2];
char *external_MethodFault = NULL;
char *external_MethodName = NULL;
char *external_MethodVersion = NULL;
char *external_MethodUUID = NULL;
char *external_MethodENV = NULL;
#ifdef DUMMY_MODE
static char *fc_script = "./ext/openwrt/scripts/icwmp.sh";
#else
static char *fc_script = "/usr/sbin/icwmp";
#endif
#define ICWMP_PROMPT "icwmp>"
void external_download_fault_resp(char *fault_code)
{
FREE(external_MethodFault);
external_MethodFault = fault_code ? strdup(fault_code) : NULL;
}
void external_fetch_download_fault_resp(char **fault)
{
*fault = external_MethodFault;
external_MethodFault = NULL;
}
void external_upload_fault_resp(char *fault_code)
{
FREE(external_MethodFault);
external_MethodFault = fault_code ? strdup(fault_code) : NULL;
}
void external_fetch_upload_fault_resp(char **fault)
{
*fault = external_MethodFault;
external_MethodFault = NULL;
}
void external_uninstall_fault_resp(char *fault_code)
{
FREE(external_MethodFault);
external_MethodFault = fault_code ? strdup(fault_code) : NULL;
}
void external_fetch_uninstall_fault_resp(char **fault)
{
*fault = external_MethodFault;
external_MethodFault = NULL;
}
void external_du_change_state_fault_resp(char *fault_code, char *version,
char *name, char *uuid, char *env)
{
FREE(external_MethodFault);
external_MethodFault = fault_code ? strdup(fault_code) : NULL;
FREE(external_MethodVersion);
external_MethodVersion = version ? strdup(version) : NULL;
FREE(external_MethodName);
external_MethodName = name ? strdup(name) : NULL;
FREE(external_MethodUUID);
external_MethodUUID = uuid ? strdup(uuid) : NULL;
FREE(external_MethodENV);
external_MethodENV = env ? strdup(env) : NULL;
}
void external_fetch_du_change_state_fault_resp(char **fault, char **version,
char **name, char **uuid, char **env)
{
*fault = external_MethodFault;
external_MethodFault = NULL;
*version = external_MethodVersion;
external_MethodVersion = NULL;
*name = external_MethodName;
external_MethodName = NULL;
*uuid = external_MethodUUID;
external_MethodUUID = NULL;
*env = external_MethodENV;
external_MethodENV = NULL;
}
static void external_read_pipe_input(int (*external_handler)(char *msg))
{
char buf[1], *value = NULL, *c = NULL;
struct pollfd fd = {.fd = pfds_in[0], .events = POLLIN};
while (1) {
poll(&fd, 1, 500000);
if (!(fd.revents & POLLIN))
break;
if (read(pfds_in[0], buf, sizeof(buf)) <= 0)
break;
if (buf[0] != '\n') {
if (value)
cwmp_asprintf(&c, "%s%c", value, buf[0]);
else
cwmp_asprintf(&c, "%c", buf[0]);
FREE(value);
value = c;
} else {
if (!value)
continue;
if (strcmp(value, ICWMP_PROMPT) == 0) {
FREE(value);
break;
}
if (external_handler)
external_handler(value);
FREE(value);
}
}
}
static void external_write_pipe_output(const char *msg)
{
char *value = NULL;
cwmp_asprintf(&value, "%s\n", msg);
if (write(pfds_out[1], value, strlen(value)) == -1) {
CWMP_LOG(ERROR, "Error occured when trying to write to the pipe");
}
free(value);
}
static void json_obj_out_add(json_object *json_obj_out, char *name, char *val)
{
json_object *json_obj_tmp;
json_obj_tmp = json_object_new_string(val);
json_object_object_add(json_obj_out, name, json_obj_tmp);
}
void external_init()
{
if (pipe(pfds_in) < 0)
return;
if (pipe(pfds_out) < 0)
return;
if ((pid = fork()) == -1)
goto error;
if (pid == 0) {
/* child */
close(pfds_out[1]);
close(pfds_in[0]);
dup2(pfds_out[0], STDIN_FILENO);
dup2(pfds_in[1], STDOUT_FILENO);
const char *argv[5];
int i = 0;
argv[i++] = "/bin/sh";
argv[i++] = fc_script;
argv[i++] = "json_continuous_input";
argv[i++] = NULL;
execvp(argv[0], (char**)argv);
close(pfds_out[0]);
close(pfds_in[1]);
exit(ESRCH);
}
close(pfds_in[1]);
close(pfds_out[0]);
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
DD(ERROR, "icwmp script intialization: signal ignoring error");
}
external_read_pipe_input(NULL);
DD(INFO, "icwmp script is listening");
return;
error:
CWMP_LOG(ERROR, "icwmp script intialization failed");
exit(EXIT_FAILURE);
}
void external_exit()
{
int status;
json_object *json_obj_out;
json_obj_out = json_object_new_object();
json_obj_out_add(json_obj_out, "command", "exit");
external_write_pipe_output(json_object_to_json_string(json_obj_out));
json_object_put(json_obj_out);
while (wait(&status) != pid) {
DD(DEBUG, "waiting for child to exit");
}
close(pfds_in[0]);
close(pfds_out[1]);
}
int external_handle_action(int (*external_handler)(char *msg))
{
json_object *json_obj_out;
json_obj_out = json_object_new_object();
json_obj_out_add(json_obj_out, "command", "end");
external_write_pipe_output(json_object_to_json_string(json_obj_out));
json_object_put(json_obj_out);
external_read_pipe_input(external_handler);
return 0;
}
int external_simple(char *command, char *arg, int c)
{
DD(INFO, "executing %s request", command);
json_object *json_obj_out;
/* send data to the script */
json_obj_out = json_object_new_object();
json_obj_out_add(json_obj_out, "command", command);
if (arg)
json_obj_out_add(json_obj_out, "arg", arg);
if (c)
json_obj_out_add(json_obj_out, "ipv6", "1");
external_write_pipe_output(json_object_to_json_string(json_obj_out));
json_object_put(json_obj_out);
return 0;
}
int external_download(char *url, char *size, char *type, char *user, char *pass,
time_t c)
{
DD(INFO, "executing download url '%s'", url);
char *id = NULL;
char *cert_path = NULL;
struct config *conf;
json_object *json_obj_out;
struct cwmp *cwmp = &cwmp_main;
conf = &(cwmp->conf);
if (strncmp(url, DOWNLOAD_PROTOCOL_HTTPS,
strlen(DOWNLOAD_PROTOCOL_HTTPS)) == 0) {
if (conf->https_ssl_capath)
cert_path = strdup(conf->https_ssl_capath);
else
cert_path = NULL;
}
if (cert_path)
CWMP_LOG(DEBUG, "https certif path %s", cert_path)
if (c)
cwmp_asprintf(&id, "%ld", c);
/* send data to the script */
json_obj_out = json_object_new_object();
json_obj_out_add(json_obj_out, "command", "download");
json_obj_out_add(json_obj_out, "url", url);
json_obj_out_add(json_obj_out, "size", size);
json_obj_out_add(json_obj_out, "type", type);
if (user)
json_obj_out_add(json_obj_out, "user", user);
if (pass)
json_obj_out_add(json_obj_out, "pass", pass);
if (id)
json_obj_out_add(json_obj_out, "ids", id);
if (cert_path)
json_obj_out_add(json_obj_out, "cert_path", cert_path);
external_write_pipe_output(json_object_to_json_string(json_obj_out));
json_object_put(json_obj_out);
if (cert_path)
free(cert_path);
if (id)
free(id);
return 0;
}
int external_upload(char *url, char *type, char *user, char *pass, char *name)
{
DD(INFO, "executing download url '%s'", url);
json_object *json_obj_out;
/* send data to the script */
json_obj_out = json_object_new_object();
json_obj_out_add(json_obj_out, "command", "upload");
json_obj_out_add(json_obj_out, "url", url);
json_obj_out_add(json_obj_out, "type", type);
json_obj_out_add(json_obj_out, "name", name);
if (user)
json_obj_out_add(json_obj_out, "user", user);
if (pass)
json_obj_out_add(json_obj_out, "pass", pass);
external_write_pipe_output(json_object_to_json_string(json_obj_out));
json_object_put(json_obj_out);
return 0;
}
int external_change_du_state_install(char *url, char *uuid, char *user,
char *pass, char *env)
{
DD(INFO, "executing DU install");
json_object *json_obj_out;
/* send data to the script */
json_obj_out = json_object_new_object();
json_obj_out_add(json_obj_out, "command", "du_install");
json_obj_out_add(json_obj_out, "url", url);
if (uuid)
json_obj_out_add(json_obj_out, "uuid", uuid);
if (user)
json_obj_out_add(json_obj_out, "user", user);
if (pass)
json_obj_out_add(json_obj_out, "pass", pass);
if (env)
json_obj_out_add(json_obj_out, "env", env);
external_write_pipe_output(json_object_to_json_string(json_obj_out));
json_object_put(json_obj_out);
return 0;
}
int external_change_du_state_update(char *uuid, char *url, char *user,
char *pass)
{
DD(INFO, "executing DU update");
json_object *json_obj_out;
/* send data to the script */
json_obj_out = json_object_new_object();
json_obj_out_add(json_obj_out, "command", "du_update");
json_obj_out_add(json_obj_out, "uuid", uuid);
json_obj_out_add(json_obj_out, "url", url);
if (user)
json_obj_out_add(json_obj_out, "user", user);
if (pass)
json_obj_out_add(json_obj_out, "pass", pass);
external_write_pipe_output(json_object_to_json_string(json_obj_out));
json_object_put(json_obj_out);
return 0;
}
int external_change_du_state_uninstall(char *name, char *env)
{
DD(INFO, "executing DU uninstall");
json_object *json_obj_out;
/* send data to the script */
json_obj_out = json_object_new_object();
json_obj_out_add(json_obj_out, "command", "du_uninstall");
json_obj_out_add(json_obj_out, "name", name);
if (env)
json_obj_out_add(json_obj_out, "env", env);
external_write_pipe_output(json_object_to_json_string(json_obj_out));
json_object_put(json_obj_out);
return 0;
}
int external_apply(char *action, char *arg, time_t c)
{
DD(INFO, "executing apply %s", action);
json_object *json_obj_out;
char *id = NULL;
if (c)
cwmp_asprintf(&id, "%ld", c);
/* send data to the script */
json_obj_out = json_object_new_object();
json_obj_out_add(json_obj_out, "command", "apply");
json_obj_out_add(json_obj_out, "action", action);
if (arg)
json_obj_out_add(json_obj_out, "arg", arg);
if (id)
json_obj_out_add(json_obj_out, "ids", id);
external_write_pipe_output(json_object_to_json_string(json_obj_out));
json_object_put(json_obj_out);
if (id) {
free(id);
id = NULL;
}
return 0;
}

26
http.c
View file

@ -18,13 +18,13 @@
#include <fcntl.h>
#include <errno.h>
#include "external.h"
#include "log.h"
#include "config.h"
#include "event.h"
#include "http.h"
#include "digestauth.h"
#include "cwmp_uci.h"
#include "ubus.h"
#define REALM "authenticate@cwmp"
#define OPAQUE "11733b200778ce33060f31c9af70a870ba96ddd4"
@ -45,7 +45,6 @@ int http_client_init(struct cwmp *cwmp)
char *acs_var_stat = NULL;
unsigned char buf[sizeof(struct in6_addr)];
uci_get_value(UCI_DHCP_DISCOVERY_PATH, &dhcp_dis);
char *uci_cmd = NULL;
if (dhcp_dis && cwmp->retry_count_session > 0 && strcmp(dhcp_dis, "enable") == 0) {
uci_get_state_value(UCI_DHCP_ACS_URL, &acs_var_stat);
@ -90,9 +89,7 @@ int http_client_init(struct cwmp *cwmp)
curl_easy_perform(curl);
int tmp = inet_pton(AF_INET, ip, buf);
cwmp_asprintf(&uci_cmd, "cwmp.acs.ip_version=%d", (tmp == 1) ? 4 : 6);
uci_set_value(uci_cmd);
free(uci_cmd);
uci_set_value(UCI_ACS_IP_VERSION, (tmp == 1) ? "4" : "6", CWMP_CMD_SET);
}
return 0;
}
@ -231,9 +228,15 @@ int http_send_message(struct cwmp *cwmp, char *msg_out, int msg_out_len, char **
else
tmp = inet_pton(AF_INET6, ip, buf);
}
external_init();
external_simple("allow_cr_ip", ip_acs, tmp);
external_exit();
char *zone_name = NULL;
get_firewall_zone_name_by_wan_iface(cwmp->conf.default_wan_iface, &zone_name);
update_firewall_cwmp_file(cwmp->conf.connection_request_port, zone_name ? zone_name : "wan", ip_acs, tmp);
FREE(zone_name);
/*
* Restart firewall service
*/
cwmp_ubus_call("uci", "commit", CWMP_UBUS_ARGS{ { "config", {.str_val = "firewall" }, UBUS_String } }, 1, NULL, NULL);
}
}
@ -387,9 +390,10 @@ void http_server_init(void)
}
break;
}
char buf[64];
sprintf(buf, UCI_CPE_PORT_PATH "=%d", cr_port);
uci_set_state_value(buf);
char cr_port_str[6];
snprintf(cr_port_str, 6, "%hu", cr_port);
cr_port_str[5] = '\0';
uci_set_value(UCI_CPE_PORT_PATH, cr_port_str, CWMP_CMD_SET);
connection_request_port_value_change(&cwmp_main, cr_port);
CWMP_LOG(INFO, "Connection Request server initiated with the port: %d", cr_port);
}

View file

@ -50,6 +50,9 @@
#define DEFAULT_ACSURL "http://192.168.1.1:8080/openacs/acs"
extern char *commandKey;
#define FIREWALL_CWMP "/etc/firewall.cwmp"
#define ICWMP_DOWNLOAD_FILE "/tmp/icwmp_download"
#define FIRMWARE_UPGRADE_IMAGE "/tmp/firmware.bin"
typedef struct env {
unsigned short boot;
@ -70,6 +73,7 @@ typedef struct config {
char *ipv6;
char *interface;
char *ubus_socket;
char *default_wan_iface;
char *connection_request_path;
int connection_request_port;
int period;
@ -436,6 +440,8 @@ typedef struct opfault {
} opfault;
extern struct cwmp cwmp_main;
extern long int flashsize;
int cwmp_exit(void);
void add_dm_parameter_to_list(struct list_head *head, char *param_name, char *param_data, char *param_type, int notification, bool writable);
void delete_dm_parameter_from_list(struct cwmp_dm_parameter *dm_parameter);
@ -446,7 +452,17 @@ void cwmp_del_list_fault_param(struct cwmp_param_fault *param_fault);
void cwmp_free_all_list_param_fault(struct list_head *list_param_fault);
int cwmp_asprintf(char **s, const char *format, ...);
bool folder_exists(const char *path);
void cwmp_reboot(char *command_key);
void cwmp_factory_reset();
void get_firewall_zone_name_by_wan_iface(char *if_wan, char **zone_name);
int update_firewall_cwmp_file(int port, char *zone_name, char *ip_addr, int ip_type);
int download_file(const char *file_path, const char *url, const char *username, const char *password);
int upload_file(const char *file_path, const char *url, const char *username, const char *password);
long int get_file_size(char *file_name);
int cwmp_check_image();
void cwmp_apply_firmware();
int opkg_install_package(char *package_path);
int copy(const char *from, const char *to);
#ifndef FREE
#define FREE(x) \
do { \

View file

@ -24,7 +24,6 @@
#include "xml.h"
#include "backupSession.h"
#include "http.h"
#include "external.h"
#include "diagnostic.h"
#include "config.h"
#include "ubus.h"

4
inc/cwmp_cli.h Normal file
View file

@ -0,0 +1,4 @@
#ifndef CWMP_CLI
#define CWMP_CLI
void execute_cwmp_cli_command(char *cmd, char *args[]);
#endif

18
inc/cwmp_du_state.h Normal file
View file

@ -0,0 +1,18 @@
/*
* 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 Omar Kallel <omar.kallel@pivasoftware.com>
*/
#ifndef CWMP_DU_STATE_H
#define CWMP_DU_STATE_H
int cwmp_du_install(char *url, char *uuid, char *user, char *pass, char *env, char **package_version, char **package_name, char **package_uuid, char **package_env, char **fault_code);
int cwmp_du_update(char *url, char *uuid, char *user, char *pass, char **package_version, char **package_name, char **package_uuid, char **package_env, char **fault_code);
int cwmp_du_uninstall(char *package_name, char *package_env, char **fault_code);
#endif

View file

@ -1,33 +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-2019 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>
*/
#ifndef _JSHN_H__
#define _JSHN_H__
#include <json-c/json.h>
#include "common.h"
struct cwmp_json_arg {
char *key;
char *val;
};
#define CWMP_JSON_ARGS (struct cwmp_json_arg[])
int cwmp_handle_download_fault(char *msg);
int cwmp_handle_upload_fault(char *msg);
int cwmp_handle_dustate_change_fault(char *msg);
int cwmp_handle_uninstall_fault(char *msg);
void cwmp_json_fprintf(FILE *fp, int argc, struct cwmp_json_arg cwmp_arg[]);
#define foreach_jsonobj_in_array(param_obj, parameters) \
int k, array_length = json_object_array_length(parameters); \
for (k = 0, param_obj = json_object_array_get_idx(parameters, 0); k < array_length; k++, param_obj = json_object_array_get_idx(parameters, k))
#endif /* _JSHN_H__ */

View file

@ -24,6 +24,7 @@
#define UCI_ACS_PASSWD_PATH "cwmp.acs.passwd"
#define UCI_ACS_PARAMETERKEY_PATH "cwmp.acs.ParameterKey"
#define UCI_ACS_SSL_CAPATH "cwmp.acs.ssl_capath"
#define UCI_ACS_IP_VERSION "cwmp.acs.ip_version"
#define UCI_HTTPS_SSL_CAPATH "cwmp.acs.https_ssl_capath"
#define UCI_ACS_INSECURE_ENABLE "cwmp.acs.insecure_enable"
#define UCI_ACS_IPV6_ENABLE "cwmp.acs.ipv6_enable"
@ -38,6 +39,7 @@
#define UCI_CPE_INTERFACE_PATH "cwmp.cpe.interface"
#define UCI_CPE_UBUS_SOCKET_PATH "cwmp.cpe.ubus_socket"
#define UCI_CPE_PORT_PATH "cwmp.cpe.port"
#define UCI_CPE_DEFAULT_WAN_IFACE "cwmp.cpe.default_wan_interface"
#define UCI_CPE_CRPATH_PATH "cwmp.cpe.path"
#define UCI_CPE_LOG_FILE_NAME "cwmp.cpe.log_file_name"
#define UCI_CPE_LOG_MAX_SIZE "cwmp.cpe.log_max_size"
@ -50,6 +52,8 @@
#define UCI_CPE_EXEC_DOWNLOAD "cwmp.cpe.exec_download"
#define UCI_CPE_NOTIFY_PERIODIC_ENABLE "cwmp.cpe.periodic_notify_enable"
#define UCI_CPE_NOTIFY_PERIOD "cwmp.cpe.periodic_notify_interval"
#define UCI_CPE_IP "cwmp.cpe.ip"
#define UCI_CPE_IPV6 "cwmp.cpe.ipv6"
#define LW_NOTIFICATION_ENABLE "cwmp.lwn.enable"
#define LW_NOTIFICATION_HOSTNAME "cwmp.lwn.hostname"
#define LW_NOTIFICATION_PORT "cwmp.lwn.port"
@ -63,8 +67,6 @@
typedef enum uci_config_action {
CWMP_CMD_SET,
CWMP_CMD_SET_STATE,
CWMP_CMD_ADD_LIST,
CWMP_CMD_DEL,
} uci_config_action;
enum uci_paths_types
@ -75,6 +77,23 @@ enum uci_paths_types
UCI_VARSTATE_CONFIG,
};
enum uci_val_type
{
UCI_INT,
UCI_STRING
};
union mult_uci_value {
int int_value;
char *str_value;
};
struct cwmp_uci_value {
union mult_uci_value value;
enum uci_val_type type;
};
#define CWMP_UCI_ARG (struct cwmp_uci_value)
enum cwmp_uci_cmp
{
CWMP_CMP_SECTION,
@ -107,16 +126,20 @@ void cwmp_uci_exit(void);
int cwmp_uci_lookup_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *package, char *section, char *option, char *value);
int cwmp_uci_get_option_value_list(char *package, char *section, char *option, struct list_head *list);
int uci_get_state_value(char *cmd, char **value);
int uci_set_state_value(char *cmd);
int uci_set_value(char *cmd);
int uci_set_value(char *cmd, char *value, uci_config_action action);
int uci_get_value(char *cmd, char **value);
char *cwmp_db_get_value_string(char *package, char *section, char *option);
struct uci_section *cwmp_uci_walk_section(char *package, char *stype, void *arg1, void *arg2, int cmp, int (*filter)(struct uci_section *s, void *value), struct uci_section *prev_section, int walk);
int cwmp_uci_get_value_by_section_string(struct uci_section *s, char *option, char **value);
int cwmp_uci_get_option_value_string(char *package, char *section, char *option, int uci_type, char **value);
int cwmp_commit_package(char *package);
int cwmp_uci_import(char *package_name, const char *input_path);
int cwmp_uci_export_package(char *package, const char *output_path);
int cwmp_uci_export(const char *output_path);
#define cwmp_uci_path_foreach_option_eq(package, stype, option, val, section) \
for (section = cwmp_uci_walk_section(package, stype, option, val, CWMP_CMP_OPTION_EQUAL, NULL, NULL, CWMP_GET_FIRST_SECTION); section != NULL; section = cwmp_uci_walk_section(package, stype, option, val, CWMP_CMP_OPTION_EQUAL, NULL, section, CWMP_GET_NEXT_SECTION))
#define cwmp_uci_path_foreach_sections(package, stype, section) for (section = cwmp_uci_walk_section(package, stype, NULL, NULL, CMP_SECTION, NULL, NULL, GET_FIRST_SECTION); section != NULL; section = cwmp_uci_walk_section(package, stype, NULL, NULL, CMP_SECTION, NULL, section, GET_NEXT_SECTION))
#define cwmp_uci_foreach_sections(package, stype, section) \
for (section = cwmp_uci_walk_section(package, stype, NULL, NULL, CWMP_CMP_SECTION, NULL, NULL, CWMP_GET_FIRST_SECTION); section != NULL; section = cwmp_uci_walk_section(package, stype, NULL, NULL, CWMP_CMP_SECTION, NULL, section, CWMP_GET_NEXT_SECTION))
#endif

View file

@ -1,7 +1,6 @@
#ifndef SRC_DATAMODELIFACE_H_
#define SRC_DATAMODELIFACE_H_
#include "common.h"
#include "cwmp_json.h"
#define DM_ROOT_OBJ "Device."
extern bool transaction_started;
@ -15,7 +14,7 @@ bool cwmp_transaction_abort();
bool cwmp_transaction_status();
char *cwmp_get_parameter_values(char *parameter_name, struct list_head *parameters_list);
char *cwmp_get_single_parameter_value(char *parameter_name, struct cwmp_dm_parameter *dm_parameter);
int cwmp_set_multiple_parameters_values(struct list_head parameters_values_list, char *parameter_key, int *flag, struct list_head *faults_list);
int cwmp_set_multiple_parameters_values(struct list_head *parameters_values_list, char *parameter_key, int *flag, struct list_head *faults_list);
char *cwmp_add_object(char *object_name, char *key, char **instance);
char *cwmp_delete_object(char *object_name, char *key);
char *cwmp_get_parameter_names(char *object_name, bool next_level, struct list_head *parameters_list);

View file

@ -1,39 +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-2019 iopsys Software Solutions AB
* Author Mohamed Kallel <mohamed.kallel@pivasoftware.com>
* Author Ahmed Zribi <ahmed.zribi@pivasoftware.com>
* Copyright (C) 2011 Luka Perkov <freecwmp@lukaperkov.net>
*
*/
#ifndef _FREECWMP_EXTERNAL_H__
#define _FREECWMP_EXTERNAL_H__
#include <time.h>
void external_du_change_state_fault_resp(char *fault_code, char *version, char *name, char *uuid, char *env);
void external_download_fault_resp(char *fault_code);
void external_fetch_download_fault_resp(char **fault_code);
void external_upload_fault_resp(char *fault_code);
void external_fetch_upload_fault_resp(char **fault_code);
void external_uninstall_fault_resp(char *fault_code);
void external_fetch_uninstall_fault_resp(char **fault);
int external_simple(char *command, char *arg, int c);
int external_download(char *url, char *size, char *type, char *user, char *pass, time_t c);
int external_upload(char *url, char *type, char *user, char *pass, char *name);
int external_apply(char *action, char *arg, time_t c);
void external_fetch_du_change_state_fault_resp(char **fault, char **version, char **name, char **uuid, char **env);
int external_change_du_state_install(char *url, char *uuid, char *user, char *pass, char *env);
int external_change_du_state_update(char *uuid, char *url, char *user, char *pass);
int external_change_du_state_uninstall(char *name, char *env);
int external_handle_action(int (*external_handler)(char *msg));
void external_add_list_paramameter(char *param_name, char *param_data, char *param_type, char *fault_code);
void external_free_list_parameter();
void external_init();
void external_exit();
#endif

View file

@ -90,7 +90,6 @@ static void freecwmp_netlink_interface(struct nlmsghdr *nlh)
struct rtattr *rth = IFA_RTA(ifa);
int rtl = IFA_PAYLOAD(nlh);
char if_name[IFNAMSIZ], if_addr[INET_ADDRSTRLEN];
char *c;
memset(&if_name, 0, sizeof(if_name));
memset(&if_addr, 0, sizeof(if_addr));
@ -122,10 +121,7 @@ static void freecwmp_netlink_interface(struct nlmsghdr *nlh)
if (cwmp_main.conf.ip)
FREE(cwmp_main.conf.ip);
cwmp_main.conf.ip = strdup(if_addr);
if (cwmp_asprintf(&c, "cwmp.cpe.ip=%s", cwmp_main.conf.ip) != -1) {
uci_set_state_value(c);
free(c);
}
uci_set_value(UCI_CPE_IP, cwmp_main.conf.ip, CWMP_CMD_SET_STATE);
connection_request_ip_value_change(&cwmp_main, IPv4);
break;
}
@ -144,10 +140,7 @@ static void freecwmp_netlink_interface(struct nlmsghdr *nlh)
if (cwmp_main.conf.ipv6)
FREE(cwmp_main.conf.ipv6);
cwmp_main.conf.ipv6 = strdup(pradd_v6);
if (cwmp_asprintf(&c, "cwmp.cpe.ipv6=%s", cwmp_main.conf.ipv6) != -1) {
uci_set_state_value(c);
free(c);
}
uci_set_value(UCI_CPE_IPV6, cwmp_main.conf.ipv6, CWMP_CMD_SET_STATE);
connection_request_ip_value_change(&cwmp_main, IPv6);
break;
}

View file

@ -1,10 +0,0 @@
#!/bin/sh
# Copyright (C) 2011-2012 Luka Perkov <freecwmp@lukaperkov.net>
# set these to appropriate values and remove comment if you want to use them
#default_management_server_acs_hostname=""
#default_management_server_connection_request_url=""
#default_wan_device_mng_interface_ip=""
#default_wan_device_mng_interface_mac=""
#default_device_hosts_dnsmasq_leases_file=""

View file

@ -1,169 +0,0 @@
#!/bin/sh
# Copyright (C) 2011-2012 Luka Perkov <freecwmp@lukaperkov.net>
# Copyright (C) 2013-2019 iopsys Software Solutions AB
# Author Ahmed Zribi <ahmed.zribi@pivasoftware.com>
# Author Mohamed Kallel <mohamed.kallel@pivasoftware.com>
FIRMWARE_UPGRADE_IMAGE="/tmp/firmware.bin"
icwmp_fault_output()
{
local MSG=""
local fault_code="$2"
if ([ "$action" = "du_install" ] || [ "$action" = "du_update" ]);then
local package_name="$3"
local package_version="$4"
local package_uuid="$5"
local package_env="$6"
fi
case "$action" in
du_install|du_update)
json_init
json_add_string "fault_code" "$fault_code"
if [ "$#" = "6" ];then
json_add_string "package_name" "$package_name"
json_add_string "package_version" "$package_version"
json_add_string "package_uuid" "$package_uuid"
json_add_string "package_env" "$package_env"
fi
json_close_object
MSG=`json_dump`
;;
*download|*upload)
json_init
json_add_string "fault_code" "$fault_code"
json_close_object
MSG=`json_dump`
;;
esac
echo "$MSG"
}
icwmp_check_image()
{
code="$(ubus -t 10 call rpc-sys upgrade_test | jsonfilter -e @.code)"
[ "$code" == "0" ] && return 0 || return 1
}
icwmp_check_flash_size()
{
local size=0
if [ -f /proc/mtd ];then
for line in `cat /proc/mtd`
do
if [ "`echo $line|grep "^([^[:space:]]+)[[:space:]]+([^[:space:]]+)[[:space:]]+([^[:space:]]+)[[:space:]]+\"([^[:space:]]+)\""`" != "" ]
then
b=`cat $line|cut -f1 -d " "`
n=`cat $line|cut -f3 -d " "`
if [ "$n" = "\"linux\"" -o "$n" = "\"firmware\"" ];then
size=`echo $(($s))`
break;
fi
fi
done
elif [ -f /proc/partitions ]
then
for line in `cat /proc/partitions`
do
if [ "`echo $line|grep "[[:space:]]*([[:digit:]]+)[[:space:]]+([[:digit:]]+)[[:space:]]+([^[:space:]]+)[[:space:]]+([^[:space:]]+)"`" != "" ]
then
b=`cat $line|cut -f2 -d " "`
n=`cat $line|cut -f3 -d " "`
if [ checkline "([^[:space:]]+)" $n ];then
size=`let $b*1024`;
break;
fi
fi
done
fi
echo "$size"
}
icwmp_apply_firmware()
{
local fault_code="9000"
sync
uci set cwmp.cpe.exec_download=1
uci commit cwmp
ubus call rpc-sys upgrade_start '{"keep":true}'
sleep 60
[ 0 -gt 1 ] # If the updade did not upgrade within 60 seconds, assume it has failed
if [ "$?" != "0" ]; then
let fault_code=$fault_code+$FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED
icwmp_fault_output "" "$fault_code"
uci set cwmp.cpe.exec_download=0
uci commit cwmp
else
icwmp_fault_output "" "$FAULT_CPE_NO_FAULT"
fi
}
icwmp_apply_web_content()
{
local fault_code="9000"
/bin/opkg install /tmp/web_content.ipk
if [ "$?" != "0" ];then
rm /tmp/web_content.ipk 2> /dev/null
let fault_code=$fault_code+$FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED
icwmp_fault_output "" "$fault_code"
else
icwmp_fault_output "" "$FAULT_CPE_NO_FAULT"
fi
}
icwmp_apply_vendor_configuration()
{
local fault_code="9000"
local current_file="/tmp/vendor_configuration_file.cfg"
if [ $# -eq 0 ]; then
/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q import < /tmp/vendor_configuration_file.cfg
else
current_file="/etc/vendor_configuration_file_$1.cfg"
/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q import < /etc/vendor_configuration_file_$1.cfg
rm "$current_file" 2> /dev/null
fi
if [ "$?" = "0" ];then
/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q commit
if [ "$?" != "0" ];then
let fault_code=$fault_code+$FAULT_CPE_INTERNAL_ERROR
icwmp_fault_output "" "$fault_code"
else
icwmp_fault_output "" "$FAULT_CPE_NO_FAULT"
sync
reboot
fi
else
if [ -f "$current_file" ]; then
rm "$current_file" 2> /dev/null;
fi
let fault_code=$fault_code+$FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED
icwmp_fault_output "" "$fault_code"
fi
}
icwmp_apply_ca_ssl_certificate_key()
{
local fault_code="9000"
local current_file="/tmp/owsd-repeater-control-cert.pem"
# if [ $# -gt 0 ]; then
# current_file="/tmp/$1"
# fi
cert=`uci get owsd.ubusproxy.peer_cert`
# i=1
# test=true
# path=""
# while [[ $test ]]
# do
# i=$((i+1))
# command="echo $cert | awk -F\"/\" '{print \$$i}'"
# dir=`eval $command`
# if [[ -z $dir ]]; then break; fi
# path=$path"/"$dir
# if [ ! -d $path ]; then mkdir $path; fi
# done
cp $current_file $cert
}

View file

@ -1,29 +0,0 @@
#!/bin/sh
# Copyright (C) 2019 iopsys Software Solutions AB
# Author: imen BHIRI <imen.bhiri@pivasoftware.com>
UCI_CONFIG_DIR="/etc/config/"
BACKUP_FILE="/etc/backup"
RESTORED_CONFIG_FILE="dropbear firewall mcpd multiwan network dhcp owsd samba system voice_client wireless"
export_config() {
rm -f $BACKUP_FILE
for i in `echo ${RESTORED_CONFIG_FILE}`; do
/sbin/uci -q ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} export /etc/config/$i >> $BACKUP_FILE
done
}
import_config() {
/sbin/uci -q ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} import < $BACKUP_FILE
}
if [ "$1" == "export_conf" ] ; then
export_config
return
elif [ "$1" == "import_conf" ] ; then
import_config
return
else
return
fi

View file

@ -1,704 +0,0 @@
#!/bin/sh
# Copyright (C) 2011-2012 Luka Perkov <freecwmp@lukaperkov.net>
# Copyright (C) 2013-2019 iopsys Software Solutions AB
# Author Mohamed Kallel <mohamed.kallel@pivasoftware.com>
# Author Ahmed Zribi <ahmed.zribi@pivasoftware.com>
. /usr/share/libubox/jshn.sh
#TODO help message
NEW_LINE='\n'
CWMP_PROMPT="icwmp>"
UCI_GET="/sbin/uci -q ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get"
UCI_SHOW="/sbin/uci -q ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} show"
UCI_IMPORT="/sbin/uci -q ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} import"
UCI_EXPORT="/sbin/uci -q ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} export"
TMP_SET_VALUE="/tmp/.tmp_set_value"
TMP_SET_NOTIFICATION="/tmp/.tmp_set_notification"
# Fault codes
FAULT_CPE_NO_FAULT="0"
FAULT_CPE_INTERNAL_ERROR="2"
FAULT_CPE_DOWNLOAD_FAILURE="10"
FAULT_CPE_UPLOAD_FAILURE="11"
FAULT_CPE_DOWNLOAD_FAIL_CONTACT_SERVER="15"
FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED="18"
FAULT_CPE_DOWNLOAD_FAIL_FILE_AUTHENTICATION="19"
ICWMP_DOWNLOAD_FILE="/tmp/icwmp_download"
FIRMWARE_UPGRADE_IMAGE="/tmp/firmware.bin"
for ffile in `ls /usr/share/icwmp/functions/`; do
. /usr/share/icwmp/functions/$ffile
done
case "$1" in
set)
if [ "$2" = "notification" ]; then
__arg1="$3"
__arg2="$4"
__arg3="$5"
action="set_notification"
elif [ "$2" = "value" ]; then
__arg1="$3"
__arg2="$4"
__arg3="$5"
action="set_value"
else
__arg1="$2"
__arg2="$3"
__arg3="$4"
action="set_value"
fi
;;
get)
if [ "$2" = "notification" ]; then
__arg1="$3"
action="get_notification"
elif [ "$2" = "value" ]; then
__arg1="$3"
action="get_value"
elif [ "$2" = "name" ]; then
__arg1="$3"
__arg2="$4"
action="get_name"
else
__arg1="$2"
action="get_value"
fi
;;
download)
__arg1="$2"
__arg2="$3"
__arg3="$4"
__arg4="$5"
__arg5="$6"
action="download"
;;
du_install)
__arg1="$2"
__arg2="$3"
__arg3="$4"
__arg4="$5"
__arg5="$6"
action="du_install"
;;
du_update)
__arg1="$2"
__arg2="$3"
__arg3="$4"
__arg4="$5"
action="du_update"
;;
du_uninstall)
__arg1="$2"
__arg2="$3"
action="du_uninstall"
;;
upload)
__arg1="$2"
__arg2="$3"
__arg3="$4"
__arg4="$5"
__arg5="$6"
action="upload"
;;
factory_reset)
action="factory_reset"
;;
factory_reset_soft)
action="factory_reset_soft"
;;
reboot)
action="reboot"
;;
apply)
if [ "$2" = "notification" ]; then
action="apply_notification"
elif [ "$2" = "value" ]; then
__arg1="$3"
action="apply_value"
elif [ "$2" = "download" ]; then
__arg1="$3"
action="apply_download"
else
__arg1="$2"
action="apply_value"
fi
;;
add)
__arg1="$2"
__arg2="$3"
action="add_object"
;;
delete)
__arg1="$2"
__arg2="$3"
action="del_object"
;;
inform)
action="inform"
;;
allow_cr_ip)
action="allow_cr_ip"
__arg1="$2"
__arg2="$3"
;;
json_continuous_input)
action="json_continuous_input"
;;
end)
echo "$CWMP_PROMPT"
;;
exit)
exit 0
;;
esac
if [ -z "$action" ]; then
echo invalid action \'$1\'
exit 1
fi
handle_action() {
local fault_code=$FAULT_CPE_NO_FAULT
if [ "$action" = "get_value" ]; then
ubus call usp.raw get "{'path':'$__arg1','proto':'cwmp'}"
fi
if [ "$action" = "get_notification" ]; then
ubus call usp.raw getm_attributes "{'paths':['$__arg1'],'proto':'cwmp'}"
fi
if [ "$action" = "get_name" ]; then
if [ $__arg2 -eq 1 ]; then
nextlevel=true
else
nextlevel=false
fi
ubus call usp.raw object_names "{'path':'$__arg1','proto':'cwmp','next-level':$nextlevel}"
fi
if [ "$action" = "set_value" ]; then
transaction_start_ret=`ubus call usp.raw transaction_start '{"app":"cwmp"}'`
if [ `echo $transaction_start_ret | jsonfilter -e @.status` = false ];then
echo "Not able to start a transaction "
exit 0
fi
transaction_id=`echo $transaction_start_ret | jsonfilter -e @.transaction_id`
set_res=`ubus call usp.raw set "{'path':'$__arg1','value':'$__arg2','proto':'cwmp','key':'$__arg3','transaction_id':$transaction_id}"`
if [ -z `echo $set_res | jsonfilter -e @.fault` ]; then
if [ `echo $set_res | jsonfilter -e @.status` = true ]; then
ubus call usp.raw transaction_commit "{'transaction_id':$transaction_id}" &> /dev/null
else
ubus call usp.raw transaction_abort "{'transaction_id':$transaction_id}" &> /dev/null
fi
else
ubus call usp.raw transaction_abort "{'transaction_id':$transaction_id}" &> /dev/null
fi
echo $set_res
exit 0
fi
if [ "$action" = "set_notification" ]; then
transaction_start_ret=`ubus call usp.raw transaction_start '{"app":"cwmp"}'`
if [ `echo $transaction_start_ret | jsonfilter -e @.status` = false ];then
echo "Not able to start a transaction "
exit 0
fi
transaction_id=`echo $transaction_start_ret | jsonfilter -e @.transaction_id`
set_notif=`ubus call usp.raw setm_attributes "{'paths':[{'path':'$__arg1','notify-type':'$__arg2','notify':'1'}], 'transaction_id': $transaction_id}"`
if [ -z `echo $set_notif | jsonfilter -e @.fault` ]; then
if [ -z `echo $set_notif | jsonfilter -e @.parameters[0].fault` ]; then
ubus call usp.raw transaction_commit "{'transaction_id':$transaction_id}" &> /dev/null
else
ubus call usp.raw transaction_abort "{'transaction_id':$transaction_id}" &> /dev/null
fi
else
ubus call usp.raw transaction_abort "{'transaction_id':$transaction_id}" &> /dev/null
fi
echo $set_notif
exit 0
fi
if [ "$action" = "add_object" -o "$action" = "del_object" ]; then
transaction_start_ret=`ubus call usp.raw transaction_start '{"app":"cwmp"}'`
if [ `echo $transaction_start_ret | jsonfilter -e @.status` = false ];then
echo "Not able to start a transaction "
exit 0
fi
transaction_id=`echo $transaction_start_ret | jsonfilter -e @.transaction_id`
adddel_obj_res=`ubus call usp.raw $action "{'path':'$__arg1','key':'$__arg2','proto':'cwmp','instance_mode':0, 'transaction_id':$transaction_id}"`
if [ -z `echo $adddel_obj_res | jsonfilter -e @.fault` ]; then
if [ -z `echo $adddel_obj_res | jsonfilter -e @.parameters[0].fault` ]; then
ubus call usp.raw transaction_commit "{'transaction_id':$transaction_id}" &> /dev/null
else
ubus call usp.raw transaction_abort "{'transaction_id':$transaction_id}" &> /dev/null
fi
else
ubus call usp.raw transaction_abort "{'transaction_id':$transaction_id}" &> /dev/null
fi
echo $adddel_obj_res
exit 0
fi
if [ "$action" = "inform" ]; then
/usr/sbin/icwmpd -m 1 "inform"
fi
if [ "$action" = "du_install" ]; then
local fault_code="9000"
ubus_args=`echo {\"url\":\"$__arg1\",\"uuid\":\"$__arg2\",\"username\":\"$__arg3\",\"password\":\"$__arg4\",\"environment\":\"$__arg5\"}`
output=`ubus -t 3 call swmodules du_install $ubus_args`
if [ "$output" != "" ];then
json_init
json_load "$output"
json_get_var status status
if [ "$status" == "0" ];then
json_get_var error error
if [ "$error" == "Download" ];then
let fault_code=$fault_code+$FAULT_CPE_DOWNLOAD_FAILURE
else
let fault_code=$fault_code+$FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED
fi
icwmp_fault_output "" "$fault_code"
return 1
else
json_get_var name name
json_get_var uuid uuid
json_get_var version version
json_get_var environment environment
icwmp_fault_output "" "$FAULT_CPE_NO_FAULT" "$name" "$version" "$uuid" "$environment"
fi
fi
fi
if [ "$action" = "du_update" ]; then
local fault_code="9000"
ubus_args=`echo {\"uuid\":\"$__arg1\",\"url\":\"$__arg2\",\"username\":\"$__arg3\",\"password\":\"$__arg4\"}`
output=`ubus -t 3 call swmodules du_update $ubus_args`
if [ "$output" != "" ];then
json_init
json_load "$output"
json_get_var status status
if [ "$status" == "0" ];then
let fault_code=$fault_code+$FAULT_CPE_DOWNLOAD_FAILURE
icwmp_fault_output "" "$fault_code"
return 1
else
json_get_var name name
json_get_var uuid uuid
json_get_var version version
json_get_var environment environment
icwmp_fault_output "" "$FAULT_CPE_NO_FAULT" "$name" "$version" "$uuid" "$environment"
fi
fi
fi
if [ "$action" = "du_uninstall" ]; then
local fault_code="9000"
ubus_args=`echo {\"name\":\"$__arg1\",\"environment\":\"$__arg2\"}`
output=`ubus -t 3 call swmodules du_uninstall $ubus_args`
if [ "$output" != "" ];then
json_init
json_load "$output"
json_get_var status status
if [ "$status" == "0" ];then
let fault_code=$fault_code+$FAULT_CPE_DOWNLOAD_FAILURE
icwmp_fault_output "" "$fault_code"
return 1
else
icwmp_fault_output "" "$FAULT_CPE_NO_FAULT"
fi
fi
fi
if [ "$action" = "download" ]; then
local fault_code="9000"
if [ "$__arg4" = "" -o "$__arg5" = "" ];then
if [ "$__arg7" != "" ];then
resp=$(curl --fail --capath $__arg7 --write-out %{http_code} --silent -o $ICWMP_DOWNLOAD_FILE $__arg1)
elif [ ${__arg1:0:8} = https:// ];then
resp=`curl --fail --write-out %{http_code} --silent -k --connect-timeout 10 --retry 1 -o $ICWMP_DOWNLOAD_FILE $__arg1`
else
resp=`curl --write-out %{http_code} --silent --connect-timeout 10 --retry 1 -o $ICWMP_DOWNLOAD_FILE $__arg1`
fi
if [ "$resp" == "404" ];then
let fault_code=$fault_code+$FAULT_CPE_DOWNLOAD_FAIL_CONTACT_SERVER
icwmp_fault_output "" "$fault_code"
return 1
elif [ "$resp" == "401" ];then
let fault_code=$fault_code+$FAULT_CPE_DOWNLOAD_FAIL_FILE_AUTHENTICATION
icwmp_fault_output "" "$fault_code"
return 1
elif [ "$resp" != "200" ];then
let fault_code=$fault_code+$FAULT_CPE_DOWNLOAD_FAILURE
icwmp_fault_output "" "$fault_code"
return 1
fi
else
local url=`echo "$__arg1" | sed -e "s@://@://$__arg4:$__arg5\@@g"`
if [ "$__arg7" != "" ];then
resp=$(curl --fail --capath $__arg7 -u $__arg4:$__arg5 --anyauth --write-out %{http_code} --silent -o $ICWMP_DOWNLOAD_FILE $__arg1)
elif [ ${__arg1:0:8} = https:// ];then
resp=`curl --fail -u $__arg4:$__arg5 --anyauth --write-out %{http_code} --silent -k --connect-timeout 10 --retry 1 -o $ICWMP_DOWNLOAD_FILE $__arg1`
else
resp=`curl --fail -u $__arg4:$__arg5 --anyauth --write-out %{http_code} --silent --connect-timeout 10 --retry 1 -o $ICWMP_DOWNLOAD_FILE $__arg1`
fi
resp=`echo $resp| awk '{print $NF}'`
if [ "$resp" == "404" ];then
let fault_code=$fault_code+$FAULT_CPE_DOWNLOAD_FAIL_CONTACT_SERVER
icwmp_fault_output "" "$fault_code"
return 1
elif [ "$resp" == "401" ];then
let fault_code=$fault_code+$FAULT_CPE_DOWNLOAD_FAIL_FILE_AUTHENTICATION
icwmp_fault_output "" "$fault_code"
return 1
elif [ "$resp" != "200" ];then
let fault_code=$fault_code+$FAULT_CPE_DOWNLOAD_FAILURE
icwmp_fault_output "" "$fault_code"
return 1
fi
fi
local flashsize=256000000 #flashsize="`icwmp_check_flash_size`"
local filesize=`ls -l $ICWMP_DOWNLOAD_FILE | awk '{ print $5 }'`
if [ $flashsize -gt 0 -a $flashsize -lt $__arg2 ]; then
let fault_code=$fault_code+$FAULT_CPE_DOWNLOAD_FAILURE
rm $ICWMP_DOWNLOAD_FILE 2> /dev/null
icwmp_fault_output "" "$fault_code"
else
if [ "$__arg3" = "1 Firmware Upgrade Image" ];then
mv $ICWMP_DOWNLOAD_FILE $FIRMWARE_UPGRADE_IMAGE 2> /dev/null
(icwmp_check_image)
if [ "$?" = "0" ];then
if [ $flashsize -gt 0 -a $filesize -gt $flashsize ];then
let fault_code=$fault_code+$FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED
rm -f $FIRMWARE_UPGRADE_IMAGE
icwmp_fault_output "" "$fault_code"
else
icwmp_fault_output "" "$FAULT_CPE_NO_FAULT"
fi
else
let fault_code=$fault_code+$FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED
rm -f $FIRMWARE_UPGRADE_IMAGE
icwmp_fault_output "" "$fault_code"
fi
elif [ "$__arg3" = "2 Web Content" ];then
mv $ICWMP_DOWNLOAD_FILE /tmp/web_content.ipk 2> /dev/null
icwmp_fault_output "" "$FAULT_CPE_NO_FAULT"
elif [ "$__arg3" = "3 Vendor Configuration File" ];then
if [ "$__arg6" != "" ]; then
local tmp="/etc/vendor_configuration_file_${__arg6}.cfg"
mv $ICWMP_DOWNLOAD_FILE "$tmp" 2> /dev/null
else
mv $ICWMP_DOWNLOAD_FILE /tmp/vendor_configuration_file.cfg 2> /dev/null
fi
icwmp_fault_output "" "$FAULT_CPE_NO_FAULT"
elif [ "$__arg3" = "6 Stored Firmware Image" ]; then
mv $ICWMP_DOWNLOAD_FILE /tmp/owsd-repeater-control-cert.pem 2> /dev/null
icwmp_fault_output "" "$FAULT_CPE_NO_FAULT"
else
let fault_code=$fault_code+$FAULT_CPE_DOWNLOAD_FAILURE
icwmp_fault_output "" "$fault_code"
rm $ICWMP_DOWNLOAD_FILE 2> /dev/null
fi
fi
fi
if [ "$action" = "upload" ]; then
local fault_code="9000"
local flname=""
case $__arg2 in
"1"*|"3"*)
if [ "$__arg5" = "" ];then
__arg5="all_configs"
$UCI_EXPORT > "/tmp/${__arg5}"
else
$UCI_EXPORT "$__arg5" > "/tmp/${__arg5}"
fi
if [ "$__arg3" = "" -o "$__arg4" = "" ];then
if [ ${__arg1:0:4} = http ];then
resp=`curl -I -T "/tmp/${__arg5}" "$__arg1" 2>&1 | awk '/^HTTP/{print $2}' | awk '!/100/'`
if [ "$resp" != "200" ];then
let fault_code=$fault_code+$FAULT_CPE_UPLOAD_FAILURE
icwmp_fault_output "" "$fault_code"
return 1
fi
else
curl -T "/tmp/${__arg5}" "$__arg1" &> /dev/null
if [ "$?" != "0" ];then
let fault_code=$fault_code+$FAULT_CPE_UPLOAD_FAILURE
icwmp_fault_output "" "$fault_code"
return 1
fi
fi
else
if [ ${__arg1:0:4} = http ];then
resp=`curl -I -T "/tmp/${__arg5}" -u $__arg3:$__arg4 "$__arg1" 2>&1 | awk '/^HTTP/{print $2}' | awk '!/100/'`
if [ "$resp" != "200" ];then
let fault_code=$fault_code+$FAULT_CPE_UPLOAD_FAILURE
icwmp_fault_output "" "$fault_code"
return 1
fi
else
curl -T "/tmp/${__arg5}" -u $__arg3:$__arg4 "$__arg1" &> /dev/null
if [ "$?" != "0" ];then
let fault_code=$fault_code+$FAULT_CPE_UPLOAD_FAILURE
icwmp_fault_output "" "$fault_code"
return 1
fi
fi
fi
;;
"2"*|"4"*)
flname=`$UCI_GET system.@system[0].log_file`
if [ "$flname" = "" ];then
let fault_code=$fault_code+$FAULT_CPE_INTERNAL_ERROR
icwmp_fault_output "" "$fault_code"
return 1
fi
if [ "$__arg3" = "" -o "$__arg4" = "" ];then
if [ ${__arg1:0:4} = http ];then
resp=`curl -I -T "$flname" "$__arg1" 2>&1 | awk '/^HTTP/{print $2}' | awk '!/100/'`
if [ "$resp" != "200" ];then
let fault_code=$fault_code+$FAULT_CPE_UPLOAD_FAILURE
icwmp_fault_output "" "$fault_code"
return 1
fi
else
curl -T "$flname" "$__arg1" &> /dev/null
if [ "$?" != "0" ];then
let fault_code=$fault_code+$FAULT_CPE_UPLOAD_FAILURE
icwmp_fault_output "" "$fault_code"
return 1
fi
fi
else
if [ ${__arg1:0:4} = http ];then
resp=`curl -I -T "$flname" -u $__arg3:$__arg4 "$__arg1" 2>&1 | awk '/^HTTP/{print $2}' | awk '!/100/'`
if [ "$resp" != "200" ];then
let fault_code=$fault_code+$FAULT_CPE_UPLOAD_FAILURE
icwmp_fault_output "" "$fault_code"
return 1
fi
else
curl -T "$flname" -u $__arg3:$__arg4 "$__arg1" &> /dev/null
if [ "$?" != "0" ];then
let fault_code=$fault_code+$FAULT_CPE_UPLOAD_FAILURE
icwmp_fault_output "" "$fault_code"
return 1
fi
fi
fi
;;
esac
fi
if [ "$action" = "apply_download" ]; then
case "$__arg1" in
"1 Firmware Upgrade Image")
icwmp_apply_firmware
;;
"2 Web Content")
if [ "$__arg2" != "0" ]; then
icwmp_apply_web_content $__arg2
else
icwmp_apply_web_content
fi
;;
"3 Vendor Configuration File")
if [ "$__arg2" != "" ]; then
icwmp_apply_vendor_configuration $__arg2
else
icwmp_apply_vendor_configuration
fi
;;
"6 Stored Firmware Image")
icwmp_apply_ca_ssl_certificate_key
;;
esac
fi
if [ "$action" = "factory_reset" ]; then
/sbin/defaultreset
fi
if [ "$action" = "factory_reset_soft" ]; then
/sbin/defaultreset
fi
if [ "$action" = "reboot" ]; then
sync
uci set cwmp.acs.ParameterKey="$commandKey"
uci commit cwmp
reboot
fi
if [ "$action" = "allow_cr_ip" ]; then
local port=`$UCI_GET cwmp.cpe.port`
local if_wan=`$UCI_GET cwmp.cpe.default_wan_interface`
local zone=`$UCI_SHOW firewall | grep "firewall\.@zone\[[0-9]\+\]\.network=.*$if_wan" | head -1 | cut -f2 -d.`
local zone_name=`$UCI_GET firewall.$zone.name`
if [ "$zone_name" = "" ]; then
zone_name=icwmp
fi
sed -i "s,^port=.*,port=${port},g" /etc/firewall.cwmp
sed -i "s,^zone_name=.*,zone_name=${zone_name},g" /etc/firewall.cwmp
# update iptables rule
if [ "$__arg2" != "1" ]; then
sed -i "s,^.*iptables.*Open ACS port.*,iptables -I zone_${zone_name}_input -p tcp -s $__arg1 --dport $port -j ACCEPT -m comment --comment=\"Open ACS port\",g" /etc/firewall.cwmp
else
sed -i "s,^.*iptables.*Open ACS port.*,ip6tables -I zone_${zone_name}_input -p tcp -s $__arg1 --dport $port -j ACCEPT -m comment --comment=\"Open ACS port\",g" /etc/firewall.cwmp
fi
fw3 reload
fi
if [ "$action" = "json_continuous_input" ]; then
echo "$CWMP_PROMPT"
while read CMD; do
[ -z "$CMD" ] && continue
result=""
json_init
json_load "$CMD"
json_get_var command command
json_get_var action action
json_get_var arg arg
case "$command" in
set)
if [ "$action" = "notification" ]; then
json_get_var __arg1 parameter
json_get_var __arg2 value
json_get_var __arg3 change
action="set_notification"
elif [ "$action" = "value" ]; then
json_get_var __arg1 parameter
json_get_var __arg2 value
action="set_value"
else
json_get_var __arg1 parameter
json_get_var __arg2 value
action="set_value"
fi
;;
get)
if [ "$action" = "notification" ]; then
json_get_var __arg1 parameter
action="get_notification"
elif [ "$action" = "value" ]; then
json_get_var __arg1 parameter
action="get_value"
elif [ "$action" = "name" ]; then
json_get_var __arg1 parameter
json_get_var __arg2 next_level
action="get_name"
else
json_get_var __arg1 parameter
action="get_value"
fi
;;
download)
json_get_var __arg1 url
json_get_var __arg2 size
json_get_var __arg3 type
json_get_var __arg4 user
json_get_var __arg5 pass
json_get_var __arg6 ids
json_get_var __arg7 cert_path
action="download"
;;
du_install)
json_get_var __arg1 url
json_get_var __arg2 uuid
json_get_var __arg3 user
json_get_var __arg4 pass
json_get_var __arg5 env
action="du_install"
;;
du_update)
json_get_var __arg1 uuid
json_get_var __arg2 url
json_get_var __arg3 user
json_get_var __arg4 pass
action="du_update"
;;
du_uninstall)
json_get_var __arg1 name
json_get_var __arg2 env
action="du_uninstall"
;;
upload)
json_get_var __arg1 url
json_get_var __arg2 type
json_get_var __arg3 user
json_get_var __arg4 pass
json_get_var __arg5 name
action="upload"
;;
factory_reset)
action="factory_reset"
;;
factory_reset_soft)
action="factory_reset_soft"
;;
reboot)
action="reboot"
commandKey="$arg"
;;
apply)
if [ "$action" = "notification" ]; then
action="apply_notification"
elif [ "$action" = "value" ]; then
json_get_var __arg1 arg
action="apply_value"
elif [ "$action" = "download" ]; then
json_get_var __arg1 arg
json_get_var __arg2 ids
action="apply_download"
else
json_get_var __arg1 arg
action="apply_value"
fi
;;
add)
json_get_var __arg1 parameter
json_get_var __arg2 parameter_key
action="add_object"
;;
delete)
json_get_var __arg1 parameter
json_get_var __arg2 parameter_key
action="del_object"
;;
inform)
action="inform"
;;
allow_cr_ip)
action="allow_cr_ip"
json_get_var __arg1 arg
json_get_var __arg2 ipv6
;;
end)
echo "$CWMP_PROMPT"
;;
exit)
exit 0
;;
*)
continue
;;
esac
handle_action
done
exit 0;
fi
}
handle_action 2> /dev/null

View file

@ -1,25 +0,0 @@
#!/usr/sbin/bash
# Copyright (C) 2013-2019 iopsys Software Solutions AB
# Author Mohamed Kallel <mohamed.kallel@pivasoftware.com>
usage()
{
echo "Usage: $0 <strength> <passphrase>"
echo "<strength> Indicate the WEP KEY strength to generate. Should be 64 or 128"
echo "<passphrase> Indicate the passphrase used to generate the WEP KEY"
echo "$0 -h display this help"
}
if [ "_$1" = "-h" ]; then
usage;
exit 0;
fi
strength=$1
passphrase=$2
if [ _$strength != "_64" -a _$strength != "_128" ] || [ _$passphrase = "_" ]; then
usage;
exit 0;
fi
/usr/sbin/icwmpd -w "$strength" "$passphrase"

View file

@ -1,16 +0,0 @@
#!/bin/sh
. /usr/share/libubox/jshn.sh
case "$1" in
list)
echo '{ "connection_request" : {} }'
;;
call)
case "$2" in
connection_request)
ubus call tr069 inform '{"event" : "6 connection request"}'
;;
esac
;;
esac

1
ubus.c
View file

@ -24,7 +24,6 @@
#include "cwmp_time.h"
#include "event.h"
#include "backupSession.h"
#include "cwmp_json.h"
static struct ubus_context *ctx = NULL;
static struct blob_buf b;

470
xml.c
View file

@ -12,19 +12,19 @@
* Copyright (C) 2011-2012 Luka Perkov <freecwmp@lukaperkov.net>
* Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com>
*/
#include "xml.h"
#include "http.h"
#include "cwmp_time.h"
#include "cwmp_zlib.h"
#include "notifications.h"
#include "external.h"
#include "messages.h"
#include "backupSession.h"
#include "log.h"
#include "datamodel_interface.h"
#include "cwmp_uci.h"
#include "diagnostic.h"
#include "ubus.h"
#include "cwmp_du_state.h"
LIST_HEAD(list_download);
LIST_HEAD(list_upload);
@ -1624,7 +1624,7 @@ int cwmp_handle_rpc_cpe_set_parameter_values(struct session *session, struct rpc
goto fault;
transaction_started = true;
}
fault_code = cwmp_set_multiple_parameters_values(list_set_param_value, parameter_key, &flag, rpc->list_set_value_fault);
fault_code = cwmp_set_multiple_parameters_values(&list_set_param_value, parameter_key, &flag, rpc->list_set_value_fault);
if (fault_code != FAULT_CPE_NO_FAULT)
goto fault;
@ -2343,37 +2343,59 @@ error:
int cwmp_launch_download(struct download *pdownload, struct transfer_complete **ptransfer_complete)
{
int i, error = FAULT_CPE_NO_FAULT;
int error = FAULT_CPE_NO_FAULT;
char *download_startTime;
struct transfer_complete *p;
char *fault_code;
char file_size[128];
download_startTime = mix_get_time();
bkp_session_delete_download(pdownload);
bkp_session_save();
sprintf(file_size, "%d", pdownload->file_size);
external_download(pdownload->url, file_size, pdownload->file_type, pdownload->username, pdownload->password, 0);
external_handle_action(cwmp_handle_download_fault);
external_fetch_download_fault_resp(&fault_code);
if (fault_code != NULL) {
if (fault_code[0] == '9') {
for (i = 1; i < __FAULT_CPE_MAX; i++) {
if (strcmp(FAULT_CPE_ARRAY[i].CODE, fault_code) == 0) {
error = i;
break;
}
}
}
free(fault_code);
if (flashsize < pdownload->file_size) {
error = FAULT_CPE_DOWNLOAD_FAILURE;
goto end_download;
}
/*else {
error = FAULT_CPE_INTERNAL_ERROR;
}*/
int http_code = download_file(ICWMP_DOWNLOAD_FILE, pdownload->url, pdownload->username, pdownload->password);
if (http_code == 404)
error = FAULT_CPE_DOWNLOAD_FAIL_CONTACT_SERVER;
else if (http_code == 401)
error = FAULT_CPE_DOWNLOAD_FAIL_FILE_AUTHENTICATION;
else if (http_code != 200)
error = FAULT_CPE_DOWNLOAD_FAILURE;
if (error != FAULT_CPE_NO_FAULT)
goto end_download;
if (strcmp(pdownload->file_type, "1 Firmware Upgrade Image") == 0) {
rename(ICWMP_DOWNLOAD_FILE, FIRMWARE_UPGRADE_IMAGE);
if (cwmp_check_image() == 0) {
long int file_size = get_file_size(FIRMWARE_UPGRADE_IMAGE);
if (file_size > flashsize) {
error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED;
remove(FIRMWARE_UPGRADE_IMAGE);
goto end_download;
} else {
error = FAULT_CPE_NO_FAULT;
goto end_download;
}
} else {
error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED;
remove(FIRMWARE_UPGRADE_IMAGE);
}
} else if (strcmp(pdownload->file_type, "2 Web Content") == 0) {
rename(ICWMP_DOWNLOAD_FILE, "/tmp/web_content.ipk");
error = FAULT_CPE_NO_FAULT;
} else if (strcmp(pdownload->file_type, "3 Vendor Configuration File") == 0) {
rename(ICWMP_DOWNLOAD_FILE, "/tmp/vendor_configuration_file.cfg");
error = FAULT_CPE_NO_FAULT;
} else {
remove(ICWMP_DOWNLOAD_FILE);
error = FAULT_CPE_NO_FAULT;
}
end_download:
p = calloc(1, sizeof(struct transfer_complete));
if (p == NULL) {
error = FAULT_CPE_INTERNAL_ERROR;
@ -2394,37 +2416,59 @@ int cwmp_launch_download(struct download *pdownload, struct transfer_complete **
int cwmp_launch_schedule_download(struct schedule_download *pdownload, struct transfer_complete **ptransfer_complete)
{
int i, error = FAULT_CPE_NO_FAULT;
int error = FAULT_CPE_NO_FAULT;
char *download_startTime;
struct transfer_complete *p;
char *fault_code;
char file_size[128];
download_startTime = mix_get_time();
bkp_session_delete_schedule_download(pdownload);
bkp_session_save();
sprintf(file_size, "%d", pdownload->file_size);
external_download(pdownload->url, file_size, pdownload->file_type, pdownload->username, pdownload->password, pdownload->timewindowstruct[0].windowstart);
external_handle_action(cwmp_handle_download_fault);
external_fetch_download_fault_resp(&fault_code);
if (fault_code != NULL) {
if (fault_code[0] == '9') {
for (i = 1; i < __FAULT_CPE_MAX; i++) {
if (strcmp(FAULT_CPE_ARRAY[i].CODE, fault_code) == 0) {
error = i;
break;
}
}
}
free(fault_code);
if (flashsize < pdownload->file_size) {
error = FAULT_CPE_DOWNLOAD_FAILURE;
goto end_download;
}
/*else {
error = FAULT_CPE_INTERNAL_ERROR;
}*/
int http_code = download_file(ICWMP_DOWNLOAD_FILE, pdownload->url, pdownload->username, pdownload->password);
if (http_code == 404)
error = FAULT_CPE_DOWNLOAD_FAIL_CONTACT_SERVER;
else if (http_code == 401)
error = FAULT_CPE_DOWNLOAD_FAIL_FILE_AUTHENTICATION;
else if (http_code != 200)
error = FAULT_CPE_DOWNLOAD_FAILURE;
if (error != FAULT_CPE_NO_FAULT)
goto end_download;
if (strcmp(pdownload->file_type, "1 Firmware Upgrade Image") == 0) {
rename(ICWMP_DOWNLOAD_FILE, FIRMWARE_UPGRADE_IMAGE);
if (cwmp_check_image() == 0) {
long int file_size = get_file_size(FIRMWARE_UPGRADE_IMAGE);
if (file_size > flashsize) {
error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED;
remove(FIRMWARE_UPGRADE_IMAGE);
goto end_download;
} else {
error = FAULT_CPE_NO_FAULT;
goto end_download;
}
} else {
error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED;
remove(FIRMWARE_UPGRADE_IMAGE);
}
} else if (strcmp(pdownload->file_type, "2 Web Content") == 0) {
rename(ICWMP_DOWNLOAD_FILE, "/tmp/web_content.ipk");
error = FAULT_CPE_NO_FAULT;
} else if (strcmp(pdownload->file_type, "3 Vendor Configuration File") == 0) {
rename(ICWMP_DOWNLOAD_FILE, "/tmp/vendor_configuration_file.cfg");
error = FAULT_CPE_NO_FAULT;
} else {
remove(ICWMP_DOWNLOAD_FILE);
error = FAULT_CPE_NO_FAULT;
}
end_download:
p = calloc(1, sizeof(struct transfer_complete));
if (p == NULL) {
error = FAULT_CPE_INTERNAL_ERROR;
@ -2464,40 +2508,81 @@ int lookup_vcf_name(char *instance, char **value)
return 0;
}
int lookup_vlf_name(char *instance, char **value)
{
char *vlf_name_parameter = NULL;
char *err = NULL;
LIST_HEAD(vlf_parameters);
cwmp_asprintf(&vlf_name_parameter, "Device.DeviceInfo.VendorLogFile.%s.Name", instance);
if ((err = cwmp_get_parameter_values(vlf_name_parameter, &vlf_parameters)) != NULL) {
FREE(vlf_name_parameter);
FREE(err);
return -1;
}
struct cwmp_dm_parameter *param_value = NULL;
list_for_each_entry (param_value, &vlf_parameters, list) {
*value = strdup(param_value->value);
break;
}
cwmp_free_all_dm_parameter_list(&vlf_parameters);
return 0;
}
int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptransfer_complete)
{
int i, error = FAULT_CPE_NO_FAULT;
int error = FAULT_CPE_NO_FAULT;
char *upload_startTime;
struct transfer_complete *p;
char *fault_code;
char *name = "";
upload_startTime = mix_get_time();
char *file_path = NULL;
bkp_session_delete_upload(pupload);
bkp_session_save();
if (pupload->f_instance && isdigit(pupload->f_instance[0])) {
lookup_vcf_name(pupload->f_instance, &name);
}
external_upload(pupload->url, pupload->file_type, pupload->username, pupload->password, name);
external_handle_action(cwmp_handle_upload_fault);
external_fetch_upload_fault_resp(&fault_code);
if (fault_code != NULL) {
if (fault_code[0] == '9') {
for (i = 1; i < __FAULT_CPE_MAX; i++) {
if (strcmp(FAULT_CPE_ARRAY[i].CODE, fault_code) == 0) {
error = i;
break;
}
if (pupload->file_type[0] == '1' || pupload->file_type[0] == '3') {
if (pupload->f_instance && isdigit(pupload->f_instance[0])) {
lookup_vcf_name(pupload->f_instance, &name);
if (name && strlen(name) > 0) {
cwmp_asprintf(&file_path, "/tmp/%s", name);
cwmp_uci_export_package(name, file_path);
FREE(name);
} else {
error = FAULT_CPE_UPLOAD_FAILURE;
goto end_upload;
}
} else {
file_path = strdup("/tmp/all_configs");
cwmp_uci_export(file_path);
}
free(fault_code);
} else {
if (pupload->f_instance && isdigit(pupload->f_instance[0])) {
lookup_vlf_name(pupload->f_instance, &name);
if (name && strlen(name) > 0) {
cwmp_asprintf(&file_path, "/tmp/%s", name);
copy(name, file_path);
FREE(name);
} else
error = FAULT_CPE_UPLOAD_FAILURE;
} else
error = FAULT_CPE_UPLOAD_FAILURE;
}
if (error != FAULT_CPE_NO_FAULT || file_path == NULL || strlen(file_path) <= 0) {
error = FAULT_CPE_UPLOAD_FAILURE;
goto end_upload;
}
if (upload_file(file_path, pupload->url, pupload->username, pupload->password) == 200)
error = FAULT_CPE_NO_FAULT;
else
error = FAULT_CPE_UPLOAD_FAILURE;
remove(file_path);
FREE(file_path);
end_upload:
p = calloc(1, sizeof(struct transfer_complete));
if (p == NULL) {
error = FAULT_CPE_INTERNAL_ERROR;
FREE(name);
return error;
}
@ -2509,7 +2594,6 @@ int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptrans
}
*ptransfer_complete = p;
FREE(name);
return error;
}
@ -2519,10 +2603,9 @@ void *thread_cwmp_rpc_cpe_download(void *v)
struct download *pdownload;
struct timespec download_timeout = { 0, 0 };
time_t current_time, stime;
int i, error = FAULT_CPE_NO_FAULT;
int error = FAULT_CPE_NO_FAULT;
struct transfer_complete *ptransfer_complete;
long int time_of_grace = 3600, timeout;
char *fault_code;
for (;;) {
if (list_download.next != &(list_download)) {
@ -2558,7 +2641,6 @@ void *thread_cwmp_rpc_cpe_download(void *v)
}
if ((timeout >= 0) && (timeout <= time_of_grace)) {
pthread_mutex_lock(&(cwmp->mutex_session_send));
external_init();
CWMP_LOG(INFO, "Launch download file %s", pdownload->url);
error = cwmp_launch_download(pdownload, &ptransfer_complete);
if (error != FAULT_CPE_NO_FAULT) {
@ -2572,33 +2654,39 @@ void *thread_cwmp_rpc_cpe_download(void *v)
}
bkp_session_insert_transfer_complete(ptransfer_complete);
bkp_session_save();
external_apply("download", pdownload->file_type, 0);
external_handle_action(cwmp_handle_download_fault);
external_fetch_download_fault_resp(&fault_code);
if (fault_code != NULL) {
if (fault_code[0] == '9') {
for (i = 1; i < __FAULT_CPE_MAX; i++) {
if (strcmp(FAULT_CPE_ARRAY[i].CODE, fault_code) == 0) {
error = i;
break;
}
}
}
free(fault_code);
if ((error == FAULT_CPE_NO_FAULT) && (pdownload->file_type[0] == '1' || pdownload->file_type[0] == '3' || pdownload->file_type[0] == '6')) {
if (pdownload->file_type[0] == '3') {
CWMP_LOG(INFO, "Download and apply new vendor config file is done successfully");
}
exit(EXIT_SUCCESS);
}
bkp_session_delete_transfer_complete(ptransfer_complete);
ptransfer_complete->fault_code = error;
bkp_session_insert_transfer_complete(ptransfer_complete);
bkp_session_save();
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
if (strcmp(pdownload->file_type, "1 Firmware Upgrade Image") == 0) {
uci_set_value(UCI_CPE_EXEC_DOWNLOAD, "1", CWMP_CMD_SET);
cwmp_apply_firmware();
sleep(70);
error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED;
} else if (strcmp(pdownload->file_type, "2 Web Content") == 0) {
int err = opkg_install_package("/tmp/web_content.ipk");
if (err == -1)
error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED;
else
error = FAULT_CPE_NO_FAULT;
} else if (strcmp(pdownload->file_type, "3 Vendor Configuration File") == 0) {
int err = cwmp_uci_import(NULL, "/tmp/vendor_configuration_file.cfg");
if (err == CWMP_OK)
error = FAULT_CPE_NO_FAULT;
else if (err == CWMP_GEN_ERR)
error = FAULT_CPE_INTERNAL_ERROR;
else if (err == -1)
error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED;
}
if ((error == FAULT_CPE_NO_FAULT) && (pdownload->file_type[0] == '1' || pdownload->file_type[0] == '3' || pdownload->file_type[0] == '6')) {
if (pdownload->file_type[0] == '3') {
CWMP_LOG(INFO, "Download and apply new vendor config file is done successfully");
}
exit(EXIT_SUCCESS);
}
bkp_session_delete_transfer_complete(ptransfer_complete);
ptransfer_complete->fault_code = error;
bkp_session_insert_transfer_complete(ptransfer_complete);
bkp_session_save();
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
}
external_exit();
pthread_mutex_unlock(&(cwmp->mutex_session_send));
pthread_cond_signal(&(cwmp->threshold_session_send));
pthread_mutex_lock(&mutex_download);
@ -2627,9 +2715,8 @@ void *thread_cwmp_rpc_cpe_schedule_download(void *v)
struct cwmp *cwmp = (struct cwmp *)v;
struct timespec download_timeout = { 0, 0 };
time_t current_time;
int i, error = FAULT_CPE_NO_FAULT;
int error = FAULT_CPE_NO_FAULT;
struct transfer_complete *ptransfer_complete;
char *fault_code;
int min_time = 0;
struct schedule_download *current_download = NULL;
struct schedule_download *p, *_p;
@ -2711,7 +2798,6 @@ void *thread_cwmp_rpc_cpe_schedule_download(void *v)
} else if (min_time <= current_time) {
if ((min_time == current_download->timewindowstruct[0].windowstart && (current_download->timewindowstruct[0].windowmode)[0] == '2') || (min_time == current_download->timewindowstruct[1].windowstart && (current_download->timewindowstruct[1].windowmode)[0] == '2')) {
pthread_mutex_lock(&mutex_schedule_download);
external_init();
ptransfer_complete = calloc(1, sizeof(struct transfer_complete));
ptransfer_complete->type = TYPE_SCHEDULE_DOWNLOAD;
error = cwmp_launch_schedule_download(current_download, &ptransfer_complete);
@ -2721,40 +2807,49 @@ void *thread_cwmp_rpc_cpe_schedule_download(void *v)
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
bkp_session_delete_transfer_complete(ptransfer_complete);
} else {
external_exit();
pthread_mutex_unlock(&mutex_schedule_download);
if (pthread_mutex_trylock(&(cwmp->mutex_session_send)) == 0) {
pthread_mutex_lock(&mutex_apply_schedule_download);
pthread_mutex_lock(&mutex_schedule_download);
external_init();
if (current_download->file_type[0] == '1') {
ptransfer_complete->old_software_version = cwmp->deviceid.softwareversion;
}
bkp_session_insert_transfer_complete(ptransfer_complete);
bkp_session_save();
external_apply("download", current_download->file_type, current_download->timewindowstruct[0].windowstart);
external_handle_action(cwmp_handle_download_fault);
external_fetch_download_fault_resp(&fault_code);
if (fault_code != NULL) {
if (fault_code[0] == '9') {
for (i = 1; i < __FAULT_CPE_MAX; i++) {
if (strcmp(FAULT_CPE_ARRAY[i].CODE, fault_code) == 0) {
error = i;
break;
}
}
}
free(fault_code);
if ((error == FAULT_CPE_NO_FAULT) && (current_download->file_type[0] == '1' || current_download->file_type[0] == '3' || current_download->file_type[0] == '6')) {
exit(EXIT_SUCCESS);
}
bkp_session_delete_transfer_complete(ptransfer_complete);
ptransfer_complete->fault_code = error;
bkp_session_insert_transfer_complete(ptransfer_complete);
bkp_session_save();
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
if (strcmp(current_download->file_type, "1 Firmware Upgrade Image") == 0) {
uci_set_value(UCI_CPE_EXEC_DOWNLOAD, "1", CWMP_CMD_SET);
cwmp_apply_firmware();
sleep(70);
error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED;
} else if (strcmp(current_download->file_type, "2 Web Content") == 0) {
int err = opkg_install_package("/tmp/web_content.ipk");
if (err == -1)
error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED;
else
error = FAULT_CPE_NO_FAULT;
} else if (strcmp(current_download->file_type, "3 Vendor Configuration File") == 0) {
int err = cwmp_uci_import(NULL, "/tmp/vendor_configuration_file.cfg");
if (err == CWMP_OK)
error = FAULT_CPE_NO_FAULT;
else if (err == CWMP_GEN_ERR)
error = FAULT_CPE_INTERNAL_ERROR;
else if (err == -1)
error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED;
}
external_exit();
if ((error == FAULT_CPE_NO_FAULT) && (current_download->file_type[0] == '1' || current_download->file_type[0] == '3' || current_download->file_type[0] == '6')) {
if (current_download->file_type[0] == '3') {
CWMP_LOG(INFO, "Download and apply new vendor config file is done successfully");
}
exit(EXIT_SUCCESS);
}
bkp_session_delete_transfer_complete(ptransfer_complete);
ptransfer_complete->fault_code = error;
bkp_session_insert_transfer_complete(ptransfer_complete);
bkp_session_save();
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
pthread_mutex_unlock(&mutex_schedule_download);
pthread_mutex_unlock(&mutex_apply_schedule_download);
pthread_mutex_unlock(&(cwmp->mutex_session_send));
@ -2775,7 +2870,6 @@ void *thread_cwmp_rpc_cpe_schedule_download(void *v)
} //AT ANY TIME OR WHEN IDLE
else {
pthread_mutex_lock(&(cwmp->mutex_session_send));
external_init();
CWMP_LOG(INFO, "Launch download file %s", current_download->url);
error = cwmp_launch_schedule_download(current_download, &ptransfer_complete);
if (error != FAULT_CPE_NO_FAULT) {
@ -2789,30 +2883,39 @@ void *thread_cwmp_rpc_cpe_schedule_download(void *v)
}
bkp_session_insert_transfer_complete(ptransfer_complete);
bkp_session_save();
external_apply("download", current_download->file_type, 0);
external_handle_action(cwmp_handle_download_fault);
external_fetch_download_fault_resp(&fault_code);
if (fault_code != NULL) {
if (fault_code[0] == '9') {
for (i = 1; i < __FAULT_CPE_MAX; i++) {
if (strcmp(FAULT_CPE_ARRAY[i].CODE, fault_code) == 0) {
error = i;
break;
}
}
}
free(fault_code);
if ((error == FAULT_CPE_NO_FAULT) && (current_download->file_type[0] == '1' || current_download->file_type[0] == '3' || current_download->file_type[0] == '6')) {
exit(EXIT_SUCCESS);
}
bkp_session_delete_transfer_complete(ptransfer_complete);
ptransfer_complete->fault_code = error;
bkp_session_insert_transfer_complete(ptransfer_complete);
bkp_session_save();
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
if (strcmp(current_download->file_type, "1 Firmware Upgrade Image") == 0) {
uci_set_value(UCI_CPE_EXEC_DOWNLOAD, "1", CWMP_CMD_SET);
cwmp_apply_firmware();
sleep(70);
error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED;
} else if (strcmp(current_download->file_type, "2 Web Content") == 0) {
int err = opkg_install_package("/tmp/web_content.ipk");
if (err == -1)
error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED;
else
error = FAULT_CPE_NO_FAULT;
} else if (strcmp(current_download->file_type, "3 Vendor Configuration File") == 0) {
int err = cwmp_uci_import(NULL, "/tmp/vendor_configuration_file.cfg");
if (err == CWMP_OK)
error = FAULT_CPE_NO_FAULT;
else if (err == CWMP_GEN_ERR)
error = FAULT_CPE_INTERNAL_ERROR;
else if (err == -1)
error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED;
}
if ((error == FAULT_CPE_NO_FAULT) && (current_download->file_type[0] == '1' || current_download->file_type[0] == '3' || current_download->file_type[0] == '6')) {
if (current_download->file_type[0] == '3') {
CWMP_LOG(INFO, "Download and apply new vendor config file is done successfully");
}
exit(EXIT_SUCCESS);
}
bkp_session_delete_transfer_complete(ptransfer_complete);
ptransfer_complete->fault_code = error;
bkp_session_insert_transfer_complete(ptransfer_complete);
bkp_session_save();
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
}
external_exit();
pthread_mutex_unlock(&(cwmp->mutex_session_send));
pthread_cond_signal(&(cwmp->threshold_session_send));
pthread_mutex_lock(&mutex_schedule_download);
@ -2845,9 +2948,8 @@ void *thread_cwmp_rpc_cpe_apply_schedule_download(void *v)
struct cwmp *cwmp = (struct cwmp *)v;
struct timespec apply_timeout = { 0, 0 };
time_t current_time;
int i, error = FAULT_CPE_NO_FAULT;
int error = FAULT_CPE_NO_FAULT;
struct transfer_complete *ptransfer_complete;
char *fault_code;
int min_time = 0;
struct apply_schedule_download *apply_download = NULL;
struct apply_schedule_download *p, *_p;
@ -2929,7 +3031,6 @@ void *thread_cwmp_rpc_cpe_apply_schedule_download(void *v)
} else if (min_time <= current_time) {
pthread_mutex_lock(&(cwmp->mutex_session_send));
pthread_mutex_lock(&mutex_schedule_download);
external_init();
bkp_session_delete_apply_schedule_download(apply_download);
bkp_session_save();
ptransfer_complete = calloc(1, sizeof(struct transfer_complete));
@ -2943,29 +3044,40 @@ void *thread_cwmp_rpc_cpe_apply_schedule_download(void *v)
ptransfer_complete->type = TYPE_SCHEDULE_DOWNLOAD;
bkp_session_insert_transfer_complete(ptransfer_complete);
bkp_session_save();
external_apply("download", apply_download->file_type, apply_download->timeintervals[0].windowstart);
external_handle_action(cwmp_handle_download_fault);
external_fetch_download_fault_resp(&fault_code);
if (fault_code != NULL) {
if (fault_code[0] == '9') {
for (i = 1; i < __FAULT_CPE_MAX; i++) {
if (strcmp(FAULT_CPE_ARRAY[i].CODE, fault_code) == 0) {
error = i;
break;
}
}
}
free(fault_code);
if ((error == FAULT_CPE_NO_FAULT) && (apply_download->file_type[0] == '1' || apply_download->file_type[0] == '3' || apply_download->file_type[0] == '6')) {
exit(EXIT_SUCCESS);
}
bkp_session_delete_transfer_complete(ptransfer_complete);
ptransfer_complete->fault_code = error;
bkp_session_insert_transfer_complete(ptransfer_complete);
bkp_session_save();
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
if (strcmp(apply_download->file_type, "1 Firmware Upgrade Image") == 0) {
uci_set_value(UCI_CPE_EXEC_DOWNLOAD, "1", CWMP_CMD_SET);
cwmp_apply_firmware();
sleep(70);
error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED;
} else if (strcmp(apply_download->file_type, "2 Web Content") == 0) {
int err = opkg_install_package("/tmp/web_content.ipk");
if (err == -1)
error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED;
else
error = FAULT_CPE_NO_FAULT;
} else if (strcmp(apply_download->file_type, "3 Vendor Configuration File") == 0) {
int err = cwmp_uci_import(NULL, "/tmp/vendor_configuration_file.cfg");
if (err == CWMP_OK)
error = FAULT_CPE_NO_FAULT;
else if (err == CWMP_GEN_ERR)
error = FAULT_CPE_INTERNAL_ERROR;
else if (err == -1)
error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED;
}
external_exit();
if ((error == FAULT_CPE_NO_FAULT) && (apply_download->file_type[0] == '1' || apply_download->file_type[0] == '3' || apply_download->file_type[0] == '6')) {
if (apply_download->file_type[0] == '3') {
CWMP_LOG(INFO, "Download and apply new vendor config file is done successfully");
}
exit(EXIT_SUCCESS);
}
bkp_session_delete_transfer_complete(ptransfer_complete);
ptransfer_complete->fault_code = error;
bkp_session_insert_transfer_complete(ptransfer_complete);
bkp_session_save();
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
pthread_mutex_unlock(&mutex_schedule_download);
pthread_mutex_unlock(&(cwmp->mutex_session_send));
pthread_cond_signal(&(cwmp->threshold_session_send));
@ -3154,9 +3266,9 @@ static int cwmp_launch_du_install(char *url, char *uuid, char *user, char *pass,
char *fault_code;
(*pchange_du_state_complete)->start_time = strdup(mix_get_time());
external_change_du_state_install(url, uuid, user, pass, env);
external_handle_action(cwmp_handle_dustate_change_fault);
external_fetch_du_change_state_fault_resp(&fault_code, package_version, package_name, package_uuid, package_env);
cwmp_du_install(url, uuid, user, pass, env, package_version, package_name, package_uuid, package_env, &fault_code);
if (fault_code != NULL) {
if (fault_code[0] == '9') {
for (i = 1; i < __FAULT_CPE_MAX; i++) {
@ -3177,9 +3289,8 @@ static int cwmp_launch_du_update(char *uuid, char *url, char *user, char *pass,
char *fault_code;
(*pchange_du_state_complete)->start_time = strdup(mix_get_time());
external_change_du_state_update(uuid, url, user, pass);
external_handle_action(cwmp_handle_dustate_change_fault);
external_fetch_du_change_state_fault_resp(&fault_code, package_version, package_name, package_uuid, package_env);
cwmp_du_update(url, uuid, user, pass, package_version, package_name, package_uuid, package_env, &fault_code);
if (fault_code != NULL) {
if (fault_code[0] == '9') {
for (i = 1; i < __FAULT_CPE_MAX; i++) {
@ -3200,9 +3311,9 @@ static int cwmp_launch_du_uninstall(char *package_name, char *package_env, struc
char *fault_code;
(*pchange_du_state_complete)->start_time = strdup(mix_get_time());
external_change_du_state_uninstall(package_name, package_env);
external_handle_action(cwmp_handle_uninstall_fault);
external_fetch_uninstall_fault_resp(&fault_code);
cwmp_du_uninstall(package_name, package_env, &fault_code);
if (fault_code != NULL) {
if (fault_code[0] == '9') {
for (i = 1; i < __FAULT_CPE_MAX; i++) {
@ -3280,7 +3391,6 @@ void *thread_cwmp_rpc_cpe_change_du_state(void *v)
list_for_each_entry_safe (p, q, &pchange_du_state->list_operation, list) {
res = calloc(1, sizeof(struct opresult));
list_add_tail(&(res->list), &(pdu_state_change_complete->list_opresult));
external_init();
switch (p->type) {
case DU_INSTALL:
@ -3392,8 +3502,6 @@ void *thread_cwmp_rpc_cpe_change_du_state(void *v)
FREE(package_env);
break;
}
external_exit();
}
bkp_session_delete_change_du_state(pchange_du_state);
@ -3468,7 +3576,6 @@ void *thread_cwmp_rpc_cpe_upload(void *v)
}
if ((timeout >= 0) && (timeout <= time_of_grace)) {
pthread_mutex_lock(&(cwmp->mutex_session_send));
external_init();
CWMP_LOG(INFO, "Launch upload file %s", pupload->url);
error = cwmp_launch_upload(pupload, &ptransfer_complete);
if (error != FAULT_CPE_NO_FAULT) {
@ -3483,7 +3590,6 @@ void *thread_cwmp_rpc_cpe_upload(void *v)
bkp_session_save();
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
}
external_exit();
pthread_mutex_unlock(&(cwmp->mutex_session_send));
pthread_cond_signal(&(cwmp->threshold_session_send));
pthread_mutex_lock(&mutex_upload);