mirror of
https://dev.iopsys.eu/bbf/icwmp.git
synced 2025-12-10 07:44:41 +01:00
Ticket #6702: icwmp: migrate from multithreading to uloop (Download/Upload)
This commit is contained in:
parent
de3f2b2f7e
commit
63d713ea85
26 changed files with 543 additions and 216 deletions
|
|
@ -862,6 +862,7 @@ void load_download(mxml_node_t *tree)
|
|||
.file_size = &download_request->file_size,
|
||||
.time = &download_request->scheduled_time };
|
||||
load_specific_backup_attributes(tree, &bkp_attrs);
|
||||
download_request->handler_timer.cb = cwmp_start_download;
|
||||
|
||||
list_for_each (ilist, &(list_download)) {
|
||||
idownload_request = list_entry(ilist, struct download, list);
|
||||
|
|
@ -872,6 +873,7 @@ void load_download(mxml_node_t *tree)
|
|||
list_add(&(download_request->list), ilist->prev);
|
||||
if (download_request->scheduled_time != 0)
|
||||
count_download_queue++;
|
||||
cwmp_set_end_session(END_SESSION_DOWNLOAD);
|
||||
}
|
||||
|
||||
void load_schedule_download(mxml_node_t *tree)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ icwmpd_SOURCES = \
|
|||
../notifications.c \
|
||||
../cwmp_zlib.c \
|
||||
../cwmp_du_state.c \
|
||||
../subprocess.c \
|
||||
../download.c \
|
||||
../upload.c \
|
||||
../sched_inform.c \
|
||||
|
|
|
|||
10
config.c
10
config.c
|
|
@ -628,11 +628,11 @@ end:
|
|||
|
||||
int cwmp_get_deviceid()
|
||||
{
|
||||
cwmp_get_leaf_value("Device.DeviceInfo.Manufacturer", &cwmp->deviceid.manufacturer);
|
||||
cwmp_get_leaf_value("Device.DeviceInfo.SerialNumber", &cwmp->deviceid.serialnumber);
|
||||
cwmp_get_leaf_value("Device.DeviceInfo.ProductClass", &cwmp->deviceid.productclass);
|
||||
cwmp_get_leaf_value("Device.DeviceInfo.ManufacturerOUI", &cwmp->deviceid.oui);
|
||||
cwmp_get_leaf_value("Device.DeviceInfo.SoftwareVersion", &cwmp->deviceid.softwareversion);
|
||||
cwmp_get_leaf_value("Device.DeviceInfo.Manufacturer", &cwmp_main->deviceid.manufacturer);
|
||||
cwmp_get_leaf_value("Device.DeviceInfo.SerialNumber", &cwmp_main->deviceid.serialnumber);
|
||||
cwmp_get_leaf_value("Device.DeviceInfo.ProductClass", &cwmp_main->deviceid.productclass);
|
||||
cwmp_get_leaf_value("Device.DeviceInfo.ManufacturerOUI", &cwmp_main->deviceid.oui);
|
||||
cwmp_get_leaf_value("Device.DeviceInfo.SoftwareVersion", &cwmp_main->deviceid.softwareversion);
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
11
cwmp.c
11
cwmp.c
|
|
@ -387,16 +387,7 @@ static void cwmp_exit()
|
|||
|
||||
void cwmp_end_handler(int signal_num __attribute__((unused)))
|
||||
{
|
||||
cwmp_stop = true;
|
||||
|
||||
if (cwmp_main->session->session_status.last_status == SESSION_RUNNING)
|
||||
http_set_timeout();
|
||||
|
||||
uloop_timeout_cancel(&retry_session_timer);
|
||||
uloop_timeout_cancel(&priodic_session_timer);
|
||||
uloop_timeout_cancel(&session_timer);
|
||||
uloop_end();
|
||||
shutdown(cwmp_main->cr_socket_desc, SHUT_RDWR);
|
||||
cwmp_ubus_call("tr069", "exit", CWMP_UBUS_ARGS{ {} }, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
|
|
|||
264
download.c
264
download.c
|
|
@ -9,6 +9,7 @@
|
|||
*/
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <libubox/blobmsg_json.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "download.h"
|
||||
|
|
@ -19,13 +20,14 @@
|
|||
#include "cwmp_time.h"
|
||||
#include "event.h"
|
||||
#include "cwmp_uci.h"
|
||||
#include "session.h"
|
||||
#include "subprocess.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;
|
||||
|
|
@ -70,6 +72,57 @@ int download_file(const char *file_path, const char *url, const char *username,
|
|||
return res_code;
|
||||
}
|
||||
|
||||
char *download_file_task_function(char *task)
|
||||
{
|
||||
|
||||
struct blob_buf bbuf;
|
||||
memset(&bbuf, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&bbuf, 0);
|
||||
|
||||
if (blobmsg_add_json_from_string(&bbuf, task) == false) {
|
||||
blob_buf_free(&bbuf);
|
||||
return NULL;
|
||||
}
|
||||
const struct blobmsg_policy p[5] = { { "task", BLOBMSG_TYPE_STRING }, { "file_path", BLOBMSG_TYPE_STRING }, { "url", BLOBMSG_TYPE_STRING }, { "username", BLOBMSG_TYPE_STRING }, { "password", BLOBMSG_TYPE_STRING } };
|
||||
|
||||
struct blob_attr *tb[5] = { NULL, NULL, NULL, NULL, NULL};
|
||||
blobmsg_parse(p, 5, tb, blobmsg_data(bbuf.head), blobmsg_len(bbuf.head));
|
||||
char *task_name = blobmsg_get_string(tb[0]);
|
||||
if (!task_name || strcmp(task_name, "download") != 0)
|
||||
return NULL;
|
||||
char *file_path = blobmsg_get_string(tb[1]);
|
||||
char *url = blobmsg_get_string(tb[2]);
|
||||
char *username = blobmsg_get_string(tb[3]);
|
||||
char *password = blobmsg_get_string(tb[4]);
|
||||
|
||||
int http_code = download_file(file_path, url, username, password);
|
||||
char *http_ret = (char *)malloc(4 * sizeof(char));
|
||||
snprintf(http_ret, 4, "%d", http_code);
|
||||
http_ret[3] = 0;
|
||||
return http_ret;
|
||||
}
|
||||
|
||||
int download_file_in_subprocess(const char *file_path, const char *url, const char *username, const char *password)
|
||||
{
|
||||
subprocess_start(download_file_task_function);
|
||||
|
||||
struct blob_buf bbuf;
|
||||
memset(&bbuf, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&bbuf, 0);
|
||||
blobmsg_add_string(&bbuf, "task", "download");
|
||||
blobmsg_add_string(&bbuf, "file_path", file_path ? file_path : "");
|
||||
blobmsg_add_string(&bbuf, "url", url ? url : "");
|
||||
blobmsg_add_string(&bbuf, "username", username ? username : "");
|
||||
blobmsg_add_string(&bbuf, "password", password ? password : "");
|
||||
char *download_task = blobmsg_format_json(bbuf.head, true);
|
||||
blob_buf_free(&bbuf);
|
||||
|
||||
if (download_task != NULL) {
|
||||
char *ret = execute_task_in_subprocess(download_task);
|
||||
return atoi(ret);
|
||||
}
|
||||
return 500;
|
||||
}
|
||||
/*
|
||||
* Check if the downloaded image can be applied
|
||||
*/
|
||||
|
|
@ -140,6 +193,58 @@ int get_available_bank_id()
|
|||
return bank_id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get Bank Status
|
||||
*/
|
||||
void ubus_get_bank_status_callback(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg)
|
||||
{
|
||||
int *bank_id = (int *)req->priv;
|
||||
int *status = bank_id;
|
||||
bool bank_found = false;
|
||||
struct blob_attr *banks = NULL;
|
||||
struct blob_attr *cur;
|
||||
int rem;
|
||||
|
||||
blobmsg_for_each_attr(cur, msg, rem)
|
||||
{
|
||||
if (blobmsg_type(cur) == BLOBMSG_TYPE_ARRAY) {
|
||||
banks = cur;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const struct blobmsg_policy p[8] = { { "name", BLOBMSG_TYPE_STRING }, { "id", BLOBMSG_TYPE_INT32 }, { "active", BLOBMSG_TYPE_BOOL }, { "upgrade", BLOBMSG_TYPE_BOOL },
|
||||
{ "fwver", BLOBMSG_TYPE_STRING }, { "swver", BLOBMSG_TYPE_STRING }, { "fwver", BLOBMSG_TYPE_STRING }, { "status", BLOBMSG_TYPE_STRING } };
|
||||
|
||||
blobmsg_for_each_attr(cur, banks, rem)
|
||||
{
|
||||
struct blob_attr *tb[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
||||
blobmsg_parse(p, 8, tb, blobmsg_data(cur), blobmsg_len(cur));
|
||||
if (!tb[0])
|
||||
continue;
|
||||
|
||||
if (blobmsg_get_u32(tb[1]) == (uint32_t)*bank_id) {
|
||||
bank_found = true;
|
||||
if (strcmp(blobmsg_get_string(tb[7]), "Available") == 0 || strcmp(blobmsg_get_string(tb[7]), "Active"))
|
||||
*status = 1;
|
||||
else
|
||||
*status = 0;
|
||||
}
|
||||
}
|
||||
if (bank_found == false)
|
||||
*status = 0;
|
||||
}
|
||||
|
||||
int get_applied_firmware_status(int *bank_id_status)
|
||||
{
|
||||
int e;
|
||||
e = cwmp_ubus_call("fwbank", "dump", CWMP_UBUS_ARGS{ {} }, 0, ubus_get_bank_status_callback, &bank_id_status);
|
||||
if (e != 0) {
|
||||
CWMP_LOG(INFO, "fwbank dump ubus method failed: Ubus err code: %d", e);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply the new firmware
|
||||
*/
|
||||
|
|
@ -154,6 +259,24 @@ int cwmp_apply_firmware()
|
|||
return e;
|
||||
}
|
||||
|
||||
void wait_firmware_to_be_applied(int bank_id)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
do {
|
||||
int bank_id_status = bank_id;
|
||||
|
||||
if (get_applied_firmware_status(&bank_id_status) != CWMP_OK)
|
||||
break;
|
||||
|
||||
if (bank_id_status == 1)
|
||||
break;
|
||||
|
||||
usleep(1000 * 1000);
|
||||
count++;
|
||||
} while(count < 15);
|
||||
}
|
||||
|
||||
int cwmp_apply_multiple_firmware()
|
||||
{
|
||||
int e;
|
||||
|
|
@ -166,9 +289,28 @@ int cwmp_apply_multiple_firmware()
|
|||
CWMP_LOG(INFO, "fwbank upgrade ubus method failed: Ubus err code: %d", e);
|
||||
return -1;
|
||||
}
|
||||
//wait until the apply completes
|
||||
wait_firmware_to_be_applied(bank_id);
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
||||
char *apply_multiple_firmware_task_function(char *task __attribute__((unused)))
|
||||
{
|
||||
int ret = cwmp_apply_multiple_firmware();
|
||||
|
||||
char *ret_str = (char *)malloc(2 * sizeof(char));
|
||||
snprintf(ret_str, 2, "%d", ret);
|
||||
ret_str[1] = 0;
|
||||
return ret_str;
|
||||
}
|
||||
|
||||
int cwmp_apply_multiple_firmware_in_subprocess()
|
||||
{
|
||||
subprocess_start(apply_multiple_firmware_task_function);
|
||||
char *ret = execute_task_in_subprocess("{}"); //empty json object
|
||||
return atoi(ret);
|
||||
}
|
||||
|
||||
int cwmp_launch_download(struct download *pdownload, char *download_file_name, enum load_type ltype, struct transfer_complete **ptransfer_complete)
|
||||
{
|
||||
int error = FAULT_CPE_NO_FAULT;
|
||||
|
|
@ -185,7 +327,7 @@ int cwmp_launch_download(struct download *pdownload, char *download_file_name, e
|
|||
goto end_download;
|
||||
}
|
||||
|
||||
int http_code = download_file(ICWMP_DOWNLOAD_FILE, pdownload->url, pdownload->username, pdownload->password);
|
||||
int http_code = download_file_in_subprocess(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)
|
||||
|
|
@ -314,7 +456,7 @@ int apply_downloaded_file(struct download *pdownload, char *download_file_name,
|
|||
error = FAULT_CPE_NO_FAULT;
|
||||
|
||||
} else if (strcmp(pdownload->file_type, STORED_FIRMWARE_IMAGE_FILE_TYPE) == 0) {
|
||||
int err = cwmp_apply_multiple_firmware();
|
||||
int err = cwmp_apply_multiple_firmware_in_subprocess();
|
||||
if (err == CWMP_OK)
|
||||
error = FAULT_CPE_NO_FAULT;
|
||||
else
|
||||
|
|
@ -330,10 +472,12 @@ int apply_downloaded_file(struct download *pdownload, char *download_file_name,
|
|||
}
|
||||
return FAULT_CPE_NO_FAULT;
|
||||
}
|
||||
|
||||
if (error != FAULT_CPE_NO_FAULT) {
|
||||
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(ptransfer_complete);
|
||||
|
|
@ -356,78 +500,6 @@ struct transfer_complete *set_download_error_transfer_complete(struct download *
|
|||
return ptransfer_complete;
|
||||
}
|
||||
|
||||
void *thread_cwmp_rpc_cpe_download(void *v __attribute__((unused)))
|
||||
{
|
||||
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 (cwmp_stop)
|
||||
break;
|
||||
|
||||
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);
|
||||
error = FAULT_CPE_DOWNLOAD_FAILURE;
|
||||
ptransfer_complete = set_download_error_transfer_complete(pdownload, TYPE_DOWNLOAD);
|
||||
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)) {
|
||||
char *download_file_name = get_file_name_by_download_url(pdownload->url);
|
||||
CWMP_LOG(INFO, "Launch download file %s", pdownload->url);
|
||||
error = cwmp_launch_download(pdownload, download_file_name, TYPE_DOWNLOAD, &ptransfer_complete);
|
||||
sleep(3);
|
||||
if (error != FAULT_CPE_NO_FAULT) {
|
||||
bkp_session_insert_transfer_complete(ptransfer_complete);
|
||||
bkp_session_save();
|
||||
cwmp_root_cause_transfer_complete(ptransfer_complete);
|
||||
bkp_session_delete_transfer_complete(ptransfer_complete);
|
||||
} else {
|
||||
error = apply_downloaded_file(pdownload, download_file_name, ptransfer_complete);
|
||||
if (error || pdownload->file_type[0] == '6')
|
||||
bkp_session_delete_transfer_complete(ptransfer_complete);
|
||||
}
|
||||
if (pdownload->file_type[0] == '6')
|
||||
sleep(30);
|
||||
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 download *schedule_download, char *start_time)
|
||||
{
|
||||
int i = 0;
|
||||
|
|
@ -889,3 +961,45 @@ int cwmp_rpc_acs_destroy_data_transfer_complete(struct rpc *rpc)
|
|||
FREE(rpc->extra_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cwmp_start_download(struct uloop_timeout *timeout)
|
||||
{
|
||||
struct download *pdownload;
|
||||
int error = FAULT_CPE_NO_FAULT;
|
||||
struct transfer_complete *ptransfer_complete;
|
||||
pdownload = container_of(timeout, struct download, handler_timer);
|
||||
|
||||
char *download_file_name = get_file_name_by_download_url(pdownload->url);
|
||||
CWMP_LOG(INFO, "Launch download file %s", pdownload->url);
|
||||
error = cwmp_launch_download(pdownload, download_file_name, TYPE_DOWNLOAD, &ptransfer_complete);
|
||||
sleep(3);
|
||||
if (error != FAULT_CPE_NO_FAULT) {
|
||||
CWMP_LOG(ERROR, "Error while downloading the file: %s", pdownload->url);
|
||||
bkp_session_insert_transfer_complete(ptransfer_complete);
|
||||
bkp_session_save();
|
||||
cwmp_root_cause_transfer_complete(ptransfer_complete);
|
||||
bkp_session_delete_transfer_complete(ptransfer_complete);
|
||||
} else {
|
||||
error = apply_downloaded_file(pdownload, download_file_name, ptransfer_complete);
|
||||
if (error != FAULT_CPE_NO_FAULT) {
|
||||
CWMP_LOG(ERROR, "Error while applying the downloaded file: %s", download_file_name);
|
||||
bkp_session_insert_transfer_complete(ptransfer_complete);
|
||||
bkp_session_save();
|
||||
cwmp_root_cause_transfer_complete(ptransfer_complete);
|
||||
bkp_session_delete_transfer_complete(ptransfer_complete);
|
||||
}
|
||||
}
|
||||
if (error == FAULT_CPE_NO_FAULT && pdownload->file_type[0] == '3') {
|
||||
cwmp_root_cause_transfer_complete(ptransfer_complete);
|
||||
bkp_session_delete_download(pdownload);
|
||||
bkp_session_delete_transfer_complete(ptransfer_complete);
|
||||
bkp_session_save();
|
||||
}
|
||||
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);
|
||||
trigger_cwmp_session_timer();
|
||||
}
|
||||
|
|
|
|||
7
event.c
7
event.c
|
|
@ -218,6 +218,9 @@ int cwmp_root_cause_transfer_complete(struct transfer_complete *p)
|
|||
if (event_container == NULL) {
|
||||
return CWMP_MEM_ERR;
|
||||
}
|
||||
if ((rpc_acs = cwmp_add_session_rpc_acs(RPC_ACS_TRANSFER_COMPLETE)) == NULL) {
|
||||
return CWMP_MEM_ERR;
|
||||
}
|
||||
switch (p->type) {
|
||||
case TYPE_DOWNLOAD:
|
||||
event_container = cwmp_add_event_container(EVENT_IDX_M_Download, p->command_key ? p->command_key : "");
|
||||
|
|
@ -238,9 +241,7 @@ int cwmp_root_cause_transfer_complete(struct transfer_complete *p)
|
|||
}
|
||||
break;
|
||||
}
|
||||
if ((rpc_acs = cwmp_add_session_rpc_acs(RPC_ACS_TRANSFER_COMPLETE)) == NULL) {
|
||||
return CWMP_MEM_ERR;
|
||||
}
|
||||
|
||||
rpc_acs->extra_data = (void *)p;
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ configure_genieacs
|
|||
echo "Checking cwmp status"
|
||||
check_cwmp_status
|
||||
|
||||
mkdir -p /var/run/icwmpd
|
||||
|
||||
[ -f funl-test-result.log ] && rm -f funl-test-result.log
|
||||
|
||||
echo "## Running script verification of functionalities ##"
|
||||
|
|
|
|||
|
|
@ -46,6 +46,12 @@ startretries=0
|
|||
priority=8
|
||||
command=/bin/bash -c "/usr/sbin/genieacs-ui --ui-jwt-secret secret"
|
||||
|
||||
[program:lighttpd]
|
||||
autorestart=false
|
||||
startretries=0
|
||||
priority=9
|
||||
command=service lighttpd restart
|
||||
|
||||
[program:icwmpd]
|
||||
autorestart=false
|
||||
startretries=0
|
||||
|
|
|
|||
|
|
@ -7,6 +7,16 @@ source ./gitlab-ci/shared.sh
|
|||
trap cleanup EXIT
|
||||
trap cleanup SIGINT
|
||||
|
||||
echo "Install lighttpd"
|
||||
apt-get update
|
||||
apt-get install -y lighttpd
|
||||
exec_cmd dd if=/dev/zero of=/builds/iopsys/icwmp/firmware_v1.0.bin bs=25MB count=1
|
||||
echo "Valid" > /builds/iopsys/icwmp/firmware_v1.0.bin
|
||||
exec_cmd cp /builds/iopsys/icwmp/firmware_v1.0.bin /var/www/html
|
||||
exec_cmd dd if=/dev/zero of=/builds/iopsys/icwmp/invalid_firmware_v1.0.bin bs=25MB count=1
|
||||
echo "Invalid" > /builds/iopsys/icwmp/invalid_firmware_v1.0.bin
|
||||
exec_cmd cp /builds/iopsys/icwmp/invalid_firmware_v1.0.bin /var/www/html
|
||||
|
||||
echo "Install Inform json files"
|
||||
exec_cmd mkdir -p /etc/icwmpd
|
||||
exec_cmd cp /builds/iopsys/icwmp/test/files/etc/icwmpd/* /etc/icwmpd
|
||||
|
|
|
|||
|
|
@ -344,6 +344,7 @@ typedef struct timewindow {
|
|||
|
||||
typedef struct download {
|
||||
struct list_head list;
|
||||
struct uloop_timeout handler_timer ;
|
||||
time_t scheduled_time;
|
||||
int file_size;
|
||||
char *command_key;
|
||||
|
|
@ -388,6 +389,7 @@ typedef struct operations {
|
|||
|
||||
typedef struct upload {
|
||||
struct list_head list;
|
||||
struct uloop_timeout handler_timer ;
|
||||
time_t scheduled_time;
|
||||
char *command_key;
|
||||
char *file_type;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ 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;
|
||||
|
|
@ -38,8 +37,8 @@ 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 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);
|
||||
int cwmp_launch_download(struct download *pdownload, char *download_file_name, enum load_type ltype, struct transfer_complete **ptransfer_complete);
|
||||
void cwmp_start_download(struct uloop_timeout *timeout);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -58,7 +58,9 @@ enum end_session_enum
|
|||
END_SESSION_SERVERSELECTION_DIAGNOSTIC = 1 << 11,
|
||||
END_SESSION_SET_NOTIFICATION_UPDATE = 1 << 12,
|
||||
END_SESSION_RESTART_SERVICES = 1 << 13,
|
||||
END_SESSION_INIT_NOTIFY = 1 << 14
|
||||
END_SESSION_INIT_NOTIFY = 1 << 14,
|
||||
END_SESSION_DOWNLOAD = 1 << 15,
|
||||
END_SESSION_UPLOAD = 1 << 16
|
||||
};
|
||||
|
||||
enum enum_session_status
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@
|
|||
#include "session.h"
|
||||
#include "xml.h"
|
||||
|
||||
|
||||
#define PROCESSING_DELAY (1) // In download/upload the message enqueued before sending the response, which cause the download/upload
|
||||
// to start just before the time. This delay is to compensate the time lapsed during the message enqueue and response
|
||||
|
||||
#define MAX_NBRE_CUSTOM_INFORM 256
|
||||
extern char *custom_forced_inform_parameters[MAX_NBRE_CUSTOM_INFORM];
|
||||
extern char *boot_inform_parameters[MAX_NBRE_CUSTOM_INFORM];
|
||||
|
|
|
|||
7
inc/subprocess.h
Normal file
7
inc/subprocess.h
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef SUB_PROC_H
|
||||
#define SUB_PROC_H
|
||||
|
||||
typedef char* (*task_function)(char *task_arg);
|
||||
int subprocess_start(task_function task_fun);
|
||||
char *execute_task_in_subprocess(char *task);
|
||||
#endif
|
||||
|
|
@ -13,10 +13,10 @@
|
|||
|
||||
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);
|
||||
void cwmp_start_upload(struct uloop_timeout *timeout);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -570,7 +570,6 @@ void sotfware_version_value_change(struct transfer_complete *p)
|
|||
|
||||
void periodic_check_notifiy(struct uloop_timeout *timeout __attribute__((unused)))
|
||||
{
|
||||
int periodic_interval = cwmp_main->conf.periodic_notify_interval;
|
||||
int is_notify = 0;
|
||||
if (cwmp_stop)
|
||||
return;
|
||||
|
|
|
|||
73
session.c
73
session.c
|
|
@ -20,6 +20,8 @@
|
|||
#include "diagnostic.h"
|
||||
#include "soap.h"
|
||||
#include "ubus.h"
|
||||
#include "download.h"
|
||||
#include "upload.h"
|
||||
|
||||
pthread_mutex_t start_session_mutext = PTHREAD_MUTEX_INITIALIZER;
|
||||
static void cwmp_priodic_session_timer(struct uloop_timeout *timeout);
|
||||
|
|
@ -71,23 +73,6 @@ int cwmp_session_rpc_destructor(struct rpc *rpc)
|
|||
|
||||
int cwmp_session_exit()
|
||||
{
|
||||
struct rpc *rpc;
|
||||
while (cwmp_main->session->head_rpc_acs.next != &(cwmp_main->session->head_rpc_acs)) {
|
||||
rpc = list_entry(cwmp_main->session->head_rpc_acs.next, struct rpc, list);
|
||||
if (!rpc)
|
||||
break;
|
||||
if (rpc_acs_methods[rpc->type].extra_clean != NULL)
|
||||
rpc_acs_methods[rpc->type].extra_clean(rpc);
|
||||
cwmp_session_rpc_destructor(rpc);
|
||||
}
|
||||
|
||||
while (cwmp_main->session->head_rpc_cpe.next != &(cwmp_main->session->head_rpc_cpe)) {
|
||||
rpc = list_entry(cwmp_main->session->head_rpc_cpe.next, struct rpc, list);
|
||||
if (!rpc)
|
||||
break;
|
||||
cwmp_session_rpc_destructor(rpc);
|
||||
}
|
||||
|
||||
cwmp_uci_exit();
|
||||
icwmp_cleanmem();
|
||||
return CWMP_OK;
|
||||
|
|
@ -97,17 +82,14 @@ static int cwmp_rpc_cpe_handle_message(struct rpc *rpc_cpe)
|
|||
{
|
||||
if (xml_prepare_msg_out())
|
||||
return -1;
|
||||
|
||||
if (rpc_cpe_methods[rpc_cpe->type].handler(rpc_cpe))
|
||||
return -1;
|
||||
|
||||
if (xml_set_cwmp_id_rpc_cpe())
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int cwmp_schedule_rpc()
|
||||
{
|
||||
struct list_head *ilist;
|
||||
|
|
@ -231,6 +213,26 @@ void set_cwmp_session_status(int status, int retry_time)
|
|||
}
|
||||
}
|
||||
|
||||
void rpc_exit()
|
||||
{
|
||||
struct rpc *rpc;
|
||||
while (cwmp_main->session->head_rpc_acs.next != &(cwmp_main->session->head_rpc_acs)) {
|
||||
rpc = list_entry(cwmp_main->session->head_rpc_acs.next, struct rpc, list);
|
||||
if (!rpc)
|
||||
break;
|
||||
if (rpc_acs_methods[rpc->type].extra_clean != NULL)
|
||||
rpc_acs_methods[rpc->type].extra_clean(rpc);
|
||||
cwmp_session_rpc_destructor(rpc);
|
||||
}
|
||||
|
||||
while (cwmp_main->session->head_rpc_cpe.next != &(cwmp_main->session->head_rpc_cpe)) {
|
||||
rpc = list_entry(cwmp_main->session->head_rpc_cpe.next, struct rpc, list);
|
||||
if (!rpc)
|
||||
break;
|
||||
cwmp_session_rpc_destructor(rpc);
|
||||
}
|
||||
}
|
||||
|
||||
void start_cwmp_session()
|
||||
{
|
||||
int t, error;
|
||||
|
|
@ -286,6 +288,8 @@ void start_cwmp_session()
|
|||
event_remove_all_event_container(RPC_SEND);
|
||||
event_remove_all_event_container(RPC_QUEUE);
|
||||
run_session_end_func();
|
||||
cwmp_session_exit();
|
||||
rpc_exit();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -300,6 +304,7 @@ void start_cwmp_session()
|
|||
//event_remove_all_event_container(RPC_QUEUE);
|
||||
cwmp_main->retry_count_session = 0;
|
||||
set_cwmp_session_status(SESSION_SUCCESS, 0);
|
||||
rpc_exit();
|
||||
}
|
||||
run_session_end_func();
|
||||
cwmp_session_exit();
|
||||
|
|
@ -506,6 +511,34 @@ int run_session_end_func(void)
|
|||
cwmp_factory_reset();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
if (end_session_flag & END_SESSION_DOWNLOAD) {
|
||||
CWMP_LOG(INFO, "Trigger Uloop Downaload Calls");
|
||||
struct list_head *ilist;
|
||||
list_for_each (ilist, &(list_download)) {
|
||||
struct download *download = list_entry(ilist, struct download, list);
|
||||
int download_delay = 0;
|
||||
if (download->scheduled_time > time(NULL)) {
|
||||
download_delay = download->scheduled_time - time(NULL);
|
||||
}
|
||||
uloop_timeout_set(&download->handler_timer, 1000 * download_delay);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (end_session_flag & END_SESSION_UPLOAD) {
|
||||
CWMP_LOG(INFO, "Trigger Uloop Upload Calls");
|
||||
struct list_head *ilist;
|
||||
list_for_each (ilist, &(list_upload)) {
|
||||
struct download *upload = list_entry(ilist, struct download, list);
|
||||
int upload_delay = 0;
|
||||
if (upload->scheduled_time > time(NULL)) {
|
||||
upload_delay = upload->scheduled_time - time(NULL);
|
||||
}
|
||||
uloop_timeout_set(&upload->handler_timer, 1000 * upload_delay);
|
||||
}
|
||||
}
|
||||
|
||||
end_session_flag = 0;
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
|
|
|||
18
soap.c
18
soap.c
|
|
@ -32,8 +32,6 @@
|
|||
#include "upload.h"
|
||||
#include "sched_inform.h"
|
||||
|
||||
#define PROCESSING_DELAY (1) // In download/upload the message enqueued before sending the response, which cause the download/upload
|
||||
// to start just before the time. This delay is to compensate the time lapsed during the message enqueue and response
|
||||
#define DM_CONN_REQ_URL "Device.ManagementServer.ConnectionRequestURL"
|
||||
|
||||
struct cwmp_namespaces ns;
|
||||
|
|
@ -533,7 +531,6 @@ int cwmp_rpc_acs_prepare_transfer_complete(struct rpc *rpc)
|
|||
{
|
||||
mxml_node_t *tree, *n;
|
||||
struct transfer_complete *p;
|
||||
|
||||
p = (struct transfer_complete *)rpc->extra_data;
|
||||
tree = mxmlLoadString(NULL, CWMP_RESPONSE_MESSAGE, MXML_OPAQUE_CALLBACK);
|
||||
n = mxmlFindElement(tree, tree, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
||||
|
|
@ -2064,6 +2061,7 @@ int cwmp_handle_rpc_cpe_download(struct rpc *rpc)
|
|||
count_download_queue++;
|
||||
download->scheduled_time = scheduled_time;
|
||||
}
|
||||
download->handler_timer.cb = cwmp_start_download;
|
||||
bkp_session_insert_download(download);
|
||||
bkp_session_save();
|
||||
if (download_delay != 0) {
|
||||
|
|
@ -2071,9 +2069,9 @@ int cwmp_handle_rpc_cpe_download(struct rpc *rpc)
|
|||
} else {
|
||||
CWMP_LOG(INFO, "Download will start at the end of session");
|
||||
}
|
||||
|
||||
cwmp_set_end_session(END_SESSION_DOWNLOAD);
|
||||
pthread_mutex_unlock(&mutex_download);
|
||||
pthread_cond_signal(&threshold_download);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -2409,15 +2407,17 @@ int cwmp_handle_rpc_cpe_upload(struct rpc *rpc)
|
|||
count_download_queue++;
|
||||
upload->scheduled_time = scheduled_time;
|
||||
}
|
||||
bkp_session_insert_upload(upload);
|
||||
upload->handler_timer.cb = cwmp_start_upload;
|
||||
bkp_session_save(upload);
|
||||
bkp_session_save();
|
||||
if (upload_delay != 0) {
|
||||
CWMP_LOG(INFO, "Upload will start in %us", upload_delay);
|
||||
CWMP_LOG(INFO, "Download will start in %us", upload_delay);
|
||||
} else {
|
||||
CWMP_LOG(INFO, "Upload will start at the end of session");
|
||||
CWMP_LOG(INFO, "Download will start at the end of session");
|
||||
}
|
||||
cwmp_set_end_session(END_SESSION_UPLOAD);
|
||||
pthread_mutex_unlock(&mutex_upload);
|
||||
pthread_cond_signal(&threshold_upload);
|
||||
|
||||
}
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
136
subprocess.c
Normal file
136
subprocess.c
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
#include <libubox/blobmsg_json.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "subprocess.h"
|
||||
#include "log.h"
|
||||
|
||||
#define END_TASK "{\"task\":\"end\"}"
|
||||
#define EXIT_TASK "{\"task\":\"exit\"}"
|
||||
|
||||
static int pipefd1[2], pipefd2[2];
|
||||
|
||||
bool check_task_name(char *task, char *name)
|
||||
{
|
||||
struct blob_buf bbuf;
|
||||
|
||||
if (strcmp(task, "{}") == 0)
|
||||
return false;
|
||||
|
||||
memset(&bbuf, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&bbuf, 0);
|
||||
|
||||
if (blobmsg_add_json_from_string(&bbuf, task) == false) {
|
||||
blob_buf_free(&bbuf);
|
||||
return false;
|
||||
}
|
||||
|
||||
const struct blobmsg_policy p[1] = { { "task", BLOBMSG_TYPE_STRING } };
|
||||
|
||||
struct blob_attr *tb[1] = { NULL };
|
||||
blobmsg_parse(p, 1, tb, blobmsg_data(bbuf.head), blobmsg_len(bbuf.head));
|
||||
if (tb[0] == NULL)
|
||||
return false;
|
||||
|
||||
char *task_name = blobmsg_get_string(tb[0]);
|
||||
|
||||
if (strcmp(task_name, name) == 0) {
|
||||
blob_buf_free(&bbuf);
|
||||
return true;
|
||||
}
|
||||
blob_buf_free(&bbuf);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool check_task_is_end(char *task)
|
||||
{
|
||||
return check_task_name(task, "end");
|
||||
}
|
||||
|
||||
bool check_task_is_exit(char *task)
|
||||
{
|
||||
return check_task_name(task, "exit");
|
||||
}
|
||||
|
||||
int subprocess_start(task_function task_fun)
|
||||
{
|
||||
if(task_fun == NULL)
|
||||
return CWMP_GEN_ERR;
|
||||
|
||||
pid_t p;
|
||||
if (pipe(pipefd1) == -1) {
|
||||
CWMP_LOG(ERROR, "pipefd1 failed\n");
|
||||
return CWMP_GEN_ERR;
|
||||
}
|
||||
if (pipe(pipefd2) == -1) {
|
||||
CWMP_LOG(ERROR, "pipefd2 failed\n");
|
||||
return CWMP_GEN_ERR;
|
||||
}
|
||||
p = fork();
|
||||
|
||||
if (p == 0) {
|
||||
while(1) {
|
||||
char from_parent[512];
|
||||
read(pipefd1[0], from_parent, 512); //The received string should has the form {"task":"TaskName", "arg1_name":"xxx", "arg2_name":"xxxx"}
|
||||
if (strlen(from_parent) == 0)
|
||||
continue;
|
||||
//get the task name
|
||||
//if the task name is end
|
||||
if (check_task_is_end(from_parent)){
|
||||
write(pipefd2[1], EXIT_TASK, strlen(EXIT_TASK)+1);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
char *to_child = task_fun(from_parent);
|
||||
|
||||
struct blob_buf bbuf;
|
||||
memset(&bbuf, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&bbuf, 0);
|
||||
blobmsg_add_string(&bbuf, "ret", to_child);
|
||||
char *to_child_json = blobmsg_format_json(bbuf.head, true);
|
||||
write(pipefd2[1], to_child_json, strlen(to_child_json)+1);
|
||||
blob_buf_free(&bbuf);
|
||||
}
|
||||
}
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
||||
char *execute_task_in_subprocess(char *task)
|
||||
{
|
||||
char *ret = NULL;
|
||||
|
||||
write(pipefd1[1], task, strlen(task) + 1);
|
||||
|
||||
while(1) {
|
||||
char from_child[512];
|
||||
read(pipefd2[0], from_child, 512);
|
||||
if(strlen(from_child) == 0)
|
||||
continue;
|
||||
//The received string from the child should has the format {"task":"exit"} or {"ret":"exit"}
|
||||
if (check_task_is_exit(from_child)){
|
||||
close(pipefd2[1]);
|
||||
close(pipefd2[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
struct blob_buf bbuf;
|
||||
memset(&bbuf, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&bbuf, 0);
|
||||
if (blobmsg_add_json_from_string(&bbuf, from_child) == false) {
|
||||
blob_buf_free(&bbuf);
|
||||
continue;
|
||||
}
|
||||
const struct blobmsg_policy p[1] = { { "ret", BLOBMSG_TYPE_STRING } };
|
||||
struct blob_attr *tb[1] = { NULL };
|
||||
blobmsg_parse(p, 1, tb, blobmsg_data(bbuf.head), blobmsg_len(bbuf.head));
|
||||
if (tb[0] == NULL) {
|
||||
blob_buf_free(&bbuf);
|
||||
continue;
|
||||
}
|
||||
ret = blobmsg_get_string(tb[0]);
|
||||
write(pipefd1[1], END_TASK, strlen(END_TASK) +1);
|
||||
}
|
||||
close(pipefd1[0]);
|
||||
close(pipefd1[1]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -10,7 +10,7 @@ UNIT_TESTS = icwmp_datamodel_interface_unit_testd icwmp_soap_msg_unit_testd icwm
|
|||
VALGRIND = valgrind --leak-check=full --show-reachable=yes --show-leak-kinds=all --errors-for-leak-kinds=all
|
||||
|
||||
libobj:
|
||||
$(CC) $(LIBCFLAGS) ../../download.c ../../upload.c ../../log.c ../../md5.c ../../digestauth.c ../../netlink.c ../../cwmp_cli.c ../../cwmp_du_state.c ../../sched_inform.c \
|
||||
$(CC) $(LIBCFLAGS) ../../subprocess.c ../../download.c ../../upload.c ../../log.c ../../md5.c ../../digestauth.c ../../netlink.c ../../cwmp_cli.c ../../cwmp_du_state.c ../../sched_inform.c \
|
||||
../../diagnostic.c ../../reboot.c ../../notifications.c ../../cwmp_zlib.c ../../datamodel_interface.c ../../http.c ../../backupSession.c \
|
||||
../../cwmp_time.c ../../config.c ../../event.c ../../session.c ../../ubus.c ../../common.c ../../xml.c ../../soap.c ../../cwmp_uci.c ../../cwmp.c $(LDFLAGS)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,4 +2,5 @@ verify_add_method.sh
|
|||
verify_delete_method.sh
|
||||
verify_get_method.sh
|
||||
verify_set_method.sh
|
||||
verify_download_method.sh
|
||||
verify_cmd_line.sh
|
||||
|
|
|
|||
|
|
@ -19,11 +19,15 @@ if [ "$status" != "1" ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
rm /etc/icwmpd/dm_enabled_notify
|
||||
rm /var/run/icwmpd/dm_enabled_notify
|
||||
remove_icwmp_log
|
||||
echo "Restarting icwmpd in order to apply the new firmware" >> ./funl-test-debug.log
|
||||
supervisorctl restart icwmpd >> ./funl-test-debug.log
|
||||
sleep 5
|
||||
echo "Restarting icwmpd in order to apply the new firmware" >> ./funl-test-debug.log
|
||||
#/builds/iopsys/icwmp/bin/icwmpd -b &
|
||||
supervisorctl stop icwmpd
|
||||
sleep 3
|
||||
supervisorctl start icwmpd >> ./funl-test-debug.log
|
||||
sleep 10
|
||||
check_session "TransferComplete"
|
||||
received_command_key=$(print_tag_value "cwmp:TransferComplete" "CommandKey")
|
||||
if [ "$sent_command_key" != "$received_command_key" ]; then
|
||||
|
|
|
|||
11
ubus.c
11
ubus.c
|
|
@ -97,7 +97,16 @@ static int cwmp_handle_command(struct ubus_context *ctx, struct ubus_object *obj
|
|||
if (snprintf(info, sizeof(info), "icwmpd daemon stopped") == -1)
|
||||
return -1;
|
||||
|
||||
cwmp_end_handler(SIGTERM);
|
||||
cwmp_stop = true;
|
||||
|
||||
if (cwmp_main->session->session_status.last_status == SESSION_RUNNING)
|
||||
http_set_timeout();
|
||||
|
||||
uloop_timeout_cancel(&retry_session_timer);
|
||||
uloop_timeout_cancel(&priodic_session_timer);
|
||||
uloop_timeout_cancel(&session_timer);
|
||||
uloop_end();
|
||||
shutdown(cwmp_main->cr_socket_desc, SHUT_RDWR);
|
||||
|
||||
} else {
|
||||
blobmsg_add_u32(&b, "status", -1);
|
||||
|
|
|
|||
166
upload.c
166
upload.c
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <pthread.h>
|
||||
#include <curl/curl.h>
|
||||
#include <libubox/blobmsg_json.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "upload.h"
|
||||
|
|
@ -20,12 +21,13 @@
|
|||
#include "backupSession.h"
|
||||
#include "cwmp_uci.h"
|
||||
#include "event.h"
|
||||
#include "subprocess.h"
|
||||
#include "session.h"
|
||||
|
||||
#define CURL_TIMEOUT 20
|
||||
|
||||
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)
|
||||
|
|
@ -62,6 +64,9 @@ int lookup_vlf_name(char *instance, char **value)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Upload file
|
||||
*/
|
||||
int upload_file(const char *file_path, const char *url, const char *username, const char *password)
|
||||
{
|
||||
int res_code = 0;
|
||||
|
|
@ -92,6 +97,58 @@ int upload_file(const char *file_path, const char *url, const char *username, co
|
|||
return res_code;
|
||||
}
|
||||
|
||||
char *upload_file_task_function(char *task)
|
||||
{
|
||||
|
||||
struct blob_buf bbuf;
|
||||
memset(&bbuf, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&bbuf, 0);
|
||||
|
||||
if (blobmsg_add_json_from_string(&bbuf, task) == false) {
|
||||
blob_buf_free(&bbuf);
|
||||
return NULL;
|
||||
}
|
||||
const struct blobmsg_policy p[5] = { { "task", BLOBMSG_TYPE_STRING }, { "file_path", BLOBMSG_TYPE_STRING }, { "url", BLOBMSG_TYPE_STRING }, { "username", BLOBMSG_TYPE_STRING }, { "password", BLOBMSG_TYPE_STRING } };
|
||||
|
||||
struct blob_attr *tb[5] = { NULL, NULL, NULL, NULL, NULL};
|
||||
blobmsg_parse(p, 5, tb, blobmsg_data(bbuf.head), blobmsg_len(bbuf.head));
|
||||
char *task_name = blobmsg_get_string(tb[0]);
|
||||
if (!task_name || strcmp(task_name, "upload") != 0)
|
||||
return NULL;
|
||||
char *file_path = blobmsg_get_string(tb[1]);
|
||||
char *url = blobmsg_get_string(tb[2]);
|
||||
char *username = blobmsg_get_string(tb[3]);
|
||||
char *password = blobmsg_get_string(tb[4]);
|
||||
|
||||
int http_code = upload_file(file_path, url, username, password);
|
||||
char *http_ret = (char *)malloc(4 * sizeof(char));
|
||||
snprintf(http_ret, 4, "%d", http_code);
|
||||
http_ret[3] = 0;
|
||||
return http_ret;
|
||||
}
|
||||
|
||||
int upload_file_in_subprocess(const char *file_path, const char *url, const char *username, const char *password)
|
||||
{
|
||||
subprocess_start(upload_file_task_function);
|
||||
|
||||
struct blob_buf bbuf;
|
||||
memset(&bbuf, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&bbuf, 0);
|
||||
blobmsg_add_string(&bbuf, "task", "upload");
|
||||
blobmsg_add_string(&bbuf, "file_path", file_path);
|
||||
blobmsg_add_string(&bbuf, "url", url);
|
||||
blobmsg_add_string(&bbuf, "username", username);
|
||||
blobmsg_add_string(&bbuf, "password", password);
|
||||
char *upload_task = blobmsg_format_json(bbuf.head, true);
|
||||
blob_buf_free(&bbuf);
|
||||
|
||||
if (upload_task != NULL) {
|
||||
char *ret = execute_task_in_subprocess(upload_task);
|
||||
return atoi(ret);
|
||||
}
|
||||
return 500;
|
||||
}
|
||||
|
||||
int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptransfer_complete)
|
||||
{
|
||||
int error = FAULT_CPE_NO_FAULT;
|
||||
|
|
@ -160,86 +217,6 @@ end_upload:
|
|||
return error;
|
||||
}
|
||||
|
||||
void *thread_cwmp_rpc_cpe_upload(void *v __attribute__((unused)))
|
||||
{
|
||||
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 (cwmp_stop)
|
||||
break;
|
||||
|
||||
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(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)) {
|
||||
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(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(ptransfer_complete);
|
||||
}
|
||||
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) {
|
||||
|
|
@ -282,3 +259,30 @@ int cwmp_scheduledUpload_remove_all()
|
|||
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
||||
void cwmp_start_upload(struct uloop_timeout *timeout)
|
||||
{
|
||||
struct upload *pupload;
|
||||
int error = FAULT_CPE_NO_FAULT;
|
||||
struct transfer_complete *ptransfer_complete;
|
||||
|
||||
pupload = container_of(timeout, struct upload, handler_timer);
|
||||
|
||||
CWMP_LOG(INFO, "Launch download file %s", pupload->url);
|
||||
error = cwmp_launch_upload(pupload, &ptransfer_complete);
|
||||
sleep(3);
|
||||
if (error != FAULT_CPE_NO_FAULT) {
|
||||
CWMP_LOG(ERROR, "Error while uploading the file: %s", pupload->url);
|
||||
}
|
||||
|
||||
bkp_session_insert_transfer_complete(ptransfer_complete);
|
||||
bkp_session_save();
|
||||
cwmp_root_cause_transfer_complete(ptransfer_complete);
|
||||
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);
|
||||
trigger_cwmp_session_timer();
|
||||
}
|
||||
|
|
|
|||
4
xml.c
4
xml.c
|
|
@ -182,7 +182,7 @@ int xml_send_message(struct rpc *rpc)
|
|||
if (b) {
|
||||
b = mxmlWalkNext(b, cwmp_main->session->tree_in, MXML_DESCEND_FIRST);
|
||||
if (b && b->type == MXML_OPAQUE && b->value.opaque)
|
||||
cwmp_main->session->hold_request = atoi(b->value.opaque);
|
||||
cwmp_main->session->hold_request = (atoi(b->value.opaque)) ? true : false;
|
||||
} else {
|
||||
if (snprintf(c, sizeof(c), "%s:%s", ns.cwmp, "HoldRequests") == -1)
|
||||
goto error;
|
||||
|
|
@ -191,7 +191,7 @@ int xml_send_message(struct rpc *rpc)
|
|||
if (b) {
|
||||
b = mxmlWalkNext(b, cwmp_main->session->tree_in, MXML_DESCEND_FIRST);
|
||||
if (b && b->type == MXML_OPAQUE && b->value.opaque)
|
||||
cwmp_main->session->hold_request = atoi(b->value.opaque);
|
||||
cwmp_main->session->hold_request = (atoi(b->value.opaque)) ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue