mirror of
https://dev.iopsys.eu/bbf/icwmp.git
synced 2025-12-10 07:44:41 +01:00
code enhancements and arrangement: session download upload scheduleInform changedustate
This commit is contained in:
parent
e6586067f9
commit
218ee7fbc7
22 changed files with 2143 additions and 1977 deletions
|
|
@ -12,11 +12,16 @@
|
|||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "backupSession.h"
|
||||
#include "xml.h"
|
||||
#include "log.h"
|
||||
#include "notifications.h"
|
||||
#include "event.h"
|
||||
#include "download.h"
|
||||
#include "cwmp_du_state.h"
|
||||
#include "upload.h"
|
||||
#include "sched_inform.h"
|
||||
|
||||
static mxml_node_t *bkp_tree = NULL;
|
||||
pthread_mutex_t mutex_backup_session = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@ icwmpd_SOURCES = \
|
|||
../notifications.c \
|
||||
../cwmp_zlib.c \
|
||||
../cwmp_du_state.c \
|
||||
../download.c \
|
||||
../upload.c \
|
||||
../sched_inform.c \
|
||||
../xml.c \
|
||||
../diagnostic.c \
|
||||
../cwmp.c
|
||||
|
|
|
|||
130
common.c
130
common.c
|
|
@ -29,6 +29,35 @@ static unsigned long int next_rand_seed = 1;
|
|||
|
||||
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 } };
|
||||
|
||||
struct FAULT_CPE FAULT_CPE_ARRAY[] = {[FAULT_CPE_METHOD_NOT_SUPPORTED] = { "9000", FAULT_9000, FAULT_CPE_TYPE_SERVER, "Method not supported" },
|
||||
[FAULT_CPE_REQUEST_DENIED] = { "9001", FAULT_9001, FAULT_CPE_TYPE_SERVER, "Request denied (no reason specified)" },
|
||||
[FAULT_CPE_INTERNAL_ERROR] = { "9002", FAULT_9002, FAULT_CPE_TYPE_SERVER, "Internal error" },
|
||||
[FAULT_CPE_INVALID_ARGUMENTS] = { "9003", FAULT_9003, FAULT_CPE_TYPE_CLIENT, "Invalid arguments" },
|
||||
[FAULT_CPE_RESOURCES_EXCEEDED] = { "9004", FAULT_9004, FAULT_CPE_TYPE_SERVER, "Resources exceeded" },
|
||||
[FAULT_CPE_INVALID_PARAMETER_NAME] = { "9005", FAULT_9005, FAULT_CPE_TYPE_CLIENT, "Invalid parameter name" },
|
||||
[FAULT_CPE_INVALID_PARAMETER_TYPE] = { "9006", FAULT_9006, FAULT_CPE_TYPE_CLIENT, "Invalid parameter type" },
|
||||
[FAULT_CPE_INVALID_PARAMETER_VALUE] = { "9007", FAULT_9007, FAULT_CPE_TYPE_CLIENT, "Invalid parameter value" },
|
||||
[FAULT_CPE_NON_WRITABLE_PARAMETER] = { "9008", FAULT_9008, FAULT_CPE_TYPE_CLIENT, "Attempt to set a non-writable parameter" },
|
||||
[FAULT_CPE_NOTIFICATION_REJECTED] = { "9009", FAULT_9009, FAULT_CPE_TYPE_SERVER, "Notification request rejected" },
|
||||
[FAULT_CPE_DOWNLOAD_FAILURE] = { "9010", FAULT_9010, FAULT_CPE_TYPE_SERVER, "Download failure" },
|
||||
[FAULT_CPE_UPLOAD_FAILURE] = { "9011", FAULT_9011, FAULT_CPE_TYPE_SERVER, "Upload failure" },
|
||||
[FAULT_CPE_FILE_TRANSFER_AUTHENTICATION_FAILURE] = { "9012", FAULT_9012, FAULT_CPE_TYPE_SERVER, "File transfer server authentication failure" },
|
||||
[FAULT_CPE_FILE_TRANSFER_UNSUPPORTED_PROTOCOL] = { "9013", FAULT_9013, FAULT_CPE_TYPE_SERVER, "Unsupported protocol for file transfer" },
|
||||
[FAULT_CPE_DOWNLOAD_FAIL_MULTICAST_GROUP] = { "9014", FAULT_9014, FAULT_CPE_TYPE_SERVER, "Download failure: unable to join multicast group" },
|
||||
[FAULT_CPE_DOWNLOAD_FAIL_CONTACT_SERVER] = { "9015", FAULT_9015, FAULT_CPE_TYPE_SERVER, "Download failure: unable to contact file server" },
|
||||
[FAULT_CPE_DOWNLOAD_FAIL_ACCESS_FILE] = { "9016", FAULT_9016, FAULT_CPE_TYPE_SERVER, "Download failure: unable to access file" },
|
||||
[FAULT_CPE_DOWNLOAD_FAIL_COMPLETE_DOWNLOAD] = { "9017", FAULT_9017, FAULT_CPE_TYPE_SERVER, "Download failure: unable to complete download" },
|
||||
[FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED] = { "9018", FAULT_9018, FAULT_CPE_TYPE_SERVER, "Download failure: file corrupted" },
|
||||
[FAULT_CPE_DOWNLOAD_FAIL_FILE_AUTHENTICATION] = { "9019", FAULT_9019, FAULT_CPE_TYPE_SERVER, "Download failure: file authentication failure" },
|
||||
[FAULT_CPE_DOWNLOAD_FAIL_WITHIN_TIME_WINDOW] = { "9020", FAULT_9020, FAULT_CPE_TYPE_SERVER, "Download failure: unable to complete download" },
|
||||
[FAULT_CPE_DUPLICATE_DEPLOYMENT_UNIT] = { "9026", FAULT_9026, FAULT_CPE_TYPE_SERVER, "Duplicate deployment unit" },
|
||||
[FAULT_CPE_SYSTEM_RESOURCES_EXCEEDED] = { "9027", FAULT_9027, FAULT_CPE_TYPE_SERVER, "System ressources exceeded" },
|
||||
[FAULT_CPE_UNKNOWN_DEPLOYMENT_UNIT] = { "9028", FAULT_9028, FAULT_CPE_TYPE_SERVER, "Unknown deployment unit" },
|
||||
[FAULT_CPE_INVALID_DEPLOYMENT_UNIT_STATE] = { "9029", FAULT_9029, FAULT_CPE_TYPE_SERVER, "Invalid deployment unit state" },
|
||||
[FAULT_CPE_INVALID_DOWNGRADE_REJECTED] = { "9030", FAULT_9030, FAULT_CPE_TYPE_SERVER, "Invalid deployment unit Update: Downgrade not permitted" },
|
||||
[FAULT_CPE_INVALID_UPDATE_VERSION_UNSPECIFIED] = { "9031", FAULT_9031, FAULT_CPE_TYPE_SERVER, "Invalid deployment unit Update: Version not specified" },
|
||||
[FAULT_CPE_INVALID_UPDATE_VERSION_EXIST] = { "9031", FAULT_9032, FAULT_CPE_TYPE_SERVER, "Invalid deployment unit Update: Version already exist" } };
|
||||
|
||||
static void show_help(void)
|
||||
{
|
||||
printf("Usage: icwmpd [OPTIONS]\n");
|
||||
|
|
@ -195,41 +224,6 @@ size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *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;
|
||||
|
|
@ -368,42 +362,6 @@ long int get_file_size(char *file_name)
|
|||
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;
|
||||
|
|
@ -503,3 +461,33 @@ void icwmp_srand(unsigned int seed) //
|
|||
{
|
||||
next_rand_seed = seed;
|
||||
}
|
||||
|
||||
int cwmp_get_fault_code(int fault_code)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i < __FAULT_CPE_MAX; i++) {
|
||||
if (FAULT_CPE_ARRAY[i].ICODE == fault_code)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == __FAULT_CPE_MAX)
|
||||
i = FAULT_CPE_INTERNAL_ERROR;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int cwmp_get_fault_code_by_string(char *fault_code)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i < __FAULT_CPE_MAX; i++) {
|
||||
if (strcmp(FAULT_CPE_ARRAY[i].CODE, fault_code) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == __FAULT_CPE_MAX)
|
||||
i = FAULT_CPE_INTERNAL_ERROR;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
|
|
|||
102
cwmp.c
102
cwmp.c
|
|
@ -14,13 +14,6 @@
|
|||
|
||||
struct cwmp cwmp_main = { 0 };
|
||||
|
||||
int cwmp_session_rpc_destructor(struct rpc *rpc)
|
||||
{
|
||||
list_del(&(rpc->list));
|
||||
free(rpc);
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
||||
int cwmp_get_retry_interval(struct cwmp *cwmp)
|
||||
{
|
||||
int retry_count = 0;
|
||||
|
|
@ -58,101 +51,6 @@ end:
|
|||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
||||
}
|
||||
|
||||
int cwmp_session_destructor(struct session *session)
|
||||
{
|
||||
struct rpc *rpc;
|
||||
|
||||
while (session->head_rpc_acs.next != &(session->head_rpc_acs)) {
|
||||
rpc = list_entry(session->head_rpc_acs.next, struct rpc, list);
|
||||
if (rpc_acs_methods[rpc->type].extra_clean != NULL)
|
||||
rpc_acs_methods[rpc->type].extra_clean(session, rpc);
|
||||
cwmp_session_rpc_destructor(rpc);
|
||||
}
|
||||
|
||||
while (session->head_rpc_cpe.next != &(session->head_rpc_cpe)) {
|
||||
rpc = list_entry(session->head_rpc_cpe.next, struct rpc, list);
|
||||
cwmp_session_rpc_destructor(rpc);
|
||||
}
|
||||
|
||||
if (session->list.next != NULL && session->list.prev != NULL)
|
||||
list_del(&(session->list));
|
||||
|
||||
free(session);
|
||||
|
||||
return CWMP_OK;
|
||||
}
|
||||
int cwmp_move_session_to_session_queue(struct cwmp *cwmp, struct session *session)
|
||||
{
|
||||
struct list_head *ilist, *jlist;
|
||||
struct rpc *rpc_acs, *queue_rpc_acs, *rpc_cpe;
|
||||
struct event_container *event_container_old, *event_container_new;
|
||||
struct session *session_queue;
|
||||
bool dup;
|
||||
|
||||
pthread_mutex_lock(&(cwmp->mutex_session_queue));
|
||||
cwmp->retry_count_session++;
|
||||
cwmp->session_send = NULL;
|
||||
if (cwmp->head_session_queue.next == &(cwmp->head_session_queue)) {
|
||||
list_add_tail(&(session->list), &(cwmp->head_session_queue));
|
||||
session->hold_request = 0;
|
||||
session->digest_auth = 0;
|
||||
cwmp->head_event_container = &(session->head_event_container);
|
||||
if (session->head_rpc_acs.next != &(session->head_rpc_acs)) {
|
||||
rpc_acs = list_entry(session->head_rpc_acs.next, struct rpc, list);
|
||||
if (rpc_acs->type != RPC_ACS_INFORM) {
|
||||
if ((rpc_acs = cwmp_add_session_rpc_acs_head(session, RPC_ACS_INFORM)) == NULL) {
|
||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
||||
return CWMP_MEM_ERR;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((rpc_acs = cwmp_add_session_rpc_acs_head(session, RPC_ACS_INFORM)) == NULL) {
|
||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
||||
return CWMP_MEM_ERR;
|
||||
}
|
||||
}
|
||||
while (session->head_rpc_cpe.next != &(session->head_rpc_cpe)) {
|
||||
rpc_cpe = list_entry(session->head_rpc_cpe.next, struct rpc, list);
|
||||
cwmp_session_rpc_destructor(rpc_cpe);
|
||||
}
|
||||
bkp_session_move_inform_to_inform_queue();
|
||||
bkp_session_save();
|
||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
||||
return CWMP_OK;
|
||||
}
|
||||
list_for_each (ilist, &(session->head_event_container)) {
|
||||
event_container_old = list_entry(ilist, struct event_container, list);
|
||||
event_container_new = cwmp_add_event_container(cwmp, event_container_old->code, event_container_old->command_key);
|
||||
if (event_container_new == NULL) {
|
||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
||||
return CWMP_MEM_ERR;
|
||||
}
|
||||
list_splice_init(&(event_container_old->head_dm_parameter), &(event_container_new->head_dm_parameter));
|
||||
cwmp_save_event_container(event_container_new);
|
||||
}
|
||||
session_queue = list_entry(cwmp->head_event_container, struct session, head_event_container);
|
||||
list_for_each (ilist, &(session->head_rpc_acs)) {
|
||||
rpc_acs = list_entry(ilist, struct rpc, list);
|
||||
dup = false;
|
||||
list_for_each (jlist, &(session_queue->head_rpc_acs)) {
|
||||
queue_rpc_acs = list_entry(jlist, struct rpc, list);
|
||||
if (queue_rpc_acs->type == rpc_acs->type && (rpc_acs->type == RPC_ACS_INFORM || rpc_acs->type == RPC_ACS_GET_RPC_METHODS)) {
|
||||
dup = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dup) {
|
||||
continue;
|
||||
}
|
||||
ilist = ilist->prev;
|
||||
list_del(&(rpc_acs->list));
|
||||
list_add_tail(&(rpc_acs->list), &(session_queue->head_rpc_acs));
|
||||
}
|
||||
cwmp_session_destructor(session);
|
||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
||||
int cwmp_schedule_rpc(struct cwmp *cwmp, struct session *session)
|
||||
{
|
||||
struct list_head *ilist;
|
||||
|
|
|
|||
470
cwmp_du_state.c
470
cwmp_du_state.c
|
|
@ -15,6 +15,14 @@
|
|||
#include "ubus.h"
|
||||
#include "cwmp_du_state.h"
|
||||
#include "log.h"
|
||||
#include "backupSession.h"
|
||||
#include "cwmp_time.h"
|
||||
#include "datamodel_interface.h"
|
||||
#include "event.h"
|
||||
|
||||
LIST_HEAD(list_change_du_state);
|
||||
pthread_mutex_t mutex_change_du_state = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_cond_t threshold_change_du_state;
|
||||
|
||||
struct change_du_state_res {
|
||||
char **pack_name;
|
||||
|
|
@ -94,3 +102,465 @@ int cwmp_du_uninstall(char *package_name, char *package_env, char **fault_code)
|
|||
}
|
||||
return FAULT_CPE_NO_FAULT;
|
||||
}
|
||||
|
||||
static char *get_software_module_object_eq(char *param1, char *val1, char *param2, char *val2, struct list_head *sw_parameters)
|
||||
{
|
||||
char *err = NULL;
|
||||
char *sw_parameter_name = NULL;
|
||||
|
||||
if (!param2)
|
||||
cwmp_asprintf(&sw_parameter_name, "Device.SoftwareModules.DeploymentUnit.[%s==\\\"%s\\\"].", param1, val1);
|
||||
else
|
||||
cwmp_asprintf(&sw_parameter_name, "Device.SoftwareModules.DeploymentUnit.[%s==\\\"%s\\\"&& %s==\\\"%s\\\"].", param1, val1, param2, val2);
|
||||
|
||||
err = cwmp_get_parameter_values(sw_parameter_name, sw_parameters);
|
||||
FREE(sw_parameter_name);
|
||||
if (err) {
|
||||
FREE(err);
|
||||
return NULL;
|
||||
}
|
||||
struct cwmp_dm_parameter *param_value = NULL;
|
||||
char instance[8];
|
||||
list_for_each_entry (param_value, sw_parameters, list) {
|
||||
snprintf(instance, (size_t)(strchr(param_value->name + strlen("Device.SoftwareModules.DeploymentUnit."), '.') - param_value->name - strlen("Device.SoftwareModules.DeploymentUnit.") + 1), "%s", (char *)(param_value->name + strlen("Device.SoftwareModules.DeploymentUnit.")));
|
||||
break;
|
||||
}
|
||||
return strdup(instance);
|
||||
}
|
||||
|
||||
static int get_deployment_unit_name_version(char *uuid, char **name, char **version, char **env)
|
||||
{
|
||||
char *sw_by_uuid_instance = NULL, *name_param = NULL, *version_param = NULL, *environment_param = NULL;
|
||||
LIST_HEAD(sw_parameters);
|
||||
sw_by_uuid_instance = get_software_module_object_eq("UUID", uuid, NULL, NULL, &sw_parameters);
|
||||
if (!sw_by_uuid_instance)
|
||||
return 0;
|
||||
|
||||
cwmp_asprintf(&name_param, "Device.SoftwareModules.DeploymentUnit.%s.Name", sw_by_uuid_instance);
|
||||
cwmp_asprintf(&version_param, "Device.SoftwareModules.DeploymentUnit.%s.Version", sw_by_uuid_instance);
|
||||
cwmp_asprintf(&environment_param, "Device.SoftwareModules.DeploymentUnit.%s.ExecutionEnvRef", sw_by_uuid_instance);
|
||||
|
||||
struct cwmp_dm_parameter *param_value = NULL;
|
||||
list_for_each_entry (param_value, &sw_parameters, list) {
|
||||
if (strcmp(param_value->name, name_param) == 0) {
|
||||
*name = strdup(param_value->value);
|
||||
continue;
|
||||
}
|
||||
if (strcmp(param_value->name, version_param) == 0) {
|
||||
*version = strdup(param_value->value);
|
||||
continue;
|
||||
}
|
||||
if (strcmp(param_value->name, environment_param) == 0) {
|
||||
*env = strdup(param_value->value);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
cwmp_free_all_dm_parameter_list(&sw_parameters);
|
||||
FREE(name_param);
|
||||
FREE(version_param);
|
||||
FREE(environment_param);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char *get_softwaremodules_uuid(char *url)
|
||||
{
|
||||
char *sw_by_url_instance = NULL, *uuid_param = NULL, *uuid = NULL;
|
||||
|
||||
LIST_HEAD(sw_parameters);
|
||||
|
||||
sw_by_url_instance = get_software_module_object_eq("URL", url, NULL, NULL, &sw_parameters);
|
||||
if (!sw_by_url_instance)
|
||||
return NULL;
|
||||
|
||||
cwmp_asprintf(&uuid_param, "Device.SoftwareModules.DeploymentUnit.%s.UUID", sw_by_url_instance);
|
||||
|
||||
struct cwmp_dm_parameter *param_value = NULL;
|
||||
list_for_each_entry (param_value, &sw_parameters, list) {
|
||||
if (strcmp(param_value->name, uuid_param) == 0) {
|
||||
uuid = strdup(param_value->value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
cwmp_free_all_dm_parameter_list(&sw_parameters);
|
||||
FREE(uuid_param);
|
||||
return uuid;
|
||||
}
|
||||
|
||||
static char *get_softwaremodules_url(char *uuid)
|
||||
{
|
||||
char *sw_by_uuid_instance = NULL, *url_param = NULL, *url = NULL;
|
||||
|
||||
LIST_HEAD(sw_parameters);
|
||||
sw_by_uuid_instance = get_software_module_object_eq("UUID", uuid, NULL, NULL, &sw_parameters);
|
||||
if (!sw_by_uuid_instance)
|
||||
return NULL;
|
||||
|
||||
cwmp_asprintf(&url_param, "Device.SoftwareModules.DeploymentUnit.%s.URL", sw_by_uuid_instance);
|
||||
|
||||
struct cwmp_dm_parameter *param_value = NULL;
|
||||
list_for_each_entry (param_value, &sw_parameters, list) {
|
||||
if (strcmp(param_value->name, url_param) == 0) {
|
||||
url = strdup(param_value->value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
cwmp_free_all_dm_parameter_list(&sw_parameters);
|
||||
FREE(url_param);
|
||||
return url;
|
||||
}
|
||||
|
||||
static char *get_deployment_unit_reference(char *package_name, char *package_env)
|
||||
{
|
||||
LIST_HEAD(sw_parameters);
|
||||
char *sw_by_name_env_instance = NULL, *deployment_unit_ref = NULL;
|
||||
sw_by_name_env_instance = get_software_module_object_eq("Name", package_name, "ExecutionEnvRef", package_env, &sw_parameters);
|
||||
cwmp_free_all_dm_parameter_list(&sw_parameters);
|
||||
if (!sw_by_name_env_instance)
|
||||
return NULL;
|
||||
|
||||
cwmp_asprintf(&deployment_unit_ref, "Device.SoftwareModules.DeploymentUnit.%s", sw_by_name_env_instance);
|
||||
return deployment_unit_ref;
|
||||
}
|
||||
|
||||
static bool environment_exists(char *environment_path)
|
||||
{
|
||||
LIST_HEAD(environment_list);
|
||||
char *err = cwmp_get_parameter_values(environment_path, &environment_list);
|
||||
cwmp_free_all_dm_parameter_list(&environment_list);
|
||||
if (err) {
|
||||
FREE(err);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static char *get_exec_env_name(char *environment_path)
|
||||
{
|
||||
char *env_param = NULL, *env_name = "";
|
||||
|
||||
LIST_HEAD(environment_list);
|
||||
char *err = cwmp_get_parameter_values(environment_path, &environment_list);
|
||||
if (err) {
|
||||
FREE(err);
|
||||
return strdup("");
|
||||
}
|
||||
struct cwmp_dm_parameter *param_value = NULL;
|
||||
cwmp_asprintf(&env_param, "%sName", environment_path);
|
||||
list_for_each_entry (param_value, &environment_list, list) {
|
||||
if (strcmp(param_value->name, env_param) == 0) {
|
||||
env_name = strdup(param_value->value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
cwmp_free_all_dm_parameter_list(&environment_list);
|
||||
FREE(env_param);
|
||||
return env_name;
|
||||
}
|
||||
|
||||
static int cwmp_launch_du_install(char *url, char *uuid, char *user, char *pass, char *env, char **package_version, char **package_name, char **package_uuid, char **package_env, struct opresult **pchange_du_state_complete)
|
||||
{
|
||||
int i, error = FAULT_CPE_NO_FAULT;
|
||||
char *fault_code;
|
||||
|
||||
(*pchange_du_state_complete)->start_time = strdup(mix_get_time());
|
||||
|
||||
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++) {
|
||||
if (strcmp(FAULT_CPE_ARRAY[i].CODE, fault_code) == 0) {
|
||||
error = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(fault_code);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
static int cwmp_launch_du_update(char *uuid, char *url, char *user, char *pass, char **package_version, char **package_name, char **package_uuid, char **package_env, struct opresult **pchange_du_state_complete)
|
||||
{
|
||||
int i, error = FAULT_CPE_NO_FAULT;
|
||||
char *fault_code;
|
||||
|
||||
(*pchange_du_state_complete)->start_time = strdup(mix_get_time());
|
||||
|
||||
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++) {
|
||||
if (strcmp(FAULT_CPE_ARRAY[i].CODE, fault_code) == 0) {
|
||||
error = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(fault_code);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
static int cwmp_launch_du_uninstall(char *package_name, char *package_env, struct opresult **pchange_du_state_complete)
|
||||
{
|
||||
int i, error = FAULT_CPE_NO_FAULT;
|
||||
char *fault_code;
|
||||
|
||||
(*pchange_du_state_complete)->start_time = strdup(mix_get_time());
|
||||
|
||||
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++) {
|
||||
if (strcmp(FAULT_CPE_ARRAY[i].CODE, fault_code) == 0) {
|
||||
error = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(fault_code);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
void *thread_cwmp_rpc_cpe_change_du_state(void *v)
|
||||
{
|
||||
struct cwmp *cwmp = (struct cwmp *)v;
|
||||
struct timespec change_du_state_timeout = { 50, 0 };
|
||||
int error = FAULT_CPE_NO_FAULT;
|
||||
struct du_state_change_complete *pdu_state_change_complete;
|
||||
long int time_of_grace = 216000;
|
||||
char *package_version;
|
||||
char *package_name;
|
||||
char *package_uuid;
|
||||
char *package_env;
|
||||
struct operations *p, *q;
|
||||
struct opresult *res;
|
||||
char *du_ref = NULL;
|
||||
char *cur_uuid = NULL;
|
||||
char *cur_url = NULL;
|
||||
|
||||
for (;;) {
|
||||
if (list_change_du_state.next != &(list_change_du_state)) {
|
||||
struct change_du_state *pchange_du_state = list_entry(list_change_du_state.next, struct change_du_state, list);
|
||||
time_t current_time = time(NULL);
|
||||
time_t timeout = current_time - pchange_du_state->timeout;
|
||||
|
||||
if ((timeout >= 0) && (timeout > time_of_grace)) {
|
||||
pthread_mutex_lock(&mutex_change_du_state);
|
||||
pdu_state_change_complete = calloc(1, sizeof(struct du_state_change_complete));
|
||||
if (pdu_state_change_complete != NULL) {
|
||||
error = FAULT_CPE_DOWNLOAD_FAILURE;
|
||||
INIT_LIST_HEAD(&(pdu_state_change_complete->list_opresult));
|
||||
pdu_state_change_complete->command_key = strdup(pchange_du_state->command_key);
|
||||
pdu_state_change_complete->timeout = pchange_du_state->timeout;
|
||||
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));
|
||||
res->uuid = strdup(p->uuid);
|
||||
res->version = strdup(p->version);
|
||||
res->current_state = strdup("Failed");
|
||||
res->start_time = strdup(mix_get_time());
|
||||
res->complete_time = strdup(res->start_time);
|
||||
res->fault = error;
|
||||
}
|
||||
bkp_session_insert_du_state_change_complete(pdu_state_change_complete);
|
||||
bkp_session_save();
|
||||
cwmp_root_cause_changedustate_complete(cwmp, pdu_state_change_complete);
|
||||
}
|
||||
list_del(&(pchange_du_state->list));
|
||||
cwmp_free_change_du_state_request(pchange_du_state);
|
||||
pthread_mutex_unlock(&mutex_change_du_state);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((timeout >= 0) && (timeout <= time_of_grace)) {
|
||||
pthread_mutex_lock(&(cwmp->mutex_session_send));
|
||||
pdu_state_change_complete = calloc(1, sizeof(struct du_state_change_complete));
|
||||
if (pdu_state_change_complete != NULL) {
|
||||
error = FAULT_CPE_NO_FAULT;
|
||||
INIT_LIST_HEAD(&(pdu_state_change_complete->list_opresult));
|
||||
pdu_state_change_complete->command_key = strdup(pchange_du_state->command_key);
|
||||
pdu_state_change_complete->timeout = pchange_du_state->timeout;
|
||||
|
||||
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));
|
||||
|
||||
switch (p->type) {
|
||||
case DU_INSTALL:
|
||||
if (!environment_exists(p->executionenvref)) {
|
||||
res->fault = FAULT_CPE_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
error = cwmp_launch_du_install(p->url, p->uuid, p->username, p->password, get_exec_env_name(p->executionenvref), &package_version, &package_name, &package_uuid, &package_env, &res);
|
||||
|
||||
if (error == FAULT_CPE_NO_FAULT) {
|
||||
du_ref = (package_name && p->executionenvref) ? get_deployment_unit_reference(package_name, p->executionenvref) : NULL;
|
||||
|
||||
res->du_ref = strdup(du_ref ? du_ref : "");
|
||||
res->uuid = strdup(package_uuid ? package_uuid : "");
|
||||
res->current_state = strdup("Installed");
|
||||
res->resolved = 1;
|
||||
res->version = strdup(package_version ? package_version : "");
|
||||
FREE(du_ref);
|
||||
} else {
|
||||
res->uuid = strdup(p->uuid);
|
||||
res->current_state = strdup("Failed");
|
||||
res->resolved = 0;
|
||||
}
|
||||
|
||||
res->complete_time = strdup(mix_get_time());
|
||||
res->fault = error;
|
||||
break;
|
||||
|
||||
case DU_UPDATE:
|
||||
cur_uuid = NULL;
|
||||
cur_url = NULL;
|
||||
|
||||
if (*(p->url) == '\0' && *(p->uuid) == '\0') {
|
||||
if (*(p->version) == '\0') {
|
||||
error = FAULT_CPE_UNKNOWN_DEPLOYMENT_UNIT;
|
||||
break;
|
||||
}
|
||||
} else if (*(p->url) && *(p->uuid) == '\0') {
|
||||
cur_uuid = get_softwaremodules_uuid(p->url);
|
||||
|
||||
if (cur_uuid == NULL || *cur_uuid == '\0') {
|
||||
error = FAULT_CPE_UNKNOWN_DEPLOYMENT_UNIT;
|
||||
break;
|
||||
}
|
||||
} else if (*(p->url) == '\0' && *(p->uuid)) {
|
||||
cur_url = get_softwaremodules_url(p->uuid);
|
||||
|
||||
if (cur_url == NULL || *cur_url == '\0') {
|
||||
error = FAULT_CPE_UNKNOWN_DEPLOYMENT_UNIT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
error = cwmp_launch_du_update((cur_uuid && *cur_uuid) ? cur_uuid : p->uuid, (cur_url && *cur_url) ? cur_url : p->url, p->username, p->password, &package_version, &package_name, &package_uuid, &package_env, &res);
|
||||
|
||||
if (error == FAULT_CPE_NO_FAULT) {
|
||||
res->uuid = strdup(package_uuid ? package_uuid : "");
|
||||
res->version = strdup(package_version ? package_version : "");
|
||||
res->current_state = strdup("Installed");
|
||||
res->resolved = 1;
|
||||
} else {
|
||||
res->uuid = strdup(p->uuid);
|
||||
res->version = strdup(p->version);
|
||||
res->current_state = strdup("Failed");
|
||||
res->resolved = 0;
|
||||
}
|
||||
|
||||
du_ref = (package_name && package_env) ? get_deployment_unit_reference(package_name, package_env) : NULL;
|
||||
res->du_ref = strdup(du_ref ? du_ref : "");
|
||||
res->complete_time = strdup(mix_get_time());
|
||||
res->fault = error;
|
||||
FREE(du_ref);
|
||||
FREE(cur_uuid);
|
||||
FREE(cur_url);
|
||||
break;
|
||||
|
||||
case DU_UNINSTALL:
|
||||
if (p->uuid == NULL || *(p->uuid) == '\0' || !environment_exists(p->executionenvref)) {
|
||||
res->fault = FAULT_CPE_UNKNOWN_DEPLOYMENT_UNIT;
|
||||
break;
|
||||
}
|
||||
|
||||
get_deployment_unit_name_version(p->uuid, &package_name, &package_version, &package_env);
|
||||
if (!package_name || *package_name == '\0' || !package_version || *package_version == '\0' || !package_env || *package_env == '\0') {
|
||||
res->fault = FAULT_CPE_UNKNOWN_DEPLOYMENT_UNIT;
|
||||
break;
|
||||
}
|
||||
|
||||
error = cwmp_launch_du_uninstall(package_name, get_exec_env_name(package_env), &res);
|
||||
|
||||
if (error == FAULT_CPE_NO_FAULT) {
|
||||
res->current_state = strdup("Uninstalled");
|
||||
res->resolved = 1;
|
||||
} else {
|
||||
res->current_state = strdup("Installed");
|
||||
res->resolved = 0;
|
||||
}
|
||||
|
||||
du_ref = (package_name && package_env) ? get_deployment_unit_reference(package_name, package_env) : NULL;
|
||||
res->du_ref = strdup(du_ref ? du_ref : "");
|
||||
res->uuid = strdup(p->uuid);
|
||||
res->version = strdup(package_version ? package_version : "");
|
||||
res->complete_time = strdup(mix_get_time());
|
||||
res->fault = error;
|
||||
FREE(du_ref);
|
||||
FREE(package_name);
|
||||
FREE(package_version);
|
||||
FREE(package_env);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bkp_session_delete_change_du_state(pchange_du_state);
|
||||
bkp_session_save();
|
||||
bkp_session_insert_du_state_change_complete(pdu_state_change_complete);
|
||||
bkp_session_save();
|
||||
cwmp_root_cause_changedustate_complete(cwmp, pdu_state_change_complete);
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&mutex_change_du_state);
|
||||
pthread_cond_timedwait(&threshold_change_du_state, &mutex_change_du_state, &change_du_state_timeout);
|
||||
pthread_mutex_unlock(&mutex_change_du_state);
|
||||
|
||||
pthread_mutex_unlock(&(cwmp->mutex_session_send));
|
||||
pthread_cond_signal(&(cwmp->threshold_session_send));
|
||||
|
||||
pthread_mutex_lock(&mutex_change_du_state);
|
||||
list_del(&(pchange_du_state->list));
|
||||
cwmp_free_change_du_state_request(pchange_du_state);
|
||||
pthread_mutex_unlock(&mutex_change_du_state);
|
||||
continue;
|
||||
} else {
|
||||
pthread_mutex_lock(&mutex_change_du_state);
|
||||
pthread_cond_wait(&threshold_change_du_state, &mutex_change_du_state);
|
||||
pthread_mutex_unlock(&mutex_change_du_state);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int cwmp_rpc_acs_destroy_data_du_state_change_complete(struct session *session __attribute__((unused)), struct rpc *rpc)
|
||||
{
|
||||
struct du_state_change_complete *p;
|
||||
if (rpc->extra_data != NULL) {
|
||||
p = (struct du_state_change_complete *)rpc->extra_data;
|
||||
bkp_session_delete_du_state_change_complete(p);
|
||||
bkp_session_save();
|
||||
FREE(p->command_key);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cwmp_free_change_du_state_request(struct change_du_state *change_du_state)
|
||||
{
|
||||
if (change_du_state != NULL) {
|
||||
struct list_head *ilist, *q;
|
||||
|
||||
list_for_each_safe (ilist, q, &(change_du_state->list_operation)) {
|
||||
struct operations *operation = list_entry(ilist, struct operations, list);
|
||||
FREE(operation->url);
|
||||
FREE(operation->uuid);
|
||||
FREE(operation->username);
|
||||
FREE(operation->password);
|
||||
FREE(operation->version);
|
||||
FREE(operation->executionenvref);
|
||||
list_del(&(operation->list));
|
||||
FREE(operation);
|
||||
}
|
||||
FREE(change_du_state->command_key);
|
||||
FREE(change_du_state);
|
||||
}
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
|
|
|||
62
diagnostic.c
62
diagnostic.c
|
|
@ -18,6 +18,7 @@
|
|||
#include "datamodel_interface.h"
|
||||
#include "ubus.h"
|
||||
#include "cwmp_uci.h"
|
||||
#include "event.h"
|
||||
|
||||
struct diagnostic_input {
|
||||
char *input_name;
|
||||
|
|
@ -71,28 +72,35 @@ struct diagnostic_input upload_diagnostics_array[UPLOAD_NUMBER_INPUTS] = {
|
|||
//{"TimeBasedTestMeasurementOffset","Device.IP.Diagnostics.UploadDiagnostics.TimeBasedTestMeasurementOffset",NULL}
|
||||
};
|
||||
|
||||
struct diagnostic_input ipping_diagnostics_array[IPPING_NUMBER_INPUTS] = { { "Host", "Device.IP.Diagnostics.IPPing.Host", NULL },
|
||||
{ "NumberOfRepetitions", "Device.IP.Diagnostics.IPPing.NumberOfRepetitions", NULL },
|
||||
{ "Timeout", "Device.IP.Diagnostics.IPPing.Timeout", NULL },
|
||||
{ "Interface", "Device.IP.Diagnostics.IPPing.Interface", NULL },
|
||||
{ "ProtocolVersion", "Device.IP.Diagnostics.IPPing.ProtocolVersion", NULL },
|
||||
{ "DSCP", "Device.IP.Diagnostics.IPPing.DSCP", NULL },
|
||||
{ "DataBlockSize", "Device.IP.Diagnostics.IPPing.DataBlockSize", NULL } };
|
||||
struct diagnostic_input seserverselection_diagnostics_array[SESERVERSELECT_NUMBER_INPUTS] = { { "Interface", "Device.IP.Diagnostics.ServerSelectionDiagnostics.Interface", NULL },
|
||||
{ "Protocol", "Device.IP.Diagnostics.ServerSelectionDiagnostics.Protocol", NULL },
|
||||
{ "HostList", "Device.IP.Diagnostics.ServerSelectionDiagnostics.HostList", NULL },
|
||||
{ "ProtocolVersion", "Device.IP.Diagnostics.ServerSelectionDiagnostics.ProtocolVersion", NULL },
|
||||
{ "NumberOfRepetitions", "Device.IP.Diagnostics.ServerSelectionDiagnostics.NumberOfRepetitions", NULL },
|
||||
{ "Timeout", "Device.IP.Diagnostics.ServerSelectionDiagnostics.Timeout", NULL } };
|
||||
struct diagnostic_input ipping_diagnostics_array[IPPING_NUMBER_INPUTS] = { //
|
||||
{ "Host", "Device.IP.Diagnostics.IPPing.Host", NULL },
|
||||
{ "NumberOfRepetitions", "Device.IP.Diagnostics.IPPing.NumberOfRepetitions", NULL },
|
||||
{ "Timeout", "Device.IP.Diagnostics.IPPing.Timeout", NULL },
|
||||
{ "Interface", "Device.IP.Diagnostics.IPPing.Interface", NULL },
|
||||
{ "ProtocolVersion", "Device.IP.Diagnostics.IPPing.ProtocolVersion", NULL },
|
||||
{ "DSCP", "Device.IP.Diagnostics.IPPing.DSCP", NULL },
|
||||
{ "DataBlockSize", "Device.IP.Diagnostics.IPPing.DataBlockSize", NULL }
|
||||
};
|
||||
|
||||
struct diagnostic_input traceroute_diagnostics_array[TRACEROUTE_NUMBER_INPUTS] = { { "Interface", "Device.IP.Diagnostics.TraceRoute.Interface", NULL },
|
||||
{ "Host", "Device.IP.Diagnostics.TraceRoute.Host", NULL },
|
||||
{ "NumberOfTries", "Device.IP.Diagnostics.TraceRoute.NumberOfTries", NULL },
|
||||
{ "ProtocolVersion", "Device.IP.Diagnostics.TraceRoute.ProtocolVersion", NULL },
|
||||
{ "Timeout", "Device.IP.Diagnostics.TraceRoute.Timeout", NULL },
|
||||
{ "DataBlockSize", "Device.IP.Diagnostics.TraceRoute.DataBlockSize", NULL },
|
||||
{ "DSCP", "Device.IP.Diagnostics.TraceRoute.DSCP", NULL },
|
||||
{ "MaxHopCount", "Device.IP.Diagnostics.TraceRoute.MaxHopCount", NULL } };
|
||||
struct diagnostic_input seserverselection_diagnostics_array[SESERVERSELECT_NUMBER_INPUTS] = { //
|
||||
{ "Interface", "Device.IP.Diagnostics.ServerSelectionDiagnostics.Interface", NULL },
|
||||
{ "Protocol", "Device.IP.Diagnostics.ServerSelectionDiagnostics.Protocol", NULL },
|
||||
{ "HostList", "Device.IP.Diagnostics.ServerSelectionDiagnostics.HostList", NULL },
|
||||
{ "ProtocolVersion", "Device.IP.Diagnostics.ServerSelectionDiagnostics.ProtocolVersion", NULL },
|
||||
{ "NumberOfRepetitions", "Device.IP.Diagnostics.ServerSelectionDiagnostics.NumberOfRepetitions", NULL },
|
||||
{ "Timeout", "Device.IP.Diagnostics.ServerSelectionDiagnostics.Timeout", NULL }
|
||||
};
|
||||
|
||||
struct diagnostic_input traceroute_diagnostics_array[TRACEROUTE_NUMBER_INPUTS] = { //
|
||||
{ "Interface", "Device.IP.Diagnostics.TraceRoute.Interface", NULL },
|
||||
{ "Host", "Device.IP.Diagnostics.TraceRoute.Host", NULL },
|
||||
{ "NumberOfTries", "Device.IP.Diagnostics.TraceRoute.NumberOfTries", NULL },
|
||||
{ "ProtocolVersion", "Device.IP.Diagnostics.TraceRoute.ProtocolVersion", NULL },
|
||||
{ "Timeout", "Device.IP.Diagnostics.TraceRoute.Timeout", NULL },
|
||||
{ "DataBlockSize", "Device.IP.Diagnostics.TraceRoute.DataBlockSize", NULL },
|
||||
{ "DSCP", "Device.IP.Diagnostics.TraceRoute.DSCP", NULL },
|
||||
{ "MaxHopCount", "Device.IP.Diagnostics.TraceRoute.MaxHopCount", NULL }
|
||||
};
|
||||
|
||||
struct diagnostic_input udpecho_diagnostics_array[UDPECHO_NUMBER_INPUTS] = {
|
||||
{ "Interface", "Device.IP.Diagnostics.UDPEchoDiagnostics.Interface", NULL },
|
||||
|
|
@ -107,11 +115,13 @@ struct diagnostic_input udpecho_diagnostics_array[UDPECHO_NUMBER_INPUTS] = {
|
|||
//{"EnableIndividualPacketResults","Device.IP.Diagnostics.UDPEchoDiagnostics.EnableIndividualPacketResults",NULL}
|
||||
};
|
||||
|
||||
struct diagnostic_input nslookup_diagnostics_array[NSLKUP_NUMBER_INPUTS] = { { "Interface", "Device.DNS.Diagnostics.NSLookupDiagnostics.Interface", NULL },
|
||||
{ "HostName", "Device.DNS.Diagnostics.NSLookupDiagnostics.HostName", NULL },
|
||||
{ "DNSServer", "Device.DNS.Diagnostics.NSLookupDiagnostics.DNSServer", NULL },
|
||||
{ "NumberOfRepetitions", "Device.DNS.Diagnostics.NSLookupDiagnostics.NumberOfRepetitions", NULL },
|
||||
{ "Timeout", "Device.DNS.Diagnostics.NSLookupDiagnostics.Timeout", NULL } };
|
||||
struct diagnostic_input nslookup_diagnostics_array[NSLKUP_NUMBER_INPUTS] = { //
|
||||
{ "Interface", "Device.DNS.Diagnostics.NSLookupDiagnostics.Interface", NULL },
|
||||
{ "HostName", "Device.DNS.Diagnostics.NSLookupDiagnostics.HostName", NULL },
|
||||
{ "DNSServer", "Device.DNS.Diagnostics.NSLookupDiagnostics.DNSServer", NULL },
|
||||
{ "NumberOfRepetitions", "Device.DNS.Diagnostics.NSLookupDiagnostics.NumberOfRepetitions", NULL },
|
||||
{ "Timeout", "Device.DNS.Diagnostics.NSLookupDiagnostics.Timeout", NULL }
|
||||
};
|
||||
|
||||
static bool set_specific_diagnostic_object_parameter_structure_value(struct diagnostic_input (*diagnostics_array)[], int number_inputs, char *parameter, char *value)
|
||||
{
|
||||
|
|
|
|||
936
download.c
Normal file
936
download.c
Normal file
|
|
@ -0,0 +1,936 @@
|
|||
/*
|
||||
* 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 <curl/curl.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "download.h"
|
||||
#include "cwmp_uci.h"
|
||||
#include "backupSession.h"
|
||||
#include "ubus.h"
|
||||
#include "log.h"
|
||||
#include "cwmp_time.h"
|
||||
#include "event.h"
|
||||
|
||||
LIST_HEAD(list_download);
|
||||
LIST_HEAD(list_schedule_download);
|
||||
LIST_HEAD(list_apply_schedule_download);
|
||||
|
||||
pthread_mutex_t mutex_download = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_cond_t threshold_download;
|
||||
pthread_mutex_t mutex_schedule_download = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_cond_t threshold_schedule_download;
|
||||
pthread_mutex_t mutex_apply_schedule_download = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_cond_t threshold_apply_schedule_download;
|
||||
|
||||
int count_download_queue = 0;
|
||||
|
||||
/*
|
||||
* Download File
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the downloaded image can be applied
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
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 cwmp_launch_download(struct download *pdownload, struct transfer_complete **ptransfer_complete)
|
||||
{
|
||||
int error = FAULT_CPE_NO_FAULT;
|
||||
char *download_startTime;
|
||||
struct transfer_complete *p;
|
||||
|
||||
download_startTime = mix_get_time();
|
||||
|
||||
bkp_session_delete_download(pdownload);
|
||||
bkp_session_save();
|
||||
|
||||
if (flashsize < pdownload->file_size) {
|
||||
error = FAULT_CPE_DOWNLOAD_FAILURE;
|
||||
goto end_download;
|
||||
}
|
||||
|
||||
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;
|
||||
return error;
|
||||
}
|
||||
|
||||
p->command_key = pdownload->command_key ? strdup(pdownload->command_key) : strdup("");
|
||||
p->start_time = strdup(download_startTime);
|
||||
p->complete_time = strdup(mix_get_time());
|
||||
if (error != FAULT_CPE_NO_FAULT) {
|
||||
p->fault_code = error;
|
||||
}
|
||||
|
||||
*ptransfer_complete = p;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int cwmp_launch_schedule_download(struct schedule_download *pdownload, struct transfer_complete **ptransfer_complete)
|
||||
{
|
||||
int error = FAULT_CPE_NO_FAULT;
|
||||
char *download_startTime;
|
||||
struct transfer_complete *p;
|
||||
|
||||
download_startTime = mix_get_time();
|
||||
|
||||
bkp_session_delete_schedule_download(pdownload);
|
||||
bkp_session_save();
|
||||
|
||||
if (flashsize < pdownload->file_size) {
|
||||
error = FAULT_CPE_DOWNLOAD_FAILURE;
|
||||
goto end_download;
|
||||
}
|
||||
|
||||
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;
|
||||
return error;
|
||||
}
|
||||
|
||||
p->command_key = strdup(pdownload->command_key);
|
||||
p->start_time = strdup(download_startTime);
|
||||
p->complete_time = strdup(mix_get_time());
|
||||
p->type = TYPE_SCHEDULE_DOWNLOAD;
|
||||
if (error != FAULT_CPE_NO_FAULT) {
|
||||
p->fault_code = error;
|
||||
}
|
||||
|
||||
*ptransfer_complete = p;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void *thread_cwmp_rpc_cpe_download(void *v)
|
||||
{
|
||||
struct cwmp *cwmp = (struct cwmp *)v;
|
||||
struct download *pdownload;
|
||||
struct timespec download_timeout = { 0, 0 };
|
||||
time_t current_time, stime;
|
||||
int error = FAULT_CPE_NO_FAULT;
|
||||
struct transfer_complete *ptransfer_complete;
|
||||
long int time_of_grace = 3600, timeout;
|
||||
|
||||
for (;;) {
|
||||
if (list_download.next != &(list_download)) {
|
||||
pdownload = list_entry(list_download.next, struct download, list);
|
||||
stime = pdownload->scheduled_time;
|
||||
current_time = time(NULL);
|
||||
if (pdownload->scheduled_time != 0)
|
||||
timeout = current_time - pdownload->scheduled_time;
|
||||
else
|
||||
timeout = 0;
|
||||
if ((timeout >= 0) && (timeout > time_of_grace)) {
|
||||
pthread_mutex_lock(&mutex_download);
|
||||
bkp_session_delete_download(pdownload);
|
||||
ptransfer_complete = calloc(1, sizeof(struct transfer_complete));
|
||||
if (ptransfer_complete != NULL) {
|
||||
error = FAULT_CPE_DOWNLOAD_FAILURE;
|
||||
|
||||
ptransfer_complete->command_key = strdup(pdownload->command_key);
|
||||
ptransfer_complete->start_time = strdup(mix_get_time());
|
||||
ptransfer_complete->complete_time = strdup(ptransfer_complete->start_time);
|
||||
ptransfer_complete->fault_code = error;
|
||||
|
||||
ptransfer_complete->type = TYPE_DOWNLOAD;
|
||||
bkp_session_insert_transfer_complete(ptransfer_complete);
|
||||
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
|
||||
}
|
||||
list_del(&(pdownload->list));
|
||||
if (pdownload->scheduled_time != 0)
|
||||
count_download_queue--;
|
||||
cwmp_free_download_request(pdownload);
|
||||
pthread_mutex_unlock(&mutex_download);
|
||||
continue;
|
||||
}
|
||||
if ((timeout >= 0) && (timeout <= time_of_grace)) {
|
||||
pthread_mutex_lock(&(cwmp->mutex_session_send));
|
||||
CWMP_LOG(INFO, "Launch download file %s", pdownload->url);
|
||||
error = cwmp_launch_download(pdownload, &ptransfer_complete);
|
||||
if (error != FAULT_CPE_NO_FAULT) {
|
||||
bkp_session_insert_transfer_complete(ptransfer_complete);
|
||||
bkp_session_save();
|
||||
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
|
||||
bkp_session_delete_transfer_complete(ptransfer_complete);
|
||||
} else {
|
||||
if (pdownload->file_type[0] == '1') {
|
||||
ptransfer_complete->old_software_version = cwmp->deviceid.softwareversion;
|
||||
}
|
||||
bkp_session_insert_transfer_complete(ptransfer_complete);
|
||||
bkp_session_save();
|
||||
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);
|
||||
}
|
||||
pthread_mutex_unlock(&(cwmp->mutex_session_send));
|
||||
pthread_cond_signal(&(cwmp->threshold_session_send));
|
||||
pthread_mutex_lock(&mutex_download);
|
||||
list_del(&(pdownload->list));
|
||||
if (pdownload->scheduled_time != 0)
|
||||
count_download_queue--;
|
||||
cwmp_free_download_request(pdownload);
|
||||
pthread_mutex_unlock(&mutex_download);
|
||||
continue;
|
||||
}
|
||||
pthread_mutex_lock(&mutex_download);
|
||||
download_timeout.tv_sec = stime;
|
||||
pthread_cond_timedwait(&threshold_download, &mutex_download, &download_timeout);
|
||||
pthread_mutex_unlock(&mutex_download);
|
||||
} else {
|
||||
pthread_mutex_lock(&mutex_download);
|
||||
pthread_cond_wait(&threshold_download, &mutex_download);
|
||||
pthread_mutex_unlock(&mutex_download);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int cwmp_add_apply_schedule_download(struct schedule_download *schedule_download, char *start_time)
|
||||
{
|
||||
int i = 0;
|
||||
int error = FAULT_CPE_NO_FAULT;
|
||||
struct apply_schedule_download *apply_schedule_download;
|
||||
|
||||
apply_schedule_download = calloc(1, sizeof(struct apply_schedule_download));
|
||||
if (apply_schedule_download == NULL) {
|
||||
error = FAULT_CPE_INTERNAL_ERROR;
|
||||
goto fault;
|
||||
}
|
||||
if (error == FAULT_CPE_NO_FAULT) {
|
||||
pthread_mutex_lock(&mutex_apply_schedule_download);
|
||||
apply_schedule_download->command_key = strdup(schedule_download->command_key);
|
||||
apply_schedule_download->file_type = strdup(schedule_download->file_type);
|
||||
apply_schedule_download->start_time = strdup(start_time);
|
||||
for (i = 0; i < 2; i++) {
|
||||
apply_schedule_download->timeintervals[i].windowstart = schedule_download->timewindowstruct[i].windowstart;
|
||||
apply_schedule_download->timeintervals[i].windowend = schedule_download->timewindowstruct[i].windowend;
|
||||
apply_schedule_download->timeintervals[i].maxretries = schedule_download->timewindowstruct[i].maxretries;
|
||||
}
|
||||
list_add_tail(&(apply_schedule_download->list), &(list_apply_schedule_download));
|
||||
|
||||
bkp_session_insert_apply_schedule_download(apply_schedule_download);
|
||||
bkp_session_save();
|
||||
pthread_mutex_unlock(&mutex_apply_schedule_download);
|
||||
pthread_cond_signal(&threshold_apply_schedule_download);
|
||||
}
|
||||
return 0;
|
||||
fault:
|
||||
cwmp_free_apply_schedule_download_request(apply_schedule_download);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 error = FAULT_CPE_NO_FAULT;
|
||||
struct transfer_complete *ptransfer_complete;
|
||||
int min_time = 0;
|
||||
struct schedule_download *current_download = NULL;
|
||||
struct schedule_download *p, *_p;
|
||||
|
||||
for (;;) {
|
||||
current_time = time(NULL);
|
||||
if (list_schedule_download.next != &(list_schedule_download)) {
|
||||
list_for_each_entry_safe (p, _p, &(list_schedule_download), list) {
|
||||
if (min_time == 0) {
|
||||
if (p->timewindowstruct[0].windowend >= current_time) {
|
||||
min_time = p->timewindowstruct[0].windowstart;
|
||||
current_download = p;
|
||||
} else if (p->timewindowstruct[1].windowend >= current_time) {
|
||||
min_time = p->timewindowstruct[1].windowstart;
|
||||
current_download = p;
|
||||
} else {
|
||||
pthread_mutex_lock(&mutex_schedule_download);
|
||||
bkp_session_delete_schedule_download(p);
|
||||
ptransfer_complete = calloc(1, sizeof(struct transfer_complete));
|
||||
if (ptransfer_complete != NULL) {
|
||||
error = FAULT_CPE_DOWNLOAD_FAIL_WITHIN_TIME_WINDOW;
|
||||
ptransfer_complete->command_key = strdup(p->command_key);
|
||||
ptransfer_complete->start_time = strdup(mix_get_time());
|
||||
ptransfer_complete->complete_time = strdup(ptransfer_complete->start_time);
|
||||
ptransfer_complete->fault_code = error;
|
||||
ptransfer_complete->type = TYPE_SCHEDULE_DOWNLOAD;
|
||||
bkp_session_insert_transfer_complete(ptransfer_complete);
|
||||
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
|
||||
}
|
||||
list_del(&(p->list));
|
||||
if (p->timewindowstruct[0].windowstart != 0)
|
||||
count_download_queue--;
|
||||
cwmp_free_schedule_download_request(p);
|
||||
pthread_mutex_unlock(&mutex_schedule_download);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (p->timewindowstruct[0].windowend >= current_time) {
|
||||
if (p->timewindowstruct[0].windowstart < min_time) {
|
||||
min_time = p->timewindowstruct[0].windowstart;
|
||||
current_download = p;
|
||||
}
|
||||
|
||||
} else if (p->timewindowstruct[1].windowend >= current_time) {
|
||||
if (p->timewindowstruct[1].windowstart < min_time) {
|
||||
min_time = p->timewindowstruct[1].windowstart;
|
||||
current_download = p;
|
||||
}
|
||||
} else {
|
||||
pthread_mutex_lock(&mutex_schedule_download);
|
||||
bkp_session_delete_schedule_download(p);
|
||||
ptransfer_complete = calloc(1, sizeof(struct transfer_complete));
|
||||
if (ptransfer_complete != NULL) {
|
||||
error = FAULT_CPE_DOWNLOAD_FAIL_WITHIN_TIME_WINDOW;
|
||||
ptransfer_complete->command_key = strdup(p->command_key);
|
||||
ptransfer_complete->start_time = strdup(mix_get_time());
|
||||
ptransfer_complete->complete_time = strdup(ptransfer_complete->start_time);
|
||||
ptransfer_complete->fault_code = error;
|
||||
ptransfer_complete->type = TYPE_SCHEDULE_DOWNLOAD;
|
||||
bkp_session_insert_transfer_complete(ptransfer_complete);
|
||||
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
|
||||
}
|
||||
list_del(&(p->list));
|
||||
if (p->timewindowstruct[0].windowstart != 0)
|
||||
count_download_queue--;
|
||||
cwmp_free_schedule_download_request(p);
|
||||
pthread_mutex_unlock(&mutex_schedule_download);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pthread_mutex_lock(&mutex_schedule_download);
|
||||
pthread_cond_wait(&threshold_schedule_download, &mutex_schedule_download);
|
||||
pthread_mutex_unlock(&mutex_schedule_download);
|
||||
}
|
||||
if (min_time == 0) {
|
||||
continue;
|
||||
} 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);
|
||||
ptransfer_complete = calloc(1, sizeof(struct transfer_complete));
|
||||
ptransfer_complete->type = TYPE_SCHEDULE_DOWNLOAD;
|
||||
error = cwmp_launch_schedule_download(current_download, &ptransfer_complete);
|
||||
if (error != FAULT_CPE_NO_FAULT) {
|
||||
bkp_session_insert_transfer_complete(ptransfer_complete);
|
||||
bkp_session_save();
|
||||
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
|
||||
bkp_session_delete_transfer_complete(ptransfer_complete);
|
||||
} else {
|
||||
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);
|
||||
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();
|
||||
|
||||
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);
|
||||
|
||||
pthread_mutex_unlock(&mutex_schedule_download);
|
||||
pthread_mutex_unlock(&mutex_apply_schedule_download);
|
||||
pthread_mutex_unlock(&(cwmp->mutex_session_send));
|
||||
pthread_cond_signal(&(cwmp->threshold_session_send));
|
||||
} else {
|
||||
cwmp_add_apply_schedule_download(current_download, ptransfer_complete->start_time);
|
||||
}
|
||||
}
|
||||
pthread_mutex_lock(&mutex_schedule_download);
|
||||
bkp_session_delete_schedule_download(current_download);
|
||||
bkp_session_save();
|
||||
list_del(&(current_download->list));
|
||||
cwmp_free_schedule_download_request(current_download);
|
||||
pthread_mutex_unlock(&mutex_schedule_download);
|
||||
min_time = 0;
|
||||
current_download = NULL;
|
||||
continue;
|
||||
} //AT ANY TIME OR WHEN IDLE
|
||||
else {
|
||||
pthread_mutex_lock(&(cwmp->mutex_session_send));
|
||||
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) {
|
||||
bkp_session_insert_transfer_complete(ptransfer_complete);
|
||||
bkp_session_save();
|
||||
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
|
||||
bkp_session_delete_transfer_complete(ptransfer_complete);
|
||||
} else {
|
||||
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();
|
||||
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);
|
||||
}
|
||||
pthread_mutex_unlock(&(cwmp->mutex_session_send));
|
||||
pthread_cond_signal(&(cwmp->threshold_session_send));
|
||||
pthread_mutex_lock(&mutex_schedule_download);
|
||||
list_del(&(current_download->list));
|
||||
if (current_download->timewindowstruct[0].windowstart != 0)
|
||||
count_download_queue--;
|
||||
cwmp_free_schedule_download_request(current_download);
|
||||
pthread_mutex_unlock(&mutex_schedule_download);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (min_time == current_download->timewindowstruct[0].windowstart) {
|
||||
pthread_mutex_lock(&mutex_schedule_download);
|
||||
download_timeout.tv_sec = min_time;
|
||||
pthread_cond_timedwait(&threshold_schedule_download, &mutex_schedule_download, &download_timeout);
|
||||
pthread_mutex_unlock(&mutex_schedule_download);
|
||||
} else if (min_time == current_download->timewindowstruct[1].windowstart) {
|
||||
pthread_mutex_lock(&mutex_schedule_download);
|
||||
download_timeout.tv_sec = min_time;
|
||||
pthread_cond_timedwait(&threshold_schedule_download, &mutex_schedule_download, &download_timeout);
|
||||
pthread_mutex_unlock(&mutex_schedule_download);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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 error = FAULT_CPE_NO_FAULT;
|
||||
struct transfer_complete *ptransfer_complete;
|
||||
int min_time = 0;
|
||||
struct apply_schedule_download *apply_download = NULL;
|
||||
struct apply_schedule_download *p, *_p;
|
||||
|
||||
for (;;) {
|
||||
current_time = time(NULL);
|
||||
if (list_apply_schedule_download.next != &(list_apply_schedule_download)) {
|
||||
list_for_each_entry_safe (p, _p, &(list_apply_schedule_download), list) {
|
||||
if (min_time == 0) {
|
||||
if (p->timeintervals[0].windowend >= current_time) {
|
||||
min_time = p->timeintervals[0].windowstart;
|
||||
apply_download = p;
|
||||
} else if (p->timeintervals[1].windowend >= current_time) {
|
||||
min_time = p->timeintervals[1].windowstart;
|
||||
apply_download = p;
|
||||
} else {
|
||||
pthread_mutex_lock(&mutex_apply_schedule_download);
|
||||
bkp_session_delete_apply_schedule_download(p);
|
||||
ptransfer_complete = calloc(1, sizeof(struct transfer_complete));
|
||||
if (ptransfer_complete != NULL) {
|
||||
error = FAULT_CPE_DOWNLOAD_FAIL_WITHIN_TIME_WINDOW;
|
||||
ptransfer_complete->command_key = strdup(p->command_key);
|
||||
ptransfer_complete->start_time = strdup(mix_get_time());
|
||||
ptransfer_complete->complete_time = strdup(ptransfer_complete->start_time);
|
||||
ptransfer_complete->fault_code = error;
|
||||
ptransfer_complete->type = TYPE_SCHEDULE_DOWNLOAD;
|
||||
bkp_session_insert_transfer_complete(ptransfer_complete);
|
||||
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
|
||||
}
|
||||
list_del(&(p->list));
|
||||
if (p->timeintervals[0].windowstart != 0)
|
||||
count_download_queue--;
|
||||
cwmp_free_apply_schedule_download_request(p);
|
||||
pthread_mutex_unlock(&mutex_apply_schedule_download);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (p->timeintervals[0].windowend >= current_time) {
|
||||
if (p->timeintervals[0].windowstart < min_time) {
|
||||
min_time = p->timeintervals[0].windowstart;
|
||||
apply_download = p;
|
||||
}
|
||||
|
||||
} else if (p->timeintervals[1].windowend >= current_time) {
|
||||
if (p->timeintervals[1].windowstart < min_time) {
|
||||
min_time = p->timeintervals[1].windowstart;
|
||||
apply_download = p;
|
||||
}
|
||||
} else {
|
||||
pthread_mutex_lock(&mutex_apply_schedule_download);
|
||||
bkp_session_delete_apply_schedule_download(p);
|
||||
ptransfer_complete = calloc(1, sizeof(struct transfer_complete));
|
||||
if (ptransfer_complete != NULL) {
|
||||
error = FAULT_CPE_DOWNLOAD_FAIL_WITHIN_TIME_WINDOW;
|
||||
ptransfer_complete->command_key = strdup(p->command_key);
|
||||
ptransfer_complete->start_time = strdup(mix_get_time());
|
||||
ptransfer_complete->complete_time = strdup(ptransfer_complete->start_time);
|
||||
ptransfer_complete->fault_code = error;
|
||||
ptransfer_complete->type = TYPE_SCHEDULE_DOWNLOAD;
|
||||
bkp_session_insert_transfer_complete(ptransfer_complete);
|
||||
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
|
||||
}
|
||||
list_del(&(p->list));
|
||||
/*if(p->timewindowintervals[0].windowstart != 0)
|
||||
count_download_queue--;*/
|
||||
cwmp_free_apply_schedule_download_request(p);
|
||||
pthread_mutex_unlock(&mutex_apply_schedule_download);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pthread_mutex_lock(&mutex_apply_schedule_download);
|
||||
pthread_cond_wait(&threshold_apply_schedule_download, &mutex_apply_schedule_download);
|
||||
pthread_mutex_unlock(&mutex_apply_schedule_download);
|
||||
}
|
||||
if (min_time == 0) {
|
||||
continue;
|
||||
} else if (min_time <= current_time) {
|
||||
pthread_mutex_lock(&(cwmp->mutex_session_send));
|
||||
pthread_mutex_lock(&mutex_schedule_download);
|
||||
bkp_session_delete_apply_schedule_download(apply_download);
|
||||
bkp_session_save();
|
||||
ptransfer_complete = calloc(1, sizeof(struct transfer_complete));
|
||||
if (apply_download->file_type[0] == '1') {
|
||||
ptransfer_complete->old_software_version = cwmp->deviceid.softwareversion;
|
||||
}
|
||||
ptransfer_complete->command_key = strdup(apply_download->command_key);
|
||||
ptransfer_complete->start_time = strdup(apply_download->start_time);
|
||||
ptransfer_complete->complete_time = strdup(mix_get_time());
|
||||
ptransfer_complete->fault_code = error;
|
||||
ptransfer_complete->type = TYPE_SCHEDULE_DOWNLOAD;
|
||||
bkp_session_insert_transfer_complete(ptransfer_complete);
|
||||
bkp_session_save();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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));
|
||||
pthread_mutex_lock(&mutex_apply_schedule_download);
|
||||
list_del(&(apply_download->list));
|
||||
/*if(pdownload->timeintervals[0].windowstart != 0)
|
||||
count_download_queue--;*/
|
||||
cwmp_free_apply_schedule_download_request(apply_download);
|
||||
pthread_mutex_unlock(&mutex_apply_schedule_download);
|
||||
continue;
|
||||
} else {
|
||||
if (min_time == apply_download->timeintervals[0].windowstart) {
|
||||
pthread_mutex_lock(&mutex_apply_schedule_download);
|
||||
apply_timeout.tv_sec = min_time;
|
||||
pthread_cond_timedwait(&threshold_apply_schedule_download, &mutex_schedule_download, &apply_timeout);
|
||||
pthread_mutex_unlock(&mutex_apply_schedule_download);
|
||||
} else if (min_time == apply_download->timeintervals[1].windowstart) {
|
||||
pthread_mutex_lock(&mutex_apply_schedule_download);
|
||||
apply_timeout.tv_sec = min_time;
|
||||
pthread_cond_timedwait(&threshold_schedule_download, &mutex_schedule_download, &apply_timeout);
|
||||
pthread_mutex_unlock(&mutex_schedule_download);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int cwmp_free_download_request(struct download *download)
|
||||
{
|
||||
if (download != NULL) {
|
||||
if (download->command_key != NULL)
|
||||
free(download->command_key);
|
||||
|
||||
if (download->file_type != NULL)
|
||||
free(download->file_type);
|
||||
|
||||
if (download->url != NULL)
|
||||
free(download->url);
|
||||
|
||||
if (download->username != NULL)
|
||||
free(download->username);
|
||||
|
||||
if (download->password != NULL)
|
||||
free(download->password);
|
||||
|
||||
free(download);
|
||||
}
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
||||
int cwmp_free_schedule_download_request(struct schedule_download *schedule_download)
|
||||
{
|
||||
if (schedule_download != NULL) {
|
||||
if (schedule_download->command_key != NULL)
|
||||
free(schedule_download->command_key);
|
||||
|
||||
if (schedule_download->file_type != NULL)
|
||||
free(schedule_download->file_type);
|
||||
|
||||
if (schedule_download->url != NULL)
|
||||
free(schedule_download->url);
|
||||
|
||||
if (schedule_download->username != NULL)
|
||||
free(schedule_download->username);
|
||||
|
||||
if (schedule_download->password != NULL)
|
||||
free(schedule_download->password);
|
||||
|
||||
for (int i = 0; i <= 1; i++) {
|
||||
if (schedule_download->timewindowstruct[i].windowmode != NULL)
|
||||
free(schedule_download->timewindowstruct[i].windowmode);
|
||||
|
||||
if (schedule_download->timewindowstruct[i].usermessage != NULL)
|
||||
free(schedule_download->timewindowstruct[i].usermessage);
|
||||
}
|
||||
free(schedule_download);
|
||||
}
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
||||
int cwmp_free_apply_schedule_download_request(struct apply_schedule_download *apply_schedule_download)
|
||||
{
|
||||
if (apply_schedule_download != NULL) {
|
||||
if (apply_schedule_download->command_key != NULL)
|
||||
free(apply_schedule_download->command_key);
|
||||
|
||||
if (apply_schedule_download->file_type != NULL)
|
||||
free(apply_schedule_download->file_type);
|
||||
|
||||
if (apply_schedule_download->start_time != NULL)
|
||||
free(apply_schedule_download->start_time);
|
||||
|
||||
free(apply_schedule_download);
|
||||
}
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
||||
int cwmp_scheduledDownload_remove_all()
|
||||
{
|
||||
struct download *download;
|
||||
|
||||
pthread_mutex_lock(&mutex_download);
|
||||
while (list_download.next != &(list_download)) {
|
||||
download = list_entry(list_download.next, struct download, list);
|
||||
list_del(&(download->list));
|
||||
bkp_session_delete_download(download);
|
||||
if (download->scheduled_time != 0)
|
||||
count_download_queue--;
|
||||
cwmp_free_download_request(download);
|
||||
}
|
||||
pthread_mutex_unlock(&mutex_download);
|
||||
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
||||
int cwmp_scheduled_Download_remove_all()
|
||||
{
|
||||
struct schedule_download *schedule_download;
|
||||
|
||||
pthread_mutex_lock(&mutex_schedule_download);
|
||||
while (list_schedule_download.next != &(list_schedule_download)) {
|
||||
schedule_download = list_entry(list_schedule_download.next, struct schedule_download, list);
|
||||
list_del(&(schedule_download->list));
|
||||
bkp_session_delete_schedule_download(schedule_download);
|
||||
if (schedule_download->timewindowstruct[0].windowstart != 0)
|
||||
count_download_queue--;
|
||||
cwmp_free_schedule_download_request(schedule_download);
|
||||
}
|
||||
pthread_mutex_unlock(&mutex_schedule_download);
|
||||
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
||||
int cwmp_apply_scheduled_Download_remove_all()
|
||||
{
|
||||
struct apply_schedule_download *apply_schedule_download;
|
||||
|
||||
pthread_mutex_lock(&mutex_apply_schedule_download);
|
||||
while (list_apply_schedule_download.next != &(list_apply_schedule_download)) {
|
||||
apply_schedule_download = list_entry(list_apply_schedule_download.next, struct apply_schedule_download, list);
|
||||
list_del(&(apply_schedule_download->list));
|
||||
bkp_session_delete_apply_schedule_download(apply_schedule_download);
|
||||
/*if(apply_schedule_download->timetimeintervals[0].windowstart != 0)
|
||||
count_download_queue--;*/ //TOCK
|
||||
cwmp_free_apply_schedule_download_request(apply_schedule_download);
|
||||
}
|
||||
pthread_mutex_unlock(&mutex_apply_schedule_download);
|
||||
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
||||
int cwmp_rpc_acs_destroy_data_transfer_complete(struct session *session __attribute__((unused)), struct rpc *rpc)
|
||||
{
|
||||
struct transfer_complete *p;
|
||||
if (rpc->extra_data != NULL) {
|
||||
p = (struct transfer_complete *)rpc->extra_data;
|
||||
bkp_session_delete_transfer_complete(p);
|
||||
bkp_session_save();
|
||||
FREE(p->command_key);
|
||||
FREE(p->start_time);
|
||||
FREE(p->complete_time);
|
||||
FREE(p->old_software_version);
|
||||
}
|
||||
FREE(rpc->extra_data);
|
||||
return 0;
|
||||
}
|
||||
5
event.c
5
event.c
|
|
@ -18,11 +18,16 @@
|
|||
#include <openssl/engine.h>*/
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "backupSession.h"
|
||||
#include "log.h"
|
||||
#include "event.h"
|
||||
#include "session.h"
|
||||
#include "xml.h"
|
||||
#include "cwmp_du_state.h"
|
||||
#include "download.h"
|
||||
#include "upload.h"
|
||||
#include "sched_inform.h"
|
||||
|
||||
const struct EVENT_CONST_STRUCT EVENT_CONST[] = {[EVENT_IDX_0BOOTSTRAP] = { "0 BOOTSTRAP", EVENT_TYPE_SINGLE, EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
||||
[EVENT_IDX_1BOOT] = { "1 BOOT", EVENT_TYPE_SINGLE, EVENT_RETRY_AFTER_TRANSMIT_FAIL },
|
||||
|
|
|
|||
43
inc/common.h
43
inc/common.h
|
|
@ -300,7 +300,45 @@ enum fault_cpe_idx
|
|||
__FAULT_CPE_MAX
|
||||
};
|
||||
|
||||
enum
|
||||
enum fault_code_enum
|
||||
{
|
||||
FAULT_9000 = 9000, // Method not supported
|
||||
FAULT_9001, // Request denied
|
||||
FAULT_9002, // Internal error
|
||||
FAULT_9003, // Invalid arguments
|
||||
FAULT_9004, // Resources exceeded
|
||||
FAULT_9005, // Invalid parameter name
|
||||
FAULT_9006, // Invalid parameter type
|
||||
FAULT_9007, // Invalid parameter value
|
||||
FAULT_9008, // Attempt to set a non-writable parameter
|
||||
FAULT_9009, // Notification request rejected
|
||||
FAULT_9010, // Download failure
|
||||
FAULT_9011, // Upload failure
|
||||
FAULT_9012, // File transfer server authentication failure
|
||||
FAULT_9013, // Unsupported protocol for file transfer
|
||||
FAULT_9014, // Download failure: unable to join multicast group
|
||||
FAULT_9015, // Download failure: unable to contact file server
|
||||
FAULT_9016, // Download failure: unable to access file
|
||||
FAULT_9017, // Download failure: unable to complete download
|
||||
FAULT_9018, // Download failure: file corrupted
|
||||
FAULT_9019, // Download failure: file authentication failure
|
||||
FAULT_9020, // Download failure: unable to complete download
|
||||
FAULT_9021, // Cancelation of file transfer not permitted
|
||||
FAULT_9022, // Invalid UUID format
|
||||
FAULT_9023, // Unknown Execution Environment
|
||||
FAULT_9024, // Disabled Execution Environment
|
||||
FAULT_9025, // Diployment Unit to Execution environment mismatch
|
||||
FAULT_9026, // Duplicate Deployment Unit
|
||||
FAULT_9027, // System Ressources Exceeded
|
||||
FAULT_9028, // Unknown Deployment Unit
|
||||
FAULT_9029, // Invalid Deployment Unit State
|
||||
FAULT_9030, // Invalid Deployment Unit Update: Downgrade not permitted
|
||||
FAULT_9031, // Invalid Deployment Unit Update: Version not specified
|
||||
FAULT_9032, // Invalid Deployment Unit Update: Version already exist
|
||||
__FAULT_MAX
|
||||
};
|
||||
|
||||
enum client_server_faults
|
||||
{
|
||||
FAULT_CPE_TYPE_CLIENT,
|
||||
FAULT_CPE_TYPE_SERVER
|
||||
|
|
@ -441,6 +479,7 @@ typedef struct opfault {
|
|||
|
||||
extern struct cwmp cwmp_main;
|
||||
extern long int flashsize;
|
||||
extern struct FAULT_CPE FAULT_CPE_ARRAY[];
|
||||
|
||||
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);
|
||||
|
|
@ -466,6 +505,8 @@ int opkg_install_package(char *package_path);
|
|||
int copy(const char *from, const char *to);
|
||||
int icwmp_rand(void);
|
||||
void icwmp_srand(unsigned int seed);
|
||||
int cwmp_get_fault_code(int fault_code);
|
||||
int cwmp_get_fault_code_by_string(char *fault_code);
|
||||
#ifndef FREE
|
||||
#define FREE(x) \
|
||||
do { \
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@
|
|||
#include "log.h"
|
||||
#include "notifications.h"
|
||||
#include "cwmp_uci.h"
|
||||
#include "cwmp_du_state.h"
|
||||
#include "download.h"
|
||||
#include "upload.h"
|
||||
#include "sched_inform.h"
|
||||
|
||||
int cwmp_rpc_cpe_handle_message(struct session *session, struct rpc *rpc_cpe);
|
||||
#endif /* _CWMP_H__ */
|
||||
|
|
|
|||
|
|
@ -11,8 +11,14 @@
|
|||
#ifndef CWMP_DU_STATE_H
|
||||
#define CWMP_DU_STATE_H
|
||||
|
||||
extern struct list_head list_change_du_state;
|
||||
extern pthread_mutex_t mutex_change_du_state;
|
||||
extern pthread_cond_t threshold_change_du_state;
|
||||
|
||||
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);
|
||||
|
||||
int cwmp_rpc_acs_destroy_data_du_state_change_complete(struct session *session, struct rpc *rpc);
|
||||
void *thread_cwmp_rpc_cpe_change_du_state(void *v);
|
||||
int cwmp_free_change_du_state_request(struct change_du_state *change_du_state);
|
||||
#endif
|
||||
|
|
|
|||
32
inc/download.h
Normal file
32
inc/download.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef CWMP_DOWNLOAD_H
|
||||
#define CWMP_DOWNLOAD_H
|
||||
|
||||
#define DOWNLOAD_PROTOCOL_HTTP "http://"
|
||||
#define DOWNLOAD_PROTOCOL_HTTPS "https://"
|
||||
#define DOWNLOAD_PROTOCOL_FTP "ftp://"
|
||||
#define MAX_DOWNLOAD_QUEUE 10
|
||||
|
||||
extern struct list_head list_download;
|
||||
extern struct list_head list_schedule_download;
|
||||
extern struct list_head list_apply_schedule_download;
|
||||
|
||||
extern pthread_mutex_t mutex_download;
|
||||
extern pthread_cond_t threshold_download;
|
||||
extern pthread_mutex_t mutex_schedule_download;
|
||||
extern pthread_cond_t threshold_schedule_download;
|
||||
extern pthread_mutex_t mutex_apply_schedule_download;
|
||||
extern pthread_cond_t threshold_apply_schedule_download;
|
||||
|
||||
extern int count_download_queue;
|
||||
|
||||
int cwmp_free_download_request(struct download *download);
|
||||
int cwmp_free_schedule_download_request(struct schedule_download *schedule_download);
|
||||
int cwmp_free_apply_schedule_download_request(struct apply_schedule_download *apply_schedule_download);
|
||||
int cwmp_scheduledDownload_remove_all();
|
||||
int cwmp_scheduled_Download_remove_all();
|
||||
int cwmp_apply_scheduled_Download_remove_all();
|
||||
int cwmp_rpc_acs_destroy_data_transfer_complete(struct session *session, struct rpc *rpc);
|
||||
void *thread_cwmp_rpc_cpe_download(void *v);
|
||||
void *thread_cwmp_rpc_cpe_schedule_download(void *v);
|
||||
void *thread_cwmp_rpc_cpe_apply_schedule_download(void *v);
|
||||
#endif
|
||||
|
|
@ -76,4 +76,6 @@ int cwmp_get_int_event_code(char *code);
|
|||
bool event_exist_in_list(struct cwmp *cwmp, int event);
|
||||
int cwmp_root_cause_events(struct cwmp *cwmp);
|
||||
int cwmp_root_cause_transfer_complete(struct cwmp *cwmp, struct transfer_complete *p);
|
||||
int cwmp_root_cause_changedustate_complete(struct cwmp *cwmp, struct du_state_change_complete *p);
|
||||
void cwmp_root_cause_event_ipdiagnostic(void);
|
||||
#endif /* SRC_INC_EVENT_H_ */
|
||||
|
|
|
|||
23
inc/sched_inform.h
Normal file
23
inc/sched_inform.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* 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_SCHED_INFORM_H
|
||||
#define CWMP_SCHED_INFORM_H
|
||||
|
||||
extern struct list_head list_schedule_inform;
|
||||
extern pthread_mutex_t mutex_schedule_inform;
|
||||
extern pthread_cond_t threshold_schedule_inform;
|
||||
extern int count_schedule_inform_queue;
|
||||
|
||||
extern pthread_mutex_t mutex_schedule_inform;
|
||||
extern pthread_cond_t threshold_schedule_inform;
|
||||
void *thread_cwmp_rpc_cpe_scheduleInform(void *v);
|
||||
int cwmp_scheduleInform_remove_all();
|
||||
#endif
|
||||
|
|
@ -64,4 +64,7 @@ struct rpc *cwmp_add_session_rpc_acs(struct session *session, int type);
|
|||
int cwmp_apply_acs_changes();
|
||||
int cwmp_move_session_to_session_send(struct cwmp *cwmp, struct session *session);
|
||||
struct rpc *cwmp_add_session_rpc_acs_head(struct session *session, int type);
|
||||
int cwmp_session_rpc_destructor(struct rpc *rpc);
|
||||
int cwmp_session_destructor(struct session *session);
|
||||
int cwmp_move_session_to_session_queue(struct cwmp *cwmp, struct session *session);
|
||||
#endif /* SRC_INC_SESSION_H_ */
|
||||
|
|
|
|||
22
inc/upload.h
Normal file
22
inc/upload.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* 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_UPLOAD_H
|
||||
#define CWMP_UPLOAD_H
|
||||
|
||||
extern struct list_head list_upload;
|
||||
extern pthread_mutex_t mutex_upload;
|
||||
extern pthread_cond_t threshold_upload;
|
||||
|
||||
int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptransfer_complete);
|
||||
void *thread_cwmp_rpc_cpe_upload(void *v);
|
||||
int cwmp_scheduledUpload_remove_all();
|
||||
int cwmp_free_upload_request(struct upload *upload);
|
||||
#endif
|
||||
74
inc/xml.h
74
inc/xml.h
|
|
@ -19,10 +19,6 @@
|
|||
#include "session.h"
|
||||
|
||||
#define CWMP_MXML_TAB_SPACE " "
|
||||
#define DOWNLOAD_PROTOCOL_HTTP "http://"
|
||||
#define DOWNLOAD_PROTOCOL_HTTPS "https://"
|
||||
#define DOWNLOAD_PROTOCOL_FTP "ftp://"
|
||||
#define MAX_DOWNLOAD_QUEUE 10
|
||||
#define MAX_SCHEDULE_INFORM_QUEUE 10
|
||||
|
||||
#define MXML_DELETE(X) \
|
||||
|
|
@ -33,54 +29,9 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
extern struct list_head list_schedule_inform;
|
||||
extern struct list_head list_download;
|
||||
extern struct list_head list_upload;
|
||||
extern struct list_head list_schedule_download;
|
||||
extern struct list_head list_apply_schedule_download;
|
||||
extern struct list_head list_change_du_state;
|
||||
extern int count_download_queue;
|
||||
extern const struct rpc_cpe_method rpc_cpe_methods[__RPC_CPE_MAX];
|
||||
extern const struct rpc_acs_method rpc_acs_methods[__RPC_ACS_MAX];
|
||||
|
||||
enum fault_code_enum
|
||||
{
|
||||
FAULT_9000 = 9000, // Method not supported
|
||||
FAULT_9001, // Request denied
|
||||
FAULT_9002, // Internal error
|
||||
FAULT_9003, // Invalid arguments
|
||||
FAULT_9004, // Resources exceeded
|
||||
FAULT_9005, // Invalid parameter name
|
||||
FAULT_9006, // Invalid parameter type
|
||||
FAULT_9007, // Invalid parameter value
|
||||
FAULT_9008, // Attempt to set a non-writable parameter
|
||||
FAULT_9009, // Notification request rejected
|
||||
FAULT_9010, // Download failure
|
||||
FAULT_9011, // Upload failure
|
||||
FAULT_9012, // File transfer server authentication failure
|
||||
FAULT_9013, // Unsupported protocol for file transfer
|
||||
FAULT_9014, // Download failure: unable to join multicast group
|
||||
FAULT_9015, // Download failure: unable to contact file server
|
||||
FAULT_9016, // Download failure: unable to access file
|
||||
FAULT_9017, // Download failure: unable to complete download
|
||||
FAULT_9018, // Download failure: file corrupted
|
||||
FAULT_9019, // Download failure: file authentication failure
|
||||
FAULT_9020, // Download failure: unable to complete download
|
||||
FAULT_9021, // Cancelation of file transfer not permitted
|
||||
FAULT_9022, // Invalid UUID format
|
||||
FAULT_9023, // Unknown Execution Environment
|
||||
FAULT_9024, // Disabled Execution Environment
|
||||
FAULT_9025, // Diployment Unit to Execution environment mismatch
|
||||
FAULT_9026, // Duplicate Deployment Unit
|
||||
FAULT_9027, // System Ressources Exceeded
|
||||
FAULT_9028, // Unknown Deployment Unit
|
||||
FAULT_9029, // Invalid Deployment Unit State
|
||||
FAULT_9030, // Invalid Deployment Unit Update: Downgrade not permitted
|
||||
FAULT_9031, // Invalid Deployment Unit Update: Version not specified
|
||||
FAULT_9032, // Invalid Deployment Unit Update: Version already exist
|
||||
__FAULT_MAX
|
||||
};
|
||||
|
||||
void xml_exit(void);
|
||||
|
||||
int cwmp_handle_rpc_cpe_get_rpc_methods(struct session *session, struct rpc *rpc);
|
||||
|
|
@ -109,40 +60,15 @@ int cwmp_rpc_acs_prepare_get_rpc_methods(struct cwmp *cwmp, struct session *sess
|
|||
int cwmp_rpc_acs_prepare_transfer_complete(struct cwmp *cwmp, struct session *session, struct rpc *rpc);
|
||||
int cwmp_rpc_acs_prepare_du_state_change_complete(struct cwmp *cwmp, struct session *session, struct rpc *rpc);
|
||||
int cwmp_rpc_acs_destroy_data_inform(struct session *session, struct rpc *rpc);
|
||||
int cwmp_rpc_acs_destroy_data_transfer_complete(struct session *session, struct rpc *rpc);
|
||||
int cwmp_rpc_acs_destroy_data_du_state_change_complete(struct session *session, struct rpc *rpc);
|
||||
|
||||
int xml_handle_message(struct session *session);
|
||||
int xml_prepare_msg_out(struct session *session);
|
||||
int xml_prepare_lwnotification_message(char **msg_out);
|
||||
int xml_set_cwmp_id_rpc_cpe(struct session *session);
|
||||
int cwmp_create_fault_message(struct session *session, struct rpc *rpc_cpe, int fault_code);
|
||||
int cwmp_get_fault_code(int fault_code);
|
||||
int cwmp_get_fault_code_by_string(char *fault_code);
|
||||
int cwmp_scheduleInform_remove_all();
|
||||
int cwmp_scheduledDownload_remove_all();
|
||||
int cwmp_scheduledUpload_remove_all();
|
||||
int cwmp_scheduled_Download_remove_all();
|
||||
int cwmp_apply_scheduled_Download_remove_all();
|
||||
struct transfer_complete *cwmp_set_data_rpc_acs_transferComplete();
|
||||
void *thread_cwmp_rpc_cpe_scheduleInform(void *v);
|
||||
void *thread_cwmp_rpc_cpe_download(void *v);
|
||||
void *thread_cwmp_rpc_cpe_upload(void *v);
|
||||
void *thread_cwmp_rpc_cpe_schedule_download(void *v);
|
||||
void *thread_cwmp_rpc_cpe_apply_schedule_download(void *v);
|
||||
void *thread_cwmp_rpc_cpe_change_du_state(void *v);
|
||||
|
||||
const char *whitespace_cb(mxml_node_t *node, int where);
|
||||
|
||||
int cwmp_root_cause_changedustate_complete(struct cwmp *cwmp, struct du_state_change_complete *p);
|
||||
void cwmp_root_cause_event_ipdiagnostic(void);
|
||||
int xml_set_cwmp_id(struct session *session);
|
||||
int xml_send_message(struct cwmp *cwmp, struct session *session, struct rpc *rpc);
|
||||
int cwmp_free_change_du_state_request(struct change_du_state *change_du_state);
|
||||
int cwmp_free_download_request(struct download *download);
|
||||
int cwmp_free_upload_request(struct upload *upload);
|
||||
int cwmp_free_schedule_download_request(struct schedule_download *schedule_download);
|
||||
int cwmp_add_apply_schedule_download(struct schedule_download *schedule_download, char *start_time);
|
||||
int cwmp_free_apply_schedule_download_request(struct apply_schedule_download *apply_schedule_download);
|
||||
char *calculate_lwnotification_cnonce();
|
||||
#endif
|
||||
|
|
|
|||
110
sched_inform.c
Normal file
110
sched_inform.c
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* 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 "common.h"
|
||||
#include "sched_inform.h"
|
||||
#include "log.h"
|
||||
#include "backupSession.h"
|
||||
#include "event.h"
|
||||
|
||||
LIST_HEAD(list_schedule_inform);
|
||||
pthread_mutex_t mutex_schedule_inform = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_cond_t threshold_schedule_inform;
|
||||
|
||||
int count_schedule_inform_queue = 0;
|
||||
|
||||
void *thread_cwmp_rpc_cpe_scheduleInform(void *v)
|
||||
{
|
||||
struct cwmp *cwmp = (struct cwmp *)v;
|
||||
struct event_container *event_container;
|
||||
struct schedule_inform *schedule_inform;
|
||||
struct timespec si_timeout = { 0, 0 };
|
||||
time_t current_time, stime;
|
||||
bool add_event_same_time = false;
|
||||
|
||||
for (;;) {
|
||||
if (list_schedule_inform.next != &(list_schedule_inform)) {
|
||||
schedule_inform = list_entry(list_schedule_inform.next, struct schedule_inform, list);
|
||||
stime = schedule_inform->scheduled_time;
|
||||
current_time = time(NULL);
|
||||
if (current_time >= schedule_inform->scheduled_time) {
|
||||
if (add_event_same_time) {
|
||||
pthread_mutex_lock(&mutex_schedule_inform);
|
||||
list_del(&(schedule_inform->list));
|
||||
if (schedule_inform->commandKey != NULL) {
|
||||
bkp_session_delete_schedule_inform(schedule_inform->scheduled_time, schedule_inform->commandKey);
|
||||
free(schedule_inform->commandKey);
|
||||
}
|
||||
free(schedule_inform);
|
||||
pthread_mutex_unlock(&mutex_schedule_inform);
|
||||
continue;
|
||||
}
|
||||
pthread_mutex_lock(&(cwmp->mutex_session_queue));
|
||||
CWMP_LOG(INFO, "Schedule Inform thread: add ScheduleInform event in the queue");
|
||||
event_container = cwmp_add_event_container(cwmp, EVENT_IDX_3SCHEDULED, "");
|
||||
if (event_container != NULL) {
|
||||
cwmp_save_event_container(event_container);
|
||||
}
|
||||
event_container = cwmp_add_event_container(cwmp, EVENT_IDX_M_ScheduleInform, schedule_inform->commandKey);
|
||||
if (event_container != NULL) {
|
||||
cwmp_save_event_container(event_container);
|
||||
}
|
||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
||||
pthread_cond_signal(&(cwmp->threshold_session_send));
|
||||
pthread_mutex_lock(&mutex_schedule_inform);
|
||||
list_del(&(schedule_inform->list));
|
||||
if (schedule_inform->commandKey != NULL) {
|
||||
bkp_session_delete_schedule_inform(schedule_inform->scheduled_time, schedule_inform->commandKey);
|
||||
free(schedule_inform->commandKey);
|
||||
}
|
||||
free(schedule_inform);
|
||||
count_schedule_inform_queue--;
|
||||
pthread_mutex_unlock(&mutex_schedule_inform);
|
||||
add_event_same_time = true;
|
||||
continue;
|
||||
}
|
||||
bkp_session_save();
|
||||
add_event_same_time = false;
|
||||
pthread_mutex_lock(&mutex_schedule_inform);
|
||||
si_timeout.tv_sec = stime;
|
||||
pthread_cond_timedwait(&threshold_schedule_inform, &mutex_schedule_inform, &si_timeout);
|
||||
pthread_mutex_unlock(&mutex_schedule_inform);
|
||||
} else {
|
||||
bkp_session_save();
|
||||
add_event_same_time = false;
|
||||
pthread_mutex_lock(&mutex_schedule_inform);
|
||||
pthread_cond_wait(&threshold_schedule_inform, &mutex_schedule_inform);
|
||||
pthread_mutex_unlock(&mutex_schedule_inform);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int cwmp_scheduleInform_remove_all()
|
||||
{
|
||||
struct schedule_inform *schedule_inform;
|
||||
|
||||
pthread_mutex_lock(&mutex_schedule_inform);
|
||||
while (list_schedule_inform.next != &(list_schedule_inform)) {
|
||||
schedule_inform = list_entry(list_schedule_inform.next, struct schedule_inform, list);
|
||||
|
||||
list_del(&(schedule_inform->list));
|
||||
if (schedule_inform->commandKey != NULL) {
|
||||
bkp_session_delete_schedule_inform(schedule_inform->scheduled_time, schedule_inform->commandKey);
|
||||
free(schedule_inform->commandKey);
|
||||
}
|
||||
free(schedule_inform);
|
||||
}
|
||||
bkp_session_save();
|
||||
pthread_mutex_unlock(&mutex_schedule_inform);
|
||||
|
||||
return CWMP_OK;
|
||||
}
|
||||
110
session.c
110
session.c
|
|
@ -13,10 +13,15 @@
|
|||
#include "event.h"
|
||||
#include "backupSession.h"
|
||||
#include "config.h"
|
||||
#include "xml.h"
|
||||
|
||||
unsigned int end_session_flag = 0;
|
||||
|
||||
void cwmp_set_end_session(unsigned int flag) { end_session_flag |= flag; }
|
||||
void cwmp_set_end_session(unsigned int flag)
|
||||
{ //
|
||||
end_session_flag |= flag;
|
||||
}
|
||||
|
||||
struct rpc *cwmp_add_session_rpc_cpe(struct session *session, int type)
|
||||
{
|
||||
struct rpc *rpc_cpe;
|
||||
|
|
@ -105,3 +110,106 @@ struct session *cwmp_add_queue_session(struct cwmp *cwmp)
|
|||
|
||||
return session;
|
||||
}
|
||||
|
||||
int cwmp_session_rpc_destructor(struct rpc *rpc)
|
||||
{
|
||||
list_del(&(rpc->list));
|
||||
free(rpc);
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
||||
int cwmp_session_destructor(struct session *session)
|
||||
{
|
||||
struct rpc *rpc;
|
||||
|
||||
while (session->head_rpc_acs.next != &(session->head_rpc_acs)) {
|
||||
rpc = list_entry(session->head_rpc_acs.next, struct rpc, list);
|
||||
if (rpc_acs_methods[rpc->type].extra_clean != NULL)
|
||||
rpc_acs_methods[rpc->type].extra_clean(session, rpc);
|
||||
cwmp_session_rpc_destructor(rpc);
|
||||
}
|
||||
|
||||
while (session->head_rpc_cpe.next != &(session->head_rpc_cpe)) {
|
||||
rpc = list_entry(session->head_rpc_cpe.next, struct rpc, list);
|
||||
cwmp_session_rpc_destructor(rpc);
|
||||
}
|
||||
|
||||
if (session->list.next != NULL && session->list.prev != NULL)
|
||||
list_del(&(session->list));
|
||||
|
||||
free(session);
|
||||
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
||||
int cwmp_move_session_to_session_queue(struct cwmp *cwmp, struct session *session)
|
||||
{
|
||||
struct list_head *ilist, *jlist;
|
||||
struct rpc *rpc_acs, *queue_rpc_acs, *rpc_cpe;
|
||||
struct event_container *event_container_old, *event_container_new;
|
||||
struct session *session_queue;
|
||||
bool dup;
|
||||
|
||||
pthread_mutex_lock(&(cwmp->mutex_session_queue));
|
||||
cwmp->retry_count_session++;
|
||||
cwmp->session_send = NULL;
|
||||
if (cwmp->head_session_queue.next == &(cwmp->head_session_queue)) {
|
||||
list_add_tail(&(session->list), &(cwmp->head_session_queue));
|
||||
session->hold_request = 0;
|
||||
session->digest_auth = 0;
|
||||
cwmp->head_event_container = &(session->head_event_container);
|
||||
if (session->head_rpc_acs.next != &(session->head_rpc_acs)) {
|
||||
rpc_acs = list_entry(session->head_rpc_acs.next, struct rpc, list);
|
||||
if (rpc_acs->type != RPC_ACS_INFORM) {
|
||||
if ((rpc_acs = cwmp_add_session_rpc_acs_head(session, RPC_ACS_INFORM)) == NULL) {
|
||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
||||
return CWMP_MEM_ERR;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((rpc_acs = cwmp_add_session_rpc_acs_head(session, RPC_ACS_INFORM)) == NULL) {
|
||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
||||
return CWMP_MEM_ERR;
|
||||
}
|
||||
}
|
||||
while (session->head_rpc_cpe.next != &(session->head_rpc_cpe)) {
|
||||
rpc_cpe = list_entry(session->head_rpc_cpe.next, struct rpc, list);
|
||||
cwmp_session_rpc_destructor(rpc_cpe);
|
||||
}
|
||||
bkp_session_move_inform_to_inform_queue();
|
||||
bkp_session_save();
|
||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
||||
return CWMP_OK;
|
||||
}
|
||||
list_for_each (ilist, &(session->head_event_container)) {
|
||||
event_container_old = list_entry(ilist, struct event_container, list);
|
||||
event_container_new = cwmp_add_event_container(cwmp, event_container_old->code, event_container_old->command_key);
|
||||
if (event_container_new == NULL) {
|
||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
||||
return CWMP_MEM_ERR;
|
||||
}
|
||||
list_splice_init(&(event_container_old->head_dm_parameter), &(event_container_new->head_dm_parameter));
|
||||
cwmp_save_event_container(event_container_new);
|
||||
}
|
||||
session_queue = list_entry(cwmp->head_event_container, struct session, head_event_container);
|
||||
list_for_each (ilist, &(session->head_rpc_acs)) {
|
||||
rpc_acs = list_entry(ilist, struct rpc, list);
|
||||
dup = false;
|
||||
list_for_each (jlist, &(session_queue->head_rpc_acs)) {
|
||||
queue_rpc_acs = list_entry(jlist, struct rpc, list);
|
||||
if (queue_rpc_acs->type == rpc_acs->type && (rpc_acs->type == RPC_ACS_INFORM || rpc_acs->type == RPC_ACS_GET_RPC_METHODS)) {
|
||||
dup = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dup) {
|
||||
continue;
|
||||
}
|
||||
ilist = ilist->prev;
|
||||
list_del(&(rpc_acs->list));
|
||||
list_add_tail(&(rpc_acs->list), &(session_queue->head_rpc_acs));
|
||||
}
|
||||
cwmp_session_destructor(session);
|
||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
|
|
|||
1
ubus.c
1
ubus.c
|
|
@ -24,6 +24,7 @@
|
|||
#include "cwmp_time.h"
|
||||
#include "event.h"
|
||||
#include "backupSession.h"
|
||||
#include "sched_inform.h"
|
||||
|
||||
static struct ubus_context *ctx = NULL;
|
||||
static struct blob_buf b;
|
||||
|
|
|
|||
259
upload.c
Normal file
259
upload.c
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
/*
|
||||
* 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 <pthread.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "upload.h"
|
||||
#include "datamodel_interface.h"
|
||||
#include "download.h"
|
||||
#include "log.h"
|
||||
#include "cwmp_time.h"
|
||||
#include "backupSession.h"
|
||||
#include "cwmp_uci.h"
|
||||
#include "event.h"
|
||||
|
||||
LIST_HEAD(list_upload);
|
||||
|
||||
pthread_cond_t threshold_upload;
|
||||
pthread_mutex_t mutex_upload = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
int lookup_vcf_name(char *instance, char **value)
|
||||
{
|
||||
char *vcf_name_parameter = NULL;
|
||||
char *err = NULL;
|
||||
LIST_HEAD(vcf_parameters);
|
||||
cwmp_asprintf(&vcf_name_parameter, "Device.DeviceInfo.VendorConfigFile.%s.Name", instance);
|
||||
if ((err = cwmp_get_parameter_values(vcf_name_parameter, &vcf_parameters)) != NULL) {
|
||||
FREE(vcf_name_parameter);
|
||||
FREE(err);
|
||||
return -1;
|
||||
}
|
||||
struct cwmp_dm_parameter *param_value = NULL;
|
||||
list_for_each_entry (param_value, &vcf_parameters, list) {
|
||||
*value = strdup(param_value->value);
|
||||
break;
|
||||
}
|
||||
cwmp_free_all_dm_parameter_list(&vcf_parameters);
|
||||
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 error = FAULT_CPE_NO_FAULT;
|
||||
char *upload_startTime;
|
||||
struct transfer_complete *p;
|
||||
char *name = "";
|
||||
upload_startTime = mix_get_time();
|
||||
char *file_path = NULL;
|
||||
bkp_session_delete_upload(pupload);
|
||||
bkp_session_save();
|
||||
|
||||
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);
|
||||
}
|
||||
} 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;
|
||||
return error;
|
||||
}
|
||||
|
||||
p->command_key = pupload->command_key ? strdup(pupload->command_key) : strdup("");
|
||||
p->start_time = strdup(upload_startTime);
|
||||
p->complete_time = strdup(mix_get_time());
|
||||
if (error != FAULT_CPE_NO_FAULT) {
|
||||
p->fault_code = error;
|
||||
}
|
||||
|
||||
*ptransfer_complete = p;
|
||||
return error;
|
||||
}
|
||||
|
||||
void *thread_cwmp_rpc_cpe_upload(void *v)
|
||||
{
|
||||
struct cwmp *cwmp = (struct cwmp *)v;
|
||||
struct upload *pupload;
|
||||
struct timespec upload_timeout = { 0, 0 };
|
||||
time_t current_time, stime;
|
||||
int error = FAULT_CPE_NO_FAULT;
|
||||
struct transfer_complete *ptransfer_complete;
|
||||
long int time_of_grace = 3600, timeout;
|
||||
|
||||
for (;;) {
|
||||
if (list_upload.next != &(list_upload)) {
|
||||
pupload = list_entry(list_upload.next, struct upload, list);
|
||||
stime = pupload->scheduled_time;
|
||||
current_time = time(NULL);
|
||||
if (pupload->scheduled_time != 0)
|
||||
timeout = current_time - pupload->scheduled_time;
|
||||
else
|
||||
timeout = 0;
|
||||
if ((timeout >= 0) && (timeout > time_of_grace)) {
|
||||
pthread_mutex_lock(&mutex_upload);
|
||||
bkp_session_delete_upload(pupload);
|
||||
ptransfer_complete = calloc(1, sizeof(struct transfer_complete));
|
||||
if (ptransfer_complete != NULL) {
|
||||
error = FAULT_CPE_DOWNLOAD_FAILURE;
|
||||
|
||||
ptransfer_complete->command_key = strdup(pupload->command_key);
|
||||
ptransfer_complete->start_time = strdup(mix_get_time());
|
||||
ptransfer_complete->complete_time = strdup(ptransfer_complete->start_time);
|
||||
ptransfer_complete->fault_code = error;
|
||||
ptransfer_complete->type = TYPE_UPLOAD;
|
||||
bkp_session_insert_transfer_complete(ptransfer_complete);
|
||||
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
|
||||
}
|
||||
list_del(&(pupload->list));
|
||||
if (pupload->scheduled_time != 0)
|
||||
count_download_queue--;
|
||||
cwmp_free_upload_request(pupload);
|
||||
pthread_mutex_unlock(&mutex_download);
|
||||
continue;
|
||||
}
|
||||
if ((timeout >= 0) && (timeout <= time_of_grace)) {
|
||||
pthread_mutex_lock(&(cwmp->mutex_session_send));
|
||||
CWMP_LOG(INFO, "Launch upload file %s", pupload->url);
|
||||
error = cwmp_launch_upload(pupload, &ptransfer_complete);
|
||||
if (error != FAULT_CPE_NO_FAULT) {
|
||||
bkp_session_insert_transfer_complete(ptransfer_complete);
|
||||
bkp_session_save();
|
||||
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
|
||||
bkp_session_delete_transfer_complete(ptransfer_complete);
|
||||
} else {
|
||||
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(&(cwmp->mutex_session_send));
|
||||
pthread_cond_signal(&(cwmp->threshold_session_send));
|
||||
pthread_mutex_lock(&mutex_upload);
|
||||
list_del(&(pupload->list));
|
||||
if (pupload->scheduled_time != 0)
|
||||
count_download_queue--;
|
||||
cwmp_free_upload_request(pupload);
|
||||
pthread_mutex_unlock(&mutex_upload);
|
||||
continue;
|
||||
}
|
||||
pthread_mutex_lock(&mutex_upload);
|
||||
upload_timeout.tv_sec = stime;
|
||||
pthread_cond_timedwait(&threshold_upload, &mutex_upload, &upload_timeout);
|
||||
pthread_mutex_unlock(&mutex_upload);
|
||||
} else {
|
||||
pthread_mutex_lock(&mutex_upload);
|
||||
pthread_cond_wait(&threshold_upload, &mutex_upload);
|
||||
pthread_mutex_unlock(&mutex_upload);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int cwmp_free_upload_request(struct upload *upload)
|
||||
{
|
||||
if (upload != NULL) {
|
||||
if (upload->command_key != NULL)
|
||||
FREE(upload->command_key);
|
||||
|
||||
if (upload->file_type != NULL)
|
||||
FREE(upload->file_type);
|
||||
|
||||
if (upload->url != NULL)
|
||||
FREE(upload->url);
|
||||
|
||||
if (upload->username != NULL)
|
||||
FREE(upload->username);
|
||||
|
||||
if (upload->password != NULL)
|
||||
FREE(upload->password);
|
||||
|
||||
if (upload->f_instance != NULL)
|
||||
FREE(upload->f_instance);
|
||||
|
||||
FREE(upload);
|
||||
}
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
||||
int cwmp_scheduledUpload_remove_all()
|
||||
{
|
||||
struct upload *upload;
|
||||
|
||||
pthread_mutex_lock(&mutex_upload);
|
||||
while (list_upload.next != &(list_upload)) {
|
||||
upload = list_entry(list_upload.next, struct upload, list);
|
||||
list_del(&(upload->list));
|
||||
bkp_session_delete_upload(upload);
|
||||
if (upload->scheduled_time != 0)
|
||||
count_download_queue--;
|
||||
cwmp_free_upload_request(upload);
|
||||
}
|
||||
pthread_mutex_unlock(&mutex_upload);
|
||||
|
||||
return CWMP_OK;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue