mirror of
https://dev.iopsys.eu/bbf/icwmp.git
synced 2025-12-10 07:44:41 +01:00
Ticket refs #6914: icwmp: migrate from multithreading to uloop
This commit is contained in:
parent
19a3ba5412
commit
34499c1cb3
59 changed files with 2988 additions and 3314 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -5,7 +5,6 @@
|
||||||
*.log
|
*.log
|
||||||
*.xml
|
*.xml
|
||||||
*.so
|
*.so
|
||||||
*.txt
|
|
||||||
*.orig
|
*.orig
|
||||||
bin/*
|
bin/*
|
||||||
!bin/Makefile.am
|
!bin/Makefile.am
|
||||||
|
|
@ -43,3 +42,4 @@ CMakeCache.txt
|
||||||
CMakeFiles/
|
CMakeFiles/
|
||||||
cmake_install.cmake
|
cmake_install.cmake
|
||||||
install_manifest.txt
|
install_manifest.txt
|
||||||
|
/report
|
||||||
|
|
|
||||||
|
|
@ -70,4 +70,6 @@ run_functional_test:
|
||||||
- funl-test-memory-report.xml
|
- funl-test-memory-report.xml
|
||||||
- funl-test-result.log
|
- funl-test-result.log
|
||||||
- funl-test-debug.log
|
- funl-test-debug.log
|
||||||
|
- memory-report.xml
|
||||||
|
- memory-report-download.xml
|
||||||
- icwmpd_debug.txt
|
- icwmpd_debug.txt
|
||||||
|
|
|
||||||
|
|
@ -8,21 +8,6 @@ pwd
|
||||||
trap cleanup EXIT
|
trap cleanup EXIT
|
||||||
trap cleanup SIGINT
|
trap cleanup SIGINT
|
||||||
|
|
||||||
function check_valgrind_xml() {
|
|
||||||
echo "Checking memory leaks..."
|
|
||||||
grep -q "<kind>UninitCondition</kind>" memory-report.xml
|
|
||||||
error_on_zero $?
|
|
||||||
|
|
||||||
grep -q "<kind>Leak_PossiblyLost</kind>" memory-report.xml
|
|
||||||
error_on_zero $?
|
|
||||||
|
|
||||||
grep -q "<kind>Leak_DefinitelyLost</kind>" memory-report.xml
|
|
||||||
error_on_zero $?
|
|
||||||
|
|
||||||
grep -q "<kind>Leak_StillReachable</kind>" memory-report.xml
|
|
||||||
error_on_zero $?
|
|
||||||
}
|
|
||||||
|
|
||||||
date +%s > timestamp.log
|
date +%s > timestamp.log
|
||||||
echo "Compiling icmwp"
|
echo "Compiling icmwp"
|
||||||
build_icwmp
|
build_icwmp
|
||||||
|
|
@ -53,12 +38,13 @@ echo "## Running script verification of functionalities ##"
|
||||||
echo > ./funl-test-result.log
|
echo > ./funl-test-result.log
|
||||||
echo > ./funl-test-debug.log
|
echo > ./funl-test-debug.log
|
||||||
test_num=0
|
test_num=0
|
||||||
for test in $(ls -I "common.sh" -I "verify_custom_notifications.sh" test/script/); do
|
for test in `cat test/script/test_seq.txt`; do
|
||||||
ret=0
|
ret=0
|
||||||
test_num=$(( test_num + 1 ))
|
test_num=$(( test_num + 1 ))
|
||||||
|
|
||||||
echo "#### Start $test ####" >> "$icwmp_master_log"
|
echo "#### Start $test ####" >> "$icwmp_master_log"
|
||||||
if ./test/script/"${test}"; then
|
./test/script/${test}
|
||||||
|
if [ "$?" -eq 0 ]; then
|
||||||
echo "ok ${test_num} - ${test}" >> ./funl-test-result.log
|
echo "ok ${test_num} - ${test}" >> ./funl-test-result.log
|
||||||
remove_icwmp_log
|
remove_icwmp_log
|
||||||
echo "#### $test Done ####" >> "$icwmp_master_log"
|
echo "#### $test Done ####" >> "$icwmp_master_log"
|
||||||
|
|
@ -74,6 +60,7 @@ done
|
||||||
echo "Stop all services"
|
echo "Stop all services"
|
||||||
supervisorctl stop icwmpd
|
supervisorctl stop icwmpd
|
||||||
|
|
||||||
|
sleep 10
|
||||||
check_valgrind_xml
|
check_valgrind_xml
|
||||||
|
|
||||||
cp test/files/etc/config/users /etc/config/
|
cp test/files/etc/config/users /etc/config/
|
||||||
|
|
@ -81,7 +68,8 @@ cp test/files/etc/config/wireless /etc/config/
|
||||||
|
|
||||||
echo "Verify Custom notifications"
|
echo "Verify Custom notifications"
|
||||||
echo "#### Start custom_notifications ####" >> "$icwmp_master_log"
|
echo "#### Start custom_notifications ####" >> "$icwmp_master_log"
|
||||||
if ./test/script/verify_custom_notifications.sh; then
|
./test/script/verify_custom_notifications.sh
|
||||||
|
if [ "$?" -eq 0 ]; then
|
||||||
echo "ok - verify_custom_notifications" >> ./funl-test-result.log
|
echo "ok - verify_custom_notifications" >> ./funl-test-result.log
|
||||||
remove_icwmp_log
|
remove_icwmp_log
|
||||||
echo "#### Done custom_notifications ####" >> "$icwmp_master_log"
|
echo "#### Done custom_notifications ####" >> "$icwmp_master_log"
|
||||||
|
|
@ -104,6 +92,7 @@ cp ./memory-report.xml ./funl-test-memory-report.xml
|
||||||
#report part
|
#report part
|
||||||
exec_cmd tap-junit --input ./funl-test-result.log --output report
|
exec_cmd tap-junit --input ./funl-test-result.log --output report
|
||||||
|
|
||||||
|
sleep 10
|
||||||
check_valgrind_xml
|
check_valgrind_xml
|
||||||
|
|
||||||
echo "Functional test :: PASS"
|
echo "Functional test :: PASS"
|
||||||
|
|
|
||||||
|
|
@ -148,15 +148,19 @@ function install_uspd()
|
||||||
|
|
||||||
function check_valgrind_xml() {
|
function check_valgrind_xml() {
|
||||||
echo "Checking memory leaks..."
|
echo "Checking memory leaks..."
|
||||||
|
echo "checking UninitCondition"
|
||||||
grep -q "<kind>UninitCondition</kind>" memory-report.xml
|
grep -q "<kind>UninitCondition</kind>" memory-report.xml
|
||||||
error_on_zero $?
|
error_on_zero $?
|
||||||
|
|
||||||
|
echo "checking Leak_PossiblyLost"
|
||||||
grep -q "<kind>Leak_PossiblyLost</kind>" memory-report.xml
|
grep -q "<kind>Leak_PossiblyLost</kind>" memory-report.xml
|
||||||
error_on_zero $?
|
error_on_zero $?
|
||||||
|
|
||||||
|
echo "checking Leak_DefinitelyLost"
|
||||||
grep -q "<kind>Leak_DefinitelyLost</kind>" memory-report.xml
|
grep -q "<kind>Leak_DefinitelyLost</kind>" memory-report.xml
|
||||||
error_on_zero $?
|
error_on_zero $?
|
||||||
|
|
||||||
|
echo "checking Leak_StillReachable"
|
||||||
grep -q "<kind>Leak_StillReachable</kind>" memory-report.xml
|
grep -q "<kind>Leak_StillReachable</kind>" memory-report.xml
|
||||||
error_on_zero $?
|
error_on_zero $?
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@
|
||||||
#include "cwmp_du_state.h"
|
#include "cwmp_du_state.h"
|
||||||
#include "notifications.h"
|
#include "notifications.h"
|
||||||
#include "xml.h"
|
#include "xml.h"
|
||||||
|
#include "cwmp_event.h"
|
||||||
|
|
||||||
static mxml_node_t *bkp_tree = NULL;
|
static mxml_node_t *bkp_tree = NULL;
|
||||||
pthread_mutex_t mutex_backup_session = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
|
|
||||||
enum backup_attributes_types
|
enum backup_attributes_types
|
||||||
{
|
{
|
||||||
|
|
@ -176,12 +176,10 @@ void bkp_session_save()
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
if (!bkp_tree)
|
if (!bkp_tree)
|
||||||
return;
|
return;
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
fp = fopen(CWMP_BKP_FILE, "w");
|
fp = fopen(CWMP_BKP_FILE, "w");
|
||||||
mxmlSaveFile(bkp_tree, fp, MXML_NO_CALLBACK);
|
mxmlSaveFile(bkp_tree, fp, MXML_NO_CALLBACK);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
sync();
|
sync();
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mxml_node_t *bkp_session_insert(mxml_node_t *tree, char *name, char *value)
|
mxml_node_t *bkp_session_insert(mxml_node_t *tree, char *name, char *value)
|
||||||
|
|
@ -236,7 +234,6 @@ mxml_node_t *bkp_session_insert_event(int index, char *command_key, int id, char
|
||||||
char event_idx[32];
|
char event_idx[32];
|
||||||
mxml_node_t *b;
|
mxml_node_t *b;
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
snprintf(parent_name, sizeof(parent_name), "%s_event", status);
|
snprintf(parent_name, sizeof(parent_name), "%s_event", status);
|
||||||
snprintf(event_id, sizeof(event_id), "%d", id);
|
snprintf(event_id, sizeof(event_id), "%d", id);
|
||||||
snprintf(event_idx, sizeof(event_idx), "%d", index);
|
snprintf(event_idx, sizeof(event_idx), "%d", index);
|
||||||
|
|
@ -249,7 +246,6 @@ mxml_node_t *bkp_session_insert_event(int index, char *command_key, int id, char
|
||||||
bkp_session_insert(b, "id", event_id);
|
bkp_session_insert(b, "id", event_id);
|
||||||
bkp_session_insert(b, "command_key", command_key);
|
bkp_session_insert(b, "command_key", command_key);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -260,7 +256,6 @@ void bkp_session_delete_event(int id, char *status)
|
||||||
char event_id[32];
|
char event_id[32];
|
||||||
mxml_node_t *b;
|
mxml_node_t *b;
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
snprintf(parent_name, sizeof(parent_name), "%s_event", status);
|
snprintf(parent_name, sizeof(parent_name), "%s_event", status);
|
||||||
snprintf(event_id, sizeof(event_id), "%d", id);
|
snprintf(event_id, sizeof(event_id), "%d", id);
|
||||||
keys[0].name = "id";
|
keys[0].name = "id";
|
||||||
|
|
@ -268,34 +263,28 @@ void bkp_session_delete_event(int id, char *status)
|
||||||
b = bkp_session_node_found(bkp_tree, parent_name, keys, 1);
|
b = bkp_session_node_found(bkp_tree, parent_name, keys, 1);
|
||||||
if (b)
|
if (b)
|
||||||
mxmlDelete(b);
|
mxmlDelete(b);
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bkp_session_insert_parameter(mxml_node_t *b, char *name)
|
void bkp_session_insert_parameter(mxml_node_t *b, char *name)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
bkp_session_insert(b, "parameter", name);
|
bkp_session_insert(b, "parameter", name);
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bkp_session_simple_insert(char *parent, char *child, char *value)
|
void bkp_session_simple_insert(char *parent, char *child, char *value)
|
||||||
{
|
{
|
||||||
mxml_node_t *b = bkp_tree;
|
mxml_node_t *b = bkp_tree;
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
b = mxmlFindElement(b, b, parent, NULL, NULL, MXML_DESCEND);
|
b = mxmlFindElement(b, b, parent, NULL, NULL, MXML_DESCEND);
|
||||||
if (b)
|
if (b)
|
||||||
mxmlDelete(b);
|
mxmlDelete(b);
|
||||||
b = bkp_session_insert(bkp_tree, parent, NULL);
|
b = bkp_session_insert(bkp_tree, parent, NULL);
|
||||||
bkp_session_insert(b, child, value);
|
bkp_session_insert(b, child, value);
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bkp_session_simple_insert_in_parent(char *parent, char *child, char *value)
|
void bkp_session_simple_insert_in_parent(char *parent, char *child, char *value)
|
||||||
{
|
{
|
||||||
mxml_node_t *n, *b = bkp_tree;
|
mxml_node_t *n, *b = bkp_tree;
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
n = mxmlFindElement(b, b, parent, NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(b, b, parent, NULL, NULL, MXML_DESCEND);
|
||||||
if (!n)
|
if (!n)
|
||||||
n = bkp_session_insert(bkp_tree, parent, NULL);
|
n = bkp_session_insert(bkp_tree, parent, NULL);
|
||||||
|
|
@ -303,14 +292,12 @@ void bkp_session_simple_insert_in_parent(char *parent, char *child, char *value)
|
||||||
if (b)
|
if (b)
|
||||||
mxmlDelete(b);
|
mxmlDelete(b);
|
||||||
bkp_session_insert(n, child, value);
|
bkp_session_insert(n, child, value);
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bkp_session_move_inform_to_inform_send()
|
void bkp_session_move_inform_to_inform_send()
|
||||||
{
|
{
|
||||||
mxml_node_t *b = bkp_tree;
|
mxml_node_t *b = bkp_tree;
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
while (b) {
|
while (b) {
|
||||||
mxml_node_t *p = mxmlGetParent(b);
|
mxml_node_t *p = mxmlGetParent(b);
|
||||||
if (mxmlGetType(b) == MXML_ELEMENT && !strcmp(mxmlGetElement(b), "queue_event") && mxmlGetType(p) == MXML_ELEMENT && !strcmp(mxmlGetElement(p), "cwmp"))
|
if (mxmlGetType(b) == MXML_ELEMENT && !strcmp(mxmlGetElement(b), "queue_event") && mxmlGetType(p) == MXML_ELEMENT && !strcmp(mxmlGetElement(p), "cwmp"))
|
||||||
|
|
@ -318,14 +305,12 @@ void bkp_session_move_inform_to_inform_send()
|
||||||
|
|
||||||
b = mxmlWalkNext(b, bkp_tree, MXML_DESCEND);
|
b = mxmlWalkNext(b, bkp_tree, MXML_DESCEND);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bkp_session_move_inform_to_inform_queue()
|
void bkp_session_move_inform_to_inform_queue()
|
||||||
{
|
{
|
||||||
mxml_node_t *b = bkp_tree;
|
mxml_node_t *b = bkp_tree;
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
while (b) {
|
while (b) {
|
||||||
mxml_node_t *p = mxmlGetParent(b);
|
mxml_node_t *p = mxmlGetParent(b);
|
||||||
if (mxmlGetType(b) == MXML_ELEMENT && !strcmp(mxmlGetElement(b), "send_event") && mxmlGetType(p) == MXML_ELEMENT && !strcmp(mxmlGetElement(p), "cwmp"))
|
if (mxmlGetType(b) == MXML_ELEMENT && !strcmp(mxmlGetElement(b), "send_event") && mxmlGetType(p) == MXML_ELEMENT && !strcmp(mxmlGetElement(p), "cwmp"))
|
||||||
|
|
@ -333,7 +318,6 @@ void bkp_session_move_inform_to_inform_queue()
|
||||||
|
|
||||||
b = mxmlWalkNext(b, bkp_tree, MXML_DESCEND);
|
b = mxmlWalkNext(b, bkp_tree, MXML_DESCEND);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bkp_session_insert_schedule_inform(time_t time, char *command_key)
|
void bkp_session_insert_schedule_inform(time_t time, char *command_key)
|
||||||
|
|
@ -341,7 +325,6 @@ void bkp_session_insert_schedule_inform(time_t time, char *command_key)
|
||||||
char schedule_time[128];
|
char schedule_time[128];
|
||||||
mxml_node_t *b;
|
mxml_node_t *b;
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
snprintf(schedule_time, sizeof(schedule_time), "%lld", (long long int)time);
|
snprintf(schedule_time, sizeof(schedule_time), "%lld", (long long int)time);
|
||||||
struct search_keywords sched_inf_insert_keys[2] = { { "command_key", command_key }, { "time", schedule_time } };
|
struct search_keywords sched_inf_insert_keys[2] = { { "command_key", command_key }, { "time", schedule_time } };
|
||||||
b = bkp_session_node_found(bkp_tree, "schedule_inform", sched_inf_insert_keys, 2);
|
b = bkp_session_node_found(bkp_tree, "schedule_inform", sched_inf_insert_keys, 2);
|
||||||
|
|
@ -350,7 +333,6 @@ void bkp_session_insert_schedule_inform(time_t time, char *command_key)
|
||||||
bkp_session_insert(b, "command_key", command_key);
|
bkp_session_insert(b, "command_key", command_key);
|
||||||
bkp_session_insert(b, "time", schedule_time);
|
bkp_session_insert(b, "time", schedule_time);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bkp_session_delete_schedule_inform(time_t time, char *command_key)
|
void bkp_session_delete_schedule_inform(time_t time, char *command_key)
|
||||||
|
|
@ -358,13 +340,11 @@ void bkp_session_delete_schedule_inform(time_t time, char *command_key)
|
||||||
char schedule_time[128];
|
char schedule_time[128];
|
||||||
mxml_node_t *b;
|
mxml_node_t *b;
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
snprintf(schedule_time, sizeof(schedule_time), "%lld", (long long int)time);
|
snprintf(schedule_time, sizeof(schedule_time), "%lld", (long long int)time);
|
||||||
struct search_keywords sched_inf_del_keys[2] = { { "command_key", command_key }, { "time", schedule_time } };
|
struct search_keywords sched_inf_del_keys[2] = { { "command_key", command_key }, { "time", schedule_time } };
|
||||||
b = bkp_session_node_found(bkp_tree, "schedule_inform", sched_inf_del_keys, 2);
|
b = bkp_session_node_found(bkp_tree, "schedule_inform", sched_inf_del_keys, 2);
|
||||||
if (b)
|
if (b)
|
||||||
mxmlDelete(b);
|
mxmlDelete(b);
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bkp_session_insert_download(struct download *pdownload)
|
void bkp_session_insert_download(struct download *pdownload)
|
||||||
|
|
@ -373,7 +353,6 @@ void bkp_session_insert_download(struct download *pdownload)
|
||||||
char file_size[128];
|
char file_size[128];
|
||||||
mxml_node_t *b;
|
mxml_node_t *b;
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
snprintf(schedule_time, sizeof(schedule_time), "%lld", (long long int)pdownload->scheduled_time);
|
snprintf(schedule_time, sizeof(schedule_time), "%lld", (long long int)pdownload->scheduled_time);
|
||||||
snprintf(file_size, sizeof(file_size), "%d", pdownload->file_size);
|
snprintf(file_size, sizeof(file_size), "%d", pdownload->file_size);
|
||||||
struct search_keywords download_insert_keys[7] = { { "url", pdownload->url }, { "command_key", pdownload->command_key }, { "file_type", pdownload->file_type }, { "username", pdownload->username }, { "password", pdownload->password }, { "file_size", file_size }, { "time", schedule_time } };
|
struct search_keywords download_insert_keys[7] = { { "url", pdownload->url }, { "command_key", pdownload->command_key }, { "file_type", pdownload->file_type }, { "username", pdownload->username }, { "password", pdownload->password }, { "file_size", file_size }, { "time", schedule_time } };
|
||||||
|
|
@ -389,7 +368,6 @@ void bkp_session_insert_download(struct download *pdownload)
|
||||||
bkp_session_insert(b, "file_size", file_size);
|
bkp_session_insert(b, "file_size", file_size);
|
||||||
bkp_session_insert(b, "time", schedule_time);
|
bkp_session_insert(b, "time", schedule_time);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bkp_session_insert_schedule_download(struct download *pschedule_download)
|
void bkp_session_insert_schedule_download(struct download *pschedule_download)
|
||||||
|
|
@ -400,7 +378,6 @@ void bkp_session_insert_schedule_download(struct download *pschedule_download)
|
||||||
char maxretrie[2][128];
|
char maxretrie[2][128];
|
||||||
mxml_node_t *b;
|
mxml_node_t *b;
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
snprintf(file_size, sizeof(file_size), "%d", pschedule_download->file_size);
|
snprintf(file_size, sizeof(file_size), "%d", pschedule_download->file_size);
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
snprintf(delay[2 * i], sizeof(delay[i]), "%lld", (long long int)pschedule_download->timewindowstruct[i].windowstart);
|
snprintf(delay[2 * i], sizeof(delay[i]), "%lld", (long long int)pschedule_download->timewindowstruct[i].windowstart);
|
||||||
|
|
@ -444,80 +421,6 @@ void bkp_session_insert_schedule_download(struct download *pschedule_download)
|
||||||
bkp_session_insert(b, "usermessage2", pschedule_download->timewindowstruct[1].usermessage);
|
bkp_session_insert(b, "usermessage2", pschedule_download->timewindowstruct[1].usermessage);
|
||||||
bkp_session_insert(b, "maxretrie2", maxretrie[1]);
|
bkp_session_insert(b, "maxretrie2", maxretrie[1]);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bkp_session_insert_apply_schedule_download(struct apply_schedule_download *papply_schedule_download)
|
|
||||||
{
|
|
||||||
char delay[4][128];
|
|
||||||
int i;
|
|
||||||
char maxretrie[2][128];
|
|
||||||
mxml_node_t *b;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
snprintf(delay[2 * i], sizeof(delay[i]), "%lld", (long long int)papply_schedule_download->timeintervals[i].windowstart);
|
|
||||||
snprintf(delay[2 * i + 1], sizeof(delay[i]), "%lld", (long long int)papply_schedule_download->timeintervals[i].windowend);
|
|
||||||
snprintf(maxretrie[i], sizeof(maxretrie[i]), "%d", papply_schedule_download->timeintervals[i].maxretries);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct search_keywords sched_download_insert_app_keys[9] = { { "command_key", papply_schedule_download->command_key },
|
|
||||||
{ "file_type", papply_schedule_download->file_type },
|
|
||||||
{ "start_time", papply_schedule_download->start_time },
|
|
||||||
{ "windowstart1", delay[0] },
|
|
||||||
{ "windowend1", delay[1] },
|
|
||||||
{ "maxretrie1", maxretrie[0] },
|
|
||||||
{ "windowstart2", delay[2] },
|
|
||||||
{ "windowend2", delay[3] },
|
|
||||||
{ "maxretrie2", maxretrie[1] } };
|
|
||||||
|
|
||||||
b = bkp_session_node_found(bkp_tree, "apply_schedule_download", sched_download_insert_app_keys, 9);
|
|
||||||
if (!b) {
|
|
||||||
CWMP_LOG(INFO, "New schedule download key %s file", papply_schedule_download->command_key);
|
|
||||||
b = bkp_session_insert(bkp_tree, "apply_schedule_download", NULL);
|
|
||||||
bkp_session_insert(b, "start_time", papply_schedule_download->start_time);
|
|
||||||
bkp_session_insert(b, "command_key", papply_schedule_download->command_key);
|
|
||||||
bkp_session_insert(b, "file_type", papply_schedule_download->file_type);
|
|
||||||
bkp_session_insert(b, "windowstart1", delay[0]);
|
|
||||||
bkp_session_insert(b, "windowend1", delay[1]);
|
|
||||||
bkp_session_insert(b, "maxretrie1", maxretrie[0]);
|
|
||||||
|
|
||||||
bkp_session_insert(b, "windowstart2", delay[2]);
|
|
||||||
bkp_session_insert(b, "windowend2", delay[3]);
|
|
||||||
bkp_session_insert(b, "maxretrie2", maxretrie[1]);
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bkp_session_delete_apply_schedule_download(struct apply_schedule_download *ps_download) //TODO
|
|
||||||
{
|
|
||||||
char delay[4][128];
|
|
||||||
char maxretrie[2][128];
|
|
||||||
int i;
|
|
||||||
mxml_node_t *b;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
snprintf(delay[2 * i], sizeof(delay[i]), "%lld", (long long int)ps_download->timeintervals[i].windowstart);
|
|
||||||
snprintf(delay[2 * i + 1], sizeof(delay[i]), "%lld", (long long int)ps_download->timeintervals[i].windowend);
|
|
||||||
snprintf(maxretrie[i], sizeof(maxretrie[i]), "%d", ps_download->timeintervals[i].maxretries);
|
|
||||||
}
|
|
||||||
struct search_keywords sched_download_del_app_keys[9] = { { "start_time", ps_download->start_time },
|
|
||||||
{ "command_key", ps_download->command_key },
|
|
||||||
{ "file_type", ps_download->file_type },
|
|
||||||
{ "windowstart1", delay[0] },
|
|
||||||
{ "windowend1", delay[1] },
|
|
||||||
{ "maxretrie1", maxretrie[0] },
|
|
||||||
{ "windowstart2", delay[2] },
|
|
||||||
{ "windowend2", delay[3] },
|
|
||||||
{ "maxretrie2", maxretrie[1] } };
|
|
||||||
|
|
||||||
b = bkp_session_node_found(bkp_tree, "apply_schedule_download", sched_download_del_app_keys, 9);
|
|
||||||
|
|
||||||
if (b)
|
|
||||||
mxmlDelete(b);
|
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bkp_session_insert_change_du_state(struct change_du_state *pchange_du_state)
|
void bkp_session_insert_change_du_state(struct change_du_state *pchange_du_state)
|
||||||
|
|
@ -526,7 +429,6 @@ void bkp_session_insert_change_du_state(struct change_du_state *pchange_du_state
|
||||||
char schedule_time[128];
|
char schedule_time[128];
|
||||||
mxml_node_t *b, *n;
|
mxml_node_t *b, *n;
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
snprintf(schedule_time, sizeof(schedule_time), "%lld", (long long int)pchange_du_state->timeout);
|
snprintf(schedule_time, sizeof(schedule_time), "%lld", (long long int)pchange_du_state->timeout);
|
||||||
b = bkp_session_insert(bkp_tree, "change_du_state", NULL);
|
b = bkp_session_insert(bkp_tree, "change_du_state", NULL);
|
||||||
bkp_session_insert(b, "command_key", pchange_du_state->command_key);
|
bkp_session_insert(b, "command_key", pchange_du_state->command_key);
|
||||||
|
|
@ -553,7 +455,6 @@ void bkp_session_insert_change_du_state(struct change_du_state *pchange_du_state
|
||||||
bkp_session_insert(n, "executionenvref", p->executionenvref);
|
bkp_session_insert(n, "executionenvref", p->executionenvref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bkp_session_delete_change_du_state(struct change_du_state *pchange_du_state)
|
void bkp_session_delete_change_du_state(struct change_du_state *pchange_du_state)
|
||||||
|
|
@ -561,13 +462,11 @@ void bkp_session_delete_change_du_state(struct change_du_state *pchange_du_state
|
||||||
char schedule_time[128];
|
char schedule_time[128];
|
||||||
mxml_node_t *b;
|
mxml_node_t *b;
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
snprintf(schedule_time, sizeof(schedule_time), "%lld", (long long int)pchange_du_state->timeout);
|
snprintf(schedule_time, sizeof(schedule_time), "%lld", (long long int)pchange_du_state->timeout);
|
||||||
struct search_keywords cds_del_keys[2] = { { "command_key", pchange_du_state->command_key }, { "time", schedule_time } };
|
struct search_keywords cds_del_keys[2] = { { "command_key", pchange_du_state->command_key }, { "time", schedule_time } };
|
||||||
b = bkp_session_node_found(bkp_tree, "change_du_state", cds_del_keys, 2);
|
b = bkp_session_node_found(bkp_tree, "change_du_state", cds_del_keys, 2);
|
||||||
if (b)
|
if (b)
|
||||||
mxmlDelete(b);
|
mxmlDelete(b);
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bkp_session_insert_upload(struct upload *pupload)
|
void bkp_session_insert_upload(struct upload *pupload)
|
||||||
|
|
@ -575,7 +474,6 @@ void bkp_session_insert_upload(struct upload *pupload)
|
||||||
char schedule_time[128];
|
char schedule_time[128];
|
||||||
mxml_node_t *b;
|
mxml_node_t *b;
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
snprintf(schedule_time, sizeof(schedule_time), "%lld", (long long int)pupload->scheduled_time);
|
snprintf(schedule_time, sizeof(schedule_time), "%lld", (long long int)pupload->scheduled_time);
|
||||||
struct search_keywords upload_insert_keys[6] = { { "url", pupload->url }, { "command_key", pupload->command_key }, { "username", pupload->username }, { "password", pupload->password }, { "time", schedule_time }, { "file_type", pupload->file_type } };
|
struct search_keywords upload_insert_keys[6] = { { "url", pupload->url }, { "command_key", pupload->command_key }, { "username", pupload->username }, { "password", pupload->password }, { "time", schedule_time }, { "file_type", pupload->file_type } };
|
||||||
|
|
||||||
|
|
@ -589,7 +487,6 @@ void bkp_session_insert_upload(struct upload *pupload)
|
||||||
bkp_session_insert(b, "password", pupload->password);
|
bkp_session_insert(b, "password", pupload->password);
|
||||||
bkp_session_insert(b, "time", schedule_time);
|
bkp_session_insert(b, "time", schedule_time);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
void bkp_session_delete_download(struct download *pdownload)
|
void bkp_session_delete_download(struct download *pdownload)
|
||||||
{
|
{
|
||||||
|
|
@ -597,7 +494,6 @@ void bkp_session_delete_download(struct download *pdownload)
|
||||||
char file_size[128];
|
char file_size[128];
|
||||||
mxml_node_t *b;
|
mxml_node_t *b;
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
snprintf(schedule_time, sizeof(schedule_time), "%lld", (long long int)pdownload->scheduled_time);
|
snprintf(schedule_time, sizeof(schedule_time), "%lld", (long long int)pdownload->scheduled_time);
|
||||||
snprintf(file_size, sizeof(file_size), "%d", pdownload->file_size);
|
snprintf(file_size, sizeof(file_size), "%d", pdownload->file_size);
|
||||||
struct search_keywords download_del_keys[7] = { { "url", pdownload->url }, { "command_key", pdownload->command_key }, { "file_type", pdownload->file_type }, { "username", pdownload->username }, { "password", pdownload->password }, { "file_size", file_size }, { "time", schedule_time } };
|
struct search_keywords download_del_keys[7] = { { "url", pdownload->url }, { "command_key", pdownload->command_key }, { "file_type", pdownload->file_type }, { "username", pdownload->username }, { "password", pdownload->password }, { "file_size", file_size }, { "time", schedule_time } };
|
||||||
|
|
@ -605,7 +501,6 @@ void bkp_session_delete_download(struct download *pdownload)
|
||||||
b = bkp_session_node_found(bkp_tree, "download", download_del_keys, 7);
|
b = bkp_session_node_found(bkp_tree, "download", download_del_keys, 7);
|
||||||
if (b)
|
if (b)
|
||||||
mxmlDelete(b);
|
mxmlDelete(b);
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bkp_session_delete_schedule_download(struct download *pschedule_download_delete)
|
void bkp_session_delete_schedule_download(struct download *pschedule_download_delete)
|
||||||
|
|
@ -616,7 +511,6 @@ void bkp_session_delete_schedule_download(struct download *pschedule_download_de
|
||||||
int i;
|
int i;
|
||||||
mxml_node_t *b;
|
mxml_node_t *b;
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
snprintf(file_size, sizeof(file_size), "%d", pschedule_download_delete->file_size);
|
snprintf(file_size, sizeof(file_size), "%d", pschedule_download_delete->file_size);
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
snprintf(delay[2 * i], sizeof(delay[i]), "%lld", (long long int)pschedule_download_delete->timewindowstruct[i].windowstart);
|
snprintf(delay[2 * i], sizeof(delay[i]), "%lld", (long long int)pschedule_download_delete->timewindowstruct[i].windowstart);
|
||||||
|
|
@ -644,20 +538,17 @@ void bkp_session_delete_schedule_download(struct download *pschedule_download_de
|
||||||
|
|
||||||
if (b)
|
if (b)
|
||||||
mxmlDelete(b);
|
mxmlDelete(b);
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
void bkp_session_delete_upload(struct upload *pupload)
|
void bkp_session_delete_upload(struct upload *pupload)
|
||||||
{
|
{
|
||||||
char schedule_time[128];
|
char schedule_time[128];
|
||||||
mxml_node_t *b;
|
mxml_node_t *b;
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
snprintf(schedule_time, sizeof(schedule_time), "%lld", (long long int)pupload->scheduled_time);
|
snprintf(schedule_time, sizeof(schedule_time), "%lld", (long long int)pupload->scheduled_time);
|
||||||
struct search_keywords upload_del_keys[6] = { { "url", pupload->url }, { "command_key", pupload->command_key }, { "file_type", pupload->file_type }, { "username", pupload->username }, { "password", pupload->password }, { "time", schedule_time } };
|
struct search_keywords upload_del_keys[6] = { { "url", pupload->url }, { "command_key", pupload->command_key }, { "file_type", pupload->file_type }, { "username", pupload->username }, { "password", pupload->password }, { "time", schedule_time } };
|
||||||
b = bkp_session_node_found(bkp_tree, "upload", upload_del_keys, 6);
|
b = bkp_session_node_found(bkp_tree, "upload", upload_del_keys, 6);
|
||||||
if (b)
|
if (b)
|
||||||
mxmlDelete(b);
|
mxmlDelete(b);
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bkp_session_insert_du_state_change_complete(struct du_state_change_complete *pdu_state_change_complete)
|
void bkp_session_insert_du_state_change_complete(struct du_state_change_complete *pdu_state_change_complete)
|
||||||
|
|
@ -666,7 +557,6 @@ void bkp_session_insert_du_state_change_complete(struct du_state_change_complete
|
||||||
struct opresult *p = NULL;
|
struct opresult *p = NULL;
|
||||||
mxml_node_t *b;
|
mxml_node_t *b;
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
snprintf(schedule_time, sizeof(schedule_time), "%lld", (long long int)pdu_state_change_complete->timeout);
|
snprintf(schedule_time, sizeof(schedule_time), "%lld", (long long int)pdu_state_change_complete->timeout);
|
||||||
b = bkp_session_insert(bkp_tree, "du_state_change_complete", NULL);
|
b = bkp_session_insert(bkp_tree, "du_state_change_complete", NULL);
|
||||||
bkp_session_insert(b, "command_key", pdu_state_change_complete->command_key);
|
bkp_session_insert(b, "command_key", pdu_state_change_complete->command_key);
|
||||||
|
|
@ -686,7 +576,6 @@ void bkp_session_insert_du_state_change_complete(struct du_state_change_complete
|
||||||
bkp_session_insert(n, "complete_time", p->complete_time);
|
bkp_session_insert(n, "complete_time", p->complete_time);
|
||||||
bkp_session_insert(n, "fault", fault_code);
|
bkp_session_insert(n, "fault", fault_code);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bkp_session_delete_du_state_change_complete(struct du_state_change_complete *pdu_state_change_complete)
|
void bkp_session_delete_du_state_change_complete(struct du_state_change_complete *pdu_state_change_complete)
|
||||||
|
|
@ -694,14 +583,12 @@ void bkp_session_delete_du_state_change_complete(struct du_state_change_complete
|
||||||
mxml_node_t *b;
|
mxml_node_t *b;
|
||||||
char schedule_time[128];
|
char schedule_time[128];
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
snprintf(schedule_time, sizeof(schedule_time), "%lld", (long long int)pdu_state_change_complete->timeout);
|
snprintf(schedule_time, sizeof(schedule_time), "%lld", (long long int)pdu_state_change_complete->timeout);
|
||||||
struct search_keywords cds_complete_keys[2] = { { "command_key", pdu_state_change_complete->command_key }, { "time", schedule_time } };
|
struct search_keywords cds_complete_keys[2] = { { "command_key", pdu_state_change_complete->command_key }, { "time", schedule_time } };
|
||||||
|
|
||||||
b = bkp_session_node_found(bkp_tree, "du_state_change_complete", cds_complete_keys, 2);
|
b = bkp_session_node_found(bkp_tree, "du_state_change_complete", cds_complete_keys, 2);
|
||||||
if (b)
|
if (b)
|
||||||
mxmlDelete(b);
|
mxmlDelete(b);
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
void bkp_session_insert_transfer_complete(struct transfer_complete *ptransfer_complete)
|
void bkp_session_insert_transfer_complete(struct transfer_complete *ptransfer_complete)
|
||||||
{
|
{
|
||||||
|
|
@ -710,7 +597,6 @@ void bkp_session_insert_transfer_complete(struct transfer_complete *ptransfer_co
|
||||||
char type[16];
|
char type[16];
|
||||||
mxml_node_t *b;
|
mxml_node_t *b;
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
snprintf(fault_code, sizeof(fault_code), "%d", ptransfer_complete->fault_code);
|
snprintf(fault_code, sizeof(fault_code), "%d", ptransfer_complete->fault_code);
|
||||||
keys[0].name = "command_key";
|
keys[0].name = "command_key";
|
||||||
keys[0].value = ptransfer_complete->command_key;
|
keys[0].value = ptransfer_complete->command_key;
|
||||||
|
|
@ -733,7 +619,6 @@ void bkp_session_insert_transfer_complete(struct transfer_complete *ptransfer_co
|
||||||
bkp_session_insert(b, "fault_code", fault_code);
|
bkp_session_insert(b, "fault_code", fault_code);
|
||||||
bkp_session_insert(b, "type", type);
|
bkp_session_insert(b, "type", type);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bkp_session_delete_transfer_complete(struct transfer_complete *ptransfer_complete)
|
void bkp_session_delete_transfer_complete(struct transfer_complete *ptransfer_complete)
|
||||||
|
|
@ -742,7 +627,6 @@ void bkp_session_delete_transfer_complete(struct transfer_complete *ptransfer_co
|
||||||
char type[16];
|
char type[16];
|
||||||
mxml_node_t *b;
|
mxml_node_t *b;
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
snprintf(fault_code, sizeof(fault_code), "%d", ptransfer_complete->fault_code);
|
snprintf(fault_code, sizeof(fault_code), "%d", ptransfer_complete->fault_code);
|
||||||
snprintf(type, sizeof(type), "%d", ptransfer_complete->type);
|
snprintf(type, sizeof(type), "%d", ptransfer_complete->type);
|
||||||
struct search_keywords trans_comp_del_keys[5] = { { "command_key", ptransfer_complete->command_key }, { "start_time", ptransfer_complete->start_time }, { "complete_time", ptransfer_complete->complete_time }, { "fault_code", fault_code }, { "type", type } };
|
struct search_keywords trans_comp_del_keys[5] = { { "command_key", ptransfer_complete->command_key }, { "start_time", ptransfer_complete->start_time }, { "complete_time", ptransfer_complete->complete_time }, { "fault_code", fault_code }, { "type", type } };
|
||||||
|
|
@ -750,14 +634,13 @@ void bkp_session_delete_transfer_complete(struct transfer_complete *ptransfer_co
|
||||||
b = bkp_session_node_found(bkp_tree, "transfer_complete", trans_comp_del_keys, 5);
|
b = bkp_session_node_found(bkp_tree, "transfer_complete", trans_comp_del_keys, 5);
|
||||||
if (b)
|
if (b)
|
||||||
mxmlDelete(b);
|
mxmlDelete(b);
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int save_acs_bkp_config(struct cwmp *cwmp)
|
int save_acs_bkp_config()
|
||||||
{
|
{
|
||||||
struct config *conf;
|
struct config *conf;
|
||||||
|
|
||||||
conf = &(cwmp->conf);
|
conf = &(cwmp_main->conf);
|
||||||
bkp_session_simple_insert("acs", "url", conf->acsurl);
|
bkp_session_simple_insert("acs", "url", conf->acsurl);
|
||||||
bkp_session_save();
|
bkp_session_save();
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
|
|
@ -786,7 +669,7 @@ char *load_child_value(mxml_node_t *tree, char *sub_name)
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_queue_event(mxml_node_t *tree, struct cwmp *cwmp)
|
void load_queue_event(mxml_node_t *tree)
|
||||||
{
|
{
|
||||||
char *command_key = NULL;
|
char *command_key = NULL;
|
||||||
mxml_node_t *b = tree, *c;
|
mxml_node_t *b = tree, *c;
|
||||||
|
|
@ -809,7 +692,7 @@ void load_queue_event(mxml_node_t *tree, struct cwmp *cwmp)
|
||||||
*/
|
*/
|
||||||
if (idx != -1) {
|
if (idx != -1) {
|
||||||
if (EVENT_CONST[idx].RETRY & EVENT_RETRY_AFTER_REBOOT) {
|
if (EVENT_CONST[idx].RETRY & EVENT_RETRY_AFTER_REBOOT) {
|
||||||
event_container_save = cwmp_add_event_container(cwmp, idx, ((command_key != NULL) ? command_key : ""));
|
event_container_save = cwmp_add_event_container(idx, ((command_key != NULL) ? command_key : ""));
|
||||||
if (event_container_save != NULL) {
|
if (event_container_save != NULL) {
|
||||||
event_container_save->id = id;
|
event_container_save->id = id;
|
||||||
}
|
}
|
||||||
|
|
@ -837,7 +720,7 @@ void load_schedule_inform(mxml_node_t *tree)
|
||||||
char *command_key = NULL;
|
char *command_key = NULL;
|
||||||
time_t scheduled_time = 0;
|
time_t scheduled_time = 0;
|
||||||
struct schedule_inform *schedule_inform = NULL;
|
struct schedule_inform *schedule_inform = NULL;
|
||||||
struct list_head *ilist;
|
struct list_head *ilist = NULL;
|
||||||
|
|
||||||
struct backup_attributes bkp_attrs = { .command_key = &command_key, .time = &scheduled_time };
|
struct backup_attributes bkp_attrs = { .command_key = &command_key, .time = &scheduled_time };
|
||||||
load_specific_backup_attributes(tree, &bkp_attrs);
|
load_specific_backup_attributes(tree, &bkp_attrs);
|
||||||
|
|
@ -872,6 +755,7 @@ void load_download(mxml_node_t *tree)
|
||||||
.file_size = &download_request->file_size,
|
.file_size = &download_request->file_size,
|
||||||
.time = &download_request->scheduled_time };
|
.time = &download_request->scheduled_time };
|
||||||
load_specific_backup_attributes(tree, &bkp_attrs);
|
load_specific_backup_attributes(tree, &bkp_attrs);
|
||||||
|
download_request->handler_timer.cb = cwmp_start_download;
|
||||||
|
|
||||||
list_for_each (ilist, &(list_download)) {
|
list_for_each (ilist, &(list_download)) {
|
||||||
idownload_request = list_entry(ilist, struct download, list);
|
idownload_request = list_entry(ilist, struct download, list);
|
||||||
|
|
@ -882,6 +766,7 @@ void load_download(mxml_node_t *tree)
|
||||||
list_add(&(download_request->list), ilist->prev);
|
list_add(&(download_request->list), ilist->prev);
|
||||||
if (download_request->scheduled_time != 0)
|
if (download_request->scheduled_time != 0)
|
||||||
count_download_queue++;
|
count_download_queue++;
|
||||||
|
cwmp_set_end_session(END_SESSION_DOWNLOAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_schedule_download(mxml_node_t *tree)
|
void load_schedule_download(mxml_node_t *tree)
|
||||||
|
|
@ -923,30 +808,6 @@ void load_schedule_download(mxml_node_t *tree)
|
||||||
count_download_queue++;
|
count_download_queue++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_apply_schedule_download(mxml_node_t *tree)
|
|
||||||
{
|
|
||||||
struct apply_schedule_download *download_request = NULL;
|
|
||||||
|
|
||||||
download_request = calloc(1, sizeof(struct apply_schedule_download));
|
|
||||||
|
|
||||||
struct backup_attributes bkp_attrs = {
|
|
||||||
.command_key = &download_request->command_key,
|
|
||||||
.file_type = &download_request->file_type,
|
|
||||||
.start_time = &download_request->start_time,
|
|
||||||
.windowstart1 = &download_request->timeintervals[0].windowstart,
|
|
||||||
.windowend1 = &download_request->timeintervals[0].windowend,
|
|
||||||
.maxretrie1 = &download_request->timeintervals[0].maxretries,
|
|
||||||
.windowstart2 = &download_request->timeintervals[1].windowstart,
|
|
||||||
.windowend2 = &download_request->timeintervals[1].windowend,
|
|
||||||
.maxretrie2 = &download_request->timeintervals[1].maxretries,
|
|
||||||
};
|
|
||||||
load_specific_backup_attributes(tree, &bkp_attrs);
|
|
||||||
|
|
||||||
list_add_tail(&(download_request->list), &(list_apply_schedule_download));
|
|
||||||
if (download_request->timeintervals[0].windowstart != 0)
|
|
||||||
count_download_queue++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void load_upload(mxml_node_t *tree)
|
void load_upload(mxml_node_t *tree)
|
||||||
{
|
{
|
||||||
struct upload *upload_request = NULL;
|
struct upload *upload_request = NULL;
|
||||||
|
|
@ -1012,7 +873,7 @@ void load_change_du_state(mxml_node_t *tree)
|
||||||
list_add_tail(&(change_du_state_request->list_operation), &(list_change_du_state));
|
list_add_tail(&(change_du_state_request->list_operation), &(list_change_du_state));
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_du_state_change_complete(mxml_node_t *tree, struct cwmp *cwmp)
|
void load_du_state_change_complete(mxml_node_t *tree)
|
||||||
{
|
{
|
||||||
mxml_node_t *b = tree;
|
mxml_node_t *b = tree;
|
||||||
struct du_state_change_complete *du_state_change_complete_request = NULL;
|
struct du_state_change_complete *du_state_change_complete_request = NULL;
|
||||||
|
|
@ -1046,10 +907,10 @@ void load_du_state_change_complete(mxml_node_t *tree, struct cwmp *cwmp)
|
||||||
}
|
}
|
||||||
b = mxmlWalkNext(b, tree, MXML_NO_DESCEND);
|
b = mxmlWalkNext(b, tree, MXML_NO_DESCEND);
|
||||||
}
|
}
|
||||||
cwmp_root_cause_changedustate_complete(cwmp, du_state_change_complete_request);
|
cwmp_root_cause_changedustate_complete(du_state_change_complete_request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_transfer_complete(mxml_node_t *tree, struct cwmp *cwmp)
|
void load_transfer_complete(mxml_node_t *tree)
|
||||||
{
|
{
|
||||||
struct transfer_complete *ptransfer_complete;
|
struct transfer_complete *ptransfer_complete;
|
||||||
|
|
||||||
|
|
@ -1063,19 +924,17 @@ void load_transfer_complete(mxml_node_t *tree, struct cwmp *cwmp)
|
||||||
.type = &ptransfer_complete->type };
|
.type = &ptransfer_complete->type };
|
||||||
load_specific_backup_attributes(tree, &bkp_attrs);
|
load_specific_backup_attributes(tree, &bkp_attrs);
|
||||||
|
|
||||||
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
|
cwmp_root_cause_transfer_complete(ptransfer_complete);
|
||||||
sotfware_version_value_change(cwmp, ptransfer_complete);
|
sotfware_version_value_change(ptransfer_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bkp_session_create_file()
|
void bkp_session_create_file()
|
||||||
{
|
{
|
||||||
FILE *pFile;
|
FILE *pFile;
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_backup_session);
|
|
||||||
pFile = fopen(CWMP_BKP_FILE, "w");
|
pFile = fopen(CWMP_BKP_FILE, "w");
|
||||||
if (pFile == NULL) {
|
if (pFile == NULL) {
|
||||||
CWMP_LOG(ERROR, "Unable to create %s file", CWMP_BKP_FILE);
|
CWMP_LOG(ERROR, "Unable to create %s file", CWMP_BKP_FILE);
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fprintf(pFile, "%s", CWMP_BACKUP_SESSION);
|
fprintf(pFile, "%s", CWMP_BACKUP_SESSION);
|
||||||
|
|
@ -1083,7 +942,6 @@ void bkp_session_create_file()
|
||||||
MXML_DELETE(bkp_tree);
|
MXML_DELETE(bkp_tree);
|
||||||
bkp_tree = mxmlLoadString(NULL, CWMP_BACKUP_SESSION, MXML_OPAQUE_CALLBACK);
|
bkp_tree = mxmlLoadString(NULL, CWMP_BACKUP_SESSION, MXML_OPAQUE_CALLBACK);
|
||||||
fclose(pFile);
|
fclose(pFile);
|
||||||
pthread_mutex_unlock(&mutex_backup_session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int bkp_session_check_file()
|
int bkp_session_check_file()
|
||||||
|
|
@ -1109,16 +967,16 @@ int bkp_session_check_file()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cwmp_init_backup_session(struct cwmp *cwmp, char **ret, enum backup_loading load)
|
int cwmp_init_backup_session(char **ret, enum backup_loading load)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
if (bkp_session_check_file())
|
if (bkp_session_check_file())
|
||||||
return 0;
|
return 0;
|
||||||
error = cwmp_load_saved_session(cwmp, ret, load);
|
error = cwmp_load_saved_session(ret, load);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cwmp_load_saved_session(struct cwmp *cwmp, char **ret, enum backup_loading load)
|
int cwmp_load_saved_session(char **ret, enum backup_loading load)
|
||||||
{
|
{
|
||||||
mxml_node_t *b;
|
mxml_node_t *b;
|
||||||
|
|
||||||
|
|
@ -1153,23 +1011,21 @@ int cwmp_load_saved_session(struct cwmp *cwmp, char **ret, enum backup_loading l
|
||||||
}
|
}
|
||||||
if (load == ALL) {
|
if (load == ALL) {
|
||||||
if (ntype == MXML_ELEMENT && strcmp(elem_name, "queue_event") == 0) {
|
if (ntype == MXML_ELEMENT && strcmp(elem_name, "queue_event") == 0) {
|
||||||
load_queue_event(b, cwmp);
|
load_queue_event(b);
|
||||||
} else if (ntype == MXML_ELEMENT && strcmp(elem_name, "download") == 0) {
|
} else if (ntype == MXML_ELEMENT && strcmp(elem_name, "download") == 0) {
|
||||||
load_download(b);
|
load_download(b);
|
||||||
} else if (ntype == MXML_ELEMENT && strcmp(elem_name, "upload") == 0) {
|
} else if (ntype == MXML_ELEMENT && strcmp(elem_name, "upload") == 0) {
|
||||||
load_upload(b);
|
load_upload(b);
|
||||||
} else if (ntype == MXML_ELEMENT && strcmp(elem_name, "transfer_complete") == 0) {
|
} else if (ntype == MXML_ELEMENT && strcmp(elem_name, "transfer_complete") == 0) {
|
||||||
load_transfer_complete(b, cwmp);
|
load_transfer_complete(b);
|
||||||
} else if (ntype == MXML_ELEMENT && strcmp(elem_name, "schedule_inform") == 0) {
|
} else if (ntype == MXML_ELEMENT && strcmp(elem_name, "schedule_inform") == 0) {
|
||||||
load_schedule_inform(b);
|
load_schedule_inform(b);
|
||||||
} else if (ntype == MXML_ELEMENT && strcmp(elem_name, "change_du_state") == 0) {
|
} else if (ntype == MXML_ELEMENT && strcmp(elem_name, "change_du_state") == 0) {
|
||||||
load_change_du_state(b);
|
load_change_du_state(b);
|
||||||
} else if (ntype == MXML_ELEMENT && strcmp(elem_name, "du_state_change_complete") == 0) {
|
} else if (ntype == MXML_ELEMENT && strcmp(elem_name, "du_state_change_complete") == 0) {
|
||||||
load_du_state_change_complete(b, cwmp);
|
load_du_state_change_complete(b);
|
||||||
} else if (ntype == MXML_ELEMENT && strcmp(elem_name, "schedule_download") == 0) {
|
} else if (ntype == MXML_ELEMENT && strcmp(elem_name, "schedule_download") == 0) {
|
||||||
load_schedule_download(b);
|
load_schedule_download(b);
|
||||||
} else if (ntype == MXML_ELEMENT && strcmp(elem_name, "apply_schedule_download") == 0) {
|
|
||||||
load_apply_schedule_download(b);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b = mxmlWalkNext(b, bkp_tree, MXML_NO_DESCEND);
|
b = mxmlWalkNext(b, bkp_tree, MXML_NO_DESCEND);
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
#ifndef _BACKUPSESSION_H__
|
#ifndef _BACKUPSESSION_H__
|
||||||
#define _BACKUPSESSION_H__
|
#define _BACKUPSESSION_H__
|
||||||
|
|
||||||
#include "xml_utils.h"
|
#include <mxml.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#define RPC_NO_STATUS -1
|
#define RPC_NO_STATUS -1
|
||||||
|
|
@ -37,11 +37,9 @@ struct search_keywords {
|
||||||
char *value;
|
char *value;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern pthread_mutex_t mutex_backup_session;
|
int cwmp_init_backup_session(char **ret, enum backup_loading load);
|
||||||
|
|
||||||
int cwmp_init_backup_session(struct cwmp *cwmp, char **ret, enum backup_loading load);
|
|
||||||
void bkp_session_save();
|
void bkp_session_save();
|
||||||
int cwmp_load_saved_session(struct cwmp *cwmp, char **acsurl, enum backup_loading load);
|
int cwmp_load_saved_session(char **acsurl, enum backup_loading load);
|
||||||
mxml_node_t *bkp_session_insert_event(int index, char *command_key, int id, char *status);
|
mxml_node_t *bkp_session_insert_event(int index, char *command_key, int id, char *status);
|
||||||
void bkp_session_delete_event(int id, char *status);
|
void bkp_session_delete_event(int id, char *status);
|
||||||
void bkp_session_simple_insert_in_parent(char *parent, char *child, char *value);
|
void bkp_session_simple_insert_in_parent(char *parent, char *child, char *value);
|
||||||
|
|
@ -59,11 +57,9 @@ void bkp_session_insert_change_du_state(struct change_du_state *pchange_du_state
|
||||||
void bkp_session_delete_change_du_state(struct change_du_state *pchange_du_state);
|
void bkp_session_delete_change_du_state(struct change_du_state *pchange_du_state);
|
||||||
void bkp_session_insert_transfer_complete(struct transfer_complete *ptransfer_complete);
|
void bkp_session_insert_transfer_complete(struct transfer_complete *ptransfer_complete);
|
||||||
void bkp_session_delete_transfer_complete(struct transfer_complete *ptransfer_complete);
|
void bkp_session_delete_transfer_complete(struct transfer_complete *ptransfer_complete);
|
||||||
int save_acs_bkp_config(struct cwmp *cwmp);
|
int save_acs_bkp_config();
|
||||||
|
|
||||||
void bkp_session_insert_schedule_download(struct download *pschedule_download);
|
void bkp_session_insert_schedule_download(struct download *pschedule_download);
|
||||||
void bkp_session_insert_apply_schedule_download(struct apply_schedule_download *papply_schedule_download);
|
|
||||||
void bkp_session_delete_apply_schedule_download(struct apply_schedule_download *papply_schedule_download);
|
|
||||||
void bkp_session_delete_du_state_change_complete(struct du_state_change_complete *pdu_state_change_complete);
|
void bkp_session_delete_du_state_change_complete(struct du_state_change_complete *pdu_state_change_complete);
|
||||||
void bkp_session_delete_schedule_download(struct download *pschedule_download);
|
void bkp_session_delete_schedule_download(struct download *pschedule_download);
|
||||||
void bkp_session_insert_du_state_change_complete(struct du_state_change_complete *pdu_state_change_complete);
|
void bkp_session_insert_du_state_change_complete(struct du_state_change_complete *pdu_state_change_complete);
|
||||||
|
|
|
||||||
98
src/common.c
98
src/common.c
|
|
@ -24,9 +24,10 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
char *commandKey = NULL;
|
char *commandKey = NULL;
|
||||||
bool thread_end = false;
|
bool cwmp_stop = false;
|
||||||
long int flashsize = 256000000;
|
long int flashsize = 256000000;
|
||||||
struct cwmp cwmp_main = { 0 };
|
struct cwmp *cwmp_main = NULL;
|
||||||
|
struct session_timer_event *global_session_event = NULL;
|
||||||
static int nbre_services = 0;
|
static int nbre_services = 0;
|
||||||
static char *list_services[MAX_NBRE_SERVICES] = { 0 };
|
static char *list_services[MAX_NBRE_SERVICES] = { 0 };
|
||||||
LIST_HEAD(cwmp_memory_list);
|
LIST_HEAD(cwmp_memory_list);
|
||||||
|
|
@ -260,6 +261,45 @@ void get_firewall_zone_name_by_wan_iface(char *if_wan, char **zone_name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int get_firewall_restart_state(char **state)
|
||||||
|
{
|
||||||
|
cwmp_uci_reinit();
|
||||||
|
return uci_get_state_value(UCI_CPE_FIREWALL_RESTART_STATE, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait till firewall restart is not complete or 5 sec, whichever is less
|
||||||
|
void check_firewall_restart_state()
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
bool init = false;
|
||||||
|
|
||||||
|
do {
|
||||||
|
char *state = NULL;
|
||||||
|
|
||||||
|
if (get_firewall_restart_state(&state) != CWMP_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (state != NULL && strcmp(state, "init") == 0) {
|
||||||
|
init = true;
|
||||||
|
FREE(state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
usleep(500 * 1000);
|
||||||
|
FREE(state);
|
||||||
|
count++;
|
||||||
|
} while(count < 10);
|
||||||
|
|
||||||
|
// mark the firewall restart as done
|
||||||
|
g_firewall_restart = false;
|
||||||
|
if (init == false) { // In case of timeout reset the firewall_restart flag
|
||||||
|
CWMP_LOG(ERROR, "Firewall restart took longer than usual");
|
||||||
|
cwmp_uci_set_varstate_value("cwmp", "cpe", "firewall_restart", "init");
|
||||||
|
cwmp_commit_package("cwmp", UCI_VARSTATE_CONFIG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reboot
|
* Reboot
|
||||||
*/
|
*/
|
||||||
|
|
@ -640,9 +680,8 @@ char *string_to_hex(const unsigned char *str, size_t size)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size == 0) {
|
if (size == 0)
|
||||||
return hex;
|
return hex;
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < size; i++)
|
for (i = 0; i < size; i++)
|
||||||
snprintf(hex + (i * 2), 3, "%02X", str[i]);
|
snprintf(hex + (i * 2), 3, "%02X", str[i]);
|
||||||
|
|
@ -690,10 +729,10 @@ void ubus_network_interface_callback(struct ubus_request *req __attribute__((unu
|
||||||
|
|
||||||
// Only update the interface if its not empty
|
// Only update the interface if its not empty
|
||||||
if (CWMP_STRLEN(l3_device)) {
|
if (CWMP_STRLEN(l3_device)) {
|
||||||
cwmp_main.conf.interface = strdup(l3_device);
|
cwmp_main->conf.interface = strdup(l3_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
CWMP_LOG(DEBUG, "CWMP IFACE - interface: %s", cwmp_main.conf.interface);
|
CWMP_LOG(DEBUG, "CWMP IFACE - interface: %s", cwmp_main->conf.interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_connection_interface(char *iface)
|
int get_connection_interface(char *iface)
|
||||||
|
|
@ -708,7 +747,7 @@ int get_connection_interface(char *iface)
|
||||||
char ubus_obj[100] = {0};
|
char ubus_obj[100] = {0};
|
||||||
snprintf(ubus_obj, sizeof(ubus_obj), "network.interface.%s", iface);
|
snprintf(ubus_obj, sizeof(ubus_obj), "network.interface.%s", iface);
|
||||||
|
|
||||||
FREE(cwmp_main.conf.interface);
|
FREE(cwmp_main->conf.interface);
|
||||||
|
|
||||||
int e = icwmp_ubus_invoke(ubus_obj, "status", b.head, ubus_network_interface_callback, NULL);
|
int e = icwmp_ubus_invoke(ubus_obj, "status", b.head, ubus_network_interface_callback, NULL);
|
||||||
blob_buf_free(&b);
|
blob_buf_free(&b);
|
||||||
|
|
@ -716,7 +755,7 @@ int get_connection_interface(char *iface)
|
||||||
if (e != 0) {
|
if (e != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (cwmp_main.conf.interface == NULL) {
|
if (cwmp_main->conf.interface == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
|
|
@ -801,3 +840,46 @@ bool match_reg_exp(char *reg_exp, char *param_name)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cwmp_invoke_intf_reset(char *path)
|
||||||
|
{
|
||||||
|
if (path == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CWMP_LOG(INFO, "Reset interface: %s", path);
|
||||||
|
struct blob_buf b = { 0 };
|
||||||
|
memset(&b, 0, sizeof(struct blob_buf));
|
||||||
|
blob_buf_init(&b, 0);
|
||||||
|
bb_add_string(&b, "path", path);
|
||||||
|
bb_add_string(&b, "action", "Reset()");
|
||||||
|
|
||||||
|
icwmp_ubus_invoke(USP_OBJECT_NAME, "operate", b.head, NULL, NULL);
|
||||||
|
blob_buf_free(&b);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_month_days(struct tm time)
|
||||||
|
{
|
||||||
|
if (time.tm_mon == 2)
|
||||||
|
return (time.tm_year % 4 == 0 ) ? 29 : 28;
|
||||||
|
if (((time.tm_mon % 2 == 0) && (time.tm_mon <= 7)) || ((time.tm_mon % 2 == 1) && (time.tm_mon > 7)))
|
||||||
|
return 30;
|
||||||
|
if (((time.tm_mon % 2 == 1) && (time.tm_mon <= 7)) || ((time.tm_mon % 2 == 0) && (time.tm_mon > 7)))
|
||||||
|
return 31;
|
||||||
|
return 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_day_to_time(struct tm *time)
|
||||||
|
{
|
||||||
|
int month_days = get_month_days(*time);
|
||||||
|
if (time->tm_mon == month_days) {
|
||||||
|
time->tm_mday = 1;
|
||||||
|
if (time->tm_mon == 12) {
|
||||||
|
time->tm_mon = 1;
|
||||||
|
time->tm_year = time->tm_year + 1;
|
||||||
|
} else
|
||||||
|
time->tm_mon = time->tm_mon + 1;
|
||||||
|
} else
|
||||||
|
time->tm_mday = time->tm_mday + 1;
|
||||||
|
}
|
||||||
|
|
|
||||||
82
src/common.h
82
src/common.h
|
|
@ -12,11 +12,16 @@
|
||||||
#ifndef __CCOMMON_H
|
#ifndef __CCOMMON_H
|
||||||
#define __CCOMMON_H
|
#define __CCOMMON_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <math.h>
|
||||||
#include <libubox/list.h>
|
#include <libubox/list.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <libubox/uloop.h>
|
||||||
|
|
||||||
#ifndef FREE
|
#ifndef FREE
|
||||||
#define FREE(x) do { if(x) {free(x); x = NULL;} } while (0)
|
#define FREE(x) do { if(x) {free(x); x = NULL;} } while (0)
|
||||||
|
|
@ -54,7 +59,7 @@
|
||||||
#define DEFAULT_RETRY_MAX_INTERVAL 60
|
#define DEFAULT_RETRY_MAX_INTERVAL 60
|
||||||
#define DEFAULT_AMD_VERSION 5
|
#define DEFAULT_AMD_VERSION 5
|
||||||
#define DEFAULT_INSTANCE_MODE 0
|
#define DEFAULT_INSTANCE_MODE 0
|
||||||
#define DEFAULT_SESSION_TIMEOUT 300
|
#define DEFAULT_SESSION_TIMEOUT 60
|
||||||
#define MAX_NBRE_SERVICES 256
|
#define MAX_NBRE_SERVICES 256
|
||||||
#define FIREWALL_CWMP "/etc/firewall.cwmp"
|
#define FIREWALL_CWMP "/etc/firewall.cwmp"
|
||||||
#define CWMP_VARSTATE_UCI_PACKAGE "/var/state/cwmp"
|
#define CWMP_VARSTATE_UCI_PACKAGE "/var/state/cwmp"
|
||||||
|
|
@ -69,7 +74,12 @@
|
||||||
for (elt = strtok_r(buffer_str, delim, &tmpchr); elt != NULL; elt = strtok_r(NULL, delim, &tmpchr))
|
for (elt = strtok_r(buffer_str, delim, &tmpchr); elt != NULL; elt = strtok_r(NULL, delim, &tmpchr))
|
||||||
|
|
||||||
extern char *commandKey;
|
extern char *commandKey;
|
||||||
extern bool thread_end;
|
extern bool cwmp_stop;
|
||||||
|
extern struct uloop_timeout session_timer;
|
||||||
|
extern struct uloop_timeout periodic_session_timer;
|
||||||
|
extern struct uloop_timeout retry_session_timer;
|
||||||
|
extern bool g_firewall_restart;
|
||||||
|
extern struct list_head intf_reset_list;
|
||||||
|
|
||||||
typedef struct env {
|
typedef struct env {
|
||||||
unsigned short boot;
|
unsigned short boot;
|
||||||
|
|
@ -126,42 +136,30 @@ struct deviceid {
|
||||||
char *softwareversion;
|
char *softwareversion;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct session_status {
|
|
||||||
time_t last_start_time;
|
|
||||||
time_t last_end_time;
|
|
||||||
int last_status;
|
|
||||||
time_t next_periodic;
|
|
||||||
time_t next_retry;
|
|
||||||
unsigned int success_session;
|
|
||||||
unsigned int failure_session;
|
|
||||||
} session_status;
|
|
||||||
|
|
||||||
typedef struct cwmp {
|
typedef struct cwmp {
|
||||||
struct env env;
|
struct env env;
|
||||||
struct config conf;
|
struct config conf;
|
||||||
struct deviceid deviceid;
|
struct deviceid deviceid;
|
||||||
struct list_head head_session_queue;
|
struct session *session;
|
||||||
pthread_mutex_t mutex_session_queue;
|
|
||||||
struct session *session_send;
|
|
||||||
bool cwmp_cr_event;
|
bool cwmp_cr_event;
|
||||||
bool init_complete;
|
bool init_complete;
|
||||||
pthread_mutex_t mutex_session_send;
|
bool prev_periodic_enable;
|
||||||
pthread_cond_t threshold_session_send;
|
bool prev_heartbeat_enable;
|
||||||
pthread_mutex_t mutex_periodic;
|
bool heart_session;
|
||||||
pthread_mutex_t mutex_notify_periodic;
|
bool diag_session;
|
||||||
pthread_cond_t threshold_periodic;
|
int prev_periodic_interval;
|
||||||
pthread_cond_t threshold_notify_periodic;
|
int prev_heartbeat_interval;
|
||||||
pthread_cond_t threshold_handle_notify;
|
|
||||||
int count_handle_notify;
|
int count_handle_notify;
|
||||||
int retry_count_session;
|
int retry_count_session;
|
||||||
struct list_head *head_event_container;
|
|
||||||
FILE *pid_file;
|
FILE *pid_file;
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
struct session_status session_status;
|
time_t prev_periodic_time;
|
||||||
|
time_t prev_heartbeat_time;
|
||||||
unsigned int cwmp_id;
|
unsigned int cwmp_id;
|
||||||
int event_id;
|
int event_id;
|
||||||
int cr_socket_desc;
|
int cr_socket_desc;
|
||||||
int cwmp_period;
|
int cwmp_period;
|
||||||
|
long int heart_session_interval;
|
||||||
time_t cwmp_periodic_time;
|
time_t cwmp_periodic_time;
|
||||||
bool cwmp_periodic_enable;
|
bool cwmp_periodic_enable;
|
||||||
bool custom_notify_active;
|
bool custom_notify_active;
|
||||||
|
|
@ -174,6 +172,11 @@ enum action {
|
||||||
RESTART,
|
RESTART,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum auth_type_enum {
|
||||||
|
AUTH_BASIC,
|
||||||
|
AUTH_DIGEST
|
||||||
|
};
|
||||||
|
|
||||||
enum cwmp_start {
|
enum cwmp_start {
|
||||||
CWMP_START_BOOT = 1,
|
CWMP_START_BOOT = 1,
|
||||||
CWMP_START_PERIODIC = 2
|
CWMP_START_PERIODIC = 2
|
||||||
|
|
@ -368,15 +371,15 @@ enum client_server_faults {
|
||||||
|
|
||||||
struct rpc_cpe_method {
|
struct rpc_cpe_method {
|
||||||
const char *name;
|
const char *name;
|
||||||
int (*handler)(struct session *session, struct rpc *rpc);
|
int (*handler)(struct rpc *rpc);
|
||||||
int amd;
|
int amd;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rpc_acs_method {
|
struct rpc_acs_method {
|
||||||
const char *name;
|
const char *name;
|
||||||
int (*prepare_message)(struct cwmp *cwmp, struct session *session, struct rpc *rpc);
|
int (*prepare_message)(struct rpc *rpc);
|
||||||
int (*parse_response)(struct cwmp *cwmp, struct session *session, struct rpc *rpc);
|
int (*parse_response)(struct rpc *rpc);
|
||||||
int (*extra_clean)(struct session *session, struct rpc *rpc);
|
int (*extra_clean)(struct rpc *rpc);
|
||||||
int acs_support;
|
int acs_support;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -389,6 +392,7 @@ typedef struct FAULT_CPE {
|
||||||
|
|
||||||
typedef struct schedule_inform {
|
typedef struct schedule_inform {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
struct uloop_timeout handler_timer ;
|
||||||
time_t scheduled_time;
|
time_t scheduled_time;
|
||||||
char *commandKey;
|
char *commandKey;
|
||||||
} schedule_inform;
|
} schedule_inform;
|
||||||
|
|
@ -403,6 +407,7 @@ typedef struct timewindow {
|
||||||
|
|
||||||
typedef struct download {
|
typedef struct download {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
struct uloop_timeout handler_timer;
|
||||||
time_t scheduled_time;
|
time_t scheduled_time;
|
||||||
int file_size;
|
int file_size;
|
||||||
char *command_key;
|
char *command_key;
|
||||||
|
|
@ -419,16 +424,9 @@ typedef struct timeinterval {
|
||||||
int maxretries;
|
int maxretries;
|
||||||
} timeinterval;
|
} timeinterval;
|
||||||
|
|
||||||
typedef struct apply_schedule_download {
|
|
||||||
struct list_head list;
|
|
||||||
char *start_time;
|
|
||||||
char *command_key;
|
|
||||||
char *file_type;
|
|
||||||
struct timeinterval timeintervals[2];
|
|
||||||
} apply_schedule_download;
|
|
||||||
|
|
||||||
typedef struct change_du_state {
|
typedef struct change_du_state {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
struct uloop_timeout handler_timer;
|
||||||
time_t timeout;
|
time_t timeout;
|
||||||
char *command_key;
|
char *command_key;
|
||||||
struct list_head list_operation;
|
struct list_head list_operation;
|
||||||
|
|
@ -447,6 +445,7 @@ typedef struct operations {
|
||||||
|
|
||||||
typedef struct upload {
|
typedef struct upload {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
struct uloop_timeout handler_timer ;
|
||||||
time_t scheduled_time;
|
time_t scheduled_time;
|
||||||
char *file_type;
|
char *file_type;
|
||||||
char *command_key;
|
char *command_key;
|
||||||
|
|
@ -494,10 +493,11 @@ typedef struct intf_reset_node {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
} intf_reset_node;
|
} intf_reset_node;
|
||||||
|
|
||||||
extern struct cwmp cwmp_main;
|
extern struct cwmp *cwmp_main;
|
||||||
extern long int flashsize;
|
extern long int flashsize;
|
||||||
extern struct FAULT_CPE FAULT_CPE_ARRAY[];
|
extern struct FAULT_CPE FAULT_CPE_ARRAY[];
|
||||||
extern struct cwmp_namespaces ns;
|
extern struct cwmp_namespaces ns;
|
||||||
|
extern struct session_timer_event *global_session_event;
|
||||||
|
|
||||||
void add_dm_parameter_to_list(struct list_head *head, char *param_name, char *param_data, char *param_type, int notification, bool writable);
|
void add_dm_parameter_to_list(struct list_head *head, char *param_name, char *param_data, char *param_type, int notification, bool writable);
|
||||||
void delete_dm_parameter_from_list(struct cwmp_dm_parameter *dm_parameter);
|
void delete_dm_parameter_from_list(struct cwmp_dm_parameter *dm_parameter);
|
||||||
|
|
@ -541,11 +541,11 @@ int get_connection_interface();
|
||||||
char *get_time(time_t t_time);
|
char *get_time(time_t t_time);
|
||||||
bool is_obj_excluded(const char *object_name);
|
bool is_obj_excluded(const char *object_name);
|
||||||
time_t convert_datetime_to_timestamp(char *value);
|
time_t convert_datetime_to_timestamp(char *value);
|
||||||
int cwmp_get_retry_interval(struct cwmp *cwmp, bool heart_beat);
|
|
||||||
int cwmp_schedule_rpc(struct cwmp *cwmp, struct session *session);
|
|
||||||
int run_session_end_func(void);
|
int run_session_end_func(void);
|
||||||
void set_interface_reset_request(char *param_name, char *value);
|
void set_interface_reset_request(char *param_name, char *value);
|
||||||
bool uci_str_to_bool(char *value);
|
bool uci_str_to_bool(char *value);
|
||||||
bool match_reg_exp(char *reg_exp, char *param_name);
|
bool match_reg_exp(char *reg_exp, char *param_name);
|
||||||
|
void cwmp_invoke_intf_reset(char *path);
|
||||||
|
void check_firewall_restart_state();
|
||||||
|
void add_day_to_time(struct tm *time);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
224
src/config.c
224
src/config.c
|
|
@ -172,7 +172,7 @@ static char* get_value_from_uci_option(struct uci_option *tb) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void config_get_cpe_elements(struct config *conf, struct uci_section *s)
|
static void config_get_cpe_elements(struct uci_section *s)
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
UCI_CPE_UBUS_SOCKET_PATH,
|
UCI_CPE_UBUS_SOCKET_PATH,
|
||||||
|
|
@ -202,8 +202,8 @@ static void config_get_cpe_elements(struct config *conf, struct uci_section *s)
|
||||||
struct uci_option *cpe_tb[__MAX_NUM_UCI_CPE_ATTRS] = {0};
|
struct uci_option *cpe_tb[__MAX_NUM_UCI_CPE_ATTRS] = {0};
|
||||||
uci_parse_section(s, cpe_opts, __MAX_NUM_UCI_CPE_ATTRS, cpe_tb);
|
uci_parse_section(s, cpe_opts, __MAX_NUM_UCI_CPE_ATTRS, cpe_tb);
|
||||||
|
|
||||||
conf->ubus_socket = CWMP_STRDUP(get_value_from_uci_option(cpe_tb[UCI_CPE_UBUS_SOCKET_PATH]));
|
cwmp_main->conf.ubus_socket = CWMP_STRDUP(get_value_from_uci_option(cpe_tb[UCI_CPE_UBUS_SOCKET_PATH]));
|
||||||
CWMP_LOG(DEBUG, "CWMP CONFIG - ubus socket: %s", conf->ubus_socket ? conf->ubus_socket : "");
|
CWMP_LOG(DEBUG, "CWMP CONFIG - ubus socket: %s", cwmp_main->conf.ubus_socket ? cwmp_main->conf.ubus_socket : "");
|
||||||
|
|
||||||
log_set_log_file_name(get_value_from_uci_option(cpe_tb[UCI_CPE_LOG_FILE_NAME]));
|
log_set_log_file_name(get_value_from_uci_option(cpe_tb[UCI_CPE_LOG_FILE_NAME]));
|
||||||
|
|
||||||
|
|
@ -217,25 +217,25 @@ static void config_get_cpe_elements(struct config *conf, struct uci_section *s)
|
||||||
|
|
||||||
log_set_on_syslog(get_value_from_uci_option(cpe_tb[UCI_CPE_ENABLE_SYSLOG]));
|
log_set_on_syslog(get_value_from_uci_option(cpe_tb[UCI_CPE_ENABLE_SYSLOG]));
|
||||||
|
|
||||||
conf->amd_version = DEFAULT_AMD_VERSION;
|
cwmp_main->conf.amd_version = DEFAULT_AMD_VERSION;
|
||||||
char *version = get_value_from_uci_option(cpe_tb[UCI_CPE_AMD_VERSION]);
|
char *version = get_value_from_uci_option(cpe_tb[UCI_CPE_AMD_VERSION]);
|
||||||
if (version != NULL) {
|
if (version != NULL) {
|
||||||
int a = atoi(version);
|
int a = atoi(version);
|
||||||
if (a >= 1 && a <= 6) {
|
if (a >= 1 && a <= 6) {
|
||||||
conf->amd_version = a;
|
cwmp_main->conf.amd_version = a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
conf->supported_amd_version = conf->amd_version;
|
cwmp_main->conf.supported_amd_version = cwmp_main->conf.amd_version;
|
||||||
CWMP_LOG(DEBUG, "CWMP CONFIG - amendement version: %d", conf->amd_version);
|
CWMP_LOG(DEBUG, "CWMP CONFIG - amendement version: %d", cwmp_main->conf.amd_version);
|
||||||
if (cpe_tb[UCI_CPE_DEFAULT_WAN_IFACE]) {
|
if (cpe_tb[UCI_CPE_DEFAULT_WAN_IFACE]) {
|
||||||
conf->default_wan_iface = strdup(get_value_from_uci_option(cpe_tb[UCI_CPE_DEFAULT_WAN_IFACE]));
|
cwmp_main->conf.default_wan_iface = strdup(get_value_from_uci_option(cpe_tb[UCI_CPE_DEFAULT_WAN_IFACE]));
|
||||||
} else {
|
} else {
|
||||||
conf->default_wan_iface = strdup("wan");
|
cwmp_main->conf.default_wan_iface = strdup("wan");
|
||||||
}
|
}
|
||||||
CWMP_LOG(DEBUG, "CWMP CONFIG - default wan interface: %s", conf->default_wan_iface);
|
CWMP_LOG(DEBUG, "CWMP CONFIG - default wan interface: %s", cwmp_main->conf.default_wan_iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void config_get_acs_elements(struct config *conf, struct uci_section *s)
|
static void config_get_acs_elements(struct uci_section *s)
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
UCI_ACS_IPV6_ENABLE,
|
UCI_ACS_IPV6_ENABLE,
|
||||||
|
|
@ -256,20 +256,20 @@ static void config_get_acs_elements(struct config *conf, struct uci_section *s)
|
||||||
memset(acs_tb, 0, sizeof(acs_tb));
|
memset(acs_tb, 0, sizeof(acs_tb));
|
||||||
uci_parse_section(s, acs_opts, __MAX_NUM_UCI_ACS_ATTRS, acs_tb);
|
uci_parse_section(s, acs_opts, __MAX_NUM_UCI_ACS_ATTRS, acs_tb);
|
||||||
|
|
||||||
conf->ipv6_enable = uci_str_to_bool(get_value_from_uci_option(acs_tb[UCI_ACS_IPV6_ENABLE]));
|
cwmp_main->conf.ipv6_enable = uci_str_to_bool(get_value_from_uci_option(acs_tb[UCI_ACS_IPV6_ENABLE]));
|
||||||
CWMP_LOG(DEBUG, "CWMP CONFIG - ipv6 enable: %d", conf->ipv6_enable);
|
CWMP_LOG(DEBUG, "CWMP CONFIG - ipv6 enable: %d", cwmp_main->conf.ipv6_enable);
|
||||||
|
|
||||||
conf->acs_ssl_capath = CWMP_STRDUP(get_value_from_uci_option(acs_tb[UCI_ACS_SSL_CAPATH]));
|
cwmp_main->conf.acs_ssl_capath = CWMP_STRDUP(get_value_from_uci_option(acs_tb[UCI_ACS_SSL_CAPATH]));
|
||||||
CWMP_LOG(DEBUG, "CWMP CONFIG - acs ssl cpath: %s", conf->acs_ssl_capath ? conf->acs_ssl_capath : "");
|
CWMP_LOG(DEBUG, "CWMP CONFIG - acs ssl cpath: %s", cwmp_main->conf.acs_ssl_capath ? cwmp_main->conf.acs_ssl_capath : "");
|
||||||
|
|
||||||
conf->http_disable_100continue = uci_str_to_bool(get_value_from_uci_option(acs_tb[HTTP_DISABLE_100CONTINUE]));
|
cwmp_main->conf.http_disable_100continue = uci_str_to_bool(get_value_from_uci_option(acs_tb[HTTP_DISABLE_100CONTINUE]));
|
||||||
CWMP_LOG(DEBUG, "CWMP CONFIG - http disable 100continue: %d", conf->http_disable_100continue);
|
CWMP_LOG(DEBUG, "CWMP CONFIG - http disable 100continue: %d", cwmp_main->conf.http_disable_100continue);
|
||||||
|
|
||||||
conf->insecure_enable = uci_str_to_bool(get_value_from_uci_option(acs_tb[UCI_ACS_INSECURE_ENABLE]));
|
cwmp_main->conf.insecure_enable = uci_str_to_bool(get_value_from_uci_option(acs_tb[UCI_ACS_INSECURE_ENABLE]));
|
||||||
CWMP_LOG(DEBUG, "CWMP CONFIG - acs insecure enable: %d", conf->insecure_enable);
|
CWMP_LOG(DEBUG, "CWMP CONFIG - acs insecure enable: %d", cwmp_main->conf.insecure_enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_preinit_config(struct config *conf)
|
int get_preinit_config()
|
||||||
{
|
{
|
||||||
struct uci_context *ctx;
|
struct uci_context *ctx;
|
||||||
struct uci_package *pkg;
|
struct uci_package *pkg;
|
||||||
|
|
@ -287,9 +287,9 @@ int get_preinit_config(struct config *conf)
|
||||||
uci_foreach_element(&pkg->sections, e) {
|
uci_foreach_element(&pkg->sections, e) {
|
||||||
struct uci_section *s = uci_to_section(e);
|
struct uci_section *s = uci_to_section(e);
|
||||||
if (strcmp(s->type, "acs") == 0) {
|
if (strcmp(s->type, "acs") == 0) {
|
||||||
config_get_acs_elements(conf, s);
|
config_get_acs_elements(s);
|
||||||
} else if (strcmp(s->type, "cpe") == 0) {
|
} else if (strcmp(s->type, "cpe") == 0) {
|
||||||
config_get_cpe_elements(conf, s);
|
config_get_cpe_elements(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -308,7 +308,7 @@ static char* get_alternate_option_value(bool discovery_enable, char *acs_val, ch
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_global_config(struct config *conf)
|
int get_global_config()
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
char *value = NULL, *value2 = NULL, *value3 = NULL;
|
char *value = NULL, *value2 = NULL, *value3 = NULL;
|
||||||
|
|
@ -322,9 +322,9 @@ int get_global_config(struct config *conf)
|
||||||
}
|
}
|
||||||
FREE(value);
|
FREE(value);
|
||||||
|
|
||||||
error = get_connection_interface(conf->default_wan_iface);
|
error = get_connection_interface(cwmp_main->conf.default_wan_iface);
|
||||||
if (error != CWMP_OK) {
|
if (error != CWMP_OK) {
|
||||||
CWMP_LOG(DEBUG, "Failed to get interface [%s] details", conf->default_wan_iface);
|
CWMP_LOG(DEBUG, "Failed to get interface [%s] details", cwmp_main->conf.default_wan_iface);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -334,8 +334,8 @@ int get_global_config(struct config *conf)
|
||||||
// now read the vendor info from ifstatus before reading the DHCP_ACS_URL from uci
|
// now read the vendor info from ifstatus before reading the DHCP_ACS_URL from uci
|
||||||
if (error == CWMP_OK && value != NULL) {
|
if (error == CWMP_OK && value != NULL) {
|
||||||
discovery_enable = uci_str_to_bool(value);
|
discovery_enable = uci_str_to_bool(value);
|
||||||
if (discovery_enable == true && conf->default_wan_iface != NULL) {
|
if (discovery_enable == true && cwmp_main->conf.default_wan_iface != NULL) {
|
||||||
get_dhcp_vendor_info(conf->default_wan_iface);
|
get_dhcp_vendor_info(cwmp_main->conf.default_wan_iface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FREE(value);
|
FREE(value);
|
||||||
|
|
@ -343,20 +343,20 @@ int get_global_config(struct config *conf)
|
||||||
uci_get_value(UCI_ACS_URL_PATH, &value2);
|
uci_get_value(UCI_ACS_URL_PATH, &value2);
|
||||||
uci_get_value(UCI_DHCP_ACS_URL, &value3);
|
uci_get_value(UCI_DHCP_ACS_URL, &value3);
|
||||||
|
|
||||||
FREE(conf->acsurl);
|
FREE(cwmp_main->conf.acsurl);
|
||||||
conf->acsurl = CWMP_STRDUP(get_alternate_option_value(discovery_enable, value2, value3));
|
cwmp_main->conf.acsurl = CWMP_STRDUP(get_alternate_option_value(discovery_enable, value2, value3));
|
||||||
|
|
||||||
FREE(value2);
|
FREE(value2);
|
||||||
FREE(value3);
|
FREE(value3);
|
||||||
|
|
||||||
if (conf->acsurl == NULL) {
|
if (cwmp_main->conf.acsurl == NULL) {
|
||||||
return CWMP_GEN_ERR;
|
return CWMP_GEN_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = uci_get_value(UCI_ACS_USERID_PATH, &value)) == CWMP_OK) {
|
if ((error = uci_get_value(UCI_ACS_USERID_PATH, &value)) == CWMP_OK) {
|
||||||
if (value != NULL) {
|
if (value != NULL) {
|
||||||
FREE(conf->acs_userid);
|
FREE(cwmp_main->conf.acs_userid);
|
||||||
conf->acs_userid = strdup(value);
|
cwmp_main->conf.acs_userid = strdup(value);
|
||||||
FREE(value);
|
FREE(value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -365,8 +365,8 @@ int get_global_config(struct config *conf)
|
||||||
|
|
||||||
if ((error = uci_get_value(UCI_ACS_PASSWD_PATH, &value)) == CWMP_OK) {
|
if ((error = uci_get_value(UCI_ACS_PASSWD_PATH, &value)) == CWMP_OK) {
|
||||||
if (value != NULL) {
|
if (value != NULL) {
|
||||||
FREE(conf->acs_passwd);
|
FREE(cwmp_main->conf.acs_passwd);
|
||||||
conf->acs_passwd = strdup(value);
|
cwmp_main->conf.acs_passwd = strdup(value);
|
||||||
FREE(value);
|
FREE(value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -374,31 +374,30 @@ int get_global_config(struct config *conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = uci_get_value(UCI_ACS_COMPRESSION, &value)) == CWMP_OK) {
|
if ((error = uci_get_value(UCI_ACS_COMPRESSION, &value)) == CWMP_OK) {
|
||||||
conf->compression = COMP_NONE;
|
cwmp_main->conf.compression = COMP_NONE;
|
||||||
if (conf->amd_version >= AMD_5 && value != NULL) {
|
if (cwmp_main->conf.amd_version >= AMD_5 && value != NULL) {
|
||||||
if (0 == strcasecmp(value, "gzip")) {
|
if (0 == strcasecmp(value, "gzip")) {
|
||||||
conf->compression = COMP_GZIP;
|
cwmp_main->conf.compression = COMP_GZIP;
|
||||||
} else if (0 == strcasecmp(value, "deflate")) {
|
} else if (0 == strcasecmp(value, "deflate")) {
|
||||||
conf->compression = COMP_DEFLATE;
|
cwmp_main->conf.compression = COMP_DEFLATE;
|
||||||
} else {
|
} else {
|
||||||
conf->compression = COMP_NONE;
|
cwmp_main->conf.compression = COMP_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FREE(value);
|
FREE(value);
|
||||||
} else {
|
} else
|
||||||
conf->compression = COMP_NONE;
|
cwmp_main->conf.compression = COMP_NONE;
|
||||||
}
|
|
||||||
|
|
||||||
conf->retry_min_wait_interval = DEFAULT_RETRY_MINIMUM_WAIT_INTERVAL;
|
cwmp_main->conf.retry_min_wait_interval = DEFAULT_RETRY_MINIMUM_WAIT_INTERVAL;
|
||||||
uci_get_value(UCI_ACS_RETRY_MIN_WAIT_INTERVAL, &value2);
|
uci_get_value(UCI_ACS_RETRY_MIN_WAIT_INTERVAL, &value2);
|
||||||
uci_get_value(UCI_DHCP_ACS_RETRY_MIN_WAIT_INTERVAL, &value3);
|
uci_get_value(UCI_DHCP_ACS_RETRY_MIN_WAIT_INTERVAL, &value3);
|
||||||
|
|
||||||
char *op_interval = get_alternate_option_value(discovery_enable, value2, value3);
|
char *op_interval = get_alternate_option_value(discovery_enable, value2, value3);
|
||||||
if (op_interval != NULL) {
|
if (op_interval != NULL) {
|
||||||
if (conf->amd_version >= AMD_3) {
|
if (cwmp_main->conf.amd_version >= AMD_3) {
|
||||||
int a = atoi(op_interval);
|
int a = atoi(op_interval);
|
||||||
if (a <= 65535 && a >= 1) {
|
if (a <= 65535 && a >= 1) {
|
||||||
conf->retry_min_wait_interval = a;
|
cwmp_main->conf.retry_min_wait_interval = a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -406,16 +405,16 @@ int get_global_config(struct config *conf)
|
||||||
FREE(value2);
|
FREE(value2);
|
||||||
FREE(value3);
|
FREE(value3);
|
||||||
|
|
||||||
conf->retry_interval_multiplier = DEFAULT_RETRY_INTERVAL_MULTIPLIER;
|
cwmp_main->conf.retry_interval_multiplier = DEFAULT_RETRY_INTERVAL_MULTIPLIER;
|
||||||
uci_get_value(UCI_ACS_RETRY_INTERVAL_MULTIPLIER, &value2);
|
uci_get_value(UCI_ACS_RETRY_INTERVAL_MULTIPLIER, &value2);
|
||||||
uci_get_value(UCI_DHCP_ACS_RETRY_INTERVAL_MULTIPLIER, &value3);
|
uci_get_value(UCI_DHCP_ACS_RETRY_INTERVAL_MULTIPLIER, &value3);
|
||||||
|
|
||||||
char *op_multi = get_alternate_option_value(discovery_enable, value2, value3);
|
char *op_multi = get_alternate_option_value(discovery_enable, value2, value3);
|
||||||
if (op_multi != NULL) {
|
if (op_multi != NULL) {
|
||||||
if (conf->amd_version >= AMD_3) {
|
if (cwmp_main->conf.amd_version >= AMD_3) {
|
||||||
int a = atoi(op_multi);
|
int a = atoi(op_multi);
|
||||||
if (a <= 65535 && a >= 1000) {
|
if (a <= 65535 && a >= 1000) {
|
||||||
conf->retry_interval_multiplier = a;
|
cwmp_main->conf.retry_interval_multiplier = a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -424,24 +423,23 @@ int get_global_config(struct config *conf)
|
||||||
FREE(value3);
|
FREE(value3);
|
||||||
|
|
||||||
if ((error = uci_get_value(UCI_CPE_USERID_PATH, &value)) == CWMP_OK) {
|
if ((error = uci_get_value(UCI_CPE_USERID_PATH, &value)) == CWMP_OK) {
|
||||||
FREE(conf->cpe_userid);
|
FREE(cwmp_main->conf.cpe_userid);
|
||||||
if (value != NULL) {
|
if (value != NULL) {
|
||||||
conf->cpe_userid = strdup(value);
|
cwmp_main->conf.cpe_userid = strdup(value);
|
||||||
FREE(value);
|
FREE(value);
|
||||||
} else {
|
} else
|
||||||
conf->cpe_userid = strdup("");
|
cwmp_main->conf.cpe_userid = strdup("");
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = uci_get_value(UCI_CPE_PASSWD_PATH, &value)) == CWMP_OK) {
|
if ((error = uci_get_value(UCI_CPE_PASSWD_PATH, &value)) == CWMP_OK) {
|
||||||
FREE(conf->cpe_passwd);
|
FREE(cwmp_main->conf.cpe_passwd);
|
||||||
if (value != NULL) {
|
if (value != NULL) {
|
||||||
conf->cpe_passwd = strdup(value);
|
cwmp_main->conf.cpe_passwd = strdup(value);
|
||||||
FREE(value);
|
FREE(value);
|
||||||
} else {
|
} else {
|
||||||
conf->cpe_passwd = strdup("");
|
cwmp_main->conf.cpe_passwd = strdup("");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return error;
|
return error;
|
||||||
|
|
@ -457,25 +455,25 @@ int get_global_config(struct config *conf)
|
||||||
|
|
||||||
if (a == 0) {
|
if (a == 0) {
|
||||||
CWMP_LOG(INFO, "Set the connection request port to the default value: %d", DEFAULT_CONNECTION_REQUEST_PORT);
|
CWMP_LOG(INFO, "Set the connection request port to the default value: %d", DEFAULT_CONNECTION_REQUEST_PORT);
|
||||||
conf->connection_request_port = DEFAULT_CONNECTION_REQUEST_PORT;
|
cwmp_main->conf.connection_request_port = DEFAULT_CONNECTION_REQUEST_PORT;
|
||||||
} else {
|
} else {
|
||||||
conf->connection_request_port = a;
|
cwmp_main->conf.connection_request_port = a;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = uci_get_value(UCI_CPE_CRPATH_PATH, &value)) == CWMP_OK) {
|
if ((error = uci_get_value(UCI_CPE_CRPATH_PATH, &value)) == CWMP_OK) {
|
||||||
FREE(conf->connection_request_path);
|
FREE(cwmp_main->conf.connection_request_path);
|
||||||
if (value == NULL)
|
if (value == NULL)
|
||||||
conf->connection_request_path = strdup("/");
|
cwmp_main->conf.connection_request_path = strdup("/");
|
||||||
else {
|
else {
|
||||||
if (value[0] == '/')
|
if (value[0] == '/')
|
||||||
conf->connection_request_path = strdup(value);
|
cwmp_main->conf.connection_request_path = strdup(value);
|
||||||
else {
|
else {
|
||||||
char cr_path[512];
|
char cr_path[512];
|
||||||
snprintf(cr_path, sizeof(cr_path), "/%s", value);
|
snprintf(cr_path, sizeof(cr_path), "/%s", value);
|
||||||
conf->connection_request_path = strdup(cr_path);
|
cwmp_main->conf.connection_request_path = strdup(cr_path);
|
||||||
}
|
}
|
||||||
FREE(value);
|
FREE(value);
|
||||||
}
|
}
|
||||||
|
|
@ -489,7 +487,7 @@ int get_global_config(struct config *conf)
|
||||||
a = uci_str_to_bool(value);
|
a = uci_str_to_bool(value);
|
||||||
FREE(value);
|
FREE(value);
|
||||||
}
|
}
|
||||||
conf->periodic_notify_enable = a;
|
cwmp_main->conf.periodic_notify_enable = a;
|
||||||
} else {
|
} else {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
@ -504,9 +502,9 @@ int get_global_config(struct config *conf)
|
||||||
|
|
||||||
if (a == 0) {
|
if (a == 0) {
|
||||||
CWMP_LOG(INFO, "Set notify period to the default value: %d", DEFAULT_NOTIFY_PERIOD);
|
CWMP_LOG(INFO, "Set notify period to the default value: %d", DEFAULT_NOTIFY_PERIOD);
|
||||||
conf->periodic_notify_interval = DEFAULT_NOTIFY_PERIOD;
|
cwmp_main->conf.periodic_notify_interval = DEFAULT_NOTIFY_PERIOD;
|
||||||
} else {
|
} else {
|
||||||
conf->periodic_notify_interval = a;
|
cwmp_main->conf.periodic_notify_interval = a;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return error;
|
return error;
|
||||||
|
|
@ -514,18 +512,16 @@ int get_global_config(struct config *conf)
|
||||||
|
|
||||||
if ((error = uci_get_value(UCI_PERIODIC_INFORM_TIME_PATH, &value)) == CWMP_OK) {
|
if ((error = uci_get_value(UCI_PERIODIC_INFORM_TIME_PATH, &value)) == CWMP_OK) {
|
||||||
if (value != NULL) {
|
if (value != NULL) {
|
||||||
conf->time = convert_datetime_to_timestamp(value);
|
cwmp_main->conf.time = convert_datetime_to_timestamp(value);
|
||||||
FREE(value);
|
FREE(value);
|
||||||
} else {
|
} else
|
||||||
conf->time = 0;
|
cwmp_main->conf.time = 0;
|
||||||
}
|
} else
|
||||||
} else {
|
|
||||||
return error;
|
return error;
|
||||||
}
|
|
||||||
|
|
||||||
char *entropy = generate_random_string(sizeof(unsigned int));
|
char *entropy = generate_random_string(sizeof(unsigned int));
|
||||||
if (entropy != NULL) {
|
if (entropy != NULL) {
|
||||||
conf->periodic_entropy = (unsigned int)strtoul(entropy, NULL, 16);
|
cwmp_main->conf.periodic_entropy = (unsigned int)strtoul(entropy, NULL, 16);
|
||||||
free(entropy);
|
free(entropy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -538,17 +534,17 @@ int get_global_config(struct config *conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a >= PERIOD_INFORM_MIN) {
|
if (a >= PERIOD_INFORM_MIN) {
|
||||||
conf->period = a;
|
cwmp_main->conf.period = a;
|
||||||
} else {
|
} else {
|
||||||
CWMP_LOG(ERROR, "Period interval of periodic inform should be > %ds. Set to default: %ds", PERIOD_INFORM_MIN, PERIOD_INFORM_DEFAULT);
|
CWMP_LOG(ERROR, "Period interval of periodic inform should be > %ds. Set to default: %ds", PERIOD_INFORM_MIN, PERIOD_INFORM_DEFAULT);
|
||||||
conf->period = PERIOD_INFORM_DEFAULT;
|
cwmp_main->conf.period = PERIOD_INFORM_DEFAULT;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = uci_get_value(UCI_PERIODIC_INFORM_ENABLE_PATH, &value)) == CWMP_OK) {
|
if ((error = uci_get_value(UCI_PERIODIC_INFORM_ENABLE_PATH, &value)) == CWMP_OK) {
|
||||||
conf->periodic_enable = uci_str_to_bool(value);
|
cwmp_main->conf.periodic_enable = uci_str_to_bool(value);
|
||||||
FREE(value);
|
FREE(value);
|
||||||
} else {
|
} else {
|
||||||
return error;
|
return error;
|
||||||
|
|
@ -557,24 +553,24 @@ int get_global_config(struct config *conf)
|
||||||
if ((error = uci_get_value(UCI_CPE_INSTANCE_MODE, &value)) == CWMP_OK) {
|
if ((error = uci_get_value(UCI_CPE_INSTANCE_MODE, &value)) == CWMP_OK) {
|
||||||
if (value != NULL) {
|
if (value != NULL) {
|
||||||
if (0 == strcmp(value, "InstanceNumber")) {
|
if (0 == strcmp(value, "InstanceNumber")) {
|
||||||
conf->instance_mode = INSTANCE_MODE_NUMBER;
|
cwmp_main->conf.instance_mode = INSTANCE_MODE_NUMBER;
|
||||||
} else {
|
} else {
|
||||||
conf->instance_mode = INSTANCE_MODE_ALIAS;
|
cwmp_main->conf.instance_mode = INSTANCE_MODE_ALIAS;
|
||||||
}
|
}
|
||||||
FREE(value);
|
FREE(value);
|
||||||
} else {
|
} else {
|
||||||
conf->instance_mode = DEFAULT_INSTANCE_MODE;
|
cwmp_main->conf.instance_mode = DEFAULT_INSTANCE_MODE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = uci_get_value(UCI_CPE_SESSION_TIMEOUT, &value)) == CWMP_OK) {
|
if ((error = uci_get_value(UCI_CPE_SESSION_TIMEOUT, &value)) == CWMP_OK) {
|
||||||
conf->session_timeout = DEFAULT_SESSION_TIMEOUT;
|
cwmp_main->conf.session_timeout = DEFAULT_SESSION_TIMEOUT;
|
||||||
if (value != NULL) {
|
if (value != NULL) {
|
||||||
int a = atoi(value);
|
int a = atoi(value);
|
||||||
if (a >= 1) {
|
if (a >= 1) {
|
||||||
conf->session_timeout = a;
|
cwmp_main->conf.session_timeout = a;
|
||||||
}
|
}
|
||||||
FREE(value);
|
FREE(value);
|
||||||
}
|
}
|
||||||
|
|
@ -583,19 +579,19 @@ int get_global_config(struct config *conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = uci_get_value(LW_NOTIFICATION_ENABLE, &value)) == CWMP_OK) {
|
if ((error = uci_get_value(LW_NOTIFICATION_ENABLE, &value)) == CWMP_OK) {
|
||||||
conf->lw_notification_enable = uci_str_to_bool(value);
|
cwmp_main->conf.lw_notification_enable = uci_str_to_bool(value);
|
||||||
FREE(value);
|
FREE(value);
|
||||||
} else {
|
} else {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = uci_get_value(LW_NOTIFICATION_HOSTNAME, &value)) == CWMP_OK) {
|
if ((error = uci_get_value(LW_NOTIFICATION_HOSTNAME, &value)) == CWMP_OK) {
|
||||||
FREE(conf->lw_notification_hostname);
|
FREE(cwmp_main->conf.lw_notification_hostname);
|
||||||
if (value != NULL) {
|
if (value != NULL) {
|
||||||
conf->lw_notification_hostname = strdup(value);
|
cwmp_main->conf.lw_notification_hostname = strdup(value);
|
||||||
FREE(value);
|
FREE(value);
|
||||||
} else {
|
} else {
|
||||||
conf->lw_notification_hostname = strdup(conf->acsurl ? conf->acsurl : "");
|
cwmp_main->conf.lw_notification_hostname = strdup(cwmp_main->conf.acsurl ? cwmp_main->conf.acsurl : "");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return error;
|
return error;
|
||||||
|
|
@ -604,10 +600,10 @@ int get_global_config(struct config *conf)
|
||||||
if ((error = uci_get_value(LW_NOTIFICATION_PORT, &value)) == CWMP_OK) {
|
if ((error = uci_get_value(LW_NOTIFICATION_PORT, &value)) == CWMP_OK) {
|
||||||
if (value != NULL) {
|
if (value != NULL) {
|
||||||
int a = atoi(value);
|
int a = atoi(value);
|
||||||
conf->lw_notification_port = a;
|
cwmp_main->conf.lw_notification_port = a;
|
||||||
FREE(value);
|
FREE(value);
|
||||||
} else {
|
} else {
|
||||||
conf->lw_notification_port = DEFAULT_LWN_PORT;
|
cwmp_main->conf.lw_notification_port = DEFAULT_LWN_PORT;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return error;
|
return error;
|
||||||
|
|
@ -615,10 +611,10 @@ int get_global_config(struct config *conf)
|
||||||
|
|
||||||
if (uci_get_value(UCI_CPE_SCHEDULE_REBOOT, &value) == CWMP_OK) {
|
if (uci_get_value(UCI_CPE_SCHEDULE_REBOOT, &value) == CWMP_OK) {
|
||||||
if (value != NULL) {
|
if (value != NULL) {
|
||||||
conf->schedule_reboot = convert_datetime_to_timestamp(value);
|
cwmp_main->conf.schedule_reboot = convert_datetime_to_timestamp(value);
|
||||||
FREE(value);
|
FREE(value);
|
||||||
} else {
|
} else {
|
||||||
conf->schedule_reboot = 0;
|
cwmp_main->conf.schedule_reboot = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return error;
|
return error;
|
||||||
|
|
@ -632,22 +628,22 @@ int get_global_config(struct config *conf)
|
||||||
FREE(value);
|
FREE(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
conf->delay_reboot = delay;
|
cwmp_main->conf.delay_reboot = delay;
|
||||||
} else {
|
} else {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
if (uci_get_value(UCI_CPE_JSON_CUSTOM_NOTIFY_FILE, &value) == CWMP_OK) {
|
if (uci_get_value(UCI_CPE_JSON_CUSTOM_NOTIFY_FILE, &value) == CWMP_OK) {
|
||||||
FREE(conf->custom_notify_json);
|
FREE(cwmp_main->conf.custom_notify_json);
|
||||||
if (value != NULL) {
|
if (value != NULL) {
|
||||||
conf->custom_notify_json = strdup(value);
|
cwmp_main->conf.custom_notify_json = strdup(value);
|
||||||
FREE(value);
|
FREE(value);
|
||||||
} else {
|
} else {
|
||||||
conf->custom_notify_json = NULL;
|
cwmp_main->conf.custom_notify_json = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = uci_get_value(UCI_ACS_HEARTBEAT_ENABLE, &value)) == CWMP_OK) {
|
if ((error = uci_get_value(UCI_ACS_HEARTBEAT_ENABLE, &value)) == CWMP_OK) {
|
||||||
conf->heart_beat_enable = uci_str_to_bool(value);
|
cwmp_main->conf.heart_beat_enable = uci_str_to_bool(value);
|
||||||
FREE(value);
|
FREE(value);
|
||||||
} else {
|
} else {
|
||||||
return error;
|
return error;
|
||||||
|
|
@ -660,17 +656,17 @@ int get_global_config(struct config *conf)
|
||||||
a = atoi(value);
|
a = atoi(value);
|
||||||
FREE(value);
|
FREE(value);
|
||||||
}
|
}
|
||||||
conf->heartbeat_interval = a;
|
cwmp_main->conf.heartbeat_interval = a;
|
||||||
} else {
|
} else {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = uci_get_value(UCI_ACS_HEARTBEAT_TIME, &value)) == CWMP_OK) {
|
if ((error = uci_get_value(UCI_ACS_HEARTBEAT_TIME, &value)) == CWMP_OK) {
|
||||||
if (value != NULL) {
|
if (value != NULL) {
|
||||||
conf->heart_time = convert_datetime_to_timestamp(value);
|
cwmp_main->conf.heart_time = convert_datetime_to_timestamp(value);
|
||||||
FREE(value);
|
FREE(value);
|
||||||
} else {
|
} else {
|
||||||
conf->heart_time = 0;
|
cwmp_main->conf.heart_time = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return error;
|
return error;
|
||||||
|
|
@ -678,20 +674,20 @@ int get_global_config(struct config *conf)
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int global_conf_init(struct cwmp *cwmp)
|
int global_conf_init()
|
||||||
{
|
{
|
||||||
int error = CWMP_OK;
|
int error = CWMP_OK;
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_config_load);
|
pthread_mutex_lock(&mutex_config_load);
|
||||||
|
|
||||||
if ((error = get_global_config(&(cwmp->conf)))) {
|
if ((error = get_global_config(&(cwmp_main->conf)))) {
|
||||||
cwmp->init_complete = false;
|
cwmp_main->init_complete = false;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
cwmp->init_complete = true;
|
cwmp_main->init_complete = true;
|
||||||
/* Launch reboot methods if needed */
|
/* Launch reboot methods if needed */
|
||||||
launch_reboot_methods(cwmp);
|
launch_reboot_methods();
|
||||||
|
|
||||||
end:
|
end:
|
||||||
pthread_mutex_unlock(&mutex_config_load);
|
pthread_mutex_unlock(&mutex_config_load);
|
||||||
|
|
@ -699,34 +695,34 @@ end:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cwmp_config_load(struct cwmp *cwmp)
|
void cwmp_config_load()
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
cwmp_uci_reinit();
|
cwmp_uci_reinit();
|
||||||
ret = global_conf_init(cwmp);
|
ret = global_conf_init();
|
||||||
while (ret != CWMP_OK && thread_end != true) {
|
while (ret != CWMP_OK && cwmp_stop != true) {
|
||||||
CWMP_LOG(DEBUG, "Error reading uci ret = %d", ret);
|
CWMP_LOG(DEBUG, "Error reading uci ret = %d", ret);
|
||||||
sleep(UCI_OPTION_READ_INTERVAL);
|
sleep(UCI_OPTION_READ_INTERVAL);
|
||||||
cwmp_uci_reinit();
|
cwmp_uci_reinit();
|
||||||
ret = global_conf_init(cwmp);
|
ret = global_conf_init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int cwmp_get_deviceid(struct cwmp *cwmp)
|
int cwmp_get_deviceid()
|
||||||
{
|
{
|
||||||
cwmp_get_leaf_value("Device.DeviceInfo.Manufacturer", &cwmp->deviceid.manufacturer);
|
cwmp_get_leaf_value("Device.DeviceInfo.Manufacturer", &cwmp_main->deviceid.manufacturer);
|
||||||
cwmp_get_leaf_value("Device.DeviceInfo.SerialNumber", &cwmp->deviceid.serialnumber);
|
cwmp_get_leaf_value("Device.DeviceInfo.SerialNumber", &cwmp_main->deviceid.serialnumber);
|
||||||
cwmp_get_leaf_value("Device.DeviceInfo.ProductClass", &cwmp->deviceid.productclass);
|
cwmp_get_leaf_value("Device.DeviceInfo.ProductClass", &cwmp_main->deviceid.productclass);
|
||||||
cwmp_get_leaf_value("Device.DeviceInfo.ManufacturerOUI", &cwmp->deviceid.oui);
|
cwmp_get_leaf_value("Device.DeviceInfo.ManufacturerOUI", &cwmp_main->deviceid.oui);
|
||||||
cwmp_get_leaf_value("Device.DeviceInfo.SoftwareVersion", &cwmp->deviceid.softwareversion);
|
cwmp_get_leaf_value("Device.DeviceInfo.SoftwareVersion", &cwmp_main->deviceid.softwareversion);
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cwmp_config_reload(struct cwmp *cwmp)
|
int cwmp_config_reload()
|
||||||
{
|
{
|
||||||
memset(&cwmp->env, 0, sizeof(struct env));
|
memset(&cwmp_main->env, 0, sizeof(struct env));
|
||||||
int err = global_conf_init(cwmp);
|
int err = global_conf_init();
|
||||||
if (err != CWMP_OK)
|
if (err != CWMP_OK)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
|
|
||||||
12
src/config.h
12
src/config.h
|
|
@ -17,10 +17,10 @@
|
||||||
|
|
||||||
extern pthread_mutex_t mutex_config_load;
|
extern pthread_mutex_t mutex_config_load;
|
||||||
|
|
||||||
int global_conf_init(struct cwmp *cwmp);
|
int global_conf_init();
|
||||||
int get_global_config(struct config *conf);
|
int get_global_config();
|
||||||
int cwmp_get_deviceid(struct cwmp *cwmp);
|
int cwmp_get_deviceid();
|
||||||
int cwmp_config_reload(struct cwmp *cwmp);
|
int cwmp_config_reload();
|
||||||
int get_preinit_config(struct config *conf);
|
int get_preinit_config();
|
||||||
void cwmp_config_load(struct cwmp *cwmp);
|
void cwmp_config_load();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
766
src/cwmp.c
766
src/cwmp.c
|
|
@ -39,40 +39,11 @@
|
||||||
#include "datamodel_interface.h"
|
#include "datamodel_interface.h"
|
||||||
#include "cwmp_du_state.h"
|
#include "cwmp_du_state.h"
|
||||||
#include "heartbeat.h"
|
#include "heartbeat.h"
|
||||||
|
#include "cwmp_http.h"
|
||||||
|
|
||||||
static pthread_t periodic_event_thread;
|
|
||||||
static pthread_t scheduleInform_thread;
|
|
||||||
static pthread_t change_du_state_thread;
|
|
||||||
static pthread_t download_thread;
|
|
||||||
static pthread_t schedule_download_thread;
|
|
||||||
static pthread_t apply_schedule_download_thread;
|
|
||||||
static pthread_t upload_thread;
|
|
||||||
static pthread_t ubus_thread;
|
|
||||||
static pthread_t http_cr_server_thread;
|
|
||||||
static pthread_t periodic_check_notify;
|
|
||||||
static pthread_t heart_beat_session_thread;
|
|
||||||
bool g_firewall_restart = false;
|
bool g_firewall_restart = false;
|
||||||
static struct ubus_context *ctx = NULL;
|
|
||||||
struct list_head intf_reset_list;
|
struct list_head intf_reset_list;
|
||||||
|
|
||||||
static void cwmp_invoke_intf_reset(char *path)
|
|
||||||
{
|
|
||||||
if (path == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
CWMP_LOG(INFO, "Reset interface: %s", path);
|
|
||||||
struct blob_buf b = { 0 };
|
|
||||||
memset(&b, 0, sizeof(struct blob_buf));
|
|
||||||
blob_buf_init(&b, 0);
|
|
||||||
bb_add_string(&b, "path", path);
|
|
||||||
bb_add_string(&b, "action", "Reset()");
|
|
||||||
|
|
||||||
icwmp_ubus_invoke(USP_OBJECT_NAME, "operate", b.head, NULL, NULL);
|
|
||||||
blob_buf_free(&b);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool interface_reset_req(char *param_name, char *value)
|
static bool interface_reset_req(char *param_name, char *value)
|
||||||
{
|
{
|
||||||
if (param_name == NULL || value == NULL)
|
if (param_name == NULL || value == NULL)
|
||||||
|
|
@ -121,475 +92,6 @@ void set_interface_reset_request(char *param_name, char *value)
|
||||||
list_add_tail(&node->list, &intf_reset_list);
|
list_add_tail(&node->list, &intf_reset_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cwmp_get_retry_interval(struct cwmp *cwmp, bool heart_beat)
|
|
||||||
{
|
|
||||||
unsigned int retry_count = 0;
|
|
||||||
double min = 0;
|
|
||||||
double max = 0;
|
|
||||||
int m = cwmp->conf.retry_min_wait_interval;
|
|
||||||
int k = cwmp->conf.retry_interval_multiplier;
|
|
||||||
int exp;
|
|
||||||
if (heart_beat)
|
|
||||||
exp = heart_beat_retry_count_session;
|
|
||||||
else
|
|
||||||
exp = cwmp->retry_count_session;
|
|
||||||
if (exp == 0)
|
|
||||||
return MAX_INT32;
|
|
||||||
if (exp > 10)
|
|
||||||
exp = 10;
|
|
||||||
min = pow(((double)k / 1000), (double)(exp - 1)) * m;
|
|
||||||
max = pow(((double)k / 1000), (double)exp) * m;
|
|
||||||
char *rand = generate_random_string(4);
|
|
||||||
if (rand) {
|
|
||||||
unsigned int dividend = (unsigned int)strtoul(rand, NULL, 16);
|
|
||||||
retry_count = dividend % ((unsigned int)max + 1 - (unsigned int)min) + (unsigned int)min;
|
|
||||||
free(rand);
|
|
||||||
}
|
|
||||||
return (retry_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cwmp_rpc_cpe_handle_message(struct session *session, struct rpc *rpc_cpe)
|
|
||||||
{
|
|
||||||
if (xml_prepare_msg_out(session))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (rpc_cpe_methods[rpc_cpe->type].handler(session, rpc_cpe))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (xml_set_cwmp_id_rpc_cpe(session))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cwmp_prepare_value_change(struct cwmp *cwmp)
|
|
||||||
{
|
|
||||||
struct event_container *event_container;
|
|
||||||
if (list_value_change.next == &(list_value_change))
|
|
||||||
return;
|
|
||||||
pthread_mutex_lock(&(cwmp->mutex_session_queue));
|
|
||||||
event_container = cwmp_add_event_container(cwmp, EVENT_IDX_4VALUE_CHANGE, "");
|
|
||||||
if (!event_container)
|
|
||||||
goto end;
|
|
||||||
pthread_mutex_lock(&(mutex_value_change));
|
|
||||||
list_splice_init(&(list_value_change), &(event_container->head_dm_parameter));
|
|
||||||
pthread_mutex_unlock(&(mutex_value_change));
|
|
||||||
cwmp_save_event_container(event_container);
|
|
||||||
|
|
||||||
end:
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_firewall_restart_state(char **state)
|
|
||||||
{
|
|
||||||
cwmp_uci_reinit();
|
|
||||||
return uci_get_state_value(UCI_CPE_FIREWALL_RESTART_STATE, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait till firewall restart is not complete or 5 sec, whichever is less
|
|
||||||
void check_firewall_restart_state()
|
|
||||||
{
|
|
||||||
int count = 0;
|
|
||||||
bool init = false;
|
|
||||||
|
|
||||||
do {
|
|
||||||
char *state = NULL;
|
|
||||||
|
|
||||||
if (get_firewall_restart_state(&state) != CWMP_OK)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (state != NULL && strcmp(state, "init") == 0) {
|
|
||||||
init = true;
|
|
||||||
FREE(state);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
usleep(500 * 1000);
|
|
||||||
FREE(state);
|
|
||||||
count++;
|
|
||||||
} while(count < 10);
|
|
||||||
|
|
||||||
// mark the firewall restart as done
|
|
||||||
g_firewall_restart = false;
|
|
||||||
if (init == false) { // In case of timeout reset the firewall_restart flag
|
|
||||||
CWMP_LOG(ERROR, "Firewall restart took longer than usual");
|
|
||||||
cwmp_uci_set_varstate_value("cwmp", "cpe", "firewall_restart", "init");
|
|
||||||
cwmp_commit_package("cwmp", UCI_VARSTATE_CONFIG);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int cwmp_schedule_rpc(struct cwmp *cwmp, struct session *session)
|
|
||||||
{
|
|
||||||
struct list_head *ilist;
|
|
||||||
struct rpc *rpc_acs, *rpc_cpe;
|
|
||||||
|
|
||||||
if (icwmp_http_client_init(cwmp) || thread_end) {
|
|
||||||
CWMP_LOG(INFO, "Initializing http client failed");
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
list_for_each (ilist, &(session->head_rpc_acs)) {
|
|
||||||
rpc_acs = list_entry(ilist, struct rpc, list);
|
|
||||||
if ((rpc_acs->type != RPC_ACS_INFORM) && (rpc_acs_methods[rpc_acs->type].acs_support == RPC_ACS_NOT_SUPPORT)) {
|
|
||||||
CWMP_LOG(WARNING, "The RPC method %s is not included in the RPCs list supported by the ACS", rpc_acs_methods[rpc_acs->type].name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!rpc_acs->type || thread_end)
|
|
||||||
goto retry;
|
|
||||||
|
|
||||||
CWMP_LOG(INFO, "Preparing the %s RPC message to send to the ACS", rpc_acs_methods[rpc_acs->type].name);
|
|
||||||
if (rpc_acs_methods[rpc_acs->type].prepare_message(cwmp, session, rpc_acs) || thread_end)
|
|
||||||
goto retry;
|
|
||||||
|
|
||||||
if (xml_set_cwmp_id(session) || thread_end)
|
|
||||||
goto retry;
|
|
||||||
|
|
||||||
CWMP_LOG(INFO, "Send the %s RPC message to the ACS", rpc_acs_methods[rpc_acs->type].name);
|
|
||||||
if (xml_send_message(cwmp, session, rpc_acs) || thread_end)
|
|
||||||
goto retry;
|
|
||||||
|
|
||||||
CWMP_LOG(INFO, "Get the %sResponse message from the ACS", rpc_acs_methods[rpc_acs->type].name);
|
|
||||||
if (rpc_acs_methods[rpc_acs->type].parse_response || thread_end)
|
|
||||||
if (rpc_acs_methods[rpc_acs->type].parse_response(cwmp, session, rpc_acs))
|
|
||||||
goto retry;
|
|
||||||
|
|
||||||
ilist = ilist->prev;
|
|
||||||
if (rpc_acs_methods[rpc_acs->type].extra_clean != NULL)
|
|
||||||
rpc_acs_methods[rpc_acs->type].extra_clean(session, rpc_acs);
|
|
||||||
cwmp_session_rpc_destructor(rpc_acs);
|
|
||||||
MXML_DELETE(session->tree_in);
|
|
||||||
MXML_DELETE(session->tree_out);
|
|
||||||
if (session->hold_request || thread_end)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If restart service caused firewall restart, wait for firewall restart to complete
|
|
||||||
if (g_firewall_restart == true)
|
|
||||||
check_firewall_restart_state();
|
|
||||||
|
|
||||||
CWMP_LOG(INFO, "Send empty message to the ACS");
|
|
||||||
if (xml_send_message(cwmp, session, NULL) || thread_end)
|
|
||||||
goto retry;
|
|
||||||
if (!session->tree_in || thread_end)
|
|
||||||
goto next;
|
|
||||||
|
|
||||||
CWMP_LOG(INFO, "Receive request from the ACS");
|
|
||||||
if (xml_handle_message(session) || thread_end)
|
|
||||||
goto retry;
|
|
||||||
|
|
||||||
while (session->head_rpc_cpe.next != &(session->head_rpc_cpe)) {
|
|
||||||
rpc_cpe = list_entry(session->head_rpc_cpe.next, struct rpc, list);
|
|
||||||
if (!rpc_cpe->type || thread_end)
|
|
||||||
goto retry;
|
|
||||||
|
|
||||||
CWMP_LOG(INFO, "Preparing the %s%s message", rpc_cpe_methods[rpc_cpe->type].name, (rpc_cpe->type != RPC_CPE_FAULT) ? "Response" : "");
|
|
||||||
if (cwmp_rpc_cpe_handle_message(session, rpc_cpe) || thread_end)
|
|
||||||
goto retry;
|
|
||||||
MXML_DELETE(session->tree_in);
|
|
||||||
|
|
||||||
CWMP_LOG(INFO, "Send the %s%s message to the ACS", rpc_cpe_methods[rpc_cpe->type].name, (rpc_cpe->type != RPC_CPE_FAULT) ? "Response" : "");
|
|
||||||
if (xml_send_message(cwmp, session, rpc_cpe) || thread_end)
|
|
||||||
goto retry;
|
|
||||||
MXML_DELETE(session->tree_out);
|
|
||||||
|
|
||||||
cwmp_session_rpc_destructor(rpc_cpe);
|
|
||||||
if (!session->tree_in || thread_end)
|
|
||||||
break;
|
|
||||||
|
|
||||||
CWMP_LOG(INFO, "Receive request from the ACS");
|
|
||||||
if (xml_handle_message(session) || thread_end)
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
|
|
||||||
next:
|
|
||||||
if (session->head_rpc_acs.next == &(session->head_rpc_acs))
|
|
||||||
break;
|
|
||||||
MXML_DELETE(session->tree_in);
|
|
||||||
MXML_DELETE(session->tree_out);
|
|
||||||
}
|
|
||||||
|
|
||||||
session->error = CWMP_OK;
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
retry:
|
|
||||||
CWMP_LOG(INFO, "Failed");
|
|
||||||
session->error = CWMP_RETRY_SESSION;
|
|
||||||
event_remove_noretry_event_container(session, cwmp);
|
|
||||||
|
|
||||||
end:
|
|
||||||
MXML_DELETE(session->tree_in);
|
|
||||||
MXML_DELETE(session->tree_out);
|
|
||||||
icwmp_http_client_exit();
|
|
||||||
xml_exit();
|
|
||||||
return session->error;
|
|
||||||
}
|
|
||||||
|
|
||||||
int run_session_end_func(void)
|
|
||||||
{
|
|
||||||
if (end_session_flag & END_SESSION_RESTART_SERVICES) {
|
|
||||||
CWMP_LOG(INFO, "Restart modified services");
|
|
||||||
icwmp_restart_services();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end_session_flag & END_SESSION_RELOAD) {
|
|
||||||
CWMP_LOG(INFO, "Config reload: end session request");
|
|
||||||
cwmp_uci_reinit();
|
|
||||||
if (cwmp_apply_acs_changes() != CWMP_OK) {
|
|
||||||
CWMP_LOG(ERROR, "config reload failed at session end");
|
|
||||||
}
|
|
||||||
check_trigger_heartbeat_session();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end_session_flag & END_SESSION_INIT_NOTIFY) {
|
|
||||||
CWMP_LOG(INFO, "SetParameterAttributes end session: reinit list notify");
|
|
||||||
reinit_list_param_notify();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end_session_flag & END_SESSION_SET_NOTIFICATION_UPDATE) {
|
|
||||||
CWMP_LOG(INFO, "SetParameterAttributes/Values end session: update enabled notify file");
|
|
||||||
cwmp_update_enabled_notify_file();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end_session_flag & END_SESSION_NSLOOKUP_DIAGNOSTIC) {
|
|
||||||
CWMP_LOG(INFO, "Executing nslookupdiagnostic: end session request");
|
|
||||||
cwmp_nslookup_diagnostics();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end_session_flag & END_SESSION_TRACEROUTE_DIAGNOSTIC) {
|
|
||||||
CWMP_LOG(INFO, "Executing traceroutediagnostic: end session request");
|
|
||||||
cwmp_traceroute_diagnostics();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end_session_flag & END_SESSION_UDPECHO_DIAGNOSTIC) {
|
|
||||||
CWMP_LOG(INFO, "Executing udpechodiagnostic: end session request");
|
|
||||||
cwmp_udp_echo_diagnostics();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end_session_flag & END_SESSION_SERVERSELECTION_DIAGNOSTIC) {
|
|
||||||
CWMP_LOG(INFO, "Executing serverselectiondiagnostic: end session request");
|
|
||||||
cwmp_serverselection_diagnostics();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end_session_flag & END_SESSION_IPPING_DIAGNOSTIC) {
|
|
||||||
CWMP_LOG(INFO, "Executing ippingdiagnostic: end session request");
|
|
||||||
cwmp_ip_ping_diagnostics();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end_session_flag & END_SESSION_DOWNLOAD_DIAGNOSTIC) {
|
|
||||||
CWMP_LOG(INFO, "Executing download diagnostic: end session request");
|
|
||||||
cwmp_download_diagnostics();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end_session_flag & END_SESSION_UPLOAD_DIAGNOSTIC) {
|
|
||||||
CWMP_LOG(INFO, "Executing upload diagnostic: end session request");
|
|
||||||
cwmp_upload_diagnostics();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end_session_flag & END_SESSION_REBOOT) {
|
|
||||||
CWMP_LOG(INFO, "Executing Reboot: end session request");
|
|
||||||
cwmp_reboot(commandKey);
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end_session_flag & END_SESSION_FACTORY_RESET) {
|
|
||||||
CWMP_LOG(INFO, "Executing factory reset: end session request");
|
|
||||||
cwmp_factory_reset();
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end_session_flag & END_SESSION_X_FACTORY_RESET_SOFT) {
|
|
||||||
CWMP_LOG(INFO, "Executing factory reset soft: end session request");
|
|
||||||
cwmp_factory_reset();
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if any interface reset request exists then take action
|
|
||||||
intf_reset_node *iter = NULL, *node = NULL;
|
|
||||||
list_for_each_entry_safe(iter, node, &intf_reset_list, list) {
|
|
||||||
CWMP_LOG(INFO, "Executing interface reset: end session request");
|
|
||||||
cwmp_invoke_intf_reset(iter->path);
|
|
||||||
list_del(&iter->list);
|
|
||||||
free(iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&intf_reset_list);
|
|
||||||
|
|
||||||
cwmp_uci_exit();
|
|
||||||
icwmp_cleanmem();
|
|
||||||
end_session_flag = 0;
|
|
||||||
return CWMP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cwmp_schedule_session(struct cwmp *cwmp)
|
|
||||||
{
|
|
||||||
int t;
|
|
||||||
struct timespec time_to_wait = { 0, 0 };
|
|
||||||
bool retry = false;
|
|
||||||
char *exec_download = NULL;
|
|
||||||
int is_notify = 0;
|
|
||||||
|
|
||||||
cwmp->cwmp_cr_event = 0;
|
|
||||||
while (1) {
|
|
||||||
struct list_head *ilist;
|
|
||||||
struct session *session;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&(cwmp->mutex_session_send));
|
|
||||||
ilist = (&(cwmp->head_session_queue))->next;
|
|
||||||
while ((ilist == &(cwmp->head_session_queue)) || retry) {
|
|
||||||
t = cwmp_get_retry_interval(cwmp, 0);
|
|
||||||
time_to_wait.tv_sec = time(NULL) + t;
|
|
||||||
CWMP_LOG(INFO, "Waiting the next session");
|
|
||||||
|
|
||||||
if (thread_end) {
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_send));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_cond_timedwait(&(cwmp->threshold_session_send), &(cwmp->mutex_session_send), &time_to_wait);
|
|
||||||
|
|
||||||
if (thread_end) {
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_send));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ilist = (&(cwmp->head_session_queue))->next;
|
|
||||||
retry = false;
|
|
||||||
}
|
|
||||||
pthread_mutex_lock(&mutex_heartbeat_session);
|
|
||||||
if (cwmp->session_status.last_status == SESSION_FAILURE) {
|
|
||||||
cwmp_config_load(cwmp);
|
|
||||||
if (thread_end) {
|
|
||||||
pthread_mutex_unlock(&mutex_heartbeat_session);
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_send));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
session = list_entry(ilist, struct session, list);
|
|
||||||
if (file_exists(DM_ENABLED_NOTIFY)) {
|
|
||||||
if (!event_exist_in_list(cwmp, EVENT_IDX_4VALUE_CHANGE))
|
|
||||||
is_notify = check_value_change();
|
|
||||||
}
|
|
||||||
if (is_notify > 0 || !file_exists(DM_ENABLED_NOTIFY) || cwmp->custom_notify_active) {
|
|
||||||
cwmp->custom_notify_active = false;
|
|
||||||
cwmp_update_enabled_notify_file();
|
|
||||||
}
|
|
||||||
cwmp_prepare_value_change(cwmp);
|
|
||||||
clean_list_value_change();
|
|
||||||
if ((error = cwmp_move_session_to_session_send(cwmp, session))) {
|
|
||||||
CWMP_LOG(EMERG, "FATAL error in the mutex process in the session scheduler!");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
cwmp->session_status.last_end_time = 0;
|
|
||||||
cwmp->session_status.last_start_time = time(NULL);
|
|
||||||
cwmp->session_status.last_status = SESSION_RUNNING;
|
|
||||||
cwmp->session_status.next_retry = 0;
|
|
||||||
|
|
||||||
if (file_exists(fc_cookies))
|
|
||||||
remove(fc_cookies);
|
|
||||||
cwmp_uci_init();
|
|
||||||
CWMP_LOG(INFO, "Start session");
|
|
||||||
|
|
||||||
uci_get_value(UCI_CPE_EXEC_DOWNLOAD, &exec_download);
|
|
||||||
if (exec_download && strcmp(exec_download, "1") == 0) {
|
|
||||||
CWMP_LOG(INFO, "Firmware downloaded and applied successfully");
|
|
||||||
cwmp_uci_set_value("cwmp", "cpe", "exec_download", "0");
|
|
||||||
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
|
|
||||||
}
|
|
||||||
FREE(exec_download);
|
|
||||||
error = cwmp_schedule_rpc(cwmp, session);
|
|
||||||
CWMP_LOG(INFO, "End session");
|
|
||||||
cwmp_uci_exit();
|
|
||||||
|
|
||||||
if (thread_end) {
|
|
||||||
event_remove_all_event_container(session, RPC_SEND);
|
|
||||||
run_session_end_func();
|
|
||||||
cwmp_session_destructor(session);
|
|
||||||
pthread_mutex_unlock(&mutex_heartbeat_session);
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_send));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (session->error == CWMP_RETRY_SESSION && (!list_empty(&(session->head_event_container)) || (list_empty(&(session->head_event_container)) && cwmp->cwmp_cr_event == 0))) {
|
|
||||||
cwmp_config_load(cwmp);
|
|
||||||
if (thread_end) {
|
|
||||||
event_remove_all_event_container(session, RPC_SEND);
|
|
||||||
run_session_end_func();
|
|
||||||
cwmp_session_destructor(session);
|
|
||||||
pthread_mutex_unlock(&mutex_heartbeat_session);
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_send));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
run_session_end_func();
|
|
||||||
error = cwmp_move_session_to_session_queue(cwmp, session);
|
|
||||||
CWMP_LOG(INFO, "Retry session, retry count = %d, retry in %ds", cwmp->retry_count_session, cwmp_get_retry_interval(cwmp, 0));
|
|
||||||
retry = true;
|
|
||||||
cwmp->session_status.last_end_time = time(NULL);
|
|
||||||
cwmp->session_status.last_status = SESSION_FAILURE;
|
|
||||||
cwmp->session_status.next_retry = time(NULL) + cwmp_get_retry_interval(cwmp, 0);
|
|
||||||
cwmp->session_status.failure_session++;
|
|
||||||
pthread_mutex_unlock(&mutex_heartbeat_session);
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_send));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
event_remove_all_event_container(session, RPC_SEND);
|
|
||||||
run_session_end_func();
|
|
||||||
cwmp_session_destructor(session);
|
|
||||||
cwmp->session_send = NULL;
|
|
||||||
cwmp->retry_count_session = 0;
|
|
||||||
cwmp->session_status.last_end_time = time(NULL);
|
|
||||||
cwmp->session_status.last_status = SESSION_SUCCESS;
|
|
||||||
cwmp->session_status.next_retry = 0;
|
|
||||||
cwmp->session_status.success_session++;
|
|
||||||
pthread_cond_signal(&threasheld_retry_session);
|
|
||||||
pthread_mutex_unlock(&mutex_heartbeat_session);
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_send));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void check_exit_timer_expiry(struct uloop_timeout *timeout)
|
|
||||||
{
|
|
||||||
if (thread_end == true) {
|
|
||||||
uloop_end();
|
|
||||||
}
|
|
||||||
|
|
||||||
uloop_timeout_set(timeout, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *thread_uloop_run(void *v __attribute__((unused)))
|
|
||||||
{
|
|
||||||
uloop_init();
|
|
||||||
|
|
||||||
ctx = ubus_connect(cwmp_main.conf.ubus_socket);
|
|
||||||
if (!ctx)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
ubus_add_uloop(ctx);
|
|
||||||
|
|
||||||
if (icwmp_register_object(ctx))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
struct uloop_timeout tm;
|
|
||||||
memset(&tm, 0, sizeof(tm));
|
|
||||||
tm.cb = check_exit_timer_expiry;
|
|
||||||
uloop_timeout_set(&tm, 1);
|
|
||||||
|
|
||||||
uloop_run();
|
|
||||||
uloop_done();
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *thread_http_cr_server_listen(void *v __attribute__((unused)))
|
|
||||||
{
|
|
||||||
icwmp_http_server_listen();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int create_cwmp_var_state_files()
|
int create_cwmp_var_state_files()
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
@ -693,19 +195,30 @@ end:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cwmp_init(struct cwmp *cwmp)
|
static int cwmp_init()
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
openlog("cwmp", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
|
||||||
|
CWMP_LOG(INFO, "STARTING ICWMP with PID :%d", getpid());
|
||||||
|
/* This is to initialize the global context in mxml,
|
||||||
|
* with out init mxml sometimes segfaults, when calling the destructor.
|
||||||
|
*/
|
||||||
|
mxml_error(NULL);
|
||||||
|
|
||||||
|
cwmp_main = (struct cwmp*)calloc(1, sizeof(struct cwmp));
|
||||||
|
cwmp_main->init_complete = false;
|
||||||
|
error = get_preinit_config();
|
||||||
|
if (error) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
icwmp_init_list_services();
|
icwmp_init_list_services();
|
||||||
cwmp->event_id = 0;
|
|
||||||
cwmp->cwmp_period = 0;
|
|
||||||
cwmp->cwmp_periodic_time = 0;
|
|
||||||
cwmp->cwmp_periodic_enable = false;
|
|
||||||
/* Only One instance should run*/
|
/* Only One instance should run*/
|
||||||
cwmp->pid_file = fopen("/var/run/icwmpd.pid", "w+");
|
cwmp_main->pid_file = fopen("/var/run/icwmpd.pid", "w+");
|
||||||
fcntl(fileno(cwmp->pid_file), F_SETFD, fcntl(fileno(cwmp->pid_file), F_GETFD) | FD_CLOEXEC);
|
fcntl(fileno(cwmp_main->pid_file), F_SETFD, fcntl(fileno(cwmp_main->pid_file), F_GETFD) | FD_CLOEXEC);
|
||||||
int rc = flock(fileno(cwmp->pid_file), LOCK_EX | LOCK_NB);
|
int rc = flock(fileno(cwmp_main->pid_file), LOCK_EX | LOCK_NB);
|
||||||
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
if (EWOULDBLOCK != errno) {
|
if (EWOULDBLOCK != errno) {
|
||||||
char *piderr = "PID file creation failed: Quit the daemon!";
|
char *piderr = "PID file creation failed: Quit the daemon!";
|
||||||
|
|
@ -715,95 +228,96 @@ static int cwmp_init(struct cwmp *cwmp)
|
||||||
} else
|
} else
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
if (cwmp->pid_file)
|
if (cwmp_main->pid_file)
|
||||||
fclose(cwmp->pid_file);
|
fclose(cwmp_main->pid_file);
|
||||||
|
|
||||||
pthread_mutex_init(&cwmp->mutex_periodic, NULL);
|
|
||||||
pthread_mutex_init(&cwmp->mutex_session_queue, NULL);
|
|
||||||
pthread_mutex_init(&cwmp->mutex_session_send, NULL);
|
|
||||||
pthread_mutex_init(&mutex_heartbeat_session, NULL);
|
|
||||||
pthread_mutex_init(&mutex_heartbeat, NULL);
|
|
||||||
INIT_LIST_HEAD(&(cwmp->head_session_queue));
|
|
||||||
|
|
||||||
if ((error = create_cwmp_var_state_files()))
|
if ((error = create_cwmp_var_state_files()))
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
CWMP_LOG(DEBUG, "Loading icwmpd configuration");
|
CWMP_LOG(DEBUG, "Loading icwmpd configuration");
|
||||||
cwmp_config_load(cwmp);
|
cwmp_config_load();
|
||||||
|
|
||||||
if (thread_end == true)
|
cwmp_main->prev_periodic_enable = cwmp_main->conf.periodic_enable;
|
||||||
|
cwmp_main->prev_periodic_interval = cwmp_main->conf.period;
|
||||||
|
cwmp_main->prev_periodic_time = cwmp_main->conf.time;
|
||||||
|
cwmp_main->prev_heartbeat_enable = cwmp_main->conf.heart_beat_enable;
|
||||||
|
cwmp_main->prev_heartbeat_interval = cwmp_main->conf.heartbeat_interval;
|
||||||
|
cwmp_main->prev_heartbeat_time = cwmp_main->conf.heart_time;
|
||||||
|
cwmp_main->heart_session = false;
|
||||||
|
cwmp_main->diag_session = false;
|
||||||
|
if (cwmp_stop == true)
|
||||||
return CWMP_GEN_ERR;
|
return CWMP_GEN_ERR;
|
||||||
|
|
||||||
CWMP_LOG(DEBUG, "Successfully load icwmpd configuration");
|
CWMP_LOG(DEBUG, "Successfully load icwmpd configuration");
|
||||||
cwmp_get_deviceid(cwmp);
|
cwmp_get_deviceid();
|
||||||
load_custom_notify_json(cwmp);
|
load_custom_notify_json();
|
||||||
init_list_param_notify();
|
init_list_param_notify();
|
||||||
|
create_cwmp_session_structure();
|
||||||
get_nonce_key();
|
get_nonce_key();
|
||||||
memset(&intf_reset_list, 0, sizeof(struct list_head));
|
memset(&intf_reset_list, 0, sizeof(struct list_head));
|
||||||
INIT_LIST_HEAD(&intf_reset_list);
|
INIT_LIST_HEAD(&intf_reset_list);
|
||||||
|
cwmp_main->start_time = time(NULL);
|
||||||
|
cwmp_main->event_id = 0;
|
||||||
|
cwmp_main->cwmp_period = 0;
|
||||||
|
cwmp_main->cwmp_periodic_time = 0;
|
||||||
|
cwmp_main->cwmp_periodic_enable = false;
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cwmp_free(struct cwmp *cwmp)
|
static void cwmp_free()
|
||||||
{
|
{
|
||||||
FREE(cwmp->deviceid.manufacturer);
|
http_server_stop();
|
||||||
FREE(cwmp->deviceid.serialnumber);
|
FREE(cwmp_main->deviceid.manufacturer);
|
||||||
FREE(cwmp->deviceid.productclass);
|
FREE(cwmp_main->deviceid.serialnumber);
|
||||||
FREE(cwmp->deviceid.oui);
|
FREE(cwmp_main->deviceid.productclass);
|
||||||
FREE(cwmp->deviceid.softwareversion);
|
FREE(cwmp_main->deviceid.oui);
|
||||||
FREE(cwmp->conf.lw_notification_hostname);
|
FREE(cwmp_main->deviceid.softwareversion);
|
||||||
FREE(cwmp->conf.ip);
|
FREE(cwmp_main->conf.lw_notification_hostname);
|
||||||
FREE(cwmp->conf.ipv6);
|
FREE(cwmp_main->conf.ip);
|
||||||
FREE(cwmp->conf.acsurl);
|
FREE(cwmp_main->conf.ipv6);
|
||||||
FREE(cwmp->conf.acs_userid);
|
FREE(cwmp_main->conf.acsurl);
|
||||||
FREE(cwmp->conf.acs_passwd);
|
FREE(cwmp_main->conf.acs_userid);
|
||||||
FREE(cwmp->conf.interface);
|
FREE(cwmp_main->conf.acs_passwd);
|
||||||
FREE(cwmp->conf.cpe_userid);
|
FREE(cwmp_main->conf.interface);
|
||||||
FREE(cwmp->conf.cpe_passwd);
|
FREE(cwmp_main->conf.cpe_userid);
|
||||||
FREE(cwmp->conf.ubus_socket);
|
FREE(cwmp_main->conf.cpe_passwd);
|
||||||
FREE(cwmp->conf.connection_request_path);
|
FREE(cwmp_main->conf.ubus_socket);
|
||||||
FREE(cwmp->conf.default_wan_iface);
|
FREE(cwmp_main->conf.connection_request_path);
|
||||||
FREE(cwmp->conf.custom_notify_json);
|
FREE(cwmp_main->conf.default_wan_iface);
|
||||||
|
FREE(cwmp_main->conf.custom_notify_json);
|
||||||
FREE(nonce_key);
|
FREE(nonce_key);
|
||||||
clean_list_param_notify();
|
clean_list_param_notify();
|
||||||
bkp_tree_clean();
|
bkp_tree_clean();
|
||||||
|
icwmp_uloop_ubus_exit();
|
||||||
if (ctx) {
|
|
||||||
icwmp_delete_object(ctx);
|
|
||||||
ubus_free(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
icwmp_cleanmem();
|
icwmp_cleanmem();
|
||||||
cwmp_uci_exit();
|
cwmp_uci_exit();
|
||||||
|
rpc_exit();
|
||||||
|
clean_cwmp_session_structure();
|
||||||
|
FREE(cwmp_main);
|
||||||
|
CWMP_LOG(INFO, "EXIT ICWMP");
|
||||||
|
closelog();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void icwmp_signal_handler(int signal_num)
|
void cwmp_exit()
|
||||||
{
|
{
|
||||||
if (signal_num == SIGINT || signal_num == SIGTERM) {
|
cwmp_stop = true;
|
||||||
thread_end = true;
|
|
||||||
|
|
||||||
CWMP_LOG(INFO, "Received signal %d", signal_num);
|
if (cwmp_main->session->session_status.last_status == SESSION_RUNNING)
|
||||||
|
http_set_timeout();
|
||||||
|
|
||||||
if (cwmp_main.session_status.last_status == SESSION_RUNNING)
|
uloop_timeout_cancel(&retry_session_timer);
|
||||||
http_set_timeout();
|
uloop_timeout_cancel(&periodic_session_timer);
|
||||||
|
uloop_timeout_cancel(&session_timer);
|
||||||
|
uloop_timeout_cancel(&heartbeat_session_timer);
|
||||||
|
uloop_end();
|
||||||
|
shutdown(cwmp_main->cr_socket_desc, SHUT_RDWR);
|
||||||
|
FREE(global_session_event);
|
||||||
|
|
||||||
pthread_cond_signal(&(cwmp_main.threshold_session_send));
|
/* Free all memory allocation */
|
||||||
pthread_cond_signal(&(cwmp_main.threshold_periodic));
|
cwmp_free();
|
||||||
pthread_cond_signal(&(cwmp_main.threshold_notify_periodic));
|
|
||||||
pthread_cond_signal(&threshold_schedule_inform);
|
|
||||||
pthread_cond_signal(&threshold_download);
|
|
||||||
pthread_cond_signal(&threshold_change_du_state);
|
|
||||||
pthread_cond_signal(&threshold_schedule_download);
|
|
||||||
pthread_cond_signal(&threshold_apply_schedule_download);
|
|
||||||
pthread_cond_signal(&threshold_upload);
|
|
||||||
pthread_cond_signal(&threshold_heartbeat_session);
|
|
||||||
pthread_cond_signal(&threasheld_retry_session);
|
|
||||||
|
|
||||||
shutdown(cwmp_main.cr_socket_desc, SHUT_RDWR);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void configure_var_state(struct cwmp *cwmp)
|
static void configure_var_state()
|
||||||
{
|
{
|
||||||
char *zone_name = NULL;
|
char *zone_name = NULL;
|
||||||
|
|
||||||
|
|
@ -814,7 +328,7 @@ static void configure_var_state(struct cwmp *cwmp)
|
||||||
cwmp_uci_add_section_with_specific_name("cwmp", "acs", "acs", UCI_VARSTATE_CONFIG);
|
cwmp_uci_add_section_with_specific_name("cwmp", "acs", "acs", UCI_VARSTATE_CONFIG);
|
||||||
cwmp_uci_add_section_with_specific_name("cwmp", "cpe", "cpe", UCI_VARSTATE_CONFIG);
|
cwmp_uci_add_section_with_specific_name("cwmp", "cpe", "cpe", UCI_VARSTATE_CONFIG);
|
||||||
|
|
||||||
get_firewall_zone_name_by_wan_iface(cwmp->conf.default_wan_iface, &zone_name);
|
get_firewall_zone_name_by_wan_iface(cwmp_main->conf.default_wan_iface, &zone_name);
|
||||||
cwmp_uci_set_varstate_value("cwmp", "acs", "zonename", zone_name ? zone_name : "wan");
|
cwmp_uci_set_varstate_value("cwmp", "acs", "zonename", zone_name ? zone_name : "wan");
|
||||||
|
|
||||||
cwmp_commit_package("cwmp", UCI_VARSTATE_CONFIG);
|
cwmp_commit_package("cwmp", UCI_VARSTATE_CONFIG);
|
||||||
|
|
@ -822,133 +336,47 @@ static void configure_var_state(struct cwmp *cwmp)
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct sigaction act;
|
|
||||||
int error;
|
int error;
|
||||||
struct env env;
|
struct env env;
|
||||||
|
|
||||||
memset(&cwmp_main, 0, sizeof(struct cwmp));
|
|
||||||
openlog("cwmp", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
|
|
||||||
|
|
||||||
/* This is to initialize the global context in mxml,
|
|
||||||
* with out init mxml sometimes segfaults, when calling the destructor.
|
|
||||||
*/
|
|
||||||
mxml_error(NULL);
|
|
||||||
|
|
||||||
cwmp_main.init_complete = false;
|
|
||||||
|
|
||||||
error = wait_for_usp_raw_object();
|
error = wait_for_usp_raw_object();
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
if ((error = cwmp_init()))
|
||||||
|
return error;
|
||||||
|
|
||||||
memset(&env, 0, sizeof(struct env));
|
memset(&env, 0, sizeof(struct env));
|
||||||
if ((error = global_env_init(argc, argv, &env)))
|
if ((error = global_env_init(argc, argv, &env)))
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
memcpy(&(cwmp_main.env), &env, sizeof(struct env));
|
memcpy(&(cwmp_main->env), &env, sizeof(struct env));
|
||||||
|
|
||||||
error = get_preinit_config(&(cwmp_main.conf));
|
if ((error = cwmp_init_backup_session(NULL, ALL)))
|
||||||
if (error) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = pthread_create(&ubus_thread, NULL, &thread_uloop_run, NULL);
|
|
||||||
if (error < 0) {
|
|
||||||
CWMP_LOG(ERROR, "Error when creating the ubus thread!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((error = cwmp_init(&cwmp_main))) {
|
|
||||||
thread_end = true;
|
|
||||||
pthread_join(ubus_thread, NULL);
|
|
||||||
cwmp_free(&cwmp_main);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
CWMP_LOG(INFO, "STARTING ICWMP with PID :%d", getpid());
|
|
||||||
cwmp_main.start_time = time(NULL);
|
|
||||||
|
|
||||||
if ((error = cwmp_init_backup_session(&cwmp_main, NULL, ALL)))
|
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
if ((error = cwmp_root_cause_events(&cwmp_main)))
|
if ((error = cwmp_root_cause_events()))
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
configure_var_state(&cwmp_main);
|
configure_var_state();
|
||||||
icwmp_http_server_init();
|
icwmp_http_server_init();
|
||||||
|
|
||||||
memset(&act, 0, sizeof(act));
|
uloop_init();
|
||||||
act.sa_handler = icwmp_signal_handler;
|
|
||||||
sigaction(SIGINT, &act, 0);
|
|
||||||
sigaction(SIGTERM, &act, 0);
|
|
||||||
|
|
||||||
error = pthread_create(&http_cr_server_thread, NULL, &thread_http_cr_server_listen, NULL);
|
icwmp_uloop_ubus_init();
|
||||||
if (error < 0) {
|
|
||||||
CWMP_LOG(ERROR, "Error when creating the http connection request server thread!");
|
|
||||||
}
|
|
||||||
|
|
||||||
error = pthread_create(&periodic_event_thread, NULL, &thread_event_periodic, (void *)&cwmp_main);
|
trigger_cwmp_session_timer();
|
||||||
if (error < 0) {
|
|
||||||
CWMP_LOG(ERROR, "Error when creating the periodic event thread!");
|
|
||||||
}
|
|
||||||
|
|
||||||
error = pthread_create(&periodic_check_notify, NULL, &thread_periodic_check_notify, (void *)&cwmp_main);
|
intiate_heartbeat_procedures();
|
||||||
if (error < 0) {
|
|
||||||
CWMP_LOG(ERROR, "Error when creating the periodic check notify thread!");
|
|
||||||
}
|
|
||||||
|
|
||||||
error = pthread_create(&heart_beat_session_thread, NULL, &thread_heartbeat_session, (void *)&cwmp_main);
|
initiate_cwmp_periodic_session_feature();
|
||||||
if (error < 0) {
|
|
||||||
CWMP_LOG(ERROR, "Error when creating heartbeat session thread!");
|
|
||||||
}
|
|
||||||
|
|
||||||
error = pthread_create(&scheduleInform_thread, NULL, &thread_cwmp_rpc_cpe_scheduleInform, (void *)&cwmp_main);
|
http_server_start();
|
||||||
if (error < 0) {
|
|
||||||
CWMP_LOG(ERROR, "Error when creating the scheduled inform thread!");
|
|
||||||
}
|
|
||||||
|
|
||||||
error = pthread_create(&download_thread, NULL, &thread_cwmp_rpc_cpe_download, (void *)&cwmp_main);
|
uloop_run();
|
||||||
if (error < 0) {
|
uloop_done();
|
||||||
CWMP_LOG(ERROR, "Error when creating the download thread!");
|
|
||||||
}
|
|
||||||
|
|
||||||
error = pthread_create(&change_du_state_thread, NULL, &thread_cwmp_rpc_cpe_change_du_state, (void *)&cwmp_main);
|
cwmp_exit();
|
||||||
if (error < 0) {
|
|
||||||
CWMP_LOG(ERROR, "Error when creating the state change thread!");
|
|
||||||
}
|
|
||||||
|
|
||||||
error = pthread_create(&schedule_download_thread, NULL, &thread_cwmp_rpc_cpe_schedule_download, (void *)&cwmp_main);
|
|
||||||
if (error < 0) {
|
|
||||||
CWMP_LOG(ERROR, "Error when creating the schedule download thread!");
|
|
||||||
}
|
|
||||||
|
|
||||||
error = pthread_create(&apply_schedule_download_thread, NULL, &thread_cwmp_rpc_cpe_apply_schedule_download, (void *)&cwmp_main);
|
|
||||||
if (error < 0) {
|
|
||||||
CWMP_LOG(ERROR, "Error when creating the schedule download thread!");
|
|
||||||
}
|
|
||||||
|
|
||||||
error = pthread_create(&upload_thread, NULL, &thread_cwmp_rpc_cpe_upload, (void *)&cwmp_main);
|
|
||||||
if (error < 0) {
|
|
||||||
CWMP_LOG(ERROR, "Error when creating the download thread!");
|
|
||||||
}
|
|
||||||
|
|
||||||
cwmp_schedule_session(&cwmp_main);
|
|
||||||
|
|
||||||
/* Join all threads */
|
|
||||||
pthread_join(periodic_event_thread, NULL);
|
|
||||||
pthread_join(periodic_check_notify, NULL);
|
|
||||||
pthread_join(scheduleInform_thread, NULL);
|
|
||||||
pthread_join(download_thread, NULL);
|
|
||||||
pthread_join(upload_thread, NULL);
|
|
||||||
pthread_join(schedule_download_thread, NULL);
|
|
||||||
pthread_join(apply_schedule_download_thread, NULL);
|
|
||||||
pthread_join(change_du_state_thread, NULL);
|
|
||||||
pthread_join(http_cr_server_thread, NULL);
|
|
||||||
pthread_join(ubus_thread, NULL);
|
|
||||||
pthread_join(heart_beat_session_thread, NULL);
|
|
||||||
|
|
||||||
/* Free all memory allocation */
|
|
||||||
cwmp_free(&cwmp_main);
|
|
||||||
|
|
||||||
CWMP_LOG(INFO, "EXIT ICWMP");
|
|
||||||
closelog();
|
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,9 @@
|
||||||
#include "datamodel_interface.h"
|
#include "datamodel_interface.h"
|
||||||
#include "backupSession.h"
|
#include "backupSession.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
|
#include "session.h"
|
||||||
|
|
||||||
LIST_HEAD(list_change_du_state);
|
LIST_HEAD(list_change_du_state);
|
||||||
pthread_mutex_t mutex_change_du_state = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
pthread_cond_t threshold_change_du_state;
|
|
||||||
|
|
||||||
void ubus_du_state_callback(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg)
|
void ubus_du_state_callback(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg)
|
||||||
{
|
{
|
||||||
|
|
@ -323,198 +322,194 @@ int get_du_version(char *du_ref, char **version)
|
||||||
return cwmp_get_leaf_value(version_param_path, version);
|
return cwmp_get_leaf_value(version_param_path, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *thread_cwmp_rpc_cpe_change_du_state(void *v)
|
int change_du_state_fault(struct change_du_state *pchange_du_state, struct du_state_change_complete **pdu_state_change_complete)
|
||||||
|
{
|
||||||
|
int error = FAULT_CPE_NO_FAULT;
|
||||||
|
struct operations *p, *q;
|
||||||
|
|
||||||
|
*pdu_state_change_complete = calloc(1, sizeof(struct du_state_change_complete));
|
||||||
|
if (*pdu_state_change_complete == NULL)
|
||||||
|
return FAULT_CPE_INTERNAL_ERROR;
|
||||||
|
|
||||||
|
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 ? 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) {
|
||||||
|
struct opresult *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(get_time(time(NULL)));
|
||||||
|
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(*pdu_state_change_complete);
|
||||||
|
list_del(&(pchange_du_state->list));
|
||||||
|
cwmp_free_change_du_state_request(pchange_du_state);
|
||||||
|
return FAULT_CPE_NO_FAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void change_du_state_execute(struct uloop_timeout *utimeout)
|
||||||
{
|
{
|
||||||
struct cwmp *cwmp = (struct cwmp *)v;
|
|
||||||
struct timespec change_du_state_timeout = { 50, 0 };
|
|
||||||
int error = FAULT_CPE_NO_FAULT;
|
int error = FAULT_CPE_NO_FAULT;
|
||||||
struct du_state_change_complete *pdu_state_change_complete;
|
|
||||||
long int time_of_grace = 216000;
|
|
||||||
char *package_version = NULL;
|
char *package_version = NULL;
|
||||||
char *package_name = NULL;
|
char *package_name = NULL;
|
||||||
char *package_env = NULL;
|
char *package_env = NULL;
|
||||||
struct operations *p, *q;
|
struct operations *p, *q;
|
||||||
struct opresult *res;
|
struct opresult *res;
|
||||||
|
struct du_state_change_complete *pdu_state_change_complete;
|
||||||
char *du_ref = NULL;
|
char *du_ref = NULL;
|
||||||
|
//struct session_timer_event cdu_inform_event = {.session_timer_evt = {.cb = cwmp_schedule_session_with_event}, .event = CDU_Evt};
|
||||||
|
struct session_timer_event *cdu_inform_event = calloc(1, sizeof(struct session_timer_event));
|
||||||
|
struct change_du_state *pchange_du_state = container_of(utimeout, struct change_du_state, handler_timer);
|
||||||
|
|
||||||
for (;;) {
|
time_t current_time = time(NULL);
|
||||||
|
time_t timeout = current_time - pchange_du_state->timeout;
|
||||||
|
|
||||||
if (thread_end)
|
if ((timeout >= 0) && (timeout > CDU_TIMEOUT)) {
|
||||||
|
int err = change_du_state_fault(pchange_du_state, &pdu_state_change_complete);
|
||||||
|
if (err) {
|
||||||
|
CWMP_LOG(ERROR, "Not able to create CDU Change Complete fault because of an internal error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
pdu_state_change_complete = calloc(1, sizeof(struct du_state_change_complete));
|
||||||
|
if (pdu_state_change_complete == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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), get_exec_env_id(p->executionenvref), &res);
|
||||||
|
|
||||||
|
package_name = get_package_name_by_url(p->url);
|
||||||
|
|
||||||
|
if (error == FAULT_CPE_NO_FAULT) {
|
||||||
|
du_ref = (package_name && p->executionenvref) ? get_deployment_unit_reference(package_name, p->executionenvref) : NULL;
|
||||||
|
get_du_version(du_ref, &package_version);
|
||||||
|
res->du_ref = strdup(du_ref ? du_ref : "");
|
||||||
|
res->uuid = strdup(p->uuid ? p->uuid : "");
|
||||||
|
res->current_state = strdup("Installed");
|
||||||
|
res->resolved = 1;
|
||||||
|
res->version = strdup(package_version);
|
||||||
|
FREE(du_ref);
|
||||||
|
} else {
|
||||||
|
res->uuid = strdup(p->uuid ? p->uuid : "");
|
||||||
|
res->current_state = strdup("Failed");
|
||||||
|
res->resolved = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
res->complete_time = strdup(get_time(time(NULL)));
|
||||||
|
res->fault = error;
|
||||||
|
FREE(du_ref);
|
||||||
|
FREE(package_version);
|
||||||
break;
|
break;
|
||||||
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)) {
|
case DU_UPDATE:
|
||||||
pthread_mutex_lock(&mutex_change_du_state);
|
if (p->url == NULL || p->uuid == NULL || *(p->url) == '\0' || *(p->uuid) == '\0') {
|
||||||
pdu_state_change_complete = calloc(1, sizeof(struct du_state_change_complete));
|
error = FAULT_CPE_UNKNOWN_DEPLOYMENT_UNIT;
|
||||||
if (pdu_state_change_complete != NULL) {
|
break;
|
||||||
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 ? 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(get_time(time(NULL)));
|
|
||||||
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)) {
|
du_ref = get_deployment_unit_by_uuid(p->uuid);
|
||||||
pthread_mutex_lock(&(cwmp->mutex_session_send));
|
if (du_ref == NULL) {
|
||||||
pdu_state_change_complete = calloc(1, sizeof(struct du_state_change_complete));
|
error = FAULT_CPE_UNKNOWN_DEPLOYMENT_UNIT;
|
||||||
if (pdu_state_change_complete != NULL) {
|
break;
|
||||||
error = FAULT_CPE_NO_FAULT;
|
}
|
||||||
INIT_LIST_HEAD(&(pdu_state_change_complete->list_opresult));
|
char *execenv = calloc(40, sizeof(char));
|
||||||
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) {
|
snprintf(execenv, 40, "Device.SoftwareModules.ExecEnv.%s.", du_ref);
|
||||||
res = calloc(1, sizeof(struct opresult));
|
error = cwmp_launch_du_update(p->uuid, p->url, p->username, p->password, get_exec_env_name(execenv), get_exec_env_id(execenv), &res);
|
||||||
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), get_exec_env_id(p->executionenvref), &res);
|
res->uuid = strdup(p->uuid ? p->uuid : "");
|
||||||
|
|
||||||
package_name = get_package_name_by_url(p->url);
|
if (error == FAULT_CPE_NO_FAULT) {
|
||||||
|
res->current_state = strdup("Installed");
|
||||||
if (error == FAULT_CPE_NO_FAULT) {
|
res->resolved = 1;
|
||||||
du_ref = (package_name && p->executionenvref) ? get_deployment_unit_reference(package_name, p->executionenvref) : NULL;
|
} else {
|
||||||
get_du_version(du_ref, &package_version);
|
res->current_state = strdup("Failed");
|
||||||
res->du_ref = strdup("");
|
res->resolved = 0;
|
||||||
res->uuid = strdup("");
|
|
||||||
res->current_state = strdup("Installed");
|
|
||||||
res->resolved = 1;
|
|
||||||
res->version = strdup("");
|
|
||||||
FREE(du_ref);
|
|
||||||
} else {
|
|
||||||
res->uuid = strdup(p->uuid ? p->uuid : "");
|
|
||||||
res->current_state = strdup("Failed");
|
|
||||||
res->resolved = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
res->complete_time = strdup(get_time(time(NULL)));
|
|
||||||
res->fault = error;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DU_UPDATE:
|
|
||||||
if (p->url == NULL || p->uuid == NULL || *(p->url) == '\0' || *(p->uuid) == '\0') {
|
|
||||||
error = FAULT_CPE_UNKNOWN_DEPLOYMENT_UNIT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
du_ref = get_deployment_unit_by_uuid(p->uuid);
|
|
||||||
if (du_ref == NULL) {
|
|
||||||
error = FAULT_CPE_UNKNOWN_DEPLOYMENT_UNIT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
char *execenv = calloc(40, sizeof(char));
|
|
||||||
|
|
||||||
snprintf(execenv, 40, "Device.SoftwareModules.ExecEnv.%s.", du_ref);
|
|
||||||
error = cwmp_launch_du_update(p->uuid, p->url, p->username, p->password, get_exec_env_name(execenv), get_exec_env_id(execenv), &res);
|
|
||||||
|
|
||||||
res->uuid = strdup(p->uuid ? p->uuid : "");
|
|
||||||
|
|
||||||
if (error == FAULT_CPE_NO_FAULT) {
|
|
||||||
res->current_state = strdup("Installed");
|
|
||||||
res->resolved = 1;
|
|
||||||
} else {
|
|
||||||
res->current_state = strdup("Failed");
|
|
||||||
res->resolved = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
get_du_version(du_ref, &package_version);
|
|
||||||
res->version = strdup(package_version ? package_version : "");
|
|
||||||
res->du_ref = strdup(du_ref ? du_ref : "");
|
|
||||||
res->complete_time = strdup(get_time(time(NULL)));
|
|
||||||
res->fault = error;
|
|
||||||
FREE(du_ref);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
du_ref = (package_name && package_env) ? get_deployment_unit_reference(package_name, package_env) : NULL;
|
|
||||||
get_du_version(du_ref, &package_version);
|
|
||||||
error = cwmp_launch_du_uninstall(package_name, get_exec_env_name(package_env), get_exec_env_id(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
res->du_ref = strdup(du_ref ? du_ref : "");
|
|
||||||
res->uuid = strdup(p->uuid);
|
|
||||||
res->version = strdup(package_version);
|
|
||||||
res->complete_time = strdup(get_time(time(NULL)));
|
|
||||||
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);
|
get_du_version(du_ref, &package_version);
|
||||||
pthread_cond_timedwait(&threshold_change_du_state, &mutex_change_du_state, &change_du_state_timeout);
|
res->version = strdup(package_version ? package_version : "");
|
||||||
pthread_mutex_unlock(&mutex_change_du_state);
|
res->du_ref = strdup(du_ref ? du_ref : "");
|
||||||
|
res->complete_time = strdup(get_time(time(NULL)));
|
||||||
|
res->fault = error;
|
||||||
|
FREE(du_ref);
|
||||||
|
FREE(package_version);
|
||||||
|
break;
|
||||||
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_send));
|
case DU_UNINSTALL:
|
||||||
pthread_cond_signal(&(cwmp->threshold_session_send));
|
if (p->uuid == NULL || *(p->uuid) == '\0' || !environment_exists(p->executionenvref)) {
|
||||||
|
res->fault = FAULT_CPE_UNKNOWN_DEPLOYMENT_UNIT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_change_du_state);
|
get_deployment_unit_name_version(p->uuid, &package_name, &package_version, &package_env);
|
||||||
list_del(&(pchange_du_state->list));
|
if (!package_name || *package_name == '\0' || !package_version || *package_version == '\0' || !package_env || *package_env == '\0') {
|
||||||
cwmp_free_change_du_state_request(pchange_du_state);
|
res->fault = FAULT_CPE_UNKNOWN_DEPLOYMENT_UNIT;
|
||||||
pthread_mutex_unlock(&mutex_change_du_state);
|
break;
|
||||||
continue;
|
}
|
||||||
} else {
|
du_ref = (package_name && package_env) ? get_deployment_unit_reference(package_name, package_env) : NULL;
|
||||||
pthread_mutex_lock(&mutex_change_du_state);
|
get_du_version(du_ref, &package_version);
|
||||||
pthread_cond_wait(&threshold_change_du_state, &mutex_change_du_state);
|
error = cwmp_launch_du_uninstall(package_name, get_exec_env_name(package_env), get_exec_env_id(package_env), &res);
|
||||||
pthread_mutex_unlock(&mutex_change_du_state);
|
if (error == FAULT_CPE_NO_FAULT) {
|
||||||
|
res->current_state = strdup("Uninstalled");
|
||||||
|
res->resolved = 1;
|
||||||
|
} else {
|
||||||
|
res->current_state = strdup("Installed");
|
||||||
|
res->resolved = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
res->du_ref = strdup(du_ref ? du_ref : "");
|
||||||
|
res->uuid = strdup(p->uuid);
|
||||||
|
res->version = strdup(package_version);
|
||||||
|
res->complete_time = strdup(get_time(time(NULL)));
|
||||||
|
res->fault = error;
|
||||||
|
FREE(du_ref);
|
||||||
|
FREE(package_name);
|
||||||
|
FREE(package_version);
|
||||||
|
FREE(package_env);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
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(pdu_state_change_complete);
|
||||||
|
|
||||||
|
list_del(&(pchange_du_state->list));
|
||||||
|
cwmp_free_change_du_state_request(pchange_du_state);
|
||||||
|
end:
|
||||||
|
cdu_inform_event->extra_data = pdu_state_change_complete;
|
||||||
|
cdu_inform_event->session_timer_evt.cb = cwmp_schedule_session_with_event;
|
||||||
|
cdu_inform_event->event = Schedule_Inform_Evt;
|
||||||
|
trigger_cwmp_session_timer_with_event(&cdu_inform_event->session_timer_evt);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int cwmp_rpc_acs_destroy_data_du_state_change_complete(struct session *session __attribute__((unused)), struct rpc *rpc)
|
int cwmp_rpc_acs_destroy_data_du_state_change_complete(struct rpc *rpc)
|
||||||
{
|
{
|
||||||
if (rpc->extra_data != NULL) {
|
if (rpc->extra_data != NULL) {
|
||||||
struct du_state_change_complete *p;
|
struct du_state_change_complete *p;
|
||||||
|
|
@ -547,3 +542,12 @@ int cwmp_free_change_du_state_request(struct change_du_state *change_du_state)
|
||||||
}
|
}
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void apply_change_du_state()
|
||||||
|
{
|
||||||
|
struct list_head *ilist;
|
||||||
|
list_for_each (ilist, &(list_change_du_state)) {
|
||||||
|
struct change_du_state *pchange_du_state = list_entry(ilist, struct change_du_state, list);;
|
||||||
|
uloop_timeout_set(&pchange_du_state->handler_timer, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,15 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
#define CDU_TIMEOUT 86400 //24 hours
|
||||||
extern struct list_head list_change_du_state;
|
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_name, int env_id, char **fault_code);
|
int cwmp_du_install(char *url, char *uuid, char *user, char *pass, char *env_name, int env_id, char **fault_code);
|
||||||
int cwmp_du_update(char *url, char *uuid, char *user, char *pass, char *env_name, int env_id, char **fault_code);
|
int cwmp_du_update(char *url, char *uuid, char *user, char *pass, char *env_name, int env_id, char **fault_code);
|
||||||
int cwmp_du_uninstall(char *package_name, char *env_name, int env_id, char **fault_code);
|
int cwmp_du_uninstall(char *package_name, char *env_name, int env_id, char **fault_code);
|
||||||
int cwmp_rpc_acs_destroy_data_du_state_change_complete(struct session *session, struct rpc *rpc);
|
int cwmp_rpc_acs_destroy_data_du_state_change_complete(struct rpc *rpc);
|
||||||
void *thread_cwmp_rpc_cpe_change_du_state(void *v);
|
void *thread_cwmp_rpc_cpe_change_du_state(void *v);
|
||||||
int cwmp_free_change_du_state_request(struct change_du_state *change_du_state);
|
int cwmp_free_change_du_state_request(struct change_du_state *change_du_state);
|
||||||
|
void change_du_state_execute(struct uloop_timeout *utimeout);
|
||||||
|
void apply_change_du_state();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
50
src/cwmp_event.c
Normal file
50
src/cwmp_event.c
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* 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 "cwmp_event.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "session.h"
|
||||||
|
|
||||||
|
pthread_mutex_t add_event_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
struct event_container *__cwmp_add_event_container(int event_code, char *command_key)
|
||||||
|
{
|
||||||
|
struct event_container *event_container = NULL;
|
||||||
|
list_for_each_entry(event_container, &cwmp_main->session->events, list) {
|
||||||
|
if (event_container->code == event_code) {
|
||||||
|
return event_container;
|
||||||
|
}
|
||||||
|
if (event_container->code > event_code) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
event_container = calloc(1, sizeof(struct event_container));
|
||||||
|
if (event_container == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
INIT_LIST_HEAD(&(event_container->head_dm_parameter));
|
||||||
|
list_add_tail(&(event_container->list), &(cwmp_main->session->events));
|
||||||
|
event_container->code = event_code;
|
||||||
|
event_container->command_key = command_key ? strdup(command_key) : strdup("");
|
||||||
|
if ((cwmp_main->event_id < 0) || (cwmp_main->event_id >= MAX_INT_ID)) {
|
||||||
|
cwmp_main->event_id = 0;
|
||||||
|
}
|
||||||
|
cwmp_main->event_id++;
|
||||||
|
event_container->id = cwmp_main->event_id;
|
||||||
|
return event_container;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct event_container *cwmp_add_event_container(int event_code, char *command_key)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&add_event_mutex);
|
||||||
|
struct event_container *event = __cwmp_add_event_container(event_code, command_key);
|
||||||
|
pthread_mutex_unlock(&add_event_mutex);
|
||||||
|
return event;
|
||||||
|
}
|
||||||
5
src/cwmp_event.h
Normal file
5
src/cwmp_event.h
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
#ifndef CWMP_EVENT_H
|
||||||
|
#define CWMP_EVENT_H
|
||||||
|
#include "event.h"
|
||||||
|
struct event_container *cwmp_add_event_container(int event_code, char *command_key);
|
||||||
|
#endif
|
||||||
51
src/cwmp_http.c
Normal file
51
src/cwmp_http.c
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* 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 "cwmp_http.h"
|
||||||
|
#include "http.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
struct uloop_fd http_event6;
|
||||||
|
|
||||||
|
pthread_t http_cr_server_thread;
|
||||||
|
|
||||||
|
void http_server_listen_uloop(struct uloop_fd *ufd __attribute__((unused)), unsigned events __attribute__((unused)))
|
||||||
|
{
|
||||||
|
icwmp_http_server_listen();
|
||||||
|
}
|
||||||
|
|
||||||
|
void http_server_start_uloop(void)
|
||||||
|
{
|
||||||
|
icwmp_http_server_init();
|
||||||
|
http_event6.fd = cwmp_main->cr_socket_desc;
|
||||||
|
http_event6.cb = http_server_listen_uloop;
|
||||||
|
uloop_fd_add(&http_event6, ULOOP_READ | ULOOP_EDGE_TRIGGER);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *thread_http_cr_server_listen(void *v __attribute__((unused)))
|
||||||
|
{
|
||||||
|
icwmp_http_server_listen();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void http_server_start(void)
|
||||||
|
{
|
||||||
|
int error = pthread_create(&http_cr_server_thread, NULL, &thread_http_cr_server_listen, NULL);
|
||||||
|
if (error < 0) {
|
||||||
|
CWMP_LOG(ERROR, "Error when creating the http connection request server thread!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void http_server_stop(void)
|
||||||
|
{
|
||||||
|
pthread_join(http_cr_server_thread, NULL);
|
||||||
|
}
|
||||||
8
src/cwmp_http.h
Normal file
8
src/cwmp_http.h
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef CWMP_HTTP_H
|
||||||
|
#define CWMP_HTTP_H
|
||||||
|
#include "http.h"
|
||||||
|
extern pthread_t http_cr_server_thread;
|
||||||
|
|
||||||
|
void http_server_start(void);
|
||||||
|
void http_server_stop(void);
|
||||||
|
#endif
|
||||||
|
|
@ -15,7 +15,6 @@
|
||||||
|
|
||||||
#include <uci.h>
|
#include <uci.h>
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
//struct uci_context *cwmp_uci_ctx = ((void *)0);
|
//struct uci_context *cwmp_uci_ctx = ((void *)0);
|
||||||
#define UCI_DHCP_DISCOVERY_PATH "cwmp.acs.dhcp_discovery"
|
#define UCI_DHCP_DISCOVERY_PATH "cwmp.acs.dhcp_discovery"
|
||||||
|
|
|
||||||
|
|
@ -325,14 +325,13 @@ void ubus_get_single_parameter_callback(struct ubus_request *req, int type __att
|
||||||
char *cwmp_get_single_parameter_value(char *parameter_name, struct cwmp_dm_parameter *dm_parameter)
|
char *cwmp_get_single_parameter_value(char *parameter_name, struct cwmp_dm_parameter *dm_parameter)
|
||||||
{
|
{
|
||||||
int e;
|
int e;
|
||||||
struct cwmp *cwmp = &cwmp_main;
|
|
||||||
struct blob_buf b = { 0 };
|
struct blob_buf b = { 0 };
|
||||||
|
|
||||||
memset(&b, 0, sizeof(struct blob_buf));
|
memset(&b, 0, sizeof(struct blob_buf));
|
||||||
blob_buf_init(&b, 0);
|
blob_buf_init(&b, 0);
|
||||||
bb_add_string(&b, "path", !parameter_name || parameter_name[0] == '\0' ? DM_ROOT_OBJ : parameter_name);
|
bb_add_string(&b, "path", !parameter_name || parameter_name[0] == '\0' ? DM_ROOT_OBJ : parameter_name);
|
||||||
bb_add_string(&b, "proto", "cwmp");
|
bb_add_string(&b, "proto", "cwmp");
|
||||||
blobmsg_add_u32(&b, "instance_mode", cwmp->conf.instance_mode);
|
blobmsg_add_u32(&b, "instance_mode", cwmp_main->conf.instance_mode);
|
||||||
|
|
||||||
e = icwmp_ubus_invoke(USP_OBJECT_NAME, "get", b.head, ubus_get_single_parameter_callback, dm_parameter);
|
e = icwmp_ubus_invoke(USP_OBJECT_NAME, "get", b.head, ubus_get_single_parameter_callback, dm_parameter);
|
||||||
blob_buf_free(&b);
|
blob_buf_free(&b);
|
||||||
|
|
@ -411,7 +410,6 @@ void ubus_get_parameter_callback(struct ubus_request *req, int type __attribute_
|
||||||
char *cwmp_get_parameter_values(char *parameter_name, struct list_head *parameters_list)
|
char *cwmp_get_parameter_values(char *parameter_name, struct list_head *parameters_list)
|
||||||
{
|
{
|
||||||
int e;
|
int e;
|
||||||
struct cwmp *cwmp = &cwmp_main;
|
|
||||||
struct list_params_result get_result = { .parameters_list = parameters_list };
|
struct list_params_result get_result = { .parameters_list = parameters_list };
|
||||||
struct blob_buf b = { 0 };
|
struct blob_buf b = { 0 };
|
||||||
char *param = CWMP_STRLEN(parameter_name) ? parameter_name : DM_ROOT_OBJ;
|
char *param = CWMP_STRLEN(parameter_name) ? parameter_name : DM_ROOT_OBJ;
|
||||||
|
|
@ -420,7 +418,7 @@ char *cwmp_get_parameter_values(char *parameter_name, struct list_head *paramete
|
||||||
blob_buf_init(&b, 0);
|
blob_buf_init(&b, 0);
|
||||||
bb_add_string(&b, "path", param);
|
bb_add_string(&b, "path", param);
|
||||||
bb_add_string(&b, "proto", "cwmp");
|
bb_add_string(&b, "proto", "cwmp");
|
||||||
blobmsg_add_u32(&b, "instance_mode", cwmp->conf.instance_mode);
|
blobmsg_add_u32(&b, "instance_mode", cwmp_main->conf.instance_mode);
|
||||||
|
|
||||||
e = icwmp_ubus_invoke(USP_OBJECT_NAME, "get", b.head, ubus_get_parameter_callback, &get_result);
|
e = icwmp_ubus_invoke(USP_OBJECT_NAME, "get", b.head, ubus_get_parameter_callback, &get_result);
|
||||||
blob_buf_free(&b);
|
blob_buf_free(&b);
|
||||||
|
|
@ -440,7 +438,6 @@ char *cwmp_get_parameter_values(char *parameter_name, struct list_head *paramete
|
||||||
char *cwmp_get_multiple_parameters_values(struct list_head *arg_params_list, struct list_head *parameters_list)
|
char *cwmp_get_multiple_parameters_values(struct list_head *arg_params_list, struct list_head *parameters_list)
|
||||||
{
|
{
|
||||||
int e;
|
int e;
|
||||||
struct cwmp *cwmp = &cwmp_main;
|
|
||||||
struct cwmp_dm_parameter *param_value = NULL;
|
struct cwmp_dm_parameter *param_value = NULL;
|
||||||
struct list_params_result get_result = { .parameters_list = parameters_list };
|
struct list_params_result get_result = { .parameters_list = parameters_list };
|
||||||
struct blob_buf b = { 0 };
|
struct blob_buf b = { 0 };
|
||||||
|
|
@ -454,7 +451,7 @@ char *cwmp_get_multiple_parameters_values(struct list_head *arg_params_list, str
|
||||||
blobmsg_add_string(&b, NULL, param_value->name);
|
blobmsg_add_string(&b, NULL, param_value->name);
|
||||||
}
|
}
|
||||||
blobmsg_close_array(&b, arr);
|
blobmsg_close_array(&b, arr);
|
||||||
blobmsg_add_u32(&b, "instance_mode", cwmp->conf.instance_mode);
|
blobmsg_add_u32(&b, "instance_mode", cwmp_main->conf.instance_mode);
|
||||||
|
|
||||||
e = icwmp_ubus_invoke(USP_OBJECT_NAME, "getm_values", b.head, ubus_get_parameter_callback, &get_result );
|
e = icwmp_ubus_invoke(USP_OBJECT_NAME, "getm_values", b.head, ubus_get_parameter_callback, &get_result );
|
||||||
blob_buf_free(&b);
|
blob_buf_free(&b);
|
||||||
|
|
@ -475,7 +472,6 @@ char *cwmp_get_parameter_names(char *object_name, bool next_level, struct list_h
|
||||||
{
|
{
|
||||||
int e;
|
int e;
|
||||||
struct list_params_result get_result = { .parameters_list = parameters_list };
|
struct list_params_result get_result = { .parameters_list = parameters_list };
|
||||||
struct cwmp *cwmp = &cwmp_main;
|
|
||||||
struct blob_buf b = { 0 };
|
struct blob_buf b = { 0 };
|
||||||
|
|
||||||
memset(&b, 0, sizeof(struct blob_buf));
|
memset(&b, 0, sizeof(struct blob_buf));
|
||||||
|
|
@ -483,7 +479,7 @@ char *cwmp_get_parameter_names(char *object_name, bool next_level, struct list_h
|
||||||
bb_add_string(&b, "path", object_name);
|
bb_add_string(&b, "path", object_name);
|
||||||
blobmsg_add_u8(&b, "next-level", next_level);
|
blobmsg_add_u8(&b, "next-level", next_level);
|
||||||
bb_add_string(&b, "proto", "cwmp");
|
bb_add_string(&b, "proto", "cwmp");
|
||||||
blobmsg_add_u32(&b, "instance_mode", cwmp->conf.instance_mode);
|
blobmsg_add_u32(&b, "instance_mode", cwmp_main->conf.instance_mode);
|
||||||
|
|
||||||
e = icwmp_ubus_invoke(USP_OBJECT_NAME, "object_names", b.head, ubus_get_parameter_callback, &get_result);
|
e = icwmp_ubus_invoke(USP_OBJECT_NAME, "object_names", b.head, ubus_get_parameter_callback, &get_result);
|
||||||
blob_buf_free(&b);
|
blob_buf_free(&b);
|
||||||
|
|
@ -539,7 +535,6 @@ int cwmp_set_multiple_parameters_values(struct list_head *parameters_values_list
|
||||||
int e;
|
int e;
|
||||||
struct cwmp_dm_parameter *param_value = NULL;
|
struct cwmp_dm_parameter *param_value = NULL;
|
||||||
struct setm_values_res set_result = { .flag = flag, .faults_list = faults_list };
|
struct setm_values_res set_result = { .flag = flag, .faults_list = faults_list };
|
||||||
struct cwmp *cwmp = &cwmp_main;
|
|
||||||
struct blob_buf b = { 0 };
|
struct blob_buf b = { 0 };
|
||||||
|
|
||||||
memset(&b, 0, sizeof(struct blob_buf));
|
memset(&b, 0, sizeof(struct blob_buf));
|
||||||
|
|
@ -557,7 +552,7 @@ int cwmp_set_multiple_parameters_values(struct list_head *parameters_values_list
|
||||||
bb_add_string(&b, "key", parameter_key);
|
bb_add_string(&b, "key", parameter_key);
|
||||||
blobmsg_add_u32(&b, "transaction_id", transaction_id);
|
blobmsg_add_u32(&b, "transaction_id", transaction_id);
|
||||||
bb_add_string(&b, "proto", "cwmp");
|
bb_add_string(&b, "proto", "cwmp");
|
||||||
blobmsg_add_u32(&b, "instance_mode", cwmp->conf.instance_mode);
|
blobmsg_add_u32(&b, "instance_mode", cwmp_main->conf.instance_mode);
|
||||||
|
|
||||||
e = icwmp_ubus_invoke(USP_OBJECT_NAME, "setm_values", b.head, ubus_setm_values_callback, &set_result);
|
e = icwmp_ubus_invoke(USP_OBJECT_NAME, "setm_values", b.head, ubus_setm_values_callback, &set_result);
|
||||||
blob_buf_free(&b);
|
blob_buf_free(&b);
|
||||||
|
|
@ -615,7 +610,7 @@ static void prepare_add_delete_blobmsg(struct blob_buf *b, char *object_name, ch
|
||||||
bb_add_string(b, "key", key);
|
bb_add_string(b, "key", key);
|
||||||
blobmsg_add_u32(b, "transaction_id", transaction_id);
|
blobmsg_add_u32(b, "transaction_id", transaction_id);
|
||||||
bb_add_string(b, "proto", "cwmp");
|
bb_add_string(b, "proto", "cwmp");
|
||||||
blobmsg_add_u32(b, "instance_mode", cwmp_main.conf.instance_mode);
|
blobmsg_add_u32(b, "instance_mode", cwmp_main->conf.instance_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *cwmp_add_object(char *object_name, char *key, char **instance)
|
char *cwmp_add_object(char *object_name, char *key, char **instance)
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,7 @@ int cwmp_download_diagnostics()
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
CWMP_LOG(INFO, "Download diagnostic is successfully executed");
|
CWMP_LOG(INFO, "Download diagnostic is successfully executed");
|
||||||
cwmp_root_cause_event_ipdiagnostic();
|
cwmp_main->diag_session = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -186,7 +186,7 @@ int cwmp_upload_diagnostics()
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
CWMP_LOG(INFO, "Upload diagnostic is successfully executed");
|
CWMP_LOG(INFO, "Upload diagnostic is successfully executed");
|
||||||
cwmp_root_cause_event_ipdiagnostic();
|
cwmp_main->diag_session = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,7 +196,7 @@ int cwmp_ip_ping_diagnostics()
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
CWMP_LOG(INFO, "IPPing diagnostic is successfully executed");
|
CWMP_LOG(INFO, "IPPing diagnostic is successfully executed");
|
||||||
cwmp_root_cause_event_ipdiagnostic();
|
cwmp_main->diag_session = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -206,7 +206,7 @@ int cwmp_nslookup_diagnostics()
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
CWMP_LOG(INFO, "Nslookup diagnostic is successfully executed");
|
CWMP_LOG(INFO, "Nslookup diagnostic is successfully executed");
|
||||||
cwmp_root_cause_event_ipdiagnostic();
|
cwmp_main->diag_session = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -216,7 +216,7 @@ int cwmp_traceroute_diagnostics()
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
CWMP_LOG(INFO, "Trace Route diagnostic is successfully executed");
|
CWMP_LOG(INFO, "Trace Route diagnostic is successfully executed");
|
||||||
cwmp_root_cause_event_ipdiagnostic();
|
cwmp_main->diag_session = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -226,7 +226,7 @@ int cwmp_udp_echo_diagnostics()
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
CWMP_LOG(INFO, "UDPEcho diagnostic is successfully executed");
|
CWMP_LOG(INFO, "UDPEcho diagnostic is successfully executed");
|
||||||
cwmp_root_cause_event_ipdiagnostic();
|
cwmp_main->diag_session = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -236,6 +236,6 @@ int cwmp_serverselection_diagnostics()
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
CWMP_LOG(INFO, "Server Selection diagnostic is successfully executed");
|
CWMP_LOG(INFO, "Server Selection diagnostic is successfully executed");
|
||||||
cwmp_root_cause_event_ipdiagnostic();
|
cwmp_main->diag_session = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,11 @@
|
||||||
|
|
||||||
extern char *nonce_key;
|
extern char *nonce_key;
|
||||||
|
|
||||||
int get_nonce_key(void);
|
|
||||||
void strip_lead_trail_char(char *str, char ch);
|
void strip_lead_trail_char(char *str, char ch);
|
||||||
|
int get_nonce_key(void);
|
||||||
int validate_http_digest_auth(const char *http_meth, const char *uri, const char *hdr,
|
int validate_http_digest_auth(const char *http_meth, const char *uri, const char *hdr,
|
||||||
const char *rlm, const char *usr, const char *psw,
|
const char *rlm, const char *usr, const char *psw,
|
||||||
unsigned int timeout, const char *req_host);
|
unsigned int timeout, const char *req_host);
|
||||||
int http_authentication_failure_resp(FILE *fp, const char *http_meth, const char *uri,
|
int http_authentication_failure_resp(FILE *fp, const char *http_meth, const char *uri,
|
||||||
const char *rlm, const char *opq);
|
const char *rlm, const char *opq);
|
||||||
|
|
||||||
|
|
|
||||||
800
src/download.c
800
src/download.c
|
|
@ -18,17 +18,12 @@
|
||||||
#include "backupSession.h"
|
#include "backupSession.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "subprocess.h"
|
||||||
|
#include "session.h"
|
||||||
|
|
||||||
LIST_HEAD(list_download);
|
LIST_HEAD(list_download);
|
||||||
LIST_HEAD(list_schedule_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;
|
int count_download_queue = 0;
|
||||||
|
|
||||||
|
|
@ -69,6 +64,57 @@ int download_file(const char *file_path, const char *url, const char *username,
|
||||||
return res_code;
|
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
|
* Check if the downloaded image can be applied
|
||||||
*/
|
*/
|
||||||
|
|
@ -150,6 +196,64 @@ int get_available_bank_id()
|
||||||
return 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;
|
||||||
|
struct blob_buf b = { 0 };
|
||||||
|
memset(&b, 0, sizeof(struct blob_buf));
|
||||||
|
blob_buf_init(&b, 0);
|
||||||
|
|
||||||
|
e = icwmp_ubus_invoke("fwbank", "dump", b.head, ubus_get_available_bank_callback, &bank_id_status);
|
||||||
|
|
||||||
|
if (e != 0) {
|
||||||
|
CWMP_LOG(INFO, "fwbank dump ubus method failed: Ubus err code: %d", e);
|
||||||
|
}
|
||||||
|
blob_buf_free(&b);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Apply the new firmware
|
* Apply the new firmware
|
||||||
*/
|
*/
|
||||||
|
|
@ -171,6 +275,24 @@ int cwmp_apply_firmware()
|
||||||
return e;
|
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 cwmp_apply_multiple_firmware()
|
||||||
{
|
{
|
||||||
int e;
|
int e;
|
||||||
|
|
@ -192,9 +314,28 @@ int cwmp_apply_multiple_firmware()
|
||||||
CWMP_LOG(INFO, "fwbank upgrade ubus method failed: Ubus err code: %d", e);
|
CWMP_LOG(INFO, "fwbank upgrade ubus method failed: Ubus err code: %d", e);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
//wait until the apply completes
|
||||||
|
wait_firmware_to_be_applied(bank_id);
|
||||||
return CWMP_OK;
|
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 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;
|
int error = FAULT_CPE_NO_FAULT;
|
||||||
|
|
@ -211,7 +352,7 @@ int cwmp_launch_download(struct download *pdownload, char *download_file_name, e
|
||||||
goto end_download;
|
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)
|
if (http_code == 404)
|
||||||
error = FAULT_CPE_DOWNLOAD_FAIL_CONTACT_SERVER;
|
error = FAULT_CPE_DOWNLOAD_FAIL_CONTACT_SERVER;
|
||||||
else if (http_code == 401)
|
else if (http_code == 401)
|
||||||
|
|
@ -290,11 +431,11 @@ char *get_file_name_by_download_url(char *url)
|
||||||
return slash+1;
|
return slash+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int apply_downloaded_file(struct cwmp *cwmp, struct download *pdownload, char *download_file_name, struct transfer_complete *ptransfer_complete)
|
int apply_downloaded_file(struct download *pdownload, char *download_file_name, struct transfer_complete *ptransfer_complete)
|
||||||
{
|
{
|
||||||
int error = FAULT_CPE_NO_FAULT;
|
int error = FAULT_CPE_NO_FAULT;
|
||||||
if (pdownload->file_type[0] == '1') {
|
if (pdownload->file_type[0] == '1') {
|
||||||
ptransfer_complete->old_software_version = cwmp->deviceid.softwareversion;
|
ptransfer_complete->old_software_version = cwmp_main->deviceid.softwareversion;
|
||||||
}
|
}
|
||||||
bkp_session_insert_transfer_complete(ptransfer_complete);
|
bkp_session_insert_transfer_complete(ptransfer_complete);
|
||||||
bkp_session_save();
|
bkp_session_save();
|
||||||
|
|
@ -341,6 +482,7 @@ int apply_downloaded_file(struct cwmp *cwmp, struct download *pdownload, char *d
|
||||||
|
|
||||||
} else if (strcmp(pdownload->file_type, STORED_FIRMWARE_IMAGE_FILE_TYPE) == 0) {
|
} else if (strcmp(pdownload->file_type, STORED_FIRMWARE_IMAGE_FILE_TYPE) == 0) {
|
||||||
int err = cwmp_apply_multiple_firmware();
|
int err = cwmp_apply_multiple_firmware();
|
||||||
|
//int err = cwmp_apply_multiple_firmware_in_subprocess();
|
||||||
if (err == CWMP_OK)
|
if (err == CWMP_OK)
|
||||||
error = FAULT_CPE_NO_FAULT;
|
error = FAULT_CPE_NO_FAULT;
|
||||||
else
|
else
|
||||||
|
|
@ -353,7 +495,7 @@ int apply_downloaded_file(struct cwmp *cwmp, struct download *pdownload, char *d
|
||||||
cwmp_commit_package("cwmp", UCI_VARSTATE_CONFIG);
|
cwmp_commit_package("cwmp", UCI_VARSTATE_CONFIG);
|
||||||
if (pdownload->file_type[0] == '3') {
|
if (pdownload->file_type[0] == '3') {
|
||||||
CWMP_LOG(INFO, "Download and apply new vendor config file is done successfully");
|
CWMP_LOG(INFO, "Download and apply new vendor config file is done successfully");
|
||||||
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
|
//cwmp_root_cause_transfer_complete(ptransfer_complete);
|
||||||
bkp_session_delete_transfer_complete(ptransfer_complete);
|
bkp_session_delete_transfer_complete(ptransfer_complete);
|
||||||
}
|
}
|
||||||
return FAULT_CPE_NO_FAULT;
|
return FAULT_CPE_NO_FAULT;
|
||||||
|
|
@ -364,11 +506,11 @@ int apply_downloaded_file(struct cwmp *cwmp, struct download *pdownload, char *d
|
||||||
}
|
}
|
||||||
bkp_session_insert_transfer_complete(ptransfer_complete);
|
bkp_session_insert_transfer_complete(ptransfer_complete);
|
||||||
bkp_session_save();
|
bkp_session_save();
|
||||||
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
|
//cwmp_root_cause_transfer_complete(ptransfer_complete);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct transfer_complete *set_download_error_transfer_complete(struct cwmp *cwmp, struct download *pdownload, enum load_type ltype)
|
struct transfer_complete *set_download_error_transfer_complete(struct download *pdownload, enum load_type ltype)
|
||||||
{
|
{
|
||||||
struct transfer_complete *ptransfer_complete;
|
struct transfer_complete *ptransfer_complete;
|
||||||
ptransfer_complete = calloc(1, sizeof(struct transfer_complete));
|
ptransfer_complete = calloc(1, sizeof(struct transfer_complete));
|
||||||
|
|
@ -379,422 +521,11 @@ struct transfer_complete *set_download_error_transfer_complete(struct cwmp *cwmp
|
||||||
ptransfer_complete->fault_code = ltype == TYPE_DOWNLOAD ? FAULT_CPE_DOWNLOAD_FAILURE : FAULT_CPE_DOWNLOAD_FAIL_WITHIN_TIME_WINDOW;
|
ptransfer_complete->fault_code = ltype == TYPE_DOWNLOAD ? FAULT_CPE_DOWNLOAD_FAILURE : FAULT_CPE_DOWNLOAD_FAIL_WITHIN_TIME_WINDOW;
|
||||||
ptransfer_complete->type = ltype;
|
ptransfer_complete->type = ltype;
|
||||||
bkp_session_insert_transfer_complete(ptransfer_complete);
|
bkp_session_insert_transfer_complete(ptransfer_complete);
|
||||||
cwmp_root_cause_transfer_complete(cwmp, ptransfer_complete);
|
cwmp_root_cause_transfer_complete(ptransfer_complete);
|
||||||
}
|
}
|
||||||
return ptransfer_complete;
|
return ptransfer_complete;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
struct transfer_complete *ptransfer_complete;
|
|
||||||
long int time_of_grace = 3600, timeout;
|
|
||||||
|
|
||||||
sleep(3);
|
|
||||||
for (;;) {
|
|
||||||
|
|
||||||
if (thread_end)
|
|
||||||
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(cwmp, 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)) {
|
|
||||||
pthread_mutex_lock(&(cwmp->mutex_session_send));
|
|
||||||
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(cwmp, ptransfer_complete);
|
|
||||||
bkp_session_delete_transfer_complete(ptransfer_complete);
|
|
||||||
} else {
|
|
||||||
error = apply_downloaded_file(cwmp, 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_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 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 end;
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
end:
|
|
||||||
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 };
|
|
||||||
int error = FAULT_CPE_NO_FAULT;
|
|
||||||
struct transfer_complete *ptransfer_complete;
|
|
||||||
int min_time = 0;
|
|
||||||
struct download *current_download = NULL;
|
|
||||||
struct download *p, *_p;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
time_t current_time;
|
|
||||||
|
|
||||||
if (thread_end)
|
|
||||||
break;
|
|
||||||
|
|
||||||
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);
|
|
||||||
error = FAULT_CPE_DOWNLOAD_FAIL_WITHIN_TIME_WINDOW;
|
|
||||||
ptransfer_complete = set_download_error_transfer_complete(cwmp, p, TYPE_SCHEDULE_DOWNLOAD);
|
|
||||||
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);
|
|
||||||
error = FAULT_CPE_DOWNLOAD_FAIL_WITHIN_TIME_WINDOW;
|
|
||||||
ptransfer_complete = set_download_error_transfer_complete(cwmp, p, TYPE_SCHEDULE_DOWNLOAD);
|
|
||||||
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) {
|
|
||||||
char *download_file_name = get_file_name_by_download_url(current_download->url);
|
|
||||||
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_download(current_download, download_file_name, TYPE_SCHEDULE_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);
|
|
||||||
error = apply_downloaded_file(cwmp, current_download, download_file_name, ptransfer_complete);
|
|
||||||
if (error == FAULT_CPE_NO_FAULT)
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
|
|
||||||
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_download(current_download, download_file_name, TYPE_SCHEDULE_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 {
|
|
||||||
error = apply_downloaded_file(cwmp, current_download, download_file_name, ptransfer_complete);
|
|
||||||
if (error == FAULT_CPE_NO_FAULT)
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
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 };
|
|
||||||
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 (;;) {
|
|
||||||
time_t current_time;
|
|
||||||
|
|
||||||
if (thread_end)
|
|
||||||
break;
|
|
||||||
|
|
||||||
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);
|
|
||||||
error = FAULT_CPE_DOWNLOAD_FAIL_WITHIN_TIME_WINDOW;
|
|
||||||
ptransfer_complete = set_download_error_transfer_complete(cwmp, (struct download *)p, TYPE_SCHEDULE_DOWNLOAD);
|
|
||||||
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);
|
|
||||||
error = FAULT_CPE_DOWNLOAD_FAIL_WITHIN_TIME_WINDOW;
|
|
||||||
ptransfer_complete = set_download_error_transfer_complete(cwmp, (struct download *)p, TYPE_SCHEDULE_DOWNLOAD);
|
|
||||||
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(get_time(time(NULL)));
|
|
||||||
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, FIRMWARE_UPGRADE_IMAGE_FILE_TYPE) == 0) {
|
|
||||||
cwmp_uci_set_value("cwmp", "cpe", "exec_download", "1");
|
|
||||||
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
|
|
||||||
cwmp_apply_firmware();
|
|
||||||
sleep(70);
|
|
||||||
error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED;
|
|
||||||
} else if (strcmp(apply_download->file_type, WEB_CONTENT_FILE_TYPE) == 0) {
|
|
||||||
//TODO Not Supported
|
|
||||||
error = FAULT_CPE_NO_FAULT;
|
|
||||||
} else if (strcmp(apply_download->file_type, VENDOR_CONFIG_FILE_TYPE) == 0) {
|
|
||||||
cwmp_uci_init();
|
|
||||||
int err = cwmp_uci_import(NULL, VENDOR_CONFIG_FILE, UCI_STANDARD_CONFIG);
|
|
||||||
cwmp_uci_exit();
|
|
||||||
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')) {
|
|
||||||
if (apply_download->file_type[0] == '3') {
|
|
||||||
CWMP_LOG(INFO, "Download and apply new vendor config file is done successfully");
|
|
||||||
}
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
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(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)
|
int cwmp_free_download_request(struct download *download)
|
||||||
{
|
{
|
||||||
if (download != NULL) {
|
if (download != NULL) {
|
||||||
|
|
@ -848,26 +579,8 @@ int cwmp_free_schedule_download_request(struct download *schedule_download)
|
||||||
return CWMP_OK;
|
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()
|
int cwmp_scheduledDownload_remove_all()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&mutex_download);
|
|
||||||
while (list_download.next != &(list_download)) {
|
while (list_download.next != &(list_download)) {
|
||||||
struct download *download;
|
struct download *download;
|
||||||
download = list_entry(list_download.next, struct download, list);
|
download = list_entry(list_download.next, struct download, list);
|
||||||
|
|
@ -877,14 +590,12 @@ int cwmp_scheduledDownload_remove_all()
|
||||||
count_download_queue--;
|
count_download_queue--;
|
||||||
cwmp_free_download_request(download);
|
cwmp_free_download_request(download);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&mutex_download);
|
|
||||||
|
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cwmp_scheduled_Download_remove_all()
|
int cwmp_scheduled_Download_remove_all()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&mutex_schedule_download);
|
|
||||||
while (list_schedule_download.next != &(list_schedule_download)) {
|
while (list_schedule_download.next != &(list_schedule_download)) {
|
||||||
struct download *schedule_download;
|
struct download *schedule_download;
|
||||||
schedule_download = list_entry(list_schedule_download.next, struct download, list);
|
schedule_download = list_entry(list_schedule_download.next, struct download, list);
|
||||||
|
|
@ -894,29 +605,11 @@ int cwmp_scheduled_Download_remove_all()
|
||||||
count_download_queue--;
|
count_download_queue--;
|
||||||
cwmp_free_schedule_download_request(schedule_download);
|
cwmp_free_schedule_download_request(schedule_download);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&mutex_schedule_download);
|
|
||||||
|
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cwmp_apply_scheduled_Download_remove_all()
|
int cwmp_rpc_acs_destroy_data_transfer_complete(struct rpc *rpc)
|
||||||
{
|
|
||||||
pthread_mutex_lock(&mutex_apply_schedule_download);
|
|
||||||
while (list_apply_schedule_download.next != &(list_apply_schedule_download)) {
|
|
||||||
struct apply_schedule_download *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)
|
|
||||||
{
|
{
|
||||||
if (rpc->extra_data != NULL) {
|
if (rpc->extra_data != NULL) {
|
||||||
struct transfer_complete *p = (struct transfer_complete *)rpc->extra_data;
|
struct transfer_complete *p = (struct transfer_complete *)rpc->extra_data;
|
||||||
|
|
@ -930,3 +623,180 @@ int cwmp_rpc_acs_destroy_data_transfer_complete(struct session *session __attrib
|
||||||
FREE(rpc->extra_data);
|
FREE(rpc->extra_data);
|
||||||
return 0;
|
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();
|
||||||
|
}
|
||||||
|
list_del(&(pdownload->list));
|
||||||
|
if (pdownload->scheduled_time != 0)
|
||||||
|
count_download_queue--;
|
||||||
|
cwmp_free_download_request(pdownload);
|
||||||
|
|
||||||
|
struct session_timer_event *download_inform_event = calloc(1, sizeof(struct session_timer_event));
|
||||||
|
|
||||||
|
download_inform_event->extra_data = ptransfer_complete;
|
||||||
|
download_inform_event->session_timer_evt.cb = cwmp_schedule_session_with_event;
|
||||||
|
download_inform_event->event = TransferClt_Evt;
|
||||||
|
trigger_cwmp_session_timer_with_event(&download_inform_event->session_timer_evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void apply_downloads()
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cwmp_start_schedule_download(struct uloop_timeout *timeout)
|
||||||
|
{
|
||||||
|
struct download *sched_download;
|
||||||
|
struct transfer_complete *ptransfer_complete;
|
||||||
|
sched_download = container_of(timeout, struct download, handler_timer);
|
||||||
|
bool outdate = false;
|
||||||
|
int delay;
|
||||||
|
int window_index;
|
||||||
|
|
||||||
|
time_t now = time(NULL);
|
||||||
|
if (sched_download->timewindowstruct[0].windowstart > now) {
|
||||||
|
delay = sched_download->timewindowstruct[0].windowstart - now;
|
||||||
|
uloop_timeout_set(&sched_download->handler_timer, 1000 * delay);
|
||||||
|
return;
|
||||||
|
} else if (sched_download->timewindowstruct[0].windowend >= now) {
|
||||||
|
outdate = false;
|
||||||
|
window_index = 0;
|
||||||
|
} else if (sched_download->timewindowstruct[1].windowstart > now) {
|
||||||
|
delay = sched_download->timewindowstruct[1].windowstart - now;
|
||||||
|
uloop_timeout_set(&sched_download->handler_timer, 1000 * delay);
|
||||||
|
return;
|
||||||
|
} else if (sched_download->timewindowstruct[1].windowend >= now) {
|
||||||
|
outdate = false;
|
||||||
|
window_index = 1;
|
||||||
|
} else {
|
||||||
|
outdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!outdate) {
|
||||||
|
int error;
|
||||||
|
char *download_file_name = get_file_name_by_download_url(sched_download->url);
|
||||||
|
CWMP_LOG(INFO, "Launch download file %s", sched_download->url);
|
||||||
|
error = cwmp_launch_download(sched_download, download_file_name, TYPE_DOWNLOAD, &ptransfer_complete);
|
||||||
|
sleep(3);
|
||||||
|
if (error != FAULT_CPE_NO_FAULT) {
|
||||||
|
CWMP_LOG(ERROR, "Error while downloading the file: %s", sched_download->url);
|
||||||
|
goto retry;
|
||||||
|
} else {
|
||||||
|
error = apply_downloaded_file(sched_download, download_file_name, ptransfer_complete);
|
||||||
|
if (error != FAULT_CPE_NO_FAULT) {
|
||||||
|
CWMP_LOG(ERROR, "Error while applying the downloaded file: %s", download_file_name);
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (error == FAULT_CPE_NO_FAULT && sched_download->file_type[0] == '3') {
|
||||||
|
//cwmp_root_cause_transfer_complete(ptransfer_complete);
|
||||||
|
bkp_session_delete_download(sched_download);
|
||||||
|
bkp_session_delete_transfer_complete(ptransfer_complete);
|
||||||
|
bkp_session_save();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CWMP_LOG(ERROR, "Schedule Download out of date");
|
||||||
|
ptransfer_complete = calloc(1, sizeof(struct transfer_complete));
|
||||||
|
if (ptransfer_complete == NULL) {
|
||||||
|
// error = FAULT_CPE_INTERNAL_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptransfer_complete->command_key = sched_download->command_key ? strdup(sched_download->command_key) : strdup("");
|
||||||
|
ptransfer_complete->start_time = strdup(get_time(now));
|
||||||
|
ptransfer_complete->complete_time = strdup(get_time(now));
|
||||||
|
ptransfer_complete->type = TYPE_DOWNLOAD;
|
||||||
|
ptransfer_complete->fault_code = FAULT_CPE_INTERNAL_ERROR;
|
||||||
|
bkp_session_insert_transfer_complete(ptransfer_complete);
|
||||||
|
bkp_session_save();
|
||||||
|
//cwmp_root_cause_transfer_complete(ptransfer_complete);
|
||||||
|
bkp_session_delete_transfer_complete(ptransfer_complete);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
retry:
|
||||||
|
if (sched_download->timewindowstruct[window_index].maxretries > 0) {
|
||||||
|
uloop_timeout_set(&sched_download->handler_timer, 10);
|
||||||
|
sched_download->timewindowstruct[window_index].maxretries--;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
bkp_session_insert_transfer_complete(ptransfer_complete);
|
||||||
|
bkp_session_save();
|
||||||
|
//cwmp_root_cause_transfer_complete(ptransfer_complete);
|
||||||
|
bkp_session_delete_transfer_complete(ptransfer_complete);
|
||||||
|
bkp_session_save();
|
||||||
|
}
|
||||||
|
list_del(&(sched_download->list));
|
||||||
|
if (sched_download->scheduled_time != 0)
|
||||||
|
count_download_queue--;
|
||||||
|
cwmp_free_schedule_download_request(sched_download);
|
||||||
|
|
||||||
|
struct session_timer_event *sched_download_inform_event = calloc(1, sizeof(struct session_timer_event));
|
||||||
|
|
||||||
|
sched_download_inform_event->extra_data = ptransfer_complete;
|
||||||
|
sched_download_inform_event->session_timer_evt.cb = cwmp_schedule_session_with_event;
|
||||||
|
sched_download_inform_event->event = TransferClt_Evt;
|
||||||
|
trigger_cwmp_session_timer_with_event(&sched_download_inform_event->session_timer_evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void apply_schedule_downloads()
|
||||||
|
{
|
||||||
|
struct list_head *ilist;
|
||||||
|
list_for_each (ilist, &(list_schedule_download)) {
|
||||||
|
struct download *sched_download = list_entry(ilist, struct download, list);
|
||||||
|
time_t now = time(NULL);
|
||||||
|
int download_delay;
|
||||||
|
if (sched_download->timewindowstruct[0].windowstart > now)
|
||||||
|
download_delay = sched_download->timewindowstruct[0].windowstart - now;
|
||||||
|
else if (sched_download->timewindowstruct[0].windowend >= now)
|
||||||
|
download_delay = 1;
|
||||||
|
else if (now < sched_download->timewindowstruct[1].windowstart)
|
||||||
|
download_delay = sched_download->timewindowstruct[1].windowstart - now;
|
||||||
|
else if (sched_download->timewindowstruct[1].windowend >= now)
|
||||||
|
download_delay = 1;
|
||||||
|
else
|
||||||
|
download_delay = 1;
|
||||||
|
|
||||||
|
uloop_timeout_set(&sched_download->handler_timer, 1000 * download_delay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@
|
||||||
*/
|
*/
|
||||||
#ifndef CWMP_DOWNLOAD_H
|
#ifndef CWMP_DOWNLOAD_H
|
||||||
#define CWMP_DOWNLOAD_H
|
#define CWMP_DOWNLOAD_H
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#define DOWNLOAD_PROTOCOL_HTTP "http://"
|
#define DOWNLOAD_PROTOCOL_HTTP "http://"
|
||||||
|
|
@ -32,26 +31,17 @@
|
||||||
|
|
||||||
extern struct list_head list_download;
|
extern struct list_head list_download;
|
||||||
extern struct list_head list_schedule_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;
|
extern int count_download_queue;
|
||||||
|
|
||||||
int cwmp_free_download_request(struct download *download);
|
int cwmp_free_download_request(struct download *download);
|
||||||
int cwmp_free_schedule_download_request(struct download *schedule_download);
|
int cwmp_free_schedule_download_request(struct download *schedule_download);
|
||||||
int cwmp_free_apply_schedule_download_request(struct apply_schedule_download *apply_schedule_download);
|
|
||||||
int cwmp_scheduledDownload_remove_all();
|
int cwmp_scheduledDownload_remove_all();
|
||||||
int cwmp_scheduled_Download_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);
|
||||||
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);
|
|
||||||
int cwmp_launch_download(struct download *pdownload, char *download_file_name, enum load_type ltype, struct transfer_complete **ptransfer_complete);
|
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);
|
||||||
|
void apply_downloads();
|
||||||
|
void apply_schedule_downloads();
|
||||||
|
void cwmp_start_schedule_download(struct uloop_timeout *timeout);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
418
src/event.c
418
src/event.c
|
|
@ -17,30 +17,33 @@
|
||||||
#include "download.h"
|
#include "download.h"
|
||||||
#include "upload.h"
|
#include "upload.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "session.h"
|
||||||
|
#include "cwmp_event.h"
|
||||||
|
//#include <libubox/list.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 },
|
const struct EVENT_CONST_STRUCT EVENT_CONST[] = {[EVENT_IDX_0BOOTSTRAP] = { "0 BOOTSTRAP", EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
||||||
[EVENT_IDX_1BOOT] = { "1 BOOT", EVENT_TYPE_SINGLE, EVENT_RETRY_AFTER_TRANSMIT_FAIL },
|
[EVENT_IDX_1BOOT] = { "1 BOOT", EVENT_RETRY_AFTER_TRANSMIT_FAIL },
|
||||||
[EVENT_IDX_2PERIODIC] = { "2 PERIODIC", EVENT_TYPE_SINGLE, EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
[EVENT_IDX_2PERIODIC] = { "2 PERIODIC", EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
||||||
[EVENT_IDX_3SCHEDULED] = { "3 SCHEDULED", EVENT_TYPE_SINGLE, EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
[EVENT_IDX_3SCHEDULED] = { "3 SCHEDULED", EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
||||||
[EVENT_IDX_4VALUE_CHANGE] = { "4 VALUE CHANGE", EVENT_TYPE_SINGLE, EVENT_RETRY_AFTER_TRANSMIT_FAIL },
|
[EVENT_IDX_4VALUE_CHANGE] = { "4 VALUE CHANGE", EVENT_RETRY_AFTER_TRANSMIT_FAIL },
|
||||||
[EVENT_IDX_5KICKED] = { "5 KICKED", EVENT_TYPE_SINGLE, EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
[EVENT_IDX_5KICKED] = { "5 KICKED", EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
||||||
[EVENT_IDX_6CONNECTION_REQUEST] = { "6 CONNECTION REQUEST", EVENT_TYPE_SINGLE, 0 },
|
[EVENT_IDX_6CONNECTION_REQUEST] = { "6 CONNECTION REQUEST", 0 },
|
||||||
[EVENT_IDX_7TRANSFER_COMPLETE] = { "7 TRANSFER COMPLETE", EVENT_TYPE_SINGLE, EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
[EVENT_IDX_7TRANSFER_COMPLETE] = { "7 TRANSFER COMPLETE", EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
||||||
[EVENT_IDX_8DIAGNOSTICS_COMPLETE] = { "8 DIAGNOSTICS COMPLETE", EVENT_TYPE_SINGLE, EVENT_RETRY_AFTER_TRANSMIT_FAIL },
|
[EVENT_IDX_8DIAGNOSTICS_COMPLETE] = { "8 DIAGNOSTICS COMPLETE", EVENT_RETRY_AFTER_TRANSMIT_FAIL },
|
||||||
[EVENT_IDX_9REQUEST_DOWNLOAD] = { "9 REQUEST DOWNLOAD", EVENT_TYPE_SINGLE, EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
[EVENT_IDX_9REQUEST_DOWNLOAD] = { "9 REQUEST DOWNLOAD", EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
||||||
[EVENT_IDX_10AUTONOMOUS_TRANSFER_COMPLETE] = { "10 AUTONOMOUS TRANSFER COMPLETE", EVENT_TYPE_SINGLE, EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
[EVENT_IDX_10AUTONOMOUS_TRANSFER_COMPLETE] = { "10 AUTONOMOUS TRANSFER COMPLETE", EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
||||||
[EVENT_IDX_11DU_STATE_CHANGE_COMPLETE] = { "11 DU STATE CHANGE COMPLETE", EVENT_TYPE_SINGLE, EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
[EVENT_IDX_11DU_STATE_CHANGE_COMPLETE] = { "11 DU STATE CHANGE COMPLETE", EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
||||||
[EVENT_IDX_M_Reboot] = { "M Reboot", EVENT_TYPE_MULTIPLE, EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
[EVENT_IDX_M_Reboot] = { "M Reboot", EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
||||||
[EVENT_IDX_M_ScheduleInform] = { "M ScheduleInform", EVENT_TYPE_MULTIPLE, EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
[EVENT_IDX_M_ScheduleInform] = { "M ScheduleInform", EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
||||||
[EVENT_IDX_M_Download] = { "M Download", EVENT_TYPE_MULTIPLE, EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
[EVENT_IDX_M_Download] = { "M Download", EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
||||||
[EVENT_IDX_M_Schedule_Download] = { "M ScheduleDownload", EVENT_TYPE_MULTIPLE, EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
[EVENT_IDX_M_Schedule_Download] = { "M ScheduleDownload", EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
||||||
[EVENT_IDX_M_Upload] = { "M Upload", EVENT_TYPE_MULTIPLE, EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
[EVENT_IDX_M_Upload] = { "M Upload", EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
||||||
[EVENT_IDX_M_ChangeDUState] = { "M ChangeDUState", EVENT_TYPE_MULTIPLE, EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
[EVENT_IDX_M_ChangeDUState] = { "M ChangeDUState", EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
|
||||||
[EVENT_IDX_14HEARTBEAT] = { "14 HEARTBEAT", EVENT_TYPE_SINGLE, EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT } };
|
[EVENT_IDX_14HEARTBEAT] = { "14 HEARTBEAT", EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT } };
|
||||||
|
|
||||||
void cwmp_save_event_container(struct event_container *event_container) //to be moved to backupsession
|
void cwmp_save_event_container(struct event_container *event_container) //to be moved to backupsession
|
||||||
{
|
{
|
||||||
if (EVENT_CONST[event_container->code].RETRY & EVENT_RETRY_AFTER_REBOOT) {
|
if (event_container && EVENT_CONST[event_container->code].RETRY & EVENT_RETRY_AFTER_REBOOT) {
|
||||||
struct list_head *ilist;
|
struct list_head *ilist;
|
||||||
mxml_node_t *b;
|
mxml_node_t *b;
|
||||||
|
|
||||||
|
|
@ -55,84 +58,27 @@ void cwmp_save_event_container(struct event_container *event_container) //to be
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct event_container *cwmp_add_event_container(struct cwmp *cwmp, int event_code, char *command_key)
|
int cwmp_root_cause_event_boot()
|
||||||
{
|
{
|
||||||
struct event_container *event_container;
|
if (cwmp_main->env.boot == CWMP_START_BOOT) {
|
||||||
struct list_head *ilist;
|
|
||||||
|
|
||||||
if (cwmp->head_event_container == NULL) {
|
|
||||||
struct session *session;
|
|
||||||
session = cwmp_add_queue_session(cwmp);
|
|
||||||
if (session == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
cwmp->head_event_container = &(session->head_event_container);
|
|
||||||
}
|
|
||||||
//session = list_entry(cwmp->head_event_container, struct session, head_event_container);
|
|
||||||
list_for_each (ilist, cwmp->head_event_container) {
|
|
||||||
event_container = list_entry(ilist, struct event_container, list);
|
|
||||||
if (event_container->code == event_code && EVENT_CONST[event_code].TYPE == EVENT_TYPE_SINGLE) {
|
|
||||||
return event_container;
|
|
||||||
}
|
|
||||||
if (event_container->code > event_code) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
event_container = calloc(1, sizeof(struct event_container));
|
|
||||||
if (event_container == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
INIT_LIST_HEAD(&(event_container->head_dm_parameter));
|
|
||||||
list_add(&(event_container->list), ilist->prev);
|
|
||||||
event_container->code = event_code;
|
|
||||||
event_container->command_key = command_key ? strdup(command_key) : strdup("");
|
|
||||||
if ((cwmp->event_id < 0) || (cwmp->event_id >= MAX_INT_ID)) {
|
|
||||||
cwmp->event_id = 0;
|
|
||||||
}
|
|
||||||
cwmp->event_id++;
|
|
||||||
event_container->id = cwmp->event_id;
|
|
||||||
return event_container;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cwmp_root_cause_event_ipdiagnostic(void)
|
|
||||||
{
|
|
||||||
struct cwmp *cwmp = &cwmp_main;
|
|
||||||
struct event_container *event_container;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&(cwmp->mutex_session_queue));
|
|
||||||
event_container = cwmp_add_event_container(cwmp, EVENT_IDX_8DIAGNOSTICS_COMPLETE, "");
|
|
||||||
if (event_container == NULL) {
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cwmp_save_event_container(event_container);
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
pthread_cond_signal(&(cwmp->threshold_session_send));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cwmp_root_cause_event_boot(struct cwmp *cwmp)
|
|
||||||
{
|
|
||||||
if (cwmp->env.boot == CWMP_START_BOOT) {
|
|
||||||
struct event_container *event_container;
|
struct event_container *event_container;
|
||||||
pthread_mutex_lock(&(cwmp->mutex_session_queue));
|
cwmp_main->env.boot = 0;
|
||||||
cwmp->env.boot = 0;
|
event_container = cwmp_add_event_container(EVENT_IDX_1BOOT, "");
|
||||||
event_container = cwmp_add_event_container(cwmp, EVENT_IDX_1BOOT, "");
|
if (event_container == NULL)
|
||||||
if (event_container == NULL) {
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return CWMP_MEM_ERR;
|
return CWMP_MEM_ERR;
|
||||||
}
|
|
||||||
cwmp_save_event_container(event_container);
|
cwmp_save_event_container(event_container);
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
}
|
}
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int event_remove_all_event_container(struct session *session, int rem_from)
|
int event_remove_all_event_container(int rem_from)
|
||||||
{
|
{
|
||||||
while (session->head_event_container.next != &(session->head_event_container)) {
|
while (cwmp_main->session->events.next != &cwmp_main->session->events) {
|
||||||
struct event_container *event_container;
|
struct event_container *event_container;
|
||||||
event_container = list_entry(session->head_event_container.next, struct event_container, list);
|
event_container = list_entry(cwmp_main->session->events.next, struct event_container, list);
|
||||||
|
if (event_container->code == EVENT_IDX_14HEARTBEAT)
|
||||||
|
continue;
|
||||||
bkp_session_delete_event(event_container->id, rem_from ? "send" : "queue");
|
bkp_session_delete_event(event_container->id, rem_from ? "send" : "queue");
|
||||||
free(event_container->command_key);
|
free(event_container->command_key);
|
||||||
cwmp_free_all_dm_parameter_list(&(event_container->head_dm_parameter));
|
cwmp_free_all_dm_parameter_list(&(event_container->head_dm_parameter));
|
||||||
|
|
@ -143,16 +89,40 @@ int event_remove_all_event_container(struct session *session, int rem_from)
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int event_remove_noretry_event_container(struct session *session, struct cwmp *cwmp)
|
int remove_single_event(int event_code)
|
||||||
|
{
|
||||||
|
while (cwmp_main->session->events.next != &cwmp_main->session->events) {
|
||||||
|
struct event_container *event_container;
|
||||||
|
event_container = list_entry(cwmp_main->session->events.next, struct event_container, list);
|
||||||
|
if (event_container->code == event_code) {
|
||||||
|
bkp_session_delete_event(event_container->id, "send");
|
||||||
|
free(event_container->command_key);
|
||||||
|
cwmp_free_all_dm_parameter_list(&(event_container->head_dm_parameter));
|
||||||
|
list_del(&(event_container->list));
|
||||||
|
free(event_container);
|
||||||
|
bkp_session_save();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (event_container) {
|
||||||
|
free(event_container->command_key);
|
||||||
|
cwmp_free_all_dm_parameter_list(&(event_container->head_dm_parameter));
|
||||||
|
list_del(&(event_container->list));
|
||||||
|
free(event_container);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CWMP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int event_remove_noretry_event_container()
|
||||||
{
|
{
|
||||||
struct list_head *ilist, *q;
|
struct list_head *ilist, *q;
|
||||||
|
|
||||||
list_for_each_safe (ilist, q, &(session->head_event_container)) {
|
list_for_each_safe (ilist, q, &(cwmp_main->session->events)) {
|
||||||
struct event_container *event_container;
|
struct event_container *event_container;
|
||||||
event_container = list_entry(ilist, struct event_container, list);
|
event_container = list_entry(ilist, struct event_container, list);
|
||||||
|
|
||||||
if (EVENT_CONST[event_container->code].CODE[0] == '6')
|
if (EVENT_CONST[event_container->code].CODE[0] == '6')
|
||||||
cwmp->cwmp_cr_event = 1;
|
cwmp_main->cwmp_cr_event = 1;
|
||||||
|
|
||||||
if (EVENT_CONST[event_container->code].RETRY == 0) {
|
if (EVENT_CONST[event_container->code].RETRY == 0) {
|
||||||
free(event_container->command_key);
|
free(event_container->command_key);
|
||||||
|
|
@ -164,254 +134,162 @@ int event_remove_noretry_event_container(struct session *session, struct cwmp *c
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cwmp_root_cause_event_bootstrap(struct cwmp *cwmp)
|
int cwmp_root_cause_event_bootstrap()
|
||||||
{
|
{
|
||||||
|
|
||||||
struct event_container *event_container;
|
struct event_container *event_container;
|
||||||
char *acsurl = NULL;
|
char *acsurl = NULL;
|
||||||
int cmp = 0;
|
int cmp = 0;
|
||||||
|
|
||||||
cwmp_load_saved_session(cwmp, &acsurl, ACS);
|
cwmp_load_saved_session(&acsurl, ACS);
|
||||||
|
|
||||||
if (acsurl == NULL)
|
if (acsurl == NULL)
|
||||||
save_acs_bkp_config(cwmp);
|
save_acs_bkp_config();
|
||||||
|
|
||||||
if (acsurl == NULL || ((cmp = CWMP_STRCMP(cwmp->conf.acsurl, acsurl)) != 0)) {
|
if (acsurl == NULL || ((cmp = strcmp(cwmp_main->conf.acsurl, acsurl)) != 0)) {
|
||||||
pthread_mutex_lock(&(cwmp->mutex_session_queue));
|
event_container = cwmp_add_event_container(EVENT_IDX_0BOOTSTRAP, "");
|
||||||
if (cwmp->head_event_container != NULL && cwmp->head_session_queue.next != &(cwmp->head_session_queue)) {
|
|
||||||
struct session *session;
|
|
||||||
session = list_entry(cwmp->head_event_container, struct session, head_event_container);
|
|
||||||
event_remove_all_event_container(session, RPC_QUEUE);
|
|
||||||
}
|
|
||||||
event_container = cwmp_add_event_container(cwmp, EVENT_IDX_0BOOTSTRAP, "");
|
|
||||||
FREE(acsurl);
|
FREE(acsurl);
|
||||||
if (event_container == NULL) {
|
if (event_container == NULL)
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return CWMP_MEM_ERR;
|
return CWMP_MEM_ERR;
|
||||||
}
|
|
||||||
cwmp_save_event_container(event_container);
|
cwmp_save_event_container(event_container);
|
||||||
cwmp_scheduleInform_remove_all();
|
cwmp_scheduleInform_remove_all();
|
||||||
cwmp_scheduledDownload_remove_all();
|
cwmp_scheduledDownload_remove_all();
|
||||||
cwmp_scheduled_Download_remove_all();
|
cwmp_scheduled_Download_remove_all();
|
||||||
cwmp_apply_scheduled_Download_remove_all();
|
|
||||||
cwmp_scheduledUpload_remove_all();
|
cwmp_scheduledUpload_remove_all();
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
} else
|
||||||
} else {
|
|
||||||
FREE(acsurl);
|
FREE(acsurl);
|
||||||
}
|
|
||||||
|
|
||||||
if (cmp) {
|
if (cmp) {
|
||||||
pthread_mutex_lock(&(cwmp->mutex_session_queue));
|
event_container = cwmp_add_event_container(EVENT_IDX_4VALUE_CHANGE, "");
|
||||||
event_container = cwmp_add_event_container(cwmp, EVENT_IDX_4VALUE_CHANGE, "");
|
if (event_container == NULL)
|
||||||
if (event_container == NULL) {
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return CWMP_MEM_ERR;
|
return CWMP_MEM_ERR;
|
||||||
}
|
|
||||||
|
|
||||||
char buf[64] = "Device.ManagementServer.URL";
|
char buf[64] = "Device.ManagementServer.URL";
|
||||||
add_dm_parameter_to_list(&(event_container->head_dm_parameter), buf, NULL, NULL, 0, false);
|
add_dm_parameter_to_list(&(event_container->head_dm_parameter), buf, NULL, NULL, 0, false);
|
||||||
cwmp_save_event_container(event_container);
|
cwmp_save_event_container(event_container);
|
||||||
save_acs_bkp_config(cwmp);
|
save_acs_bkp_config();
|
||||||
cwmp_scheduleInform_remove_all();
|
cwmp_scheduleInform_remove_all();
|
||||||
cwmp_scheduledDownload_remove_all();
|
cwmp_scheduledDownload_remove_all();
|
||||||
cwmp_apply_scheduled_Download_remove_all();
|
|
||||||
cwmp_scheduled_Download_remove_all();
|
cwmp_scheduled_Download_remove_all();
|
||||||
cwmp_scheduledUpload_remove_all();
|
cwmp_scheduledUpload_remove_all();
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cwmp_root_cause_transfer_complete(struct cwmp *cwmp, struct transfer_complete *p)
|
int cwmp_root_cause_transfer_complete(struct transfer_complete *p)
|
||||||
{
|
{
|
||||||
struct event_container *event_container;
|
struct event_container *event_container;
|
||||||
struct session *session;
|
|
||||||
struct rpc *rpc_acs;
|
struct rpc *rpc_acs;
|
||||||
|
|
||||||
pthread_mutex_lock(&(cwmp->mutex_session_queue));
|
event_container = cwmp_add_event_container(EVENT_IDX_7TRANSFER_COMPLETE, "");
|
||||||
event_container = cwmp_add_event_container(cwmp, EVENT_IDX_7TRANSFER_COMPLETE, "");
|
if (event_container == NULL)
|
||||||
if (event_container == NULL) {
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return CWMP_MEM_ERR;
|
return CWMP_MEM_ERR;
|
||||||
}
|
|
||||||
|
if ((rpc_acs = cwmp_add_session_rpc_acs(RPC_ACS_TRANSFER_COMPLETE)) == NULL)
|
||||||
|
return CWMP_MEM_ERR;
|
||||||
|
|
||||||
switch (p->type) {
|
switch (p->type) {
|
||||||
case TYPE_DOWNLOAD:
|
case TYPE_DOWNLOAD:
|
||||||
event_container = cwmp_add_event_container(cwmp, EVENT_IDX_M_Download, p->command_key ? p->command_key : "");
|
event_container = cwmp_add_event_container(EVENT_IDX_M_Download, p->command_key ? p->command_key : "");
|
||||||
if (event_container == NULL) {
|
if (event_container == NULL)
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return CWMP_MEM_ERR;
|
return CWMP_MEM_ERR;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case TYPE_UPLOAD:
|
case TYPE_UPLOAD:
|
||||||
event_container = cwmp_add_event_container(cwmp, EVENT_IDX_M_Upload, p->command_key ? p->command_key : "");
|
event_container = cwmp_add_event_container(EVENT_IDX_M_Upload, p->command_key ? p->command_key : "");
|
||||||
if (event_container == NULL) {
|
if (event_container == NULL)
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return CWMP_MEM_ERR;
|
return CWMP_MEM_ERR;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case TYPE_SCHEDULE_DOWNLOAD:
|
case TYPE_SCHEDULE_DOWNLOAD:
|
||||||
event_container = cwmp_add_event_container(cwmp, EVENT_IDX_M_Schedule_Download, p->command_key ? p->command_key : "");
|
event_container = cwmp_add_event_container(EVENT_IDX_M_Schedule_Download, p->command_key ? p->command_key : "");
|
||||||
if (event_container == NULL) {
|
if (event_container == NULL)
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return CWMP_MEM_ERR;
|
return CWMP_MEM_ERR;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
session = list_entry(cwmp->head_event_container, struct session, head_event_container);
|
|
||||||
if ((rpc_acs = cwmp_add_session_rpc_acs(session, RPC_ACS_TRANSFER_COMPLETE)) == NULL) {
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return CWMP_MEM_ERR;
|
|
||||||
}
|
|
||||||
rpc_acs->extra_data = (void *)p;
|
rpc_acs->extra_data = (void *)p;
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cwmp_root_cause_changedustate_complete(struct cwmp *cwmp, struct du_state_change_complete *p)
|
int cwmp_root_cause_changedustate_complete(struct du_state_change_complete *p)
|
||||||
{
|
{
|
||||||
struct event_container *event_container;
|
struct event_container *event_container;
|
||||||
struct session *session;
|
|
||||||
struct rpc *rpc_acs;
|
struct rpc *rpc_acs;
|
||||||
|
|
||||||
pthread_mutex_lock(&(cwmp->mutex_session_queue));
|
event_container = cwmp_add_event_container(EVENT_IDX_11DU_STATE_CHANGE_COMPLETE, "");
|
||||||
event_container = cwmp_add_event_container(cwmp, EVENT_IDX_11DU_STATE_CHANGE_COMPLETE, "");
|
if (event_container == NULL)
|
||||||
if (event_container == NULL) {
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return CWMP_MEM_ERR;
|
return CWMP_MEM_ERR;
|
||||||
}
|
|
||||||
|
|
||||||
event_container = cwmp_add_event_container(cwmp, EVENT_IDX_M_ChangeDUState, p->command_key ? p->command_key : "");
|
event_container = cwmp_add_event_container(EVENT_IDX_M_ChangeDUState, p->command_key ? p->command_key : "");
|
||||||
if (event_container == NULL) {
|
if (event_container == NULL)
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return CWMP_MEM_ERR;
|
return CWMP_MEM_ERR;
|
||||||
}
|
|
||||||
session = list_entry(cwmp->head_event_container, struct session, head_event_container);
|
if ((rpc_acs = cwmp_add_session_rpc_acs(RPC_ACS_DU_STATE_CHANGE_COMPLETE)) == NULL)
|
||||||
if ((rpc_acs = cwmp_add_session_rpc_acs(session, RPC_ACS_DU_STATE_CHANGE_COMPLETE)) == NULL) {
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return CWMP_MEM_ERR;
|
return CWMP_MEM_ERR;
|
||||||
}
|
|
||||||
rpc_acs->extra_data = (void *)p;
|
rpc_acs->extra_data = (void *)p;
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cwmp_root_cause_get_rpc_method(struct cwmp *cwmp)
|
int cwmp_root_cause_schedule_inform(struct schedule_inform *schedule_inform)
|
||||||
{
|
{
|
||||||
if (cwmp->env.periodic == CWMP_START_PERIODIC) {
|
|
||||||
struct event_container *event_container;
|
|
||||||
struct session *session;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&(cwmp->mutex_session_queue));
|
|
||||||
cwmp->env.periodic = 0;
|
|
||||||
event_container = cwmp_add_event_container(cwmp, EVENT_IDX_2PERIODIC, "");
|
|
||||||
if (event_container == NULL) {
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return CWMP_MEM_ERR;
|
|
||||||
}
|
|
||||||
cwmp_save_event_container(event_container);
|
|
||||||
session = list_entry(cwmp->head_event_container, struct session, head_event_container);
|
|
||||||
if (cwmp_add_session_rpc_acs(session, RPC_ACS_GET_RPC_METHODS) == NULL) {
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return CWMP_MEM_ERR;
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
}
|
|
||||||
|
|
||||||
return CWMP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *thread_event_periodic(void *v)
|
|
||||||
{
|
|
||||||
struct cwmp *cwmp = (struct cwmp *)v;
|
|
||||||
struct event_container *event_container;
|
struct event_container *event_container;
|
||||||
int periodic_interval;
|
event_container = cwmp_add_event_container(EVENT_IDX_3SCHEDULED, "");
|
||||||
bool periodic_enable;
|
if (event_container != NULL) {
|
||||||
time_t periodic_time;
|
|
||||||
struct timespec periodic_timeout = { 0, 0 };
|
|
||||||
time_t current_time;
|
|
||||||
long int delta_time;
|
|
||||||
time_t unknown_time;
|
|
||||||
|
|
||||||
periodic_interval = cwmp->conf.period;
|
|
||||||
periodic_enable = cwmp->conf.periodic_enable;
|
|
||||||
periodic_time = cwmp->conf.time;
|
|
||||||
unknown_time = convert_datetime_to_timestamp("0001-01-01T00:00:00Z");
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
pthread_mutex_lock(&(cwmp->mutex_periodic));
|
|
||||||
if (cwmp->conf.periodic_enable) {
|
|
||||||
current_time = time(NULL);
|
|
||||||
if (periodic_time != 0) {
|
|
||||||
if (periodic_time == unknown_time) {
|
|
||||||
delta_time = (current_time + cwmp->conf.periodic_entropy) % periodic_interval;
|
|
||||||
} else {
|
|
||||||
delta_time = (current_time - periodic_time) % periodic_interval;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (delta_time >= 0)
|
|
||||||
periodic_timeout.tv_sec = current_time + periodic_interval - delta_time;
|
|
||||||
else
|
|
||||||
periodic_timeout.tv_sec = current_time - delta_time;
|
|
||||||
} else {
|
|
||||||
periodic_timeout.tv_sec = current_time + periodic_interval;
|
|
||||||
}
|
|
||||||
cwmp->session_status.next_periodic = periodic_timeout.tv_sec;
|
|
||||||
pthread_cond_timedwait(&(cwmp->threshold_periodic), &(cwmp->mutex_periodic), &periodic_timeout);
|
|
||||||
} else {
|
|
||||||
cwmp->session_status.next_periodic = 0;
|
|
||||||
pthread_cond_wait(&(cwmp->threshold_periodic), &(cwmp->mutex_periodic));
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_periodic));
|
|
||||||
|
|
||||||
if (thread_end)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (periodic_interval != cwmp->conf.period || periodic_enable != cwmp->conf.periodic_enable || periodic_time != cwmp->conf.time) {
|
|
||||||
periodic_enable = cwmp->conf.periodic_enable;
|
|
||||||
periodic_interval = cwmp->conf.period;
|
|
||||||
periodic_time = cwmp->conf.time;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
CWMP_LOG(INFO, "Periodic thread: add periodic event in the queue");
|
|
||||||
pthread_mutex_lock(&(cwmp->mutex_session_queue));
|
|
||||||
event_container = cwmp_add_event_container(cwmp, EVENT_IDX_2PERIODIC, "");
|
|
||||||
if (event_container == NULL) {
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
cwmp_save_event_container(event_container);
|
cwmp_save_event_container(event_container);
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
pthread_cond_signal(&(cwmp->threshold_session_send));
|
|
||||||
}
|
}
|
||||||
return NULL;
|
event_container = cwmp_add_event_container(EVENT_IDX_M_ScheduleInform, schedule_inform->commandKey);
|
||||||
|
if (event_container != NULL) {
|
||||||
|
cwmp_save_event_container(event_container);
|
||||||
|
}
|
||||||
|
remove_schedule_inform(schedule_inform);
|
||||||
|
count_schedule_inform_queue--;
|
||||||
|
bkp_session_save();
|
||||||
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool event_exist_in_list(struct cwmp *cwmp, int event)
|
int cwmp_root_cause_get_rpc_method()
|
||||||
|
{
|
||||||
|
if (cwmp_main->env.periodic == CWMP_START_PERIODIC) {
|
||||||
|
struct event_container *event_container;
|
||||||
|
|
||||||
|
cwmp_main->env.periodic = 0;
|
||||||
|
event_container = cwmp_add_event_container(EVENT_IDX_2PERIODIC, "");
|
||||||
|
if (event_container == NULL)
|
||||||
|
return CWMP_MEM_ERR;
|
||||||
|
|
||||||
|
cwmp_save_event_container(event_container);
|
||||||
|
if (cwmp_add_session_rpc_acs(RPC_ACS_GET_RPC_METHODS) == NULL)
|
||||||
|
return CWMP_MEM_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CWMP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool event_exist_in_list(int event)
|
||||||
{
|
{
|
||||||
struct event_container *event_container = NULL;
|
struct event_container *event_container = NULL;
|
||||||
list_for_each_entry (event_container, cwmp->head_event_container, list) {
|
list_for_each_entry (event_container, &cwmp_main->session->events, list) {
|
||||||
if (event_container->code == event)
|
if (event_container->code == event)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cwmp_root_cause_event_periodic(struct cwmp *cwmp)
|
int cwmp_root_cause_event_periodic()
|
||||||
{
|
{
|
||||||
char local_time[27] = { 0 };
|
char local_time[27] = { 0 };
|
||||||
struct tm *t_tm;
|
struct tm *t_tm;
|
||||||
|
|
||||||
if (cwmp->cwmp_period == cwmp->conf.period && cwmp->cwmp_periodic_enable == cwmp->conf.periodic_enable && cwmp->cwmp_periodic_time == cwmp->conf.time)
|
if (cwmp_main->cwmp_period == cwmp_main->conf.period && cwmp_main->cwmp_periodic_enable == cwmp_main->conf.periodic_enable && cwmp_main->cwmp_periodic_time == cwmp_main->conf.time)
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
|
|
||||||
pthread_mutex_lock(&(cwmp->mutex_periodic));
|
cwmp_main->cwmp_period = cwmp_main->conf.period;
|
||||||
cwmp->cwmp_period = cwmp->conf.period;
|
cwmp_main->cwmp_periodic_enable = cwmp_main->conf.periodic_enable;
|
||||||
cwmp->cwmp_periodic_enable = cwmp->conf.periodic_enable;
|
cwmp_main->cwmp_periodic_time = cwmp_main->conf.time;
|
||||||
cwmp->cwmp_periodic_time = cwmp->conf.time;
|
CWMP_LOG(INFO, cwmp_main->cwmp_periodic_enable ? "Periodic event is enabled. Interval period = %ds" : "Periodic event is disabled", cwmp_main->cwmp_period);
|
||||||
CWMP_LOG(INFO, cwmp->cwmp_periodic_enable ? "Periodic event is enabled. Interval period = %ds" : "Periodic event is disabled", cwmp->cwmp_period);
|
|
||||||
|
|
||||||
t_tm = localtime(&cwmp->cwmp_periodic_time);
|
t_tm = localtime(&cwmp_main->cwmp_periodic_time);
|
||||||
if (t_tm == NULL)
|
if (t_tm == NULL)
|
||||||
return CWMP_GEN_ERR;
|
return CWMP_GEN_ERR;
|
||||||
|
|
||||||
|
|
@ -423,22 +301,20 @@ int cwmp_root_cause_event_periodic(struct cwmp *cwmp)
|
||||||
local_time[22] = ':';
|
local_time[22] = ':';
|
||||||
local_time[26] = '\0';
|
local_time[26] = '\0';
|
||||||
|
|
||||||
CWMP_LOG(INFO, cwmp->cwmp_periodic_time ? "Periodic time is %s" : "Periodic time is Unknown", local_time);
|
CWMP_LOG(INFO, cwmp_main->cwmp_periodic_time ? "Periodic time is %s" : "Periodic time is Unknown", local_time);
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_periodic));
|
|
||||||
pthread_cond_signal(&(cwmp->threshold_periodic));
|
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void connection_request_ip_value_change(struct cwmp *cwmp, int version)
|
void connection_request_ip_value_change(int version)
|
||||||
{
|
{
|
||||||
char *bip = NULL;
|
char *bip = NULL;
|
||||||
char *ip_version = (version == IPv6) ? "ipv6" : "ip";
|
char *ip_version = (version == IPv6) ? "ipv6" : "ip";
|
||||||
char *ip_value = (version == IPv6) ? cwmp->conf.ipv6 : cwmp->conf.ip;
|
char *ip_value = (version == IPv6) ? cwmp_main->conf.ipv6 : cwmp_main->conf.ip;
|
||||||
|
|
||||||
if (version == IPv6)
|
if (version == IPv6)
|
||||||
cwmp_load_saved_session(cwmp, &bip, CR_IPv6);
|
cwmp_load_saved_session(&bip, CR_IPv6);
|
||||||
else
|
else
|
||||||
cwmp_load_saved_session(cwmp, &bip, CR_IP);
|
cwmp_load_saved_session(&bip, CR_IP);
|
||||||
|
|
||||||
if (bip == NULL) {
|
if (bip == NULL) {
|
||||||
bkp_session_simple_insert_in_parent("connection_request", ip_version, ip_value);
|
bkp_session_simple_insert_in_parent("connection_request", ip_version, ip_value);
|
||||||
|
|
@ -447,30 +323,26 @@ void connection_request_ip_value_change(struct cwmp *cwmp, int version)
|
||||||
}
|
}
|
||||||
if (strcmp(bip, ip_value) != 0) {
|
if (strcmp(bip, ip_value) != 0) {
|
||||||
struct event_container *event_container;
|
struct event_container *event_container;
|
||||||
pthread_mutex_lock(&(cwmp->mutex_session_queue));
|
event_container = cwmp_add_event_container(EVENT_IDX_4VALUE_CHANGE, "");
|
||||||
event_container = cwmp_add_event_container(cwmp, EVENT_IDX_4VALUE_CHANGE, "");
|
|
||||||
if (event_container == NULL) {
|
if (event_container == NULL) {
|
||||||
FREE(bip);
|
FREE(bip);
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cwmp_save_event_container(event_container);
|
cwmp_save_event_container(event_container);
|
||||||
bkp_session_simple_insert_in_parent("connection_request", ip_version, ip_value);
|
bkp_session_simple_insert_in_parent("connection_request", ip_version, ip_value);
|
||||||
bkp_session_save();
|
bkp_session_save();
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
pthread_cond_signal(&(cwmp->threshold_session_send));
|
|
||||||
}
|
}
|
||||||
FREE(bip);
|
FREE(bip);
|
||||||
}
|
}
|
||||||
|
|
||||||
void connection_request_port_value_change(struct cwmp *cwmp, int port)
|
void connection_request_port_value_change(int port)
|
||||||
{
|
{
|
||||||
char *bport = NULL;
|
char *bport = NULL;
|
||||||
char bufport[16];
|
char bufport[16];
|
||||||
|
|
||||||
snprintf(bufport, sizeof(bufport), "%d", port);
|
snprintf(bufport, sizeof(bufport), "%d", port);
|
||||||
|
|
||||||
cwmp_load_saved_session(cwmp, &bport, CR_PORT);
|
cwmp_load_saved_session(&bport, CR_PORT);
|
||||||
|
|
||||||
if (bport == NULL) {
|
if (bport == NULL) {
|
||||||
bkp_session_simple_insert_in_parent("connection_request", "port", bufport);
|
bkp_session_simple_insert_in_parent("connection_request", "port", bufport);
|
||||||
|
|
@ -479,7 +351,7 @@ void connection_request_port_value_change(struct cwmp *cwmp, int port)
|
||||||
}
|
}
|
||||||
if (strcmp(bport, bufport) != 0) {
|
if (strcmp(bport, bufport) != 0) {
|
||||||
struct event_container *event_container;
|
struct event_container *event_container;
|
||||||
event_container = cwmp_add_event_container(cwmp, EVENT_IDX_4VALUE_CHANGE, "");
|
event_container = cwmp_add_event_container(EVENT_IDX_4VALUE_CHANGE, "");
|
||||||
if (event_container == NULL) {
|
if (event_container == NULL) {
|
||||||
FREE(bport);
|
FREE(bport);
|
||||||
return;
|
return;
|
||||||
|
|
@ -491,20 +363,20 @@ void connection_request_port_value_change(struct cwmp *cwmp, int port)
|
||||||
FREE(bport);
|
FREE(bport);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cwmp_root_cause_events(struct cwmp *cwmp)
|
int cwmp_root_cause_events()
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if ((error = cwmp_root_cause_event_bootstrap(cwmp)))
|
if ((error = cwmp_root_cause_event_bootstrap()))
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
if ((error = cwmp_root_cause_event_boot(cwmp)))
|
if ((error = cwmp_root_cause_event_boot()))
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
if ((error = cwmp_root_cause_get_rpc_method(cwmp)))
|
if ((error = cwmp_root_cause_get_rpc_method()))
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
if ((error = cwmp_root_cause_event_periodic(cwmp)))
|
if ((error = cwmp_root_cause_event_periodic()))
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
|
|
|
||||||
33
src/event.h
33
src/event.h
|
|
@ -13,7 +13,7 @@
|
||||||
#define EVENT_H_
|
#define EVENT_H_
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "session.h"
|
#include "event.h"
|
||||||
|
|
||||||
typedef struct event_container {
|
typedef struct event_container {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
|
@ -25,7 +25,6 @@ typedef struct event_container {
|
||||||
|
|
||||||
typedef struct EVENT_CONST_STRUCT {
|
typedef struct EVENT_CONST_STRUCT {
|
||||||
char *CODE;
|
char *CODE;
|
||||||
unsigned int TYPE;
|
|
||||||
unsigned short RETRY;
|
unsigned short RETRY;
|
||||||
|
|
||||||
} EVENT_CONST_STRUCT;
|
} EVENT_CONST_STRUCT;
|
||||||
|
|
@ -37,12 +36,6 @@ enum event_retry_after_enum
|
||||||
EVENT_RETRY_AFTER_BOOTSTRAP = 0x4
|
EVENT_RETRY_AFTER_BOOTSTRAP = 0x4
|
||||||
};
|
};
|
||||||
|
|
||||||
enum event_type_enum
|
|
||||||
{
|
|
||||||
EVENT_TYPE_SINGLE = 0x0,
|
|
||||||
EVENT_TYPE_MULTIPLE = 0x1
|
|
||||||
};
|
|
||||||
|
|
||||||
enum event_idx_enum
|
enum event_idx_enum
|
||||||
{
|
{
|
||||||
EVENT_IDX_0BOOTSTRAP,
|
EVENT_IDX_0BOOTSTRAP,
|
||||||
|
|
@ -64,22 +57,24 @@ enum event_idx_enum
|
||||||
EVENT_IDX_M_Upload,
|
EVENT_IDX_M_Upload,
|
||||||
EVENT_IDX_M_ChangeDUState,
|
EVENT_IDX_M_ChangeDUState,
|
||||||
EVENT_IDX_14HEARTBEAT,
|
EVENT_IDX_14HEARTBEAT,
|
||||||
|
TransferClt_Evt,
|
||||||
|
Schedule_Inform_Evt,
|
||||||
|
CDU_Evt,
|
||||||
__EVENT_IDX_MAX
|
__EVENT_IDX_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct EVENT_CONST_STRUCT EVENT_CONST[__EVENT_IDX_MAX];
|
extern const struct EVENT_CONST_STRUCT EVENT_CONST[__EVENT_IDX_MAX];
|
||||||
|
|
||||||
struct event_container *cwmp_add_event_container(struct cwmp *cwmp, int event_idx, char *command_key);
|
int event_remove_all_event_container(int rem_from);
|
||||||
int event_remove_all_event_container(struct session *session, int rem_from);
|
int remove_single_event(int event_code);
|
||||||
int event_remove_noretry_event_container(struct session *session, struct cwmp *cwmp);
|
int event_remove_noretry_event_container();
|
||||||
void cwmp_save_event_container(struct event_container *event_container);
|
void cwmp_save_event_container(struct event_container *event_container);
|
||||||
void *thread_event_periodic(void *v);
|
void connection_request_ip_value_change( int version);
|
||||||
void connection_request_ip_value_change(struct cwmp *cwmp, int version);
|
void connection_request_port_value_change(int port);
|
||||||
void connection_request_port_value_change(struct cwmp *cwmp, int port);
|
|
||||||
int cwmp_get_int_event_code(const char *code);
|
int cwmp_get_int_event_code(const char *code);
|
||||||
bool event_exist_in_list(struct cwmp *cwmp, int event);
|
bool event_exist_in_list(int event);
|
||||||
int cwmp_root_cause_events(struct cwmp *cwmp);
|
int cwmp_root_cause_events();
|
||||||
int cwmp_root_cause_transfer_complete(struct cwmp *cwmp, struct transfer_complete *p);
|
int cwmp_root_cause_transfer_complete(struct transfer_complete *p);
|
||||||
int cwmp_root_cause_changedustate_complete(struct cwmp *cwmp, struct du_state_change_complete *p);
|
int cwmp_root_cause_changedustate_complete(struct du_state_change_complete *p);
|
||||||
void cwmp_root_cause_event_ipdiagnostic(void);
|
int cwmp_root_cause_schedule_inform(struct schedule_inform *schedule_inform);
|
||||||
#endif /* SRC_INC_EVENT_H_ */
|
#endif /* SRC_INC_EVENT_H_ */
|
||||||
|
|
|
||||||
214
src/heartbeat.c
214
src/heartbeat.c
|
|
@ -10,6 +10,7 @@
|
||||||
*/
|
*/
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <libubox/uloop.h>
|
||||||
|
|
||||||
#include "heartbeat.h"
|
#include "heartbeat.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
@ -20,156 +21,89 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
|
#include "cwmp_event.h"
|
||||||
|
|
||||||
pthread_cond_t threshold_heartbeat_session;
|
|
||||||
pthread_cond_t threasheld_retry_session;
|
|
||||||
pthread_mutex_t mutex_heartbeat;
|
|
||||||
pthread_mutex_t mutex_heartbeat_session;
|
|
||||||
bool old_heartbeat_enable = false;
|
bool old_heartbeat_enable = false;
|
||||||
int heart_beat_retry_count_session = 0;
|
int heart_beat_retry_count_session = 0;
|
||||||
|
|
||||||
static struct session_status heart_beat_session_status = {0};
|
struct uloop_timeout heartbeat_session_timer = { .cb = cwmp_heartbeat_session_timer };
|
||||||
|
|
||||||
void check_trigger_heartbeat_session()
|
long int cwmp_heartbeat_session_time(void)
|
||||||
{
|
{
|
||||||
if (cwmp_main.conf.heart_beat_enable && !old_heartbeat_enable)
|
long int heartbeat_report;
|
||||||
pthread_cond_signal(&threshold_heartbeat_session);
|
time_t now = time(NULL);
|
||||||
}
|
struct tm *now_tm = gmtime((const time_t *)&now);
|
||||||
|
struct tm *heart_time = gmtime((const time_t *)&cwmp_main->conf.heart_time);
|
||||||
int add_heart_beat_event(struct session *heartbeat_session)
|
struct tm heart_init_tm = {.tm_year = now_tm->tm_year, .tm_mon = now_tm->tm_mon, .tm_mday = now_tm->tm_mday, .tm_hour = heart_time->tm_hour, .tm_min = heart_time->tm_min, .tm_sec = heart_time->tm_sec};
|
||||||
{
|
time_t heart_init_time = mktime(&heart_init_tm);
|
||||||
struct event_container *event_container;
|
if (heart_init_time - mktime(now_tm) < 0) {
|
||||||
event_container = calloc(1, sizeof(struct event_container));
|
add_day_to_time(&heart_init_tm);
|
||||||
if (event_container == NULL) {
|
heart_init_time = mktime(&heart_init_tm);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
INIT_LIST_HEAD(&(event_container->head_dm_parameter));
|
|
||||||
list_add(&(event_container->list), heartbeat_session->head_event_container.prev);
|
heartbeat_report = heart_init_time - mktime(now_tm);
|
||||||
event_container->code = EVENT_IDX_14HEARTBEAT;
|
|
||||||
event_container->command_key = strdup("");
|
return heartbeat_report;
|
||||||
event_container->id = 1;
|
|
||||||
/*
|
|
||||||
* event_container will be freed in the destruction of the session heartbeat_session
|
|
||||||
*/
|
|
||||||
// cppcheck-suppress memleak
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *thread_heartbeat_session(void *v __attribute__((unused)))
|
void cwmp_heartbeat_session_timer(struct uloop_timeout *timeout __attribute__((unused)))
|
||||||
{
|
{
|
||||||
static struct timespec heartbeat_interval = { 0, 0 };
|
if (cwmp_main->conf.heart_beat_enable) {
|
||||||
|
//HEARTBEAT event must wait a Non-HEARTBEAT Inform is being retried to be completed
|
||||||
sleep(2);
|
if (cwmp_main->session->session_status.last_status == SESSION_FAILURE) {
|
||||||
for (;;) {
|
cwmp_main->session->session_status.next_heartbeat = true;
|
||||||
if (thread_end)
|
cwmp_main->session->session_status.is_heartbeat = false;
|
||||||
break;
|
return;
|
||||||
|
|
||||||
if (cwmp_main.conf.heart_beat_enable) {
|
|
||||||
heartbeat_interval.tv_sec = time(NULL) + cwmp_main.conf.heartbeat_interval;
|
|
||||||
pthread_mutex_lock(&mutex_heartbeat);
|
|
||||||
pthread_cond_timedwait(&threshold_heartbeat_session, &mutex_heartbeat, &heartbeat_interval);
|
|
||||||
if (thread_end)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (cwmp_main.session_status.last_status == SESSION_FAILURE) {
|
|
||||||
CWMP_LOG(WARNING, "Not able to start HEARTBEAT Session for this period: CWMP Session is retrying");
|
|
||||||
pthread_cond_wait(&threasheld_retry_session, &mutex_heartbeat);
|
|
||||||
//continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thread_end)
|
|
||||||
break;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_heartbeat_session);
|
|
||||||
struct session *heartbeat_session = NULL;
|
|
||||||
heartbeat_session = calloc(1, sizeof(struct session));
|
|
||||||
if (heartbeat_session == NULL) {
|
|
||||||
pthread_mutex_unlock(&mutex_heartbeat_session);
|
|
||||||
pthread_mutex_unlock(&mutex_heartbeat);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
INIT_LIST_HEAD(&(heartbeat_session->head_event_container));
|
|
||||||
INIT_LIST_HEAD(&(heartbeat_session->head_rpc_acs));
|
|
||||||
INIT_LIST_HEAD(&(heartbeat_session->head_rpc_cpe));
|
|
||||||
struct rpc *rpc_acs;
|
|
||||||
rpc_acs = cwmp_add_session_rpc_acs_head(heartbeat_session, RPC_ACS_INFORM);
|
|
||||||
if (rpc_acs == NULL) {
|
|
||||||
cwmp_session_destructor(heartbeat_session);
|
|
||||||
pthread_mutex_unlock(&mutex_heartbeat_session);
|
|
||||||
pthread_mutex_unlock(&mutex_heartbeat);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (add_heart_beat_event(heartbeat_session) != 0) {
|
|
||||||
cwmp_session_destructor(heartbeat_session);
|
|
||||||
pthread_mutex_unlock(&mutex_heartbeat_session);
|
|
||||||
pthread_mutex_unlock(&mutex_heartbeat);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (heart_beat_session_status.last_status == SESSION_FAILURE) {
|
|
||||||
cwmp_config_load(&cwmp_main);
|
|
||||||
if (thread_end) {
|
|
||||||
cwmp_session_destructor(heartbeat_session);
|
|
||||||
pthread_mutex_unlock(&mutex_heartbeat_session);
|
|
||||||
pthread_mutex_unlock(&mutex_heartbeat);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
heart_beat_session_status.last_end_time = 0;
|
|
||||||
heart_beat_session_status.last_start_time = time(NULL);
|
|
||||||
heart_beat_session_status.last_status = SESSION_RUNNING;
|
|
||||||
heart_beat_session_status.next_retry = 0;
|
|
||||||
|
|
||||||
if (file_exists(fc_cookies))
|
|
||||||
remove(fc_cookies);
|
|
||||||
|
|
||||||
cwmp_uci_init();
|
|
||||||
CWMP_LOG(INFO, "Start HEARTBEAT session");
|
|
||||||
int error = cwmp_schedule_rpc(&cwmp_main, heartbeat_session);
|
|
||||||
CWMP_LOG(INFO, "End HEARTBEAT session");
|
|
||||||
cwmp_uci_exit();
|
|
||||||
|
|
||||||
if (thread_end) {
|
|
||||||
event_remove_all_event_container(heartbeat_session, RPC_SEND);
|
|
||||||
run_session_end_func();
|
|
||||||
cwmp_session_destructor(heartbeat_session);
|
|
||||||
pthread_mutex_unlock(&(cwmp_main.mutex_session_send));
|
|
||||||
pthread_mutex_unlock(&mutex_heartbeat);
|
|
||||||
// Exiting to avoid race conditions
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error || heartbeat_session->error == CWMP_RETRY_SESSION) {
|
|
||||||
cwmp_config_load(&cwmp_main);
|
|
||||||
heart_beat_retry_count_session++;
|
|
||||||
run_session_end_func();
|
|
||||||
CWMP_LOG(INFO, "Retry HEARTBEAT session, retry count = %d, retry in %ds", cwmp_main.retry_count_session, cwmp_get_retry_interval(&cwmp_main, 1));
|
|
||||||
heart_beat_session_status.last_end_time = time(NULL);
|
|
||||||
heart_beat_session_status.last_status = SESSION_FAILURE;
|
|
||||||
heart_beat_session_status.next_retry = time(NULL) + cwmp_get_retry_interval(&cwmp_main, 1);
|
|
||||||
heartbeat_interval.tv_sec = time(NULL) + cwmp_get_retry_interval(&cwmp_main, 1);
|
|
||||||
heart_beat_session_status.failure_session++;
|
|
||||||
pthread_mutex_unlock(&mutex_heartbeat_session);
|
|
||||||
pthread_mutex_unlock(&mutex_heartbeat);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
event_remove_all_event_container(heartbeat_session, RPC_SEND);
|
|
||||||
run_session_end_func();
|
|
||||||
cwmp_session_destructor(heartbeat_session);
|
|
||||||
heart_beat_retry_count_session = 0;
|
|
||||||
heart_beat_session_status.last_end_time = time(NULL);
|
|
||||||
heart_beat_session_status.last_status = SESSION_SUCCESS;
|
|
||||||
heart_beat_session_status.next_retry = 0;
|
|
||||||
heart_beat_session_status.success_session++;
|
|
||||||
heartbeat_interval.tv_sec = time(NULL) + cwmp_main.conf.heartbeat_interval;
|
|
||||||
pthread_mutex_unlock(&mutex_heartbeat_session);
|
|
||||||
pthread_mutex_unlock(&mutex_heartbeat);
|
|
||||||
} else {
|
|
||||||
pthread_mutex_lock(&mutex_heartbeat);
|
|
||||||
pthread_cond_wait(&threshold_heartbeat_session, &mutex_heartbeat);
|
|
||||||
pthread_mutex_unlock(&mutex_heartbeat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//struct session_timer_event *heartbeat_inform_event = calloc(1, sizeof(struct session_timer_event));
|
||||||
|
|
||||||
|
|
||||||
|
uloop_timeout_set(&heartbeat_session_timer, cwmp_main->conf.heartbeat_interval * 1000);
|
||||||
|
|
||||||
|
cwmp_main->session->session_status.next_heartbeat = false;
|
||||||
|
cwmp_main->session->session_status.is_heartbeat = true;
|
||||||
|
cwmp_add_event_container(EVENT_IDX_14HEARTBEAT, "");
|
||||||
|
start_cwmp_session();
|
||||||
}
|
}
|
||||||
return NULL;
|
}
|
||||||
|
|
||||||
|
void intiate_heartbeat_procedures()
|
||||||
|
{
|
||||||
|
uloop_timeout_cancel(&heartbeat_session_timer);
|
||||||
|
if (cwmp_main->conf.heart_beat_enable) {
|
||||||
|
if (cwmp_main->conf.heart_time == 0) {
|
||||||
|
uloop_timeout_set(&heartbeat_session_timer, cwmp_main->conf.heartbeat_interval * 1000);
|
||||||
|
} else {
|
||||||
|
time_t hearttime_interval = cwmp_main->conf.heart_time - time(NULL);
|
||||||
|
if (hearttime_interval >= 0) {
|
||||||
|
uloop_timeout_set(&heartbeat_session_timer, hearttime_interval * 1000);
|
||||||
|
} else {
|
||||||
|
uloop_timeout_set(&heartbeat_session_timer, cwmp_heartbeat_session_time() * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reinit_heartbeat_procedures()
|
||||||
|
{
|
||||||
|
if (cwmp_main->conf.heart_beat_enable) {
|
||||||
|
if (!cwmp_main->prev_heartbeat_enable || (cwmp_main->prev_heartbeat_interval != cwmp_main->conf.heartbeat_interval) || (cwmp_main->prev_heartbeat_time != cwmp_main->conf.heart_time)) {
|
||||||
|
cwmp_main->heart_session = true;
|
||||||
|
if ((cwmp_main->prev_heartbeat_time != cwmp_main->conf.heart_time) && cwmp_main->conf.heart_time != 0) {
|
||||||
|
time_t hearttime_interval = cwmp_main->conf.heart_time - time(NULL);
|
||||||
|
if (hearttime_interval >= 0)
|
||||||
|
cwmp_main->heart_session_interval = hearttime_interval;
|
||||||
|
else
|
||||||
|
cwmp_main->heart_session_interval = cwmp_heartbeat_session_time();
|
||||||
|
} else
|
||||||
|
cwmp_main->heart_session_interval = cwmp_main->conf.heartbeat_interval;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
uloop_timeout_cancel(&heartbeat_session_timer);
|
||||||
|
|
||||||
|
cwmp_main->prev_heartbeat_enable = cwmp_main->conf.heart_beat_enable;
|
||||||
|
cwmp_main->prev_heartbeat_interval = cwmp_main->conf.heartbeat_interval;
|
||||||
|
cwmp_main->prev_heartbeat_time = cwmp_main->conf.heart_time;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,11 @@
|
||||||
#define HEARTBEAT_H
|
#define HEARTBEAT_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
extern pthread_mutex_t mutex_heartbeat;
|
extern struct uloop_timeout heartbeat_session_timer;
|
||||||
extern pthread_mutex_t mutex_heartbeat_session;
|
|
||||||
extern pthread_cond_t threshold_heartbeat_session;
|
|
||||||
extern pthread_cond_t threasheld_retry_session;
|
|
||||||
extern int heart_beat_retry_count_session;
|
extern int heart_beat_retry_count_session;
|
||||||
extern bool old_heartbeat_enable;
|
extern bool old_heartbeat_enable;
|
||||||
|
|
||||||
void *thread_heartbeat_session(void *v);
|
void cwmp_heartbeat_session_timer(struct uloop_timeout *timeout);
|
||||||
void check_trigger_heartbeat_session();
|
void intiate_heartbeat_procedures();
|
||||||
|
void reinit_heartbeat_procedures();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
102
src/http.c
102
src/http.c
|
|
@ -39,14 +39,14 @@ void http_set_timeout(void)
|
||||||
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 1);
|
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int icwmp_http_client_init(struct cwmp *cwmp)
|
int icwmp_http_client_init()
|
||||||
{
|
{
|
||||||
char *dhcp_dis = NULL;
|
char *dhcp_dis = NULL;
|
||||||
char *acs_var_stat = NULL;
|
char *acs_var_stat = NULL;
|
||||||
|
|
||||||
uci_get_value(UCI_DHCP_DISCOVERY_PATH, &dhcp_dis);
|
uci_get_value(UCI_DHCP_DISCOVERY_PATH, &dhcp_dis);
|
||||||
|
|
||||||
if (dhcp_dis && cwmp->retry_count_session > 0 && strcmp(dhcp_dis, "enable") == 0) {
|
if (dhcp_dis && cwmp_main->retry_count_session > 0 && strcmp(dhcp_dis, "enable") == 0) {
|
||||||
uci_get_state_value(UCI_DHCP_ACS_URL, &acs_var_stat);
|
uci_get_state_value(UCI_DHCP_ACS_URL, &acs_var_stat);
|
||||||
if (acs_var_stat) {
|
if (acs_var_stat) {
|
||||||
if (icwmp_asprintf(&http_c.url, "%s", acs_var_stat) == -1) {
|
if (icwmp_asprintf(&http_c.url, "%s", acs_var_stat) == -1) {
|
||||||
|
|
@ -55,13 +55,13 @@ int icwmp_http_client_init(struct cwmp *cwmp)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (cwmp->conf.acsurl == NULL || icwmp_asprintf(&http_c.url, "%s", cwmp->conf.acsurl) == -1) {
|
if (cwmp_main->conf.acsurl == NULL || icwmp_asprintf(&http_c.url, "%s", cwmp_main->conf.acsurl) == -1) {
|
||||||
FREE(dhcp_dis);
|
FREE(dhcp_dis);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (cwmp->conf.acsurl == NULL || icwmp_asprintf(&http_c.url, "%s", cwmp->conf.acsurl) == -1) {
|
if (cwmp_main->conf.acsurl == NULL || icwmp_asprintf(&http_c.url, "%s", cwmp_main->conf.acsurl) == -1) {
|
||||||
FREE(dhcp_dis);
|
FREE(dhcp_dis);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -79,7 +79,7 @@ int icwmp_http_client_init(struct cwmp *cwmp)
|
||||||
if (!curl)
|
if (!curl)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (cwmp->conf.ipv6_enable) {
|
if (cwmp_main->conf.ipv6_enable) {
|
||||||
unsigned char buf[sizeof(struct in6_addr)];
|
unsigned char buf[sizeof(struct in6_addr)];
|
||||||
|
|
||||||
char *ip = NULL;
|
char *ip = NULL;
|
||||||
|
|
@ -131,21 +131,21 @@ static size_t http_get_response(void *buffer, size_t size, size_t rxed, char **m
|
||||||
return size * rxed;
|
return size * rxed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void http_set_security_options(struct cwmp *cwmp)
|
static void http_set_security_options()
|
||||||
{
|
{
|
||||||
curl_easy_setopt(curl, CURLOPT_USERNAME, cwmp->conf.acs_userid);
|
curl_easy_setopt(curl, CURLOPT_USERNAME, cwmp_main->conf.acs_userid);
|
||||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, cwmp->conf.acs_passwd);
|
curl_easy_setopt(curl, CURLOPT_PASSWORD, cwmp_main->conf.acs_passwd);
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC | CURLAUTH_DIGEST);
|
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC | CURLAUTH_DIGEST);
|
||||||
|
|
||||||
if (cwmp->conf.acs_ssl_capath)
|
if (cwmp_main->conf.acs_ssl_capath)
|
||||||
curl_easy_setopt(curl, CURLOPT_CAPATH, cwmp->conf.acs_ssl_capath);
|
curl_easy_setopt(curl, CURLOPT_CAPATH, cwmp_main->conf.acs_ssl_capath);
|
||||||
if (cwmp->conf.insecure_enable) {
|
if (cwmp_main->conf.insecure_enable) {
|
||||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void http_set_connection_options(struct cwmp *cwmp)
|
static void http_set_connection_options()
|
||||||
{
|
{
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, http_c.url);
|
curl_easy_setopt(curl, CURLOPT_URL, http_c.url);
|
||||||
|
|
||||||
|
|
@ -161,12 +161,12 @@ static void http_set_connection_options(struct cwmp *cwmp)
|
||||||
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, fc_cookies);
|
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, fc_cookies);
|
||||||
curl_easy_setopt(curl, CURLOPT_COOKIEJAR, fc_cookies);
|
curl_easy_setopt(curl, CURLOPT_COOKIEJAR, fc_cookies);
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_INTERFACE, cwmp->conf.interface);
|
curl_easy_setopt(curl, CURLOPT_INTERFACE, cwmp_main->conf.interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void http_set_header_list_options(struct cwmp *cwmp)
|
static void http_set_header_list_options()
|
||||||
{
|
{
|
||||||
switch (cwmp->conf.compression) {
|
switch (cwmp_main->conf.compression) {
|
||||||
case COMP_NONE:
|
case COMP_NONE:
|
||||||
break;
|
break;
|
||||||
case COMP_GZIP:
|
case COMP_GZIP:
|
||||||
|
|
@ -193,7 +193,7 @@ static void http_set_inout_options(char *msg_out, int msg_out_len, char **msg_in
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, msg_in);
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, msg_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
int icwmp_http_send_message(struct cwmp *cwmp, char *msg_out, int msg_out_len, char **msg_in)
|
int icwmp_http_send_message(char *msg_out, int msg_out_len, char **msg_in)
|
||||||
{
|
{
|
||||||
unsigned char buf[sizeof(struct in6_addr)];
|
unsigned char buf[sizeof(struct in6_addr)];
|
||||||
int tmp = 0;
|
int tmp = 0;
|
||||||
|
|
@ -212,15 +212,15 @@ int icwmp_http_send_message(struct cwmp *cwmp, char *msg_out, int msg_out_len, c
|
||||||
if (!http_c.header_list)
|
if (!http_c.header_list)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (cwmp->conf.http_disable_100continue) {
|
if (cwmp_main->conf.http_disable_100continue) {
|
||||||
http_c.header_list = curl_slist_append(http_c.header_list, "Expect:");
|
http_c.header_list = curl_slist_append(http_c.header_list, "Expect:");
|
||||||
if (!http_c.header_list)
|
if (!http_c.header_list)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
http_set_connection_options(cwmp);
|
http_set_connection_options();
|
||||||
http_set_security_options(cwmp);
|
http_set_security_options();
|
||||||
http_set_header_list_options(cwmp);
|
http_set_header_list_options();
|
||||||
http_set_inout_options(msg_out, msg_out_len, msg_in);
|
http_set_inout_options(msg_out, msg_out_len, msg_in);
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
|
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
|
||||||
|
|
@ -272,7 +272,7 @@ int icwmp_http_send_message(struct cwmp *cwmp, char *msg_out, int msg_out_len, c
|
||||||
}
|
}
|
||||||
|
|
||||||
if (http_code == 415) {
|
if (http_code == 415) {
|
||||||
cwmp->conf.compression = COMP_NONE;
|
cwmp_main->conf.compression = COMP_NONE;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (http_code != 200 && http_code != 204)
|
if (http_code != 200 && http_code != 204)
|
||||||
|
|
@ -301,11 +301,12 @@ error:
|
||||||
|
|
||||||
static void http_success_cr(void)
|
static void http_success_cr(void)
|
||||||
{
|
{
|
||||||
CWMP_LOG(INFO, "Connection Request thread: add connection request event in the queue");
|
CWMP_LOG(INFO, "Connection Request triggering ...");
|
||||||
pthread_mutex_lock(&(cwmp_main.mutex_session_queue));
|
struct blob_buf b = { 0 };
|
||||||
cwmp_add_event_container(&cwmp_main, EVENT_IDX_6CONNECTION_REQUEST, "");
|
memset(&b, 0, sizeof(struct blob_buf));
|
||||||
pthread_mutex_unlock(&(cwmp_main.mutex_session_queue));
|
blob_buf_init(&b, 0);
|
||||||
pthread_cond_signal(&(cwmp_main.threshold_session_send));
|
icwmp_ubus_invoke("tr069", "inform", b.head, NULL, NULL);
|
||||||
|
blob_buf_free(&b);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void http_cr_new_client(int client, bool service_available)
|
static void http_cr_new_client(int client, bool service_available)
|
||||||
|
|
@ -323,8 +324,8 @@ static void http_cr_new_client(int client, bool service_available)
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex_config_load);
|
pthread_mutex_lock(&mutex_config_load);
|
||||||
fp = fdopen(client, "r+");
|
fp = fdopen(client, "r+");
|
||||||
char *username = cwmp_main.conf.cpe_userid;
|
char *username = cwmp_main->conf.cpe_userid;
|
||||||
char *password = cwmp_main.conf.cpe_passwd;
|
char *password = cwmp_main->conf.cpe_passwd;
|
||||||
|
|
||||||
memset(auth_digest_buffer, 0, BUFSIZ);
|
memset(auth_digest_buffer, 0, BUFSIZ);
|
||||||
if (!username || !password) {
|
if (!username || !password) {
|
||||||
|
|
@ -332,7 +333,8 @@ static void http_cr_new_client(int client, bool service_available)
|
||||||
service_available = false;
|
service_available = false;
|
||||||
goto http_end;
|
goto http_end;
|
||||||
}
|
}
|
||||||
snprintf(cr_http_get_head, sizeof(cr_http_get_head), "GET %s HTTP/1.1", cwmp_main.conf.connection_request_path);
|
snprintf(cr_http_get_head, sizeof(cr_http_get_head), "GET %s HTTP/1.1", cwmp_main->conf.connection_request_path);
|
||||||
|
pthread_mutex_unlock(&mutex_config_load);
|
||||||
while (fgets(buffer, sizeof(buffer), fp)) {
|
while (fgets(buffer, sizeof(buffer), fp)) {
|
||||||
if (buffer[0] == '\r' || buffer[0] == '\n') {
|
if (buffer[0] == '\r' || buffer[0] == '\n') {
|
||||||
/* end of http request (empty line) */
|
/* end of http request (empty line) */
|
||||||
|
|
@ -363,6 +365,7 @@ static void http_cr_new_client(int client, bool service_available)
|
||||||
|
|
||||||
strip_lead_trail_char(buffer, '\n');
|
strip_lead_trail_char(buffer, '\n');
|
||||||
strip_lead_trail_char(buffer, '\r');
|
strip_lead_trail_char(buffer, '\r');
|
||||||
|
|
||||||
if (!strncasecmp(buffer, "Authorization: Digest ", strlen("Authorization: Digest "))) {
|
if (!strncasecmp(buffer, "Authorization: Digest ", strlen("Authorization: Digest "))) {
|
||||||
auth_digest_checked = true;
|
auth_digest_checked = true;
|
||||||
CWMP_STRNCPY(auth_digest_buffer, buffer, BUFSIZ);
|
CWMP_STRNCPY(auth_digest_buffer, buffer, BUFSIZ);
|
||||||
|
|
@ -377,7 +380,8 @@ static void http_cr_new_client(int client, bool service_available)
|
||||||
}
|
}
|
||||||
|
|
||||||
CWMP_LOG(INFO, "Received host: (%s)", request_host);
|
CWMP_LOG(INFO, "Received host: (%s)", request_host);
|
||||||
int auth_check = validate_http_digest_auth("GET", cwmp_main.conf.connection_request_path, auth_digest_buffer + strlen("Authorization: Digest "), REALM, username, password, cwmp_main.conf.session_timeout, request_host);
|
int auth_check = validate_http_digest_auth("GET", cwmp_main->conf.connection_request_path, auth_digest_buffer + strlen("Authorization: Digest "), REALM, username, password, cwmp_main->conf.session_timeout, request_host);
|
||||||
|
|
||||||
if (auth_check == -1) { /* invalid nonce */
|
if (auth_check == -1) { /* invalid nonce */
|
||||||
internal_error = true;
|
internal_error = true;
|
||||||
goto http_end;
|
goto http_end;
|
||||||
|
|
@ -392,11 +396,17 @@ http_end:
|
||||||
fputs("HTTP/1.1 503 Service Unavailable\r\n", fp);
|
fputs("HTTP/1.1 503 Service Unavailable\r\n", fp);
|
||||||
fputs("Connection: close\r\n", fp);
|
fputs("Connection: close\r\n", fp);
|
||||||
fputs("Content-Length: 0\r\n", fp);
|
fputs("Content-Length: 0\r\n", fp);
|
||||||
|
fputs("\r\n", fp);
|
||||||
|
fclose(fp);
|
||||||
|
close(client);
|
||||||
} else if (auth_status) {
|
} else if (auth_status) {
|
||||||
CWMP_LOG(INFO, "Receive Connection Request: success authentication");
|
CWMP_LOG(INFO, "Receive Connection Request: success authentication");
|
||||||
fputs("HTTP/1.1 200 OK\r\n", fp);
|
fputs("HTTP/1.1 200 OK\r\n", fp);
|
||||||
fputs("Connection: close\r\n", fp);
|
fputs("Connection: close\r\n", fp);
|
||||||
fputs("Content-Length: 0\r\n", fp);
|
fputs("Content-Length: 0\r\n", fp);
|
||||||
|
fputs("\r\n", fp);
|
||||||
|
fclose(fp);
|
||||||
|
close(client);
|
||||||
http_success_cr();
|
http_success_cr();
|
||||||
} else if (internal_error) {
|
} else if (internal_error) {
|
||||||
CWMP_LOG(INFO, "Receive Connection Request: Return 500 Internal Error");
|
CWMP_LOG(INFO, "Receive Connection Request: Return 500 Internal Error");
|
||||||
|
|
@ -408,13 +418,12 @@ http_end:
|
||||||
CWMP_LOG(INFO, "Receive Connection Request: Return 401 Unauthorized");
|
CWMP_LOG(INFO, "Receive Connection Request: Return 401 Unauthorized");
|
||||||
fputs("HTTP/1.1 401 Unauthorized\r\n", fp);
|
fputs("HTTP/1.1 401 Unauthorized\r\n", fp);
|
||||||
fputs("Connection: close\r\n", fp);
|
fputs("Connection: close\r\n", fp);
|
||||||
http_authentication_failure_resp(fp, "GET", cwmp_main.conf.connection_request_path, REALM, OPAQUE);
|
http_authentication_failure_resp(fp, "GET", cwmp_main->conf.connection_request_path, REALM, OPAQUE);
|
||||||
fputs("\r\n", fp);
|
fputs("\r\n", fp);
|
||||||
|
fputs("\r\n", fp);
|
||||||
|
fclose(fp);
|
||||||
|
close(client);
|
||||||
}
|
}
|
||||||
fputs("\r\n", fp);
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
pthread_mutex_unlock(&mutex_config_load);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void icwmp_http_server_init(void)
|
void icwmp_http_server_init(void)
|
||||||
|
|
@ -423,20 +432,20 @@ void icwmp_http_server_init(void)
|
||||||
unsigned short cr_port;
|
unsigned short cr_port;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
cr_port = (unsigned short)(cwmp_main.conf.connection_request_port);
|
cr_port = (unsigned short)(cwmp_main->conf.connection_request_port);
|
||||||
unsigned short i = (DEFAULT_CONNECTION_REQUEST_PORT == cr_port) ? 1 : 0;
|
unsigned short i = (DEFAULT_CONNECTION_REQUEST_PORT == cr_port) ? 1 : 0;
|
||||||
//Create socket
|
//Create socket
|
||||||
cwmp_main.cr_socket_desc = socket(AF_INET6, SOCK_STREAM, 0);
|
cwmp_main->cr_socket_desc = socket(AF_INET6, SOCK_STREAM, 0);
|
||||||
if (cwmp_main.cr_socket_desc == -1) {
|
if (cwmp_main->cr_socket_desc == -1) {
|
||||||
CWMP_LOG(ERROR, "Could not open server socket for Connection Requests, Error no is : %d, Error description is : %s", errno, strerror(errno));
|
CWMP_LOG(ERROR, "Could not open server socket for Connection Requests, Error no is : %d, Error description is : %s", errno, strerror(errno));
|
||||||
sleep(1);
|
sleep(1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
fcntl(cwmp_main.cr_socket_desc, F_SETFD, fcntl(cwmp_main.cr_socket_desc, F_GETFD) | FD_CLOEXEC);
|
fcntl(cwmp_main->cr_socket_desc, F_SETFD, fcntl(cwmp_main->cr_socket_desc, F_GETFD) | FD_CLOEXEC);
|
||||||
|
|
||||||
int reusaddr = 1;
|
int reusaddr = 1;
|
||||||
if (setsockopt(cwmp_main.cr_socket_desc, SOL_SOCKET, SO_REUSEADDR, &reusaddr, sizeof(int)) < 0) {
|
if (setsockopt(cwmp_main->cr_socket_desc, SOL_SOCKET, SO_REUSEADDR, &reusaddr, sizeof(int)) < 0) {
|
||||||
CWMP_LOG(WARNING, "setsockopt(SO_REUSEADDR) failed");
|
CWMP_LOG(WARNING, "setsockopt(SO_REUSEADDR) failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -447,7 +456,7 @@ void icwmp_http_server_init(void)
|
||||||
for (;; i++) {
|
for (;; i++) {
|
||||||
server.sin6_port = htons(cr_port);
|
server.sin6_port = htons(cr_port);
|
||||||
//Bind
|
//Bind
|
||||||
if (bind(cwmp_main.cr_socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0) {
|
if (bind(cwmp_main->cr_socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0) {
|
||||||
//print the error message
|
//print the error message
|
||||||
CWMP_LOG(ERROR, "Could not bind server socket on the port %d, Error no is : %d, Error description is : %s", cr_port, errno, strerror(errno));
|
CWMP_LOG(ERROR, "Could not bind server socket on the port %d, Error no is : %d, Error description is : %s", cr_port, errno, strerror(errno));
|
||||||
cr_port = DEFAULT_CONNECTION_REQUEST_PORT + i;
|
cr_port = DEFAULT_CONNECTION_REQUEST_PORT + i;
|
||||||
|
|
@ -461,9 +470,11 @@ void icwmp_http_server_init(void)
|
||||||
char cr_port_str[6];
|
char cr_port_str[6];
|
||||||
snprintf(cr_port_str, 6, "%hu", cr_port);
|
snprintf(cr_port_str, 6, "%hu", cr_port);
|
||||||
cr_port_str[5] = '\0';
|
cr_port_str[5] = '\0';
|
||||||
|
cwmp_uci_init();
|
||||||
cwmp_uci_set_value("cwmp", "cpe", "port", cr_port_str);
|
cwmp_uci_set_value("cwmp", "cpe", "port", cr_port_str);
|
||||||
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
|
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
|
||||||
connection_request_port_value_change(&cwmp_main, cr_port);
|
connection_request_port_value_change(cr_port);
|
||||||
|
cwmp_uci_exit();
|
||||||
CWMP_LOG(INFO, "Connection Request server initiated with the port: %d", cr_port);
|
CWMP_LOG(INFO, "Connection Request server initiated with the port: %d", cr_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -475,15 +486,15 @@ void icwmp_http_server_listen(void)
|
||||||
struct sockaddr_in6 client;
|
struct sockaddr_in6 client;
|
||||||
|
|
||||||
//Listen
|
//Listen
|
||||||
listen(cwmp_main.cr_socket_desc, 3);
|
listen(cwmp_main->cr_socket_desc, 3);
|
||||||
|
|
||||||
//Accept and incoming connection
|
//Accept and incoming connection
|
||||||
c = sizeof(struct sockaddr_in);
|
c = sizeof(struct sockaddr_in);
|
||||||
while ((client_sock = accept(cwmp_main.cr_socket_desc, (struct sockaddr *)&client, (socklen_t *)&c))) {
|
while ((client_sock = accept(cwmp_main->cr_socket_desc, (struct sockaddr *)&client, (socklen_t *)&c))) {
|
||||||
bool service_available;
|
bool service_available;
|
||||||
time_t current_time;
|
time_t current_time;
|
||||||
|
|
||||||
if (thread_end)
|
if (cwmp_stop)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
current_time = time(NULL);
|
current_time = time(NULL);
|
||||||
|
|
@ -499,7 +510,6 @@ void icwmp_http_server_listen(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
http_cr_new_client(client_sock, service_available);
|
http_cr_new_client(client_sock, service_available);
|
||||||
close(client_sock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client_sock < 0) {
|
if (client_sock < 0) {
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,11 @@ struct http_client {
|
||||||
|
|
||||||
void http_set_timeout(void);
|
void http_set_timeout(void);
|
||||||
|
|
||||||
int icwmp_http_client_init(struct cwmp *cwmp);
|
int icwmp_http_client_init();
|
||||||
void icwmp_http_client_exit(void);
|
void icwmp_http_client_exit(void);
|
||||||
int icwmp_http_send_message(struct cwmp *cwmp, char *msg_out, int msg_out_len, char **msg_in);
|
int icwmp_http_send_message(char *msg_out, int msg_out_len, char **msg_in);
|
||||||
|
|
||||||
void icwmp_http_server_init(void);
|
int http_cr_server_init(void);
|
||||||
void icwmp_http_server_listen(void);
|
void icwmp_http_server_listen(void);
|
||||||
|
void icwmp_http_server_init(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,13 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "xml.h"
|
#include "xml.h"
|
||||||
|
#include "cwmp_event.h"
|
||||||
|
|
||||||
LIST_HEAD(list_value_change);
|
LIST_HEAD(list_value_change);
|
||||||
LIST_HEAD(list_lw_value_change);
|
LIST_HEAD(list_lw_value_change);
|
||||||
LIST_HEAD(list_param_obj_notify);
|
LIST_HEAD(list_param_obj_notify);
|
||||||
pthread_mutex_t mutex_value_change = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
|
struct uloop_timeout check_notify_timer = { .cb = periodic_check_notifiy };
|
||||||
|
|
||||||
char *notifications[7] = {"disabled" , "passive", "active", "passive_lw", "passive_passive_lw", "active_lw", "passive_active_lw"};
|
char *notifications[7] = {"disabled" , "passive", "active", "passive_lw", "passive_passive_lw", "active_lw", "passive_active_lw"};
|
||||||
|
|
||||||
|
|
@ -392,15 +394,15 @@ void cwmp_update_enabled_notify_file(void)
|
||||||
/*
|
/*
|
||||||
* Load custom notify json file
|
* Load custom notify json file
|
||||||
*/
|
*/
|
||||||
void load_custom_notify_json(struct cwmp *cwmp)
|
void load_custom_notify_json()
|
||||||
{
|
{
|
||||||
struct blob_buf bbuf;
|
struct blob_buf bbuf;
|
||||||
struct blob_attr *cur;
|
struct blob_attr *cur;
|
||||||
struct blob_attr *custom_notify_list = NULL;
|
struct blob_attr *custom_notify_list = NULL;
|
||||||
int rem;
|
int rem;
|
||||||
|
|
||||||
cwmp->custom_notify_active = false;
|
cwmp_main->custom_notify_active = false;
|
||||||
if (cwmp->conf.custom_notify_json == NULL || !file_exists(cwmp->conf.custom_notify_json))
|
if (cwmp_main->conf.custom_notify_json == NULL || !file_exists(cwmp_main->conf.custom_notify_json))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Check for custom notification success import marker
|
// Check for custom notification success import marker
|
||||||
|
|
@ -411,8 +413,8 @@ void load_custom_notify_json(struct cwmp *cwmp)
|
||||||
blob_buf_init(&bbuf, 0);
|
blob_buf_init(&bbuf, 0);
|
||||||
|
|
||||||
// Create success marker in temp area, so that it can be in sync with backup script
|
// Create success marker in temp area, so that it can be in sync with backup script
|
||||||
if (blobmsg_add_json_from_file(&bbuf, cwmp->conf.custom_notify_json) == false) {
|
if (blobmsg_add_json_from_file(&bbuf, cwmp_main->conf.custom_notify_json) == false) {
|
||||||
CWMP_LOG(WARNING, "The file %s is not a valid JSON file", cwmp->conf.custom_notify_json);
|
CWMP_LOG(WARNING, "The file %s is not a valid JSON file", cwmp_main->conf.custom_notify_json);
|
||||||
blob_buf_free(&bbuf);
|
blob_buf_free(&bbuf);
|
||||||
creat(RUN_NOTIFY_MARKER, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
creat(RUN_NOTIFY_MARKER, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||||
return;
|
return;
|
||||||
|
|
@ -422,7 +424,7 @@ void load_custom_notify_json(struct cwmp *cwmp)
|
||||||
struct blob_attr *tb_notif[1] = { NULL};
|
struct blob_attr *tb_notif[1] = { NULL};
|
||||||
blobmsg_parse(p_notif, 1, tb_notif, blobmsg_data(bbuf.head), blobmsg_len(bbuf.head));
|
blobmsg_parse(p_notif, 1, tb_notif, blobmsg_data(bbuf.head), blobmsg_len(bbuf.head));
|
||||||
if (tb_notif[0] == NULL) {
|
if (tb_notif[0] == NULL) {
|
||||||
CWMP_LOG(WARNING, "The JSON file %s doesn't contain a notify parameters list", cwmp->conf.custom_notify_json);
|
CWMP_LOG(WARNING, "The JSON file %s doesn't contain a notify parameters list", cwmp_main->conf.custom_notify_json);
|
||||||
blob_buf_free(&bbuf);
|
blob_buf_free(&bbuf);
|
||||||
creat(RUN_NOTIFY_MARKER, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
creat(RUN_NOTIFY_MARKER, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||||
return;
|
return;
|
||||||
|
|
@ -454,7 +456,7 @@ void load_custom_notify_json(struct cwmp *cwmp)
|
||||||
}
|
}
|
||||||
blob_buf_free(&bbuf);
|
blob_buf_free(&bbuf);
|
||||||
creat(RUN_NOTIFY_MARKER, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
creat(RUN_NOTIFY_MARKER, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||||
cwmp->custom_notify_active = true;
|
cwmp_main->custom_notify_active = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -545,92 +547,70 @@ int check_value_change(void)
|
||||||
return int_ret;
|
return int_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sotfware_version_value_change(struct cwmp *cwmp, struct transfer_complete *p)
|
void cwmp_prepare_value_change()
|
||||||
|
{
|
||||||
|
struct event_container *event_container;
|
||||||
|
if (list_value_change.next == &(list_value_change))
|
||||||
|
return;
|
||||||
|
event_container = cwmp_add_event_container(EVENT_IDX_4VALUE_CHANGE, "");
|
||||||
|
if (!event_container)
|
||||||
|
return;
|
||||||
|
list_splice_init(&(list_value_change), &(event_container->head_dm_parameter));
|
||||||
|
cwmp_save_event_container(event_container);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sotfware_version_value_change(struct transfer_complete *p)
|
||||||
{
|
{
|
||||||
char *current_software_version = NULL;
|
char *current_software_version = NULL;
|
||||||
|
|
||||||
if (!p->old_software_version || p->old_software_version[0] == 0)
|
if (!p->old_software_version || p->old_software_version[0] == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
current_software_version = cwmp->deviceid.softwareversion;
|
current_software_version = cwmp_main->deviceid.softwareversion;
|
||||||
if (p->old_software_version && current_software_version && strcmp(p->old_software_version, current_software_version) != 0) {
|
if (p->old_software_version && current_software_version && strcmp(p->old_software_version, current_software_version) != 0)
|
||||||
pthread_mutex_lock(&(cwmp->mutex_session_queue));
|
cwmp_add_event_container(EVENT_IDX_4VALUE_CHANGE, "");
|
||||||
cwmp_add_event_container(cwmp, EVENT_IDX_4VALUE_CHANGE, "");
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *thread_periodic_check_notify(void *v)
|
void periodic_check_notifiy(struct uloop_timeout *timeout __attribute__((unused)))
|
||||||
{
|
{
|
||||||
struct cwmp *cwmp = (struct cwmp *)v;
|
int is_notify = 0;
|
||||||
int periodic_interval;
|
if (cwmp_stop)
|
||||||
bool periodic_enable;
|
return;
|
||||||
struct timespec periodic_timeout = { 0, 0 };
|
is_notify = check_value_change();
|
||||||
time_t current_time;
|
if (is_notify > 0)
|
||||||
int is_notify;
|
cwmp_update_enabled_notify_file();
|
||||||
|
if (is_notify & NOTIF_ACTIVE)
|
||||||
|
send_active_value_change();
|
||||||
|
if (is_notify & NOTIF_LW_ACTIVE)
|
||||||
|
cwmp_lwnotification();
|
||||||
|
|
||||||
periodic_interval = cwmp->conf.periodic_notify_interval;
|
uloop_timeout_set(&check_notify_timer, cwmp_main->conf.periodic_notify_interval * 1000);
|
||||||
periodic_enable = cwmp->conf.periodic_notify_enable;
|
}
|
||||||
|
|
||||||
for (;;) {
|
void trigger_periodic_notify_check()
|
||||||
if (periodic_enable) {
|
{
|
||||||
pthread_mutex_lock(&(cwmp->mutex_notify_periodic));
|
uloop_timeout_set(&check_notify_timer, 10);
|
||||||
current_time = time(NULL);
|
|
||||||
periodic_timeout.tv_sec = current_time + periodic_interval;
|
|
||||||
|
|
||||||
if (thread_end)
|
|
||||||
break;
|
|
||||||
|
|
||||||
pthread_cond_timedwait(&(cwmp->threshold_notify_periodic), &(cwmp->mutex_notify_periodic), &periodic_timeout);
|
|
||||||
|
|
||||||
if (thread_end)
|
|
||||||
break;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&(cwmp->mutex_session_send));
|
|
||||||
is_notify = check_value_change();
|
|
||||||
if (is_notify > 0)
|
|
||||||
cwmp_update_enabled_notify_file();
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_send));
|
|
||||||
if (is_notify & NOTIF_ACTIVE)
|
|
||||||
send_active_value_change();
|
|
||||||
if (is_notify & NOTIF_LW_ACTIVE)
|
|
||||||
cwmp_lwnotification();
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_notify_periodic));
|
|
||||||
} else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_list_value_change(char *param_name, char *param_data, char *param_type)
|
void add_list_value_change(char *param_name, char *param_data, char *param_type)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&(mutex_value_change));
|
|
||||||
add_dm_parameter_to_list(&list_value_change, param_name, param_data, param_type, 0, false);
|
add_dm_parameter_to_list(&list_value_change, param_name, param_data, param_type, 0, false);
|
||||||
pthread_mutex_unlock(&(mutex_value_change));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clean_list_value_change()
|
void clean_list_value_change()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&(mutex_value_change));
|
|
||||||
cwmp_free_all_dm_parameter_list(&list_value_change);
|
cwmp_free_all_dm_parameter_list(&list_value_change);
|
||||||
pthread_mutex_unlock(&(mutex_value_change));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_active_value_change(void)
|
void send_active_value_change(void)
|
||||||
{
|
{
|
||||||
struct cwmp *cwmp = &cwmp_main;
|
|
||||||
struct event_container *event_container;
|
struct event_container *event_container;
|
||||||
|
|
||||||
pthread_mutex_lock(&(cwmp->mutex_session_queue));
|
event_container = cwmp_add_event_container(EVENT_IDX_4VALUE_CHANGE, "");
|
||||||
event_container = cwmp_add_event_container(cwmp, EVENT_IDX_4VALUE_CHANGE, "");
|
if (event_container == NULL)
|
||||||
if (event_container == NULL) {
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
cwmp_save_event_container(event_container);
|
cwmp_save_event_container(event_container);
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
pthread_cond_signal(&(cwmp->threshold_session_send));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -641,10 +621,9 @@ void add_lw_list_value_change(char *param_name, char *param_data, char *param_ty
|
||||||
static void udplw_server_param(struct addrinfo **res)
|
static void udplw_server_param(struct addrinfo **res)
|
||||||
{
|
{
|
||||||
struct addrinfo hints = { 0 };
|
struct addrinfo hints = { 0 };
|
||||||
struct cwmp *cwmp = &cwmp_main;
|
struct config *conf = &(cwmp_main->conf);
|
||||||
struct config *conf;
|
|
||||||
char port[32];
|
char port[32];
|
||||||
conf = &(cwmp->conf);
|
|
||||||
hints.ai_family = AF_UNSPEC;
|
hints.ai_family = AF_UNSPEC;
|
||||||
hints.ai_socktype = SOCK_DGRAM;
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
snprintf(port, sizeof(port), "%d", conf->lw_notification_port);
|
snprintf(port, sizeof(port), "%d", conf->lw_notification_port);
|
||||||
|
|
@ -703,9 +682,8 @@ void cwmp_lwnotification()
|
||||||
char msg[1024], *msg_out;
|
char msg[1024], *msg_out;
|
||||||
char signature[41];
|
char signature[41];
|
||||||
struct addrinfo *servaddr;
|
struct addrinfo *servaddr;
|
||||||
struct cwmp *cwmp = &cwmp_main;
|
|
||||||
struct config *conf;
|
struct config *conf;
|
||||||
conf = &(cwmp->conf);
|
conf = &(cwmp_main->conf);
|
||||||
|
|
||||||
udplw_server_param(&servaddr);
|
udplw_server_param(&servaddr);
|
||||||
xml_prepare_lwnotification_message(&msg_out);
|
xml_prepare_lwnotification_message(&msg_out);
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,8 @@ enum NOTIFICATION_STATUS
|
||||||
extern struct cwmp_dm_parameter forced_notifications_parameters[];
|
extern struct cwmp_dm_parameter forced_notifications_parameters[];
|
||||||
extern struct list_head list_lw_value_change;
|
extern struct list_head list_lw_value_change;
|
||||||
extern struct list_head list_value_change;
|
extern struct list_head list_value_change;
|
||||||
extern pthread_mutex_t mutex_value_change;
|
|
||||||
extern struct list_head list_param_obj_notify;
|
extern struct list_head list_param_obj_notify;
|
||||||
|
extern struct uloop_timeout check_notify_timer;
|
||||||
|
|
||||||
/*#define foreach_parameter_notification(function, parameter, notification) \
|
/*#define foreach_parameter_notification(function, parameter, notification) \
|
||||||
#ifndef NOTIF_VARIABLES_##function \
|
#ifndef NOTIF_VARIABLES_##function \
|
||||||
|
|
@ -53,18 +53,21 @@ void cwmp_update_enabled_notify_file(void);
|
||||||
int check_value_change(void);
|
int check_value_change(void);
|
||||||
void create_list_param_obj_notify();
|
void create_list_param_obj_notify();
|
||||||
void create_list_param_leaf_notify();
|
void create_list_param_leaf_notify();
|
||||||
void sotfware_version_value_change(struct cwmp *cwmp, struct transfer_complete *p);
|
void sotfware_version_value_change(struct transfer_complete *p);
|
||||||
void *thread_periodic_check_notify(void *v);
|
void *thread_periodic_check_notify(void *v);
|
||||||
void send_active_value_change(void);
|
void send_active_value_change(void);
|
||||||
void add_list_value_change(char *param_name, char *param_data, char *param_type);
|
void add_list_value_change(char *param_name, char *param_data, char *param_type);
|
||||||
void clean_list_value_change();
|
void clean_list_value_change();
|
||||||
char *cwmp_set_parameter_attributes(char *parameter_name, int notification);
|
char *cwmp_set_parameter_attributes(char *parameter_name, int notification);
|
||||||
char *cwmp_get_parameter_attributes(char *parameter_name, struct list_head *parameters_list);
|
char *cwmp_get_parameter_attributes(char *parameter_name, struct list_head *parameters_list);
|
||||||
void load_custom_notify_json(struct cwmp *cwmp);
|
void load_custom_notify_json();
|
||||||
void add_lw_list_value_change(char *param_name, char *param_data, char *param_type);
|
void add_lw_list_value_change(char *param_name, char *param_data, char *param_type);
|
||||||
char *calculate_lwnotification_cnonce();
|
char *calculate_lwnotification_cnonce();
|
||||||
void cwmp_lwnotification();
|
void cwmp_lwnotification();
|
||||||
void clean_list_param_notify();
|
void clean_list_param_notify();
|
||||||
void init_list_param_notify();
|
void init_list_param_notify();
|
||||||
void reinit_list_param_notify();
|
void reinit_list_param_notify();
|
||||||
|
void cwmp_prepare_value_change();
|
||||||
|
void periodic_check_notifiy(struct uloop_timeout *timeout __attribute__((unused)));
|
||||||
|
void trigger_periodic_notify_check();
|
||||||
#endif /* SRC_INC_NOTIFICATIONS_H_ */
|
#endif /* SRC_INC_NOTIFICATIONS_H_ */
|
||||||
|
|
|
||||||
133
src/reboot.c
133
src/reboot.c
|
|
@ -1,121 +1,64 @@
|
||||||
/*
|
/*
|
||||||
* reboot.c - Reboot method fuctions
|
* 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) 2022, IOPSYS Software Solutions AB.
|
* Copyright (C) 2021 iopsys Software Solutions AB
|
||||||
*
|
* Author Omar Kallel <omar.kallel@pivasoftware.com>
|
||||||
* Author Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
|
|
||||||
*
|
|
||||||
* See LICENSE file for license related information.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "reboot.h"
|
#include "session.h"
|
||||||
#include "cwmp_uci.h"
|
#include "cwmp_uci.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "session.h"
|
#include "reboot.h"
|
||||||
|
|
||||||
static pthread_t delay_reboot_thread;
|
void cwmp_schedule_reboot(struct uloop_timeout *timeout __attribute__((unused)));
|
||||||
static pthread_t delay_schedule_thread;
|
void cwmp_delay_reboot(struct uloop_timeout *timeout __attribute__((unused)));
|
||||||
static int g_curr_delay_reboot = -1;
|
|
||||||
static time_t g_curr_schedule_redoot = 0;
|
|
||||||
|
|
||||||
static void *thread_delay_reboot(void *arg)
|
struct uloop_timeout schedule_reboot_timer = { .cb = cwmp_schedule_reboot };
|
||||||
|
struct uloop_timeout delay_reboot_timer = { .cb = cwmp_delay_reboot };
|
||||||
|
|
||||||
|
void cwmp_schedule_reboot(struct uloop_timeout *timeout __attribute__((unused)))
|
||||||
{
|
{
|
||||||
struct cwmp *cwmp = (struct cwmp *)arg;
|
cwmp_uci_set_value("cwmp", "cpe", "schedule_reboot", "0001-01-01T00:00:00Z");
|
||||||
|
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
|
||||||
|
if (time(NULL) > cwmp_main->conf.schedule_reboot)
|
||||||
|
return;
|
||||||
|
cwmp_reboot("schedule_reboot");
|
||||||
|
}
|
||||||
|
|
||||||
CWMP_LOG(INFO, "The device will reboot after %d seconds", cwmp->conf.delay_reboot);
|
void cwmp_delay_reboot(struct uloop_timeout *timeout __attribute__((unused)))
|
||||||
sleep(cwmp->conf.delay_reboot);
|
{
|
||||||
cwmp_uci_set_value("cwmp", "cpe", "delay_reboot", "-1");
|
cwmp_uci_set_value("cwmp", "cpe", "delay_reboot", "-1");
|
||||||
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
|
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
|
||||||
/* check if the session is running before calling reboot method */
|
if (cwmp_main->session->session_status.last_status == SESSION_RUNNING) {
|
||||||
/* if the session is in progress, wait until the end of the session */
|
|
||||||
/* else calling reboot method */
|
|
||||||
if (cwmp->session_status.last_status == SESSION_RUNNING) {
|
|
||||||
cwmp_set_end_session(END_SESSION_REBOOT);
|
cwmp_set_end_session(END_SESSION_REBOOT);
|
||||||
} else {
|
} else {
|
||||||
cwmp_reboot("delay_reboot");
|
cwmp_reboot("delay_reboot");
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_delay_reboot_thread(struct cwmp *cwmp, bool thread_exist)
|
void launch_reboot_methods()
|
||||||
{
|
{
|
||||||
if (thread_exist) {
|
static int curr_delay_reboot = -1;
|
||||||
CWMP_LOG(INFO, "There is already a delay reboot thread!, Cancel the current thread");
|
static time_t curr_schedule_redoot = 0;
|
||||||
|
|
||||||
pthread_cancel(delay_reboot_thread);
|
if (cwmp_main->conf.delay_reboot != curr_delay_reboot && cwmp_main->conf.delay_reboot > 0) {
|
||||||
create_delay_reboot_thread(cwmp, false);
|
CWMP_LOG(INFO, "The device will reboot after %ld seconds", cwmp_main->conf.delay_reboot);
|
||||||
} else {
|
curr_delay_reboot = cwmp_main->conf.delay_reboot;
|
||||||
CWMP_LOG(INFO, "Create a delay reboot thread");
|
uloop_timeout_cancel(&delay_reboot_timer);
|
||||||
|
uloop_timeout_set(&delay_reboot_timer, cwmp_main->conf.delay_reboot * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
if (pthread_create(&delay_reboot_thread, NULL, &thread_delay_reboot, (void *)cwmp)) {
|
if (cwmp_main->conf.schedule_reboot != curr_schedule_redoot && (cwmp_main->conf.schedule_reboot - time(NULL)) > 0) {
|
||||||
CWMP_LOG(ERROR, "Error when creating the delay reboot thread!");
|
curr_schedule_redoot = cwmp_main->conf.schedule_reboot;
|
||||||
}
|
time_t remaining_time = cwmp_main->conf.schedule_reboot - time(NULL);
|
||||||
|
CWMP_LOG(INFO, "The device will reboot after %ld seconds", remaining_time);
|
||||||
if (pthread_detach(delay_reboot_thread)) {
|
uloop_timeout_cancel(&schedule_reboot_timer);
|
||||||
CWMP_LOG(ERROR, "Error when creating the delay reboot thread!");
|
uloop_timeout_set(&schedule_reboot_timer, remaining_time * 1000);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *thread_schedule_reboot(void *arg)
|
|
||||||
{
|
|
||||||
struct cwmp *cwmp = (struct cwmp *)arg;
|
|
||||||
time_t remaining_time = cwmp->conf.schedule_reboot - time(NULL);
|
|
||||||
|
|
||||||
CWMP_LOG(INFO, "The device will reboot after %ld seconds", remaining_time);
|
|
||||||
sleep(remaining_time);
|
|
||||||
cwmp_uci_set_value("cwmp", "cpe", "schedule_reboot", "0001-01-01T00:00:00Z");
|
|
||||||
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
|
|
||||||
|
|
||||||
/* check if the session is running before calling reboot method */
|
|
||||||
/* if the session is in progress, wait until the end of the session */
|
|
||||||
/* else calling reboot method */
|
|
||||||
if (cwmp->session_status.last_status == SESSION_RUNNING) {
|
|
||||||
cwmp_set_end_session(END_SESSION_REBOOT);
|
|
||||||
} else {
|
|
||||||
cwmp_reboot("schedule_reboot");
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void create_schedule_reboot_thread(struct cwmp *cwmp, bool thread_exist)
|
|
||||||
{
|
|
||||||
if (thread_exist) {
|
|
||||||
CWMP_LOG(INFO, "There is already a schedule reboot thread!, Cancel the current thread");
|
|
||||||
|
|
||||||
pthread_cancel(delay_schedule_thread);
|
|
||||||
create_schedule_reboot_thread(cwmp, false);
|
|
||||||
} else {
|
|
||||||
CWMP_LOG(INFO, "Create a schedule reboot thread");
|
|
||||||
|
|
||||||
if (pthread_create(&delay_schedule_thread, NULL, &thread_schedule_reboot, (void *)cwmp)) {
|
|
||||||
CWMP_LOG(ERROR, "Error when creating the schedule reboot thread!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pthread_detach(delay_schedule_thread)) {
|
|
||||||
CWMP_LOG(ERROR, "Error when detaching the schedule reboot thread!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void launch_reboot_methods(struct cwmp *cwmp)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (cwmp->conf.delay_reboot != g_curr_delay_reboot && cwmp->conf.delay_reboot > 0) {
|
|
||||||
|
|
||||||
create_delay_reboot_thread(cwmp, (g_curr_delay_reboot != -1));
|
|
||||||
g_curr_delay_reboot = cwmp->conf.delay_reboot;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cwmp->conf.schedule_reboot != g_curr_schedule_redoot && (cwmp->conf.schedule_reboot - time(NULL)) > 0) {
|
|
||||||
|
|
||||||
create_schedule_reboot_thread(cwmp, (g_curr_schedule_redoot != 0));
|
|
||||||
g_curr_schedule_redoot = cwmp->conf.schedule_reboot;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
void launch_reboot_methods(struct cwmp *cwmp);
|
void launch_reboot_methods();
|
||||||
|
|
||||||
#endif //_REBOOT_H__
|
#endif //_REBOOT_H__
|
||||||
|
|
||||||
|
|
|
||||||
52
src/rpc.h
52
src/rpc.h
|
|
@ -20,34 +20,34 @@
|
||||||
extern const struct rpc_cpe_method rpc_cpe_methods[__RPC_CPE_MAX];
|
extern const struct rpc_cpe_method rpc_cpe_methods[__RPC_CPE_MAX];
|
||||||
extern struct rpc_acs_method rpc_acs_methods[__RPC_ACS_MAX];
|
extern struct rpc_acs_method rpc_acs_methods[__RPC_ACS_MAX];
|
||||||
|
|
||||||
int cwmp_handle_rpc_cpe_get_rpc_methods(struct session *session, struct rpc *rpc);
|
int cwmp_handle_rpc_cpe_get_rpc_methods(struct rpc *rpc);
|
||||||
int cwmp_handle_rpc_cpe_set_parameter_values(struct session *session, struct rpc *rpc);
|
int cwmp_handle_rpc_cpe_set_parameter_values(struct rpc *rpc);
|
||||||
int cwmp_handle_rpc_cpe_get_parameter_values(struct session *session, struct rpc *rpc);
|
int cwmp_handle_rpc_cpe_get_parameter_values(struct rpc *rpc);
|
||||||
int cwmp_handle_rpc_cpe_get_parameter_names(struct session *session, struct rpc *rpc);
|
int cwmp_handle_rpc_cpe_get_parameter_names(struct rpc *rpc);
|
||||||
int cwmp_handle_rpc_cpe_set_parameter_attributes(struct session *session, struct rpc *rpc);
|
int cwmp_handle_rpc_cpe_set_parameter_attributes(struct rpc *rpc);
|
||||||
int cwmp_handle_rpc_cpe_get_parameter_attributes(struct session *session, struct rpc *rpc);
|
int cwmp_handle_rpc_cpe_get_parameter_attributes(struct rpc *rpc);
|
||||||
int cwmp_handle_rpc_cpe_add_object(struct session *session, struct rpc *rpc);
|
int cwmp_handle_rpc_cpe_add_object(struct rpc *rpc);
|
||||||
int cwmp_handle_rpc_cpe_delete_object(struct session *session, struct rpc *rpc);
|
int cwmp_handle_rpc_cpe_delete_object(struct rpc *rpc);
|
||||||
int cwmp_handle_rpc_cpe_reboot(struct session *session, struct rpc *rpc);
|
int cwmp_handle_rpc_cpe_reboot(struct rpc *rpc);
|
||||||
int cwmp_handle_rpc_cpe_download(struct session *session, struct rpc *rpc);
|
int cwmp_handle_rpc_cpe_download(struct rpc *rpc);
|
||||||
int cwmp_handle_rpc_cpe_upload(struct session *session, struct rpc *rpc);
|
int cwmp_handle_rpc_cpe_upload(struct rpc *rpc);
|
||||||
int cwmp_handle_rpc_cpe_factory_reset(struct session *session, struct rpc *rpc);
|
int cwmp_handle_rpc_cpe_factory_reset(struct rpc *rpc);
|
||||||
int cwmp_handle_rpc_cpe_x_factory_reset_soft(struct session *session, struct rpc *rpc);
|
int cwmp_handle_rpc_cpe_x_factory_reset_soft(struct rpc *rpc);
|
||||||
int cancel_transfer(char *key);
|
int cancel_transfer(char *key);
|
||||||
int cwmp_handle_rpc_cpe_cancel_transfer(struct session *session, struct rpc *rpc);
|
int cwmp_handle_rpc_cpe_cancel_transfer(struct rpc *rpc);
|
||||||
int cwmp_handle_rpc_cpe_schedule_inform(struct session *session, struct rpc *rpc);
|
int cwmp_handle_rpc_cpe_schedule_inform(struct rpc *rpc);
|
||||||
int cwmp_handle_rpc_cpe_schedule_download(struct session *session, struct rpc *rpc);
|
int cwmp_handle_rpc_cpe_schedule_download(struct rpc *rpc);
|
||||||
int cwmp_handle_rpc_cpe_change_du_state(struct session *session, struct rpc *rpc);
|
int cwmp_handle_rpc_cpe_change_du_state(struct rpc *rpc);
|
||||||
int cwmp_handle_rpc_cpe_fault(struct session *session, struct rpc *rpc);
|
int cwmp_handle_rpc_cpe_fault(struct rpc *rpc);
|
||||||
|
|
||||||
int cwmp_rpc_acs_prepare_message_inform(struct cwmp *cwmp, struct session *session, struct rpc *rpc);
|
int cwmp_rpc_acs_prepare_message_inform(struct rpc *rpc);
|
||||||
int cwmp_rpc_acs_parse_response_inform(struct cwmp *cwmp, struct session *session, struct rpc *rpc);
|
int cwmp_rpc_acs_parse_response_inform(struct rpc *rpc);
|
||||||
int cwmp_rpc_acs_parse_response_get_rpc_methods(struct cwmp *cwmp, struct session *session, struct rpc *this);
|
int cwmp_rpc_acs_parse_response_get_rpc_methods(struct rpc *this);
|
||||||
int cwmp_rpc_acs_prepare_get_rpc_methods(struct cwmp *cwmp, struct session *session, struct rpc *rpc);
|
int cwmp_rpc_acs_prepare_get_rpc_methods(struct rpc *rpc);
|
||||||
int cwmp_rpc_acs_prepare_transfer_complete(struct cwmp *cwmp, struct session *session, struct rpc *rpc);
|
int cwmp_rpc_acs_prepare_transfer_complete(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_prepare_du_state_change_complete(struct rpc *rpc);
|
||||||
|
|
||||||
int xml_handle_message(struct session *session);
|
int xml_handle_message();
|
||||||
int cwmp_create_fault_message(struct session *session, struct rpc *rpc_cpe, int fault_code);
|
int cwmp_create_fault_message(struct rpc *rpc_cpe, int fault_code);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -13,101 +13,59 @@
|
||||||
#include "backupSession.h"
|
#include "backupSession.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "cwmp_event.h"
|
||||||
|
#include "session.h"
|
||||||
|
|
||||||
LIST_HEAD(list_schedule_inform);
|
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;
|
int count_schedule_inform_queue = 0;
|
||||||
|
|
||||||
void *thread_cwmp_rpc_cpe_scheduleInform(void *v)
|
int remove_schedule_inform(struct schedule_inform *schedule_inform)
|
||||||
{
|
{
|
||||||
struct cwmp *cwmp = (struct cwmp *)v;
|
if (schedule_inform != NULL) {
|
||||||
struct event_container *event_container;
|
list_del(&(schedule_inform->list));
|
||||||
struct schedule_inform *schedule_inform;
|
bkp_session_delete_schedule_inform(schedule_inform->scheduled_time, schedule_inform->commandKey ? schedule_inform->commandKey : "");
|
||||||
struct timespec si_timeout = { 0, 0 };
|
FREE(schedule_inform->commandKey);
|
||||||
time_t current_time, stime;
|
free(schedule_inform);
|
||||||
bool add_event_same_time = false;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
|
|
||||||
if (thread_end)
|
|
||||||
break;
|
|
||||||
|
|
||||||
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 CWMP_OK;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int cwmp_scheduleInform_remove_all()
|
int cwmp_scheduleInform_remove_all()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&mutex_schedule_inform);
|
|
||||||
while (list_schedule_inform.next != &(list_schedule_inform)) {
|
while (list_schedule_inform.next != &(list_schedule_inform)) {
|
||||||
struct schedule_inform *schedule_inform;
|
struct schedule_inform *schedule_inform;
|
||||||
schedule_inform = list_entry(list_schedule_inform.next, struct schedule_inform, list);
|
schedule_inform = list_entry(list_schedule_inform.next, struct schedule_inform, list);
|
||||||
|
|
||||||
list_del(&(schedule_inform->list));
|
remove_schedule_inform(schedule_inform);
|
||||||
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();
|
bkp_session_save();
|
||||||
pthread_mutex_unlock(&mutex_schedule_inform);
|
|
||||||
|
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cwmp_start_schedule_inform(struct uloop_timeout *timeout)
|
||||||
|
{
|
||||||
|
struct schedule_inform *schedule_inform = container_of(timeout, struct schedule_inform, handler_timer);;
|
||||||
|
|
||||||
|
struct session_timer_event *schedinform_inform_event = calloc(1, sizeof(struct session_timer_event));
|
||||||
|
|
||||||
|
schedinform_inform_event->extra_data = schedule_inform;
|
||||||
|
schedinform_inform_event->session_timer_evt.cb = cwmp_schedule_session_with_event;
|
||||||
|
schedinform_inform_event->event = Schedule_Inform_Evt;
|
||||||
|
trigger_cwmp_session_timer_with_event(&schedinform_inform_event->session_timer_evt);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void apply_schedule_inform()
|
||||||
|
{
|
||||||
|
struct list_head *ilist;
|
||||||
|
list_for_each (ilist, &(list_schedule_inform)) {
|
||||||
|
struct schedule_inform *sched_inform = list_entry(ilist, struct schedule_inform, list);
|
||||||
|
int sched_inform_delay = 0;
|
||||||
|
if (sched_inform->scheduled_time > time(NULL)) {
|
||||||
|
sched_inform_delay = sched_inform->scheduled_time - time(NULL);
|
||||||
|
}
|
||||||
|
uloop_timeout_set(&sched_inform->handler_timer, 1000 * sched_inform_delay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,15 +11,12 @@
|
||||||
|
|
||||||
#ifndef CWMP_SCHED_INFORM_H
|
#ifndef CWMP_SCHED_INFORM_H
|
||||||
#define CWMP_SCHED_INFORM_H
|
#define CWMP_SCHED_INFORM_H
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
extern struct list_head list_schedule_inform;
|
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 int count_schedule_inform_queue;
|
||||||
|
|
||||||
void *thread_cwmp_rpc_cpe_scheduleInform(void *v);
|
void cwmp_start_schedule_inform(struct uloop_timeout *timeout);
|
||||||
int cwmp_scheduleInform_remove_all();
|
int cwmp_scheduleInform_remove_all();
|
||||||
|
void apply_schedule_inform();
|
||||||
|
int remove_schedule_inform(struct schedule_inform *schedule_inform);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
775
src/session.c
775
src/session.c
|
|
@ -10,22 +10,493 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <mxml.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "rpc.h"
|
#include "rpc.h"
|
||||||
#include "backupSession.h"
|
#include "backupSession.h"
|
||||||
#include "heartbeat.h"
|
#include "heartbeat.h"
|
||||||
|
#include "http.h"
|
||||||
|
#include "download.h"
|
||||||
|
#include "upload.h"
|
||||||
|
#include "xml.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "notifications.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "ssl_utils.h"
|
||||||
|
#include "cwmp_event.h"
|
||||||
|
#include "diagnostic.h"
|
||||||
|
#include "heartbeat.h"
|
||||||
|
#include "sched_inform.h"
|
||||||
|
#include "cwmp_du_state.h"
|
||||||
|
|
||||||
|
static void cwmp_periodic_session_timer(struct uloop_timeout *timeout);
|
||||||
|
struct uloop_timeout session_timer = { .cb = cwmp_schedule_session };
|
||||||
|
struct uloop_timeout periodic_session_timer = { .cb = cwmp_periodic_session_timer };
|
||||||
|
struct uloop_timeout retry_session_timer = { .cb = cwmp_schedule_session };
|
||||||
|
//struct session_timer_event session_timer_evt = {.session_timer_evt = {.cb = cwmp_schedule_session_with_event}, .event = -1};
|
||||||
|
|
||||||
unsigned int end_session_flag = 0;
|
unsigned int end_session_flag = 0;
|
||||||
|
|
||||||
void cwmp_set_end_session(unsigned int flag)
|
int create_cwmp_session_structure()
|
||||||
{
|
{
|
||||||
end_session_flag |= flag;
|
cwmp_main->session = calloc(1, sizeof(struct session));
|
||||||
|
if (cwmp_main->session == NULL)
|
||||||
|
return CWMP_GEN_ERR;
|
||||||
|
INIT_LIST_HEAD(&(cwmp_main->session->events));
|
||||||
|
INIT_LIST_HEAD(&(cwmp_main->session->head_rpc_acs));
|
||||||
|
INIT_LIST_HEAD(&(cwmp_main->session->head_rpc_cpe));
|
||||||
|
cwmp_main->session->session_status.is_heartbeat = false;
|
||||||
|
cwmp_main->session->session_status.next_heartbeat = false;
|
||||||
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct rpc *cwmp_add_session_rpc_cpe(struct session *session, int type)
|
int cwmp_session_init()
|
||||||
|
{
|
||||||
|
struct rpc *rpc_acs;
|
||||||
|
|
||||||
|
cwmp_main->cwmp_cr_event = 0;
|
||||||
|
|
||||||
|
cwmp_uci_init();
|
||||||
|
/*
|
||||||
|
* Set Required methods as initial value of
|
||||||
|
*/
|
||||||
|
rpc_acs = cwmp_add_session_rpc_acs_head(RPC_ACS_GET_RPC_METHODS);
|
||||||
|
if (rpc_acs == NULL)
|
||||||
|
return CWMP_GEN_ERR;
|
||||||
|
|
||||||
|
rpc_acs = cwmp_add_session_rpc_acs_head(RPC_ACS_INFORM);
|
||||||
|
if (rpc_acs == NULL)
|
||||||
|
return CWMP_GEN_ERR;
|
||||||
|
|
||||||
|
set_cwmp_session_status(SESSION_RUNNING, 0);
|
||||||
|
if (file_exists(fc_cookies))
|
||||||
|
remove(fc_cookies);
|
||||||
|
return CWMP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int clean_cwmp_session_structure()
|
||||||
|
{
|
||||||
|
FREE(cwmp_main->session);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cwmp_session_rpc_destructor(struct rpc *rpc)
|
||||||
|
{
|
||||||
|
list_del(&(rpc->list));
|
||||||
|
free(rpc);
|
||||||
|
return CWMP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cwmp_session_exit()
|
||||||
|
{
|
||||||
|
cwmp_uci_exit();
|
||||||
|
icwmp_cleanmem();
|
||||||
|
return CWMP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cwmp_schedule_rpc()
|
||||||
|
{
|
||||||
|
struct list_head *ilist;
|
||||||
|
struct rpc *rpc_acs, *rpc_cpe;
|
||||||
|
|
||||||
|
if (icwmp_http_client_init() || cwmp_stop) {
|
||||||
|
CWMP_LOG(INFO, "Initializing http client failed");
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
list_for_each (ilist, &(cwmp_main->session->head_rpc_acs)) {
|
||||||
|
rpc_acs = list_entry(ilist, struct rpc, list);
|
||||||
|
if (rpc_acs_methods[rpc_acs->type].acs_support == RPC_ACS_NOT_SUPPORT) {
|
||||||
|
CWMP_LOG(WARNING, "The RPC method %s is not included in the RPCs list supported by the ACS", rpc_acs_methods[rpc_acs->type].name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!rpc_acs->type || cwmp_stop)
|
||||||
|
goto retry;
|
||||||
|
|
||||||
|
CWMP_LOG(INFO, "Preparing the %s RPC message to send to the ACS", rpc_acs_methods[rpc_acs->type].name);
|
||||||
|
if (rpc_acs_methods[rpc_acs->type].prepare_message(rpc_acs) || cwmp_stop)
|
||||||
|
goto retry;
|
||||||
|
|
||||||
|
if (xml_set_cwmp_id() || cwmp_stop)
|
||||||
|
goto retry;
|
||||||
|
|
||||||
|
CWMP_LOG(INFO, "Send the %s RPC message to the ACS", rpc_acs_methods[rpc_acs->type].name);
|
||||||
|
if (xml_send_message(rpc_acs) || cwmp_stop)
|
||||||
|
goto retry;
|
||||||
|
|
||||||
|
CWMP_LOG(INFO, "Get the %sResponse message from the ACS", rpc_acs_methods[rpc_acs->type].name);
|
||||||
|
if (rpc_acs_methods[rpc_acs->type].parse_response || cwmp_stop)
|
||||||
|
if (rpc_acs_methods[rpc_acs->type].parse_response(rpc_acs))
|
||||||
|
goto retry;
|
||||||
|
|
||||||
|
ilist = ilist->prev;
|
||||||
|
if (rpc_acs_methods[rpc_acs->type].extra_clean != NULL)
|
||||||
|
rpc_acs_methods[rpc_acs->type].extra_clean(rpc_acs);
|
||||||
|
cwmp_session_rpc_destructor(rpc_acs);
|
||||||
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
|
if (cwmp_main->session->hold_request || cwmp_stop)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If restart service caused firewall restart, wait for firewall restart to complete
|
||||||
|
if (g_firewall_restart == true)
|
||||||
|
check_firewall_restart_state();
|
||||||
|
|
||||||
|
CWMP_LOG(INFO, "Send empty message to the ACS");
|
||||||
|
if (xml_send_message(NULL) || cwmp_stop)
|
||||||
|
goto retry;
|
||||||
|
if (!cwmp_main->session->tree_in || cwmp_stop)
|
||||||
|
goto next;
|
||||||
|
|
||||||
|
CWMP_LOG(INFO, "Receive request from the ACS");
|
||||||
|
if (xml_handle_message() || cwmp_stop)
|
||||||
|
goto retry;
|
||||||
|
|
||||||
|
while (cwmp_main->session->head_rpc_cpe.next != &(cwmp_main->session->head_rpc_cpe)) {
|
||||||
|
|
||||||
|
rpc_cpe = list_entry(cwmp_main->session->head_rpc_cpe.next, struct rpc, list);
|
||||||
|
if (!rpc_cpe->type || cwmp_stop)
|
||||||
|
goto retry;
|
||||||
|
|
||||||
|
CWMP_LOG(INFO, "Preparing the %s%s message", rpc_cpe_methods[rpc_cpe->type].name, (rpc_cpe->type != RPC_CPE_FAULT) ? "Response" : "");
|
||||||
|
if (cwmp_rpc_cpe_handle_message(rpc_cpe) || cwmp_stop)
|
||||||
|
goto retry;
|
||||||
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
|
|
||||||
|
CWMP_LOG(INFO, "Send the %s%s message to the ACS", rpc_cpe_methods[rpc_cpe->type].name, (rpc_cpe->type != RPC_CPE_FAULT) ? "Response" : "");
|
||||||
|
if (xml_send_message(rpc_cpe) || cwmp_stop)
|
||||||
|
goto retry;
|
||||||
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
|
|
||||||
|
cwmp_session_rpc_destructor(rpc_cpe);
|
||||||
|
if (!cwmp_main->session->tree_in || cwmp_stop)
|
||||||
|
break;
|
||||||
|
|
||||||
|
CWMP_LOG(INFO, "Receive request from the ACS");
|
||||||
|
if (xml_handle_message() || cwmp_stop)
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
|
||||||
|
next:
|
||||||
|
if (cwmp_main->session->head_rpc_acs.next == &(cwmp_main->session->head_rpc_acs))
|
||||||
|
break;
|
||||||
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
|
}
|
||||||
|
|
||||||
|
cwmp_main->session->error = CWMP_OK;
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
retry:
|
||||||
|
CWMP_LOG(INFO, "Failed");
|
||||||
|
cwmp_main->session->error = CWMP_RETRY_SESSION;
|
||||||
|
event_remove_noretry_event_container();
|
||||||
|
|
||||||
|
end:
|
||||||
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
|
icwmp_http_client_exit();
|
||||||
|
xml_exit();
|
||||||
|
return cwmp_main->session->error;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cwmp_get_retry_interval(bool heart_beat)
|
||||||
|
{
|
||||||
|
unsigned int retry_count = 0;
|
||||||
|
double min = 0;
|
||||||
|
double max = 0;
|
||||||
|
int m = cwmp_main->conf.retry_min_wait_interval;
|
||||||
|
int k = cwmp_main->conf.retry_interval_multiplier;
|
||||||
|
int exp;
|
||||||
|
if (heart_beat)
|
||||||
|
exp = heart_beat_retry_count_session;
|
||||||
|
else
|
||||||
|
exp = cwmp_main->retry_count_session;
|
||||||
|
if (exp == 0)
|
||||||
|
return MAX_INT32;
|
||||||
|
if (exp > 10)
|
||||||
|
exp = 10;
|
||||||
|
min = pow(((double)k / 1000), (double)(exp - 1)) * m;
|
||||||
|
max = pow(((double)k / 1000), (double)exp) * m;
|
||||||
|
char *rand = generate_random_string(4);
|
||||||
|
if (rand) {
|
||||||
|
unsigned int dividend = (unsigned int)strtoul(rand, NULL, 16);
|
||||||
|
retry_count = dividend % ((unsigned int)max + 1 - (unsigned int)min) + (unsigned int)min;
|
||||||
|
free(rand);
|
||||||
|
}
|
||||||
|
return (retry_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_cwmp_session_status(int status, int retry_time)
|
||||||
|
{
|
||||||
|
cwmp_main->session->session_status.last_status = status;
|
||||||
|
if (status == SESSION_SUCCESS) {
|
||||||
|
cwmp_main->session->session_status.last_end_time = time(NULL);
|
||||||
|
cwmp_main->session->session_status.next_retry = 0;
|
||||||
|
cwmp_main->session->session_status.success_session++;
|
||||||
|
} else if (status == SESSION_RUNNING) {
|
||||||
|
cwmp_main->session->session_status.last_end_time = 0;
|
||||||
|
cwmp_main->session->session_status.next_retry = 0;
|
||||||
|
cwmp_main->session->session_status.last_start_time = time(NULL);
|
||||||
|
} else {
|
||||||
|
cwmp_main->session->session_status.last_end_time = time(NULL);
|
||||||
|
cwmp_main->session->session_status.next_retry = time(NULL) + retry_time;
|
||||||
|
cwmp_main->session->session_status.failure_session++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
char *exec_download = NULL;
|
||||||
|
|
||||||
|
uloop_timeout_cancel(&check_notify_timer);
|
||||||
|
if (cwmp_session_init() != CWMP_OK) {
|
||||||
|
CWMP_LOG(ERROR, "Not able to init a CWMP session");
|
||||||
|
t = cwmp_get_retry_interval(0);
|
||||||
|
CWMP_LOG(INFO, "Retry session, retry count = %d, retry in %ds", cwmp_main->retry_count_session, t);
|
||||||
|
set_cwmp_session_status(SESSION_FAILURE, t);
|
||||||
|
cwmp_config_load();
|
||||||
|
trigger_periodic_notify_check();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cwmp_main->session->session_status.last_status == SESSION_FAILURE)
|
||||||
|
cwmp_config_load();
|
||||||
|
/*
|
||||||
|
* Value changes
|
||||||
|
*/
|
||||||
|
if (!cwmp_main->session->session_status.is_heartbeat) {
|
||||||
|
int is_notify = 0;
|
||||||
|
if (file_exists(DM_ENABLED_NOTIFY)) {
|
||||||
|
if (!event_exist_in_list(EVENT_IDX_4VALUE_CHANGE))
|
||||||
|
is_notify = check_value_change();
|
||||||
|
}
|
||||||
|
if (is_notify > 0 || !file_exists(DM_ENABLED_NOTIFY) || cwmp_main->custom_notify_active) {
|
||||||
|
cwmp_main->custom_notify_active = false;
|
||||||
|
cwmp_update_enabled_notify_file();
|
||||||
|
}
|
||||||
|
cwmp_prepare_value_change(cwmp_main);
|
||||||
|
clean_list_value_change();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Start session
|
||||||
|
*/
|
||||||
|
|
||||||
|
CWMP_LOG(INFO, "Start session");
|
||||||
|
|
||||||
|
uci_get_value(UCI_CPE_EXEC_DOWNLOAD, &exec_download);
|
||||||
|
if (exec_download && strcmp(exec_download, "1") == 0) {
|
||||||
|
CWMP_LOG(INFO, "Firmware downloaded and applied successfully");
|
||||||
|
cwmp_uci_set_value("cwmp", "cpe", "exec_download", "0");
|
||||||
|
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
|
||||||
|
}
|
||||||
|
FREE(exec_download);
|
||||||
|
error = cwmp_schedule_rpc();
|
||||||
|
if (error != CWMP_OK) {
|
||||||
|
CWMP_LOG(ERROR, "CWMP session error: %d", error);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* End session
|
||||||
|
*/
|
||||||
|
CWMP_LOG(INFO, "End session");
|
||||||
|
|
||||||
|
if (cwmp_stop) {
|
||||||
|
event_remove_all_event_container(RPC_SEND);
|
||||||
|
event_remove_all_event_container(RPC_QUEUE);
|
||||||
|
run_session_end_func();
|
||||||
|
cwmp_session_exit();
|
||||||
|
rpc_exit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cwmp_main->session->error == CWMP_RETRY_SESSION && (!list_empty(&(cwmp_main->session->events)) || (list_empty(&(cwmp_main->session->events)) && cwmp_main->cwmp_cr_event == 0))) { //CWMP Retry session
|
||||||
|
cwmp_config_load();
|
||||||
|
cwmp_main->retry_count_session++;
|
||||||
|
t = cwmp_get_retry_interval(0);
|
||||||
|
CWMP_LOG(INFO, "Retry session, retry count = %d, retry in %ds", cwmp_main->retry_count_session, t);
|
||||||
|
if (!cwmp_main->session->session_status.is_heartbeat) {
|
||||||
|
set_cwmp_session_status(SESSION_FAILURE, t);
|
||||||
|
uloop_timeout_set(&retry_session_timer, 1000 * t);
|
||||||
|
} else {
|
||||||
|
uloop_timeout_cancel(&heartbeat_session_timer);
|
||||||
|
uloop_timeout_set(&heartbeat_session_timer, 1000 * t);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!cwmp_main->session->session_status.is_heartbeat)
|
||||||
|
event_remove_all_event_container(RPC_SEND);
|
||||||
|
else
|
||||||
|
remove_single_event(EVENT_IDX_14HEARTBEAT);
|
||||||
|
//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();
|
||||||
|
CWMP_LOG(INFO, "Waiting the next session");
|
||||||
|
if (cwmp_main->session->session_status.next_heartbeat && (cwmp_main->session->session_status.last_status == SESSION_SUCCESS)) {
|
||||||
|
cwmp_main->session->session_status.next_heartbeat = false;
|
||||||
|
uloop_timeout_cancel(&heartbeat_session_timer);
|
||||||
|
uloop_timeout_set(&heartbeat_session_timer, 1000);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
cwmp_main->session->session_status.is_heartbeat = false;
|
||||||
|
trigger_periodic_notify_check();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void trigger_cwmp_session_timer()
|
||||||
|
{
|
||||||
|
uloop_timeout_cancel(&retry_session_timer);
|
||||||
|
uloop_timeout_set(&session_timer, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cwmp_schedule_session(struct uloop_timeout *timeout __attribute__((unused)))
|
||||||
|
{
|
||||||
|
start_cwmp_session();
|
||||||
|
}
|
||||||
|
|
||||||
|
void trigger_cwmp_session_timer_with_event(struct uloop_timeout *timeout)
|
||||||
|
{
|
||||||
|
uloop_timeout_cancel(&retry_session_timer);
|
||||||
|
uloop_timeout_cancel(timeout);
|
||||||
|
uloop_timeout_set(timeout, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cwmp_schedule_session_with_event(struct uloop_timeout *timeout)
|
||||||
|
{
|
||||||
|
struct session_timer_event *session_event = container_of(timeout, struct session_timer_event, session_timer_evt);
|
||||||
|
FREE(global_session_event);
|
||||||
|
global_session_event = session_event;
|
||||||
|
if (session_event->event == TransferClt_Evt) {
|
||||||
|
struct transfer_complete *ptransfer_complete = (struct transfer_complete *)session_event->extra_data;
|
||||||
|
cwmp_root_cause_transfer_complete(ptransfer_complete);
|
||||||
|
} else if (session_event->event == CDU_Evt) {
|
||||||
|
struct du_state_change_complete *pdu_state_change_complete = (struct du_state_change_complete *)session_event->extra_data;
|
||||||
|
cwmp_root_cause_changedustate_complete(pdu_state_change_complete);
|
||||||
|
} else if (session_event->event == Schedule_Inform_Evt) {
|
||||||
|
struct schedule_inform *schedule_inform = (struct schedule_inform *)session_event->extra_data;
|
||||||
|
cwmp_root_cause_schedule_inform(schedule_inform);
|
||||||
|
} else if (session_event->event == EVENT_IDX_14HEARTBEAT) {
|
||||||
|
cwmp_main->session->session_status.next_heartbeat = false;
|
||||||
|
cwmp_main->session->session_status.is_heartbeat = true;
|
||||||
|
cwmp_add_event_container(EVENT_IDX_14HEARTBEAT, "");
|
||||||
|
} else if (session_event->event >= 0) {
|
||||||
|
struct event_container *event_container = NULL;
|
||||||
|
event_container = cwmp_add_event_container(session_event->event, "");
|
||||||
|
if (event_container == NULL) {
|
||||||
|
CWMP_LOG(ERROR, "Not able to add the event %s for the new session", EVENT_CONST[session_event->event].CODE);
|
||||||
|
}
|
||||||
|
session_event->event = -1;
|
||||||
|
cwmp_save_event_container(event_container);
|
||||||
|
}
|
||||||
|
|
||||||
|
start_cwmp_session();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cwmp_periodic_session_timer(struct uloop_timeout *timeout __attribute__((unused)))
|
||||||
|
{
|
||||||
|
if (cwmp_main->conf.periodic_enable && cwmp_main->conf.period > 0) {
|
||||||
|
cwmp_main->session->session_status.next_periodic = time(NULL) + cwmp_main->conf.period;
|
||||||
|
uloop_timeout_set(&periodic_session_timer, cwmp_main->conf.period * 1000);
|
||||||
|
}
|
||||||
|
if (cwmp_main->conf.periodic_enable) {
|
||||||
|
struct session_timer_event *periodic_inform_event = calloc(1, sizeof(struct session_timer_event));
|
||||||
|
|
||||||
|
periodic_inform_event->session_timer_evt.cb = cwmp_schedule_session_with_event;
|
||||||
|
periodic_inform_event->event = EVENT_IDX_2PERIODIC;
|
||||||
|
trigger_cwmp_session_timer_with_event(&periodic_inform_event->session_timer_evt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long int cwmp_periodic_session_time(void)
|
||||||
|
{
|
||||||
|
long int delta_time;
|
||||||
|
long int periodic_time;
|
||||||
|
|
||||||
|
delta_time = time(NULL) - cwmp_main->conf.time;
|
||||||
|
if(delta_time > 0)
|
||||||
|
periodic_time = cwmp_main->conf.period - (delta_time % cwmp_main->conf.period);
|
||||||
|
else
|
||||||
|
periodic_time = (-delta_time) % cwmp_main->conf.period;
|
||||||
|
|
||||||
|
cwmp_main->session->session_status.next_periodic = time(NULL) + periodic_time;
|
||||||
|
return periodic_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
void initiate_cwmp_periodic_session_feature()
|
||||||
|
{
|
||||||
|
uloop_timeout_cancel(&periodic_session_timer);
|
||||||
|
if (cwmp_main->conf.periodic_enable && cwmp_main->conf.period > 0) {
|
||||||
|
if (cwmp_main->conf.time > 0){
|
||||||
|
CWMP_LOG(INFO, "Init periodic inform: periodic_inform time = %ld, interval = %d\n", cwmp_main->conf.time, cwmp_main->conf.period);
|
||||||
|
uloop_timeout_set(&periodic_session_timer, cwmp_periodic_session_time() * 1000);
|
||||||
|
} else {
|
||||||
|
CWMP_LOG(INFO, "Init periodic inform: interval = %d\n", cwmp_main->conf.period);
|
||||||
|
cwmp_main->session->session_status.next_periodic = time(NULL) + cwmp_main->conf.period;
|
||||||
|
uloop_timeout_set(&periodic_session_timer, cwmp_main->conf.period * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reinit_cwmp_periodic_session_feature()
|
||||||
|
{
|
||||||
|
if (cwmp_main->conf.periodic_enable) {
|
||||||
|
if (!cwmp_main->prev_periodic_enable || (cwmp_main->prev_periodic_interval != cwmp_main->conf.period) || (cwmp_main->prev_periodic_time != cwmp_main->conf.time)) {
|
||||||
|
uloop_timeout_cancel(&periodic_session_timer);
|
||||||
|
if ((cwmp_main->prev_periodic_time != cwmp_main->conf.time) && cwmp_main->conf.time > 0)
|
||||||
|
uloop_timeout_set(&periodic_session_timer, cwmp_periodic_session_time() * 1000);
|
||||||
|
else
|
||||||
|
uloop_timeout_set(&periodic_session_timer, cwmp_main->conf.period * 1000);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
uloop_timeout_cancel(&periodic_session_timer);
|
||||||
|
|
||||||
|
cwmp_main->prev_periodic_enable = cwmp_main->conf.periodic_enable;
|
||||||
|
cwmp_main->prev_periodic_interval = cwmp_main->conf.period;
|
||||||
|
cwmp_main->prev_periodic_time = cwmp_main->conf.time;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct rpc *cwmp_add_session_rpc_cpe(int type)
|
||||||
{
|
{
|
||||||
struct rpc *rpc_cpe;
|
struct rpc *rpc_cpe;
|
||||||
|
|
||||||
|
|
@ -34,11 +505,11 @@ struct rpc *cwmp_add_session_rpc_cpe(struct session *session, int type)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
rpc_cpe->type = type;
|
rpc_cpe->type = type;
|
||||||
list_add_tail(&(rpc_cpe->list), &(session->head_rpc_cpe));
|
list_add_tail(&(rpc_cpe->list), &(cwmp_main->session->head_rpc_cpe));
|
||||||
return rpc_cpe;
|
return rpc_cpe;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct rpc *cwmp_add_session_rpc_acs(struct session *session, int type)
|
struct rpc *cwmp_add_session_rpc_acs(int type)
|
||||||
{
|
{
|
||||||
struct rpc *rpc_acs;
|
struct rpc *rpc_acs;
|
||||||
|
|
||||||
|
|
@ -47,7 +518,7 @@ struct rpc *cwmp_add_session_rpc_acs(struct session *session, int type)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
rpc_acs->type = type;
|
rpc_acs->type = type;
|
||||||
list_add_tail(&(rpc_acs->list), &(session->head_rpc_acs));
|
list_add_tail(&(rpc_acs->list), &(cwmp_main->session->head_rpc_acs));
|
||||||
return rpc_acs;
|
return rpc_acs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -55,7 +526,7 @@ int cwmp_apply_acs_changes(void)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
old_heartbeat_enable = cwmp_main.conf.heart_beat_enable;
|
old_heartbeat_enable = cwmp_main->conf.heart_beat_enable;
|
||||||
|
|
||||||
if ((error = cwmp_config_reload(&cwmp_main)))
|
if ((error = cwmp_config_reload(&cwmp_main)))
|
||||||
return error;
|
return error;
|
||||||
|
|
@ -66,23 +537,7 @@ int cwmp_apply_acs_changes(void)
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cwmp_move_session_to_session_send(struct cwmp *cwmp, struct session *session)
|
struct rpc *cwmp_add_session_rpc_acs_head(int type)
|
||||||
{
|
|
||||||
pthread_mutex_lock(&(cwmp->mutex_session_queue));
|
|
||||||
if (cwmp->session_send != NULL) {
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return CWMP_MUTEX_ERR;
|
|
||||||
}
|
|
||||||
list_del(&(session->list));
|
|
||||||
cwmp->session_send = session;
|
|
||||||
cwmp->head_event_container = NULL;
|
|
||||||
bkp_session_move_inform_to_inform_send();
|
|
||||||
bkp_session_save();
|
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return CWMP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct rpc *cwmp_add_session_rpc_acs_head(struct session *session, int type)
|
|
||||||
{
|
{
|
||||||
struct rpc *rpc_acs;
|
struct rpc *rpc_acs;
|
||||||
|
|
||||||
|
|
@ -91,151 +546,145 @@ struct rpc *cwmp_add_session_rpc_acs_head(struct session *session, int type)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
rpc_acs->type = type;
|
rpc_acs->type = type;
|
||||||
list_add(&(rpc_acs->list), &(session->head_rpc_acs));
|
list_add(&(rpc_acs->list), &(cwmp_main->session->head_rpc_acs));
|
||||||
return rpc_acs;
|
return rpc_acs;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct session *cwmp_add_queue_session(struct cwmp *cwmp)
|
void cwmp_set_end_session(unsigned int flag)
|
||||||
{
|
{
|
||||||
struct session *session = NULL;
|
end_session_flag |= flag;
|
||||||
struct rpc *rpc_acs;
|
|
||||||
|
|
||||||
session = calloc(1, sizeof(struct session));
|
|
||||||
if (session == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
list_add_tail(&(session->list), &(cwmp->head_session_queue));
|
|
||||||
INIT_LIST_HEAD(&(session->head_event_container));
|
|
||||||
INIT_LIST_HEAD(&(session->head_rpc_acs));
|
|
||||||
INIT_LIST_HEAD(&(session->head_rpc_cpe));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set Required methods as initial value of
|
|
||||||
*/
|
|
||||||
rpc_acs = cwmp_add_session_rpc_acs_head(session, RPC_ACS_GET_RPC_METHODS);
|
|
||||||
if (rpc_acs == NULL) {
|
|
||||||
FREE(session);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
rpc_acs = cwmp_add_session_rpc_acs_head(session, RPC_ACS_INFORM);
|
|
||||||
if (rpc_acs == NULL) {
|
|
||||||
FREE(session);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return session;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int cwmp_session_rpc_destructor(struct rpc *rpc)
|
int run_session_end_func(void)
|
||||||
{
|
{
|
||||||
list_del(&(rpc->list));
|
if (end_session_flag & END_SESSION_RESTART_SERVICES) {
|
||||||
free(rpc);
|
CWMP_LOG(INFO, "Restart modified services");
|
||||||
return CWMP_OK;
|
icwmp_restart_services();
|
||||||
}
|
}
|
||||||
|
|
||||||
int cwmp_session_destructor(struct session *session)
|
if (end_session_flag & END_SESSION_RELOAD) {
|
||||||
{
|
CWMP_LOG(INFO, "Config reload: end session request");
|
||||||
struct rpc *rpc;
|
cwmp_uci_reinit();
|
||||||
while (session->head_rpc_acs.next != &(session->head_rpc_acs)) {
|
if (cwmp_apply_acs_changes() != CWMP_OK) {
|
||||||
rpc = list_entry(session->head_rpc_acs.next, struct rpc, list);
|
CWMP_LOG(ERROR, "config reload failed at session end");
|
||||||
if (!rpc)
|
}
|
||||||
break;
|
reinit_cwmp_periodic_session_feature();
|
||||||
if (rpc_acs_methods[rpc->type].extra_clean != NULL)
|
reinit_heartbeat_procedures();
|
||||||
rpc_acs_methods[rpc->type].extra_clean(session, rpc);
|
}
|
||||||
cwmp_session_rpc_destructor(rpc);
|
|
||||||
}
|
if (end_session_flag & END_SESSION_INIT_NOTIFY) {
|
||||||
|
CWMP_LOG(INFO, "SetParameterAttributes end session: reinit list notify");
|
||||||
while (session->head_rpc_cpe.next != &(session->head_rpc_cpe)) {
|
reinit_list_param_notify();
|
||||||
rpc = list_entry(session->head_rpc_cpe.next, struct rpc, list);
|
}
|
||||||
if (!rpc)
|
|
||||||
break;
|
if (end_session_flag & END_SESSION_SET_NOTIFICATION_UPDATE) {
|
||||||
cwmp_session_rpc_destructor(rpc);
|
CWMP_LOG(INFO, "SetParameterAttributes/Values end session: update enabled notify file");
|
||||||
}
|
cwmp_update_enabled_notify_file();
|
||||||
|
}
|
||||||
if (session->list.next != NULL && session->list.prev != NULL)
|
|
||||||
list_del(&(session->list));
|
if (end_session_flag & END_SESSION_NSLOOKUP_DIAGNOSTIC) {
|
||||||
free(session);
|
CWMP_LOG(INFO, "Executing nslookupdiagnostic: end session request");
|
||||||
|
cwmp_nslookup_diagnostics();
|
||||||
return CWMP_OK;
|
}
|
||||||
}
|
|
||||||
|
if (end_session_flag & END_SESSION_TRACEROUTE_DIAGNOSTIC) {
|
||||||
int cwmp_move_session_to_session_queue(struct cwmp *cwmp, struct session *session)
|
CWMP_LOG(INFO, "Executing traceroutediagnostic: end session request");
|
||||||
{
|
cwmp_traceroute_diagnostics();
|
||||||
struct list_head *ilist, *jlist;
|
}
|
||||||
struct rpc *rpc_acs, *queue_rpc_acs;
|
|
||||||
struct session *session_queue;
|
if (end_session_flag & END_SESSION_UDPECHO_DIAGNOSTIC) {
|
||||||
|
CWMP_LOG(INFO, "Executing udpechodiagnostic: end session request");
|
||||||
pthread_mutex_lock(&(cwmp->mutex_session_queue));
|
cwmp_udp_echo_diagnostics();
|
||||||
cwmp->retry_count_session++;
|
}
|
||||||
cwmp->session_send = NULL;
|
|
||||||
if (cwmp->head_session_queue.next == &(cwmp->head_session_queue)) {
|
if (end_session_flag & END_SESSION_SERVERSELECTION_DIAGNOSTIC) {
|
||||||
list_add_tail(&(session->list), &(cwmp->head_session_queue));
|
CWMP_LOG(INFO, "Executing serverselectiondiagnostic: end session request");
|
||||||
session->hold_request = 0;
|
cwmp_serverselection_diagnostics();
|
||||||
session->digest_auth = 0;
|
}
|
||||||
cwmp->head_event_container = &(session->head_event_container);
|
|
||||||
if (session->head_rpc_acs.next != &(session->head_rpc_acs)) {
|
if (end_session_flag & END_SESSION_IPPING_DIAGNOSTIC) {
|
||||||
rpc_acs = list_entry(session->head_rpc_acs.next, struct rpc, list);
|
CWMP_LOG(INFO, "Executing ippingdiagnostic: end session request");
|
||||||
if (rpc_acs->type != RPC_ACS_INFORM) {
|
cwmp_ip_ping_diagnostics();
|
||||||
if (cwmp_add_session_rpc_acs_head(session, RPC_ACS_GET_RPC_METHODS) == NULL) {
|
}
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return CWMP_MEM_ERR;
|
if (end_session_flag & END_SESSION_DOWNLOAD_DIAGNOSTIC) {
|
||||||
}
|
CWMP_LOG(INFO, "Executing download diagnostic: end session request");
|
||||||
if (cwmp_add_session_rpc_acs_head(session, RPC_ACS_INFORM) == NULL) {
|
cwmp_download_diagnostics();
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
}
|
||||||
return CWMP_MEM_ERR;
|
|
||||||
}
|
if (end_session_flag & END_SESSION_UPLOAD_DIAGNOSTIC) {
|
||||||
}
|
CWMP_LOG(INFO, "Executing upload diagnostic: end session request");
|
||||||
} else {
|
cwmp_upload_diagnostics();
|
||||||
if (cwmp_add_session_rpc_acs_head(session, RPC_ACS_GET_RPC_METHODS) == NULL) {
|
}
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return CWMP_MEM_ERR;
|
if (cwmp_main->diag_session) {
|
||||||
}
|
struct session_timer_event *periodic_inform_event = calloc(1, sizeof(struct session_timer_event));
|
||||||
if (cwmp_add_session_rpc_acs_head(session, RPC_ACS_INFORM) == NULL) {
|
periodic_inform_event->session_timer_evt.cb = cwmp_schedule_session_with_event;
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
periodic_inform_event->event = EVENT_IDX_8DIAGNOSTICS_COMPLETE;
|
||||||
return CWMP_MEM_ERR;
|
trigger_cwmp_session_timer_with_event(&periodic_inform_event->session_timer_evt);
|
||||||
}
|
cwmp_main->diag_session = false;
|
||||||
}
|
}
|
||||||
while (session->head_rpc_cpe.next != &(session->head_rpc_cpe)) {
|
|
||||||
struct rpc *rpc_cpe;
|
if (end_session_flag & END_SESSION_DOWNLOAD) {
|
||||||
rpc_cpe = list_entry(session->head_rpc_cpe.next, struct rpc, list);
|
CWMP_LOG(INFO, "Apply Downaload Calls");
|
||||||
cwmp_session_rpc_destructor(rpc_cpe);
|
apply_downloads();
|
||||||
}
|
}
|
||||||
bkp_session_move_inform_to_inform_queue();
|
|
||||||
bkp_session_save();
|
if (end_session_flag & END_SESSION_SCHEDULE_DOWNLOAD) {
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
CWMP_LOG(INFO, "Apply ScheduleDownaload Calls");
|
||||||
return CWMP_OK;
|
apply_schedule_downloads();
|
||||||
}
|
}
|
||||||
list_for_each (ilist, &(session->head_event_container)) {
|
|
||||||
struct event_container *event_container_new, *event_container_old;
|
if (end_session_flag & END_SESSION_UPLOAD) {
|
||||||
event_container_old = list_entry(ilist, struct event_container, list);
|
CWMP_LOG(INFO, "Apply Upload Calls");
|
||||||
event_container_new = cwmp_add_event_container(cwmp, event_container_old->code, event_container_old->command_key);
|
apply_upload();
|
||||||
if (event_container_new == NULL) {
|
}
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
|
||||||
return CWMP_MEM_ERR;
|
if (end_session_flag & END_SESSION_SCHEDULE_INFORM) {
|
||||||
}
|
CWMP_LOG(INFO, "Apply ScheduleInform Calls");
|
||||||
list_splice_init(&(event_container_old->head_dm_parameter), &(event_container_new->head_dm_parameter));
|
apply_schedule_inform();
|
||||||
cwmp_save_event_container(event_container_new);
|
}
|
||||||
}
|
|
||||||
session_queue = list_entry(cwmp->head_event_container, struct session, head_event_container);
|
if (end_session_flag & END_SESSION_CDU) {
|
||||||
list_for_each (ilist, &(session->head_rpc_acs)) {
|
CWMP_LOG(INFO, "Apply CDU Calls");
|
||||||
rpc_acs = list_entry(ilist, struct rpc, list);
|
apply_change_du_state();
|
||||||
bool dup;
|
}
|
||||||
dup = false;
|
|
||||||
list_for_each (jlist, &(session_queue->head_rpc_acs)) {
|
if (cwmp_main->heart_session) {
|
||||||
queue_rpc_acs = list_entry(jlist, struct rpc, list);
|
uloop_timeout_cancel(&heartbeat_session_timer);
|
||||||
if (queue_rpc_acs->type == rpc_acs->type && (rpc_acs->type == RPC_ACS_INFORM || rpc_acs->type == RPC_ACS_GET_RPC_METHODS)) {
|
uloop_timeout_set(&heartbeat_session_timer, cwmp_main->heart_session_interval * 1000);
|
||||||
dup = true;
|
cwmp_main->heart_session = false;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
}
|
if (end_session_flag & END_SESSION_REBOOT) {
|
||||||
if (dup) {
|
CWMP_LOG(INFO, "Executing Reboot: end session request");
|
||||||
continue;
|
cwmp_reboot(commandKey);
|
||||||
}
|
exit(EXIT_SUCCESS);
|
||||||
ilist = ilist->prev;
|
}
|
||||||
list_del(&(rpc_acs->list));
|
|
||||||
list_add_tail(&(rpc_acs->list), &(session_queue->head_rpc_acs));
|
if (end_session_flag & END_SESSION_FACTORY_RESET) {
|
||||||
}
|
CWMP_LOG(INFO, "Executing factory reset: end session request");
|
||||||
cwmp_session_destructor(session);
|
cwmp_factory_reset();
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end_session_flag & END_SESSION_X_FACTORY_RESET_SOFT) {
|
||||||
|
CWMP_LOG(INFO, "Executing factory reset soft: end session request");
|
||||||
|
cwmp_factory_reset();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if any interface reset request exists then take action
|
||||||
|
intf_reset_node *iter = NULL, *node = NULL;
|
||||||
|
list_for_each_entry_safe(iter, node, &intf_reset_list, list) {
|
||||||
|
CWMP_LOG(INFO, "Executing interface reset: end session request");
|
||||||
|
cwmp_invoke_intf_reset(iter->path);
|
||||||
|
list_del(&iter->list);
|
||||||
|
free(iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&intf_reset_list);
|
||||||
|
|
||||||
|
end_session_flag = 0;
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,29 @@
|
||||||
#ifndef SESSION_H_
|
#ifndef SESSION_H_
|
||||||
#define SESSION_H_
|
#define SESSION_H_
|
||||||
|
|
||||||
#include "xml_utils.h"
|
#include <mxml.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern struct uloop_timeout retry_session_timer;
|
||||||
|
|
||||||
|
typedef struct session_status {
|
||||||
|
time_t last_start_time;
|
||||||
|
time_t last_end_time;
|
||||||
|
int last_status;
|
||||||
|
bool is_heartbeat;
|
||||||
|
time_t next_periodic;
|
||||||
|
time_t next_retry;
|
||||||
|
bool next_heartbeat;
|
||||||
|
unsigned int success_session;
|
||||||
|
unsigned int failure_session;
|
||||||
|
} session_status;
|
||||||
|
|
||||||
typedef struct session {
|
typedef struct session {
|
||||||
struct list_head list;
|
|
||||||
struct list_head head_event_container;
|
|
||||||
struct list_head head_rpc_cpe;
|
struct list_head head_rpc_cpe;
|
||||||
struct list_head head_rpc_acs;
|
struct list_head head_rpc_acs;
|
||||||
|
struct list_head events;
|
||||||
|
struct session_status session_status;
|
||||||
mxml_node_t *tree_in;
|
mxml_node_t *tree_in;
|
||||||
mxml_node_t *tree_out;
|
mxml_node_t *tree_out;
|
||||||
mxml_node_t *body_in;
|
mxml_node_t *body_in;
|
||||||
|
|
@ -29,6 +44,15 @@ typedef struct session {
|
||||||
int error;
|
int error;
|
||||||
} session;
|
} session;
|
||||||
|
|
||||||
|
struct session_timer_event {
|
||||||
|
struct uloop_timeout session_timer_evt;
|
||||||
|
int event;
|
||||||
|
void *extra_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//extern struct session_timer_event session_timer_evt;
|
||||||
|
|
||||||
enum end_session_enum
|
enum end_session_enum
|
||||||
{
|
{
|
||||||
END_SESSION_REBOOT = 1,
|
END_SESSION_REBOOT = 1,
|
||||||
|
|
@ -45,7 +69,12 @@ enum end_session_enum
|
||||||
END_SESSION_SERVERSELECTION_DIAGNOSTIC = 1 << 11,
|
END_SESSION_SERVERSELECTION_DIAGNOSTIC = 1 << 11,
|
||||||
END_SESSION_SET_NOTIFICATION_UPDATE = 1 << 12,
|
END_SESSION_SET_NOTIFICATION_UPDATE = 1 << 12,
|
||||||
END_SESSION_RESTART_SERVICES = 1 << 13,
|
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_SCHEDULE_DOWNLOAD = 1 << 16,
|
||||||
|
END_SESSION_UPLOAD = 1 << 17,
|
||||||
|
END_SESSION_SCHEDULE_INFORM = 1 << 18,
|
||||||
|
END_SESSION_CDU = 1 << 19
|
||||||
};
|
};
|
||||||
|
|
||||||
enum enum_session_status
|
enum enum_session_status
|
||||||
|
|
@ -59,13 +88,25 @@ enum enum_session_status
|
||||||
extern unsigned int end_session_flag;
|
extern unsigned int end_session_flag;
|
||||||
|
|
||||||
void cwmp_set_end_session(unsigned int flag);
|
void cwmp_set_end_session(unsigned int flag);
|
||||||
struct rpc *cwmp_add_session_rpc_cpe(struct session *session, int type);
|
struct rpc *cwmp_add_session_rpc_cpe(int type);
|
||||||
struct session *cwmp_add_queue_session(struct cwmp *cwmp);
|
struct rpc *cwmp_add_session_rpc_acs(int type);
|
||||||
struct rpc *cwmp_add_session_rpc_acs(struct session *session, int type);
|
struct rpc *cwmp_add_session_rpc_acs_head(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_rpc_destructor(struct rpc *rpc);
|
||||||
int cwmp_session_destructor(struct session *session);
|
void trigger_cwmp_session_timer();
|
||||||
int cwmp_move_session_to_session_queue(struct cwmp *cwmp, struct session *session);
|
void trigger_session_by_ubus(char *event);
|
||||||
|
void initiate_cwmp_periodic_session_feature();
|
||||||
|
int run_session_end_func(void);
|
||||||
|
void cwmp_schedule_session(struct uloop_timeout *timeout);
|
||||||
|
void cwmp_schedule_session_with_event(struct uloop_timeout *timeout);
|
||||||
|
void trigger_cwmp_session_timer_with_event(struct uloop_timeout *timeout);
|
||||||
|
void start_cwmp_session();
|
||||||
|
int create_cwmp_session_structure();
|
||||||
|
int clean_cwmp_session_structure();
|
||||||
|
void set_cwmp_session_status(int status, int retry_time);
|
||||||
|
int cwmp_session_init();
|
||||||
|
int cwmp_session_exit();
|
||||||
|
int cwmp_schedule_rpc();
|
||||||
|
int cwmp_get_retry_interval(bool heart_beat);
|
||||||
|
int cwmp_apply_acs_changes(void);
|
||||||
|
void rpc_exit();
|
||||||
#endif /* SRC_INC_SESSION_H_ */
|
#endif /* SRC_INC_SESSION_H_ */
|
||||||
|
|
|
||||||
|
|
@ -118,9 +118,8 @@ end:
|
||||||
void message_compute_signature(char *msg_out, char *signature, size_t len)
|
void message_compute_signature(char *msg_out, char *signature, size_t len)
|
||||||
{
|
{
|
||||||
int result_len = 20;
|
int result_len = 20;
|
||||||
struct cwmp *cwmp = &cwmp_main;
|
|
||||||
struct config *conf;
|
struct config *conf;
|
||||||
conf = &(cwmp->conf);
|
conf = &(cwmp_main->conf);
|
||||||
|
|
||||||
#ifdef LMBEDTLS
|
#ifdef LMBEDTLS
|
||||||
unsigned char result[MBEDTLS_MD_MAX_SIZE] = {0};
|
unsigned char result[MBEDTLS_MD_MAX_SIZE] = {0};
|
||||||
|
|
|
||||||
146
src/subprocess.c
Normal file
146
src/subprocess.c
Normal file
|
|
@ -0,0 +1,146 @@
|
||||||
|
/*
|
||||||
|
* 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 <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);
|
||||||
|
FREE(to_child);
|
||||||
|
FREE(to_child_json);
|
||||||
|
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;
|
||||||
|
}
|
||||||
7
src/subprocess.h
Normal file
7
src/subprocess.h
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
#ifndef SUB_PROC_H
|
||||||
|
#define SUB_PROC_H
|
||||||
|
#include <libubox/blobmsg_json.h>
|
||||||
|
typedef char* (*task_function)(char *task_arg);
|
||||||
|
int subprocess_start(task_function task_fun);
|
||||||
|
char *execute_task_in_subprocess(char *task);
|
||||||
|
#endif
|
||||||
166
src/ubus_utils.c
166
src/ubus_utils.c
|
|
@ -14,9 +14,13 @@
|
||||||
#include "sched_inform.h"
|
#include "sched_inform.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "cwmp_uci.h"
|
#include "cwmp_uci.h"
|
||||||
|
#include "session.h"
|
||||||
|
#include "cwmp_event.h"
|
||||||
|
|
||||||
typedef int (*callback)(struct blob_buf *b);
|
typedef int (*callback)(struct blob_buf *b);
|
||||||
|
|
||||||
|
static struct ubus_context *ubus_ctx = NULL;
|
||||||
|
|
||||||
struct command_cb {
|
struct command_cb {
|
||||||
char *str;
|
char *str;
|
||||||
callback cb;
|
callback cb;
|
||||||
|
|
@ -33,16 +37,14 @@ static const char *arr_session_status[] = {
|
||||||
static int reload_cmd(struct blob_buf *b)
|
static int reload_cmd(struct blob_buf *b)
|
||||||
{
|
{
|
||||||
CWMP_LOG(INFO, "triggered ubus reload");
|
CWMP_LOG(INFO, "triggered ubus reload");
|
||||||
if (cwmp_main.session_status.last_status == SESSION_RUNNING) {
|
if (cwmp_main->session->session_status.last_status == SESSION_RUNNING) {
|
||||||
cwmp_set_end_session(END_SESSION_RELOAD);
|
cwmp_set_end_session(END_SESSION_RELOAD);
|
||||||
blobmsg_add_u32(b, "status", 0);
|
blobmsg_add_u32(b, "status", 0);
|
||||||
blobmsg_add_string(b, "info", "Session running, reload at the end of the session");
|
blobmsg_add_string(b, "info", "Session running, reload at the end of the session");
|
||||||
} else {
|
} else {
|
||||||
int error = CWMP_OK;
|
int error = CWMP_OK;
|
||||||
pthread_mutex_lock(&(cwmp_main.mutex_session_queue));
|
|
||||||
cwmp_uci_reinit();
|
cwmp_uci_reinit();
|
||||||
error = cwmp_apply_acs_changes();
|
error = cwmp_apply_acs_changes();
|
||||||
pthread_mutex_unlock(&(cwmp_main.mutex_session_queue));
|
|
||||||
if (error != CWMP_OK) {
|
if (error != CWMP_OK) {
|
||||||
// Failed to load cwmp config
|
// Failed to load cwmp config
|
||||||
CWMP_LOG(ERROR, "cwmp failed to reload the configuration");
|
CWMP_LOG(ERROR, "cwmp failed to reload the configuration");
|
||||||
|
|
@ -102,7 +104,7 @@ static const struct blobmsg_policy icwmp_cmd_policy[] = {
|
||||||
|
|
||||||
static int icwmp_command_handler(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), struct ubus_request_data *req, const char *method __attribute__((unused)), struct blob_attr *msg)
|
static int icwmp_command_handler(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), struct ubus_request_data *req, const char *method __attribute__((unused)), struct blob_attr *msg)
|
||||||
{
|
{
|
||||||
if (cwmp_main.init_complete == false) {
|
if (cwmp_main->init_complete == false) {
|
||||||
CWMP_LOG(INFO, "Request can't be handled since icwmpd is still in init state");
|
CWMP_LOG(INFO, "Request can't be handled since icwmpd is still in init state");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -168,7 +170,7 @@ static time_t get_next_session_time()
|
||||||
sched_time = schedule_inform->scheduled_time;
|
sched_time = schedule_inform->scheduled_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t next_time = get_nonzero_min_time(sched_time, cwmp_main.session_status.next_retry, cwmp_main.session_status.next_periodic);
|
time_t next_time = get_nonzero_min_time(sched_time, cwmp_main->session->session_status.next_retry, cwmp_main->session->session_status.next_periodic);
|
||||||
|
|
||||||
return next_time;
|
return next_time;
|
||||||
}
|
}
|
||||||
|
|
@ -176,20 +178,20 @@ static time_t get_next_session_time()
|
||||||
static void bb_add_icwmp_status(struct blob_buf *bb)
|
static void bb_add_icwmp_status(struct blob_buf *bb)
|
||||||
{
|
{
|
||||||
void *tbl = blobmsg_open_table(bb, "cwmp");
|
void *tbl = blobmsg_open_table(bb, "cwmp");
|
||||||
bb_add_string(bb, "status", cwmp_main.init_complete ? "up" : "init");
|
bb_add_string(bb, "status", cwmp_main->init_complete ? "up" : "init");
|
||||||
bb_add_string(bb, "start_time", get_time(cwmp_main.start_time));
|
bb_add_string(bb, "start_time", get_time(cwmp_main->start_time));
|
||||||
bb_add_string(bb, "acs_url", cwmp_main.conf.acsurl);
|
bb_add_string(bb, "acs_url", cwmp_main->conf.acsurl);
|
||||||
blobmsg_close_table(bb, tbl);
|
blobmsg_close_table(bb, tbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bb_add_icwmp_last_session(struct blob_buf *bb)
|
static void bb_add_icwmp_last_session(struct blob_buf *bb)
|
||||||
{
|
{
|
||||||
void *tbl = blobmsg_open_table(bb, "last_session");
|
void *tbl = blobmsg_open_table(bb, "last_session");
|
||||||
const char *status = cwmp_main.session_status.last_start_time ? arr_session_status[cwmp_main.session_status.last_status] : "N/A";
|
const char *status = cwmp_main->session->session_status.last_start_time ? arr_session_status[cwmp_main->session->session_status.last_status] : "N/A";
|
||||||
bb_add_string(bb, "status", status);
|
bb_add_string(bb, "status", status);
|
||||||
char *start_time = cwmp_main.session_status.last_start_time ? get_time(cwmp_main.session_status.last_start_time) : "N/A";
|
char *start_time = cwmp_main->session->session_status.last_start_time ? get_time(cwmp_main->session->session_status.last_start_time) : "N/A";
|
||||||
bb_add_string(bb, "start_time", start_time);
|
bb_add_string(bb, "start_time", start_time);
|
||||||
char *end_time = cwmp_main.session_status.last_end_time ? get_time(cwmp_main.session_status.last_end_time) : "N/A";
|
char *end_time = cwmp_main->session->session_status.last_end_time ? get_time(cwmp_main->session->session_status.last_end_time) : "N/A";
|
||||||
bb_add_string(bb, "end_time", end_time);
|
bb_add_string(bb, "end_time", end_time);
|
||||||
blobmsg_close_table(bb, tbl);
|
blobmsg_close_table(bb, tbl);
|
||||||
}
|
}
|
||||||
|
|
@ -208,9 +210,9 @@ static void bb_add_icwmp_next_session(struct blob_buf *bb)
|
||||||
static void bb_add_icwmp_statistics(struct blob_buf *bb)
|
static void bb_add_icwmp_statistics(struct blob_buf *bb)
|
||||||
{
|
{
|
||||||
void *tbl = blobmsg_open_table(bb, "statistics");
|
void *tbl = blobmsg_open_table(bb, "statistics");
|
||||||
blobmsg_add_u32(bb, "success_sessions", cwmp_main.session_status.success_session);
|
blobmsg_add_u32(bb, "success_sessions", cwmp_main->session->session_status.success_session);
|
||||||
blobmsg_add_u32(bb, "failure_sessions", cwmp_main.session_status.failure_session);
|
blobmsg_add_u32(bb, "failure_sessions", cwmp_main->session->session_status.failure_session);
|
||||||
blobmsg_add_u32(bb, "total_sessions", cwmp_main.session_status.success_session + cwmp_main.session_status.failure_session);
|
blobmsg_add_u32(bb, "total_sessions", cwmp_main->session->session_status.success_session + cwmp_main->session->session_status.failure_session);
|
||||||
blobmsg_close_table(bb, tbl);
|
blobmsg_close_table(bb, tbl);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -245,81 +247,51 @@ static const struct blobmsg_policy icwmp_inform_policy[] = {
|
||||||
[INFORM_EVENT] = {.name = "event", .type = BLOBMSG_TYPE_STRING },
|
[INFORM_EVENT] = {.name = "event", .type = BLOBMSG_TYPE_STRING },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void icwmp_inform_get_rpc_method(struct ubus_context *ctx, struct ubus_request_data *req)
|
static int icwmp_inform_get_rpc_method(struct blob_buf *bb)
|
||||||
{
|
{
|
||||||
struct event_container *event_container;
|
if (cwmp_add_session_rpc_acs(RPC_ACS_GET_RPC_METHODS) == NULL)
|
||||||
struct session *session;
|
return -1;
|
||||||
struct blob_buf bb;
|
|
||||||
|
|
||||||
if (ctx == NULL)
|
blobmsg_add_u32(bb, "status", 1);
|
||||||
return;
|
blobmsg_add_string(bb, "info", "Session with GetRPCMethods will start");
|
||||||
|
|
||||||
memset(&bb, 0, sizeof(struct blob_buf));
|
return EVENT_IDX_2PERIODIC;
|
||||||
blob_buf_init(&bb, 0);
|
|
||||||
|
|
||||||
pthread_mutex_lock(&(cwmp_main.mutex_session_queue));
|
|
||||||
event_container = cwmp_add_event_container(&cwmp_main, EVENT_IDX_2PERIODIC, "");
|
|
||||||
if (event_container == NULL) {
|
|
||||||
pthread_mutex_unlock(&(cwmp_main.mutex_session_queue));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cwmp_save_event_container(event_container);
|
|
||||||
session = list_entry(cwmp_main.head_event_container, struct session, head_event_container);
|
|
||||||
if (cwmp_add_session_rpc_acs(session, RPC_ACS_GET_RPC_METHODS) == NULL) {
|
|
||||||
pthread_mutex_unlock(&(cwmp_main.mutex_session_queue));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&(cwmp_main.mutex_session_queue));
|
|
||||||
pthread_cond_signal(&(cwmp_main.threshold_session_send));
|
|
||||||
blobmsg_add_u32(&bb, "status", 1);
|
|
||||||
blobmsg_add_string(&bb, "info", "Session with GetRPCMethods will start");
|
|
||||||
|
|
||||||
ubus_send_reply(ctx, req, bb.head);
|
|
||||||
blob_buf_free(&bb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void icwmp_inform_event(struct ubus_context *ctx, struct ubus_request_data *req, char *event)
|
static int icwmp_inform_event(struct blob_buf *bb, char *event)
|
||||||
{
|
{
|
||||||
struct blob_buf bb;
|
|
||||||
|
|
||||||
if (ctx == NULL || event == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
memset(&bb, 0, sizeof(struct blob_buf));
|
|
||||||
blob_buf_init(&bb, 0);
|
|
||||||
|
|
||||||
int event_code = cwmp_get_int_event_code(event);
|
int event_code = cwmp_get_int_event_code(event);
|
||||||
pthread_mutex_lock(&(cwmp_main.mutex_session_queue));
|
|
||||||
cwmp_add_event_container(&cwmp_main, event_code, "");
|
|
||||||
pthread_mutex_unlock(&(cwmp_main.mutex_session_queue));
|
|
||||||
if (event_code != EVENT_IDX_14HEARTBEAT) {
|
if (event_code != EVENT_IDX_14HEARTBEAT) {
|
||||||
pthread_cond_signal(&(cwmp_main.threshold_session_send));
|
if (cwmp_main->session->session_status.last_status == SESSION_RUNNING) {
|
||||||
if (cwmp_main.session_status.last_status == SESSION_RUNNING) {
|
blobmsg_add_u32(bb, "status", -1);
|
||||||
blobmsg_add_u32(&bb, "status", -1);
|
blobmsg_add_string(bb, "info", "Session already running, event will be sent at the end of the session");
|
||||||
blobmsg_add_string(&bb, "info", "Session already running, event will be sent at the end of the session");
|
|
||||||
} else {
|
} else {
|
||||||
blobmsg_add_u32(&bb, "status", 1);
|
blobmsg_add_u32(bb, "status", 1);
|
||||||
blobmsg_add_string(&bb, "info", "Session started");
|
blobmsg_add_string(bb, "info", "Session started");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return event_code;
|
||||||
ubus_send_reply(ctx, req, bb.head);
|
|
||||||
blob_buf_free(&bb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int icwmp_inform_handler(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), struct ubus_request_data *req, const char *method __attribute__((unused)), struct blob_attr *msg)
|
static int icwmp_inform_handler(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), struct ubus_request_data *req, const char *method __attribute__((unused)), struct blob_attr *msg)
|
||||||
{
|
{
|
||||||
if (cwmp_main.init_complete == false) {
|
struct blob_buf bb;
|
||||||
CWMP_LOG(INFO, "Inform can't be sent since icwmpd is still in init state");
|
memset(&bb, 0, sizeof(struct blob_buf));
|
||||||
return 0;
|
blob_buf_init(&bb, 0);
|
||||||
|
|
||||||
|
if (cwmp_main->init_complete == false) {
|
||||||
|
CWMP_LOG(WARNING, "Inform can't be sent since icwmpd is still in init state");
|
||||||
|
blobmsg_add_u32(&bb, "status", -1);
|
||||||
|
blobmsg_add_string(&bb, "info", "icwmpd is still in init state");
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct blob_attr *tb[__INFORM_MAX] = {0};
|
struct blob_attr *tb[__INFORM_MAX] = {0};
|
||||||
bool is_get_rpc = false;
|
bool is_get_rpc = false;
|
||||||
char *event = "";
|
char *event = "";
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
int event_code = -1;
|
||||||
|
|
||||||
ret = blobmsg_parse(icwmp_inform_policy, ARRAY_SIZE(icwmp_inform_policy), tb, blob_data(msg), blob_len(msg));
|
ret = blobmsg_parse(icwmp_inform_policy, ARRAY_SIZE(icwmp_inform_policy), tb, blob_data(msg), blob_len(msg));
|
||||||
|
|
||||||
|
|
@ -332,11 +304,26 @@ static int icwmp_inform_handler(struct ubus_context *ctx, struct ubus_object *ob
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_get_rpc) {
|
if (is_get_rpc) {
|
||||||
icwmp_inform_get_rpc_method(ctx, req);
|
event_code = icwmp_inform_get_rpc_method(&bb);
|
||||||
} else {
|
} else {
|
||||||
icwmp_inform_event(ctx, req, event);
|
event_code = icwmp_inform_event(&bb, event);
|
||||||
|
}
|
||||||
|
if (event_code == -1) {
|
||||||
|
CWMP_LOG(WARNING, "tr069 ubus: ubus inform method not able to get the event code");
|
||||||
|
blobmsg_add_u32(&bb, "status", -1);
|
||||||
|
blobmsg_add_string(&bb, "info", "not able to get the event code");
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct session_timer_event *ubus_inform_event = calloc(1, sizeof(struct session_timer_event));
|
||||||
|
|
||||||
|
ubus_inform_event->session_timer_evt.cb = cwmp_schedule_session_with_event;
|
||||||
|
ubus_inform_event->event = event_code;
|
||||||
|
trigger_cwmp_session_timer_with_event(&ubus_inform_event->session_timer_evt);
|
||||||
|
|
||||||
|
end:
|
||||||
|
ubus_send_reply(ctx, req, bb.head);
|
||||||
|
blob_buf_free(&bb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -376,25 +363,48 @@ void bb_add_string(struct blob_buf *bb, const char *name, const char *value)
|
||||||
blobmsg_add_string(bb, name, "");
|
blobmsg_add_string(bb, name, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int icwmp_uloop_ubus_init()
|
||||||
|
{
|
||||||
|
ubus_ctx = ubus_connect(cwmp_main->conf.ubus_socket);
|
||||||
|
if (!ubus_ctx)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ubus_add_uloop(ubus_ctx);
|
||||||
|
|
||||||
|
if (icwmp_register_object(ubus_ctx))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void icwmp_uloop_ubus_exit()
|
||||||
|
{
|
||||||
|
if (ubus_ctx) {
|
||||||
|
ubus_remove_object(ubus_ctx, &tr069_object);
|
||||||
|
ubus_free(ubus_ctx);
|
||||||
|
ubus_ctx = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int icwmp_ubus_invoke(const char *obj, const char *method, struct blob_attr *msg, icwmp_ubus_cb icwmp_callback, void *callback_arg)
|
int icwmp_ubus_invoke(const char *obj, const char *method, struct blob_attr *msg, icwmp_ubus_cb icwmp_callback, void *callback_arg)
|
||||||
{
|
{
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
struct ubus_context *ubus_ctx = NULL;
|
struct ubus_context *ctx = NULL;
|
||||||
|
|
||||||
ubus_ctx = ubus_connect(NULL);
|
ctx = ubus_connect(NULL);
|
||||||
if (ubus_ctx == NULL)
|
if (ctx == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!ubus_lookup_id(ubus_ctx, obj, &id))
|
if (!ubus_lookup_id(ctx, obj, &id))
|
||||||
rc = ubus_invoke(ubus_ctx, id, method, msg, icwmp_callback, callback_arg, 20000);
|
rc = ubus_invoke(ctx, id, method, msg, icwmp_callback, callback_arg, 20000);
|
||||||
else
|
else
|
||||||
rc = -1;
|
rc = -1;
|
||||||
|
|
||||||
if (ubus_ctx) {
|
if (ctx) {
|
||||||
ubus_free(ubus_ctx);
|
ubus_free(ctx);
|
||||||
ubus_ctx = NULL;
|
ctx = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
||||||
|
|
@ -21,5 +21,6 @@ int icwmp_register_object(struct ubus_context *ctx);
|
||||||
int icwmp_delete_object(struct ubus_context *ctx);
|
int icwmp_delete_object(struct ubus_context *ctx);
|
||||||
int icwmp_ubus_invoke(const char *obj, const char *method, struct blob_attr *msg,
|
int icwmp_ubus_invoke(const char *obj, const char *method, struct blob_attr *msg,
|
||||||
icwmp_ubus_cb icwmp_callback, void *callback_arg);
|
icwmp_ubus_cb icwmp_callback, void *callback_arg);
|
||||||
|
int icwmp_uloop_ubus_init();
|
||||||
|
void icwmp_uloop_ubus_exit();
|
||||||
#endif /* __ICWMP_UBUS_UTILS_H__ */
|
#endif /* __ICWMP_UBUS_UTILS_H__ */
|
||||||
|
|
|
||||||
193
src/upload.c
193
src/upload.c
|
|
@ -20,14 +20,13 @@
|
||||||
#include "backupSession.h"
|
#include "backupSession.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "cwmp_uci.h"
|
#include "cwmp_uci.h"
|
||||||
|
#include "subprocess.h"
|
||||||
|
#include "session.h"
|
||||||
|
|
||||||
#define CURL_TIMEOUT 20
|
#define CURL_TIMEOUT 20
|
||||||
|
|
||||||
LIST_HEAD(list_upload);
|
LIST_HEAD(list_upload);
|
||||||
|
|
||||||
pthread_cond_t threshold_upload;
|
|
||||||
pthread_mutex_t mutex_upload = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
|
|
||||||
int lookup_vcf_name(int instance, char **value)
|
int lookup_vcf_name(int instance, char **value)
|
||||||
{
|
{
|
||||||
char vcf_name_parameter[256];
|
char vcf_name_parameter[256];
|
||||||
|
|
@ -64,6 +63,9 @@ int lookup_vlf_name(int instance, char **value)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Upload file
|
||||||
|
*/
|
||||||
int upload_file(const char *file_path, const char *url, const char *username, const char *password)
|
int upload_file(const char *file_path, const char *url, const char *username, const char *password)
|
||||||
{
|
{
|
||||||
int res_code = 0;
|
int res_code = 0;
|
||||||
|
|
@ -109,6 +111,58 @@ int upload_file(const char *file_path, const char *url, const char *username, co
|
||||||
return res_code;
|
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 cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptransfer_complete)
|
||||||
{
|
{
|
||||||
int error = FAULT_CPE_NO_FAULT;
|
int error = FAULT_CPE_NO_FAULT;
|
||||||
|
|
@ -156,7 +210,7 @@ int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptrans
|
||||||
goto end_upload;
|
goto end_upload;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = upload_file(file_path, pupload->url, pupload->username, pupload->password);
|
int ret = upload_file_in_subprocess(file_path, pupload->url, pupload->username, pupload->password);
|
||||||
if (ret == 200 || ret == 204)
|
if (ret == 200 || ret == 204)
|
||||||
error = FAULT_CPE_NO_FAULT;
|
error = FAULT_CPE_NO_FAULT;
|
||||||
else
|
else
|
||||||
|
|
@ -182,90 +236,6 @@ end_upload:
|
||||||
return error;
|
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 (thread_end)
|
|
||||||
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(get_time(time(NULL)));
|
|
||||||
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)
|
int cwmp_free_upload_request(struct upload *upload)
|
||||||
{
|
{
|
||||||
if (upload != NULL) {
|
if (upload != NULL) {
|
||||||
|
|
@ -291,7 +261,6 @@ int cwmp_free_upload_request(struct upload *upload)
|
||||||
|
|
||||||
int cwmp_scheduledUpload_remove_all()
|
int cwmp_scheduledUpload_remove_all()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&mutex_upload);
|
|
||||||
while (list_upload.next != &(list_upload)) {
|
while (list_upload.next != &(list_upload)) {
|
||||||
struct upload *upload;
|
struct upload *upload;
|
||||||
upload = list_entry(list_upload.next, struct upload, list);
|
upload = list_entry(list_upload.next, struct upload, list);
|
||||||
|
|
@ -301,7 +270,49 @@ int cwmp_scheduledUpload_remove_all()
|
||||||
count_download_queue--;
|
count_download_queue--;
|
||||||
cwmp_free_upload_request(upload);
|
cwmp_free_upload_request(upload);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&mutex_upload);
|
|
||||||
|
|
||||||
return CWMP_OK;
|
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);
|
||||||
|
list_del(&(pupload->list));
|
||||||
|
if (pupload->scheduled_time != 0)
|
||||||
|
count_download_queue--;
|
||||||
|
cwmp_free_upload_request(pupload);
|
||||||
|
|
||||||
|
struct session_timer_event *upload_inform_event = calloc(1, sizeof(struct session_timer_event));
|
||||||
|
|
||||||
|
upload_inform_event->extra_data = ptransfer_complete;
|
||||||
|
upload_inform_event->session_timer_evt.cb = cwmp_schedule_session_with_event;
|
||||||
|
upload_inform_event->event = TransferClt_Evt;
|
||||||
|
trigger_cwmp_session_timer_with_event(&upload_inform_event->session_timer_evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void apply_upload()
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,11 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
extern struct list_head list_upload;
|
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);
|
int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptransfer_complete);
|
||||||
void *thread_cwmp_rpc_cpe_upload(void *v);
|
void *thread_cwmp_rpc_cpe_upload(void *v);
|
||||||
int cwmp_scheduledUpload_remove_all();
|
int cwmp_scheduledUpload_remove_all();
|
||||||
int cwmp_free_upload_request(struct upload *upload);
|
int cwmp_free_upload_request(struct upload *upload);
|
||||||
|
void cwmp_start_upload(struct uloop_timeout *timeout);
|
||||||
|
void apply_upload();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
112
src/xml.c
112
src/xml.c
|
|
@ -52,7 +52,7 @@ struct xml_node_data xml_nodes_data[] = {
|
||||||
[SOAP_TIMEWINDOW_REF] = {XML_LIST, SOAP_TIME_REF, NULL, {}},
|
[SOAP_TIMEWINDOW_REF] = {XML_LIST, SOAP_TIME_REF, NULL, {}},
|
||||||
[SOAP_TIME_REF] = {XML_SINGLE, 0, NULL, {{"WindowStart", XML_LINTEGER, 0, NULL}, {"WindowEnd", XML_LINTEGER, 0, NULL}, {"WindowMode", XML_STRING, 0, NULL}, {"WindowMode", XML_FUNC, 0, load_sched_download_window_mode}, {"MaxRetries", XML_INTEGER, 0, NULL}}},
|
[SOAP_TIME_REF] = {XML_SINGLE, 0, NULL, {{"WindowStart", XML_LINTEGER, 0, NULL}, {"WindowEnd", XML_LINTEGER, 0, NULL}, {"WindowMode", XML_STRING, 0, NULL}, {"WindowMode", XML_FUNC, 0, load_sched_download_window_mode}, {"MaxRetries", XML_INTEGER, 0, NULL}}},
|
||||||
[SOAP_REQ_CDU_OPERATIONS] = {XML_LIST, SOAP_REQ_CDU_OPS_REF, "Operations", {}},
|
[SOAP_REQ_CDU_OPERATIONS] = {XML_LIST, SOAP_REQ_CDU_OPS_REF, "Operations", {}},
|
||||||
[SOAP_REQ_CDU_OPS_REF] = {XML_SINGLE, 0, NULL, {{"Operations", XML_FUNC, 0, NULL}}},
|
[SOAP_REQ_CDU_OPS_REF] = {XML_SINGLE, 0, NULL, {{"Operations", XML_FUNC, 0, load_change_du_state_operation}}},
|
||||||
[SOAP_REQ_DU_INSTALL] = {XML_SINGLE, 0, NULL, {{"URL", XML_STRING, 0, NULL}, {"UUID", XML_STRING, 0, NULL}, {"Username", XML_STRING, 0, NULL}, {"Password", XML_STRING, 0, NULL}, {"ExecutionEnvRef", XML_STRING, 0, NULL}}},
|
[SOAP_REQ_DU_INSTALL] = {XML_SINGLE, 0, NULL, {{"URL", XML_STRING, 0, NULL}, {"UUID", XML_STRING, 0, NULL}, {"Username", XML_STRING, 0, NULL}, {"Password", XML_STRING, 0, NULL}, {"ExecutionEnvRef", XML_STRING, 0, NULL}}},
|
||||||
[SOAP_REQ_DU_UPDATE] = {XML_SINGLE, 0, NULL, {{"URL", XML_STRING, 0, NULL}, {"UUID", XML_STRING, 0, NULL}, {"Username", XML_STRING, 0, NULL}, {"Password", XML_STRING, 0, NULL}, {"Version", XML_STRING, 0, NULL}}},
|
[SOAP_REQ_DU_UPDATE] = {XML_SINGLE, 0, NULL, {{"URL", XML_STRING, 0, NULL}, {"UUID", XML_STRING, 0, NULL}, {"Username", XML_STRING, 0, NULL}, {"Password", XML_STRING, 0, NULL}, {"Version", XML_STRING, 0, NULL}}},
|
||||||
[SOAP_REQ_DU_UNINSTALL] = {XML_SINGLE, 0, NULL, {{"Version", XML_STRING, 0, NULL}, {"ExecutionEnvRef", XML_STRING, 0, NULL}, {"URL", XML_STRING, 0, NULL}}},
|
[SOAP_REQ_DU_UNINSTALL] = {XML_SINGLE, 0, NULL, {{"Version", XML_STRING, 0, NULL}, {"ExecutionEnvRef", XML_STRING, 0, NULL}, {"URL", XML_STRING, 0, NULL}}},
|
||||||
|
|
@ -88,7 +88,7 @@ struct xml_node_data xml_nodes_data[] = {
|
||||||
[SOAP_INFORM_CWMP] = {XML_SINGLE, 0, NULL, {{"DeviceId", XML_REC, SOAP_DEVID, NULL}, {"Event", XML_FUNC, 0, build_inform_events}, {"MaxEnvelopes", XML_INTEGER, 0, NULL}, {"CurrentTime", XML_STRING, 0, NULL}, {"RetryCount", XML_INTEGER, 0, NULL}}},
|
[SOAP_INFORM_CWMP] = {XML_SINGLE, 0, NULL, {{"DeviceId", XML_REC, SOAP_DEVID, NULL}, {"Event", XML_FUNC, 0, build_inform_events}, {"MaxEnvelopes", XML_INTEGER, 0, NULL}, {"CurrentTime", XML_STRING, 0, NULL}, {"RetryCount", XML_INTEGER, 0, NULL}}},
|
||||||
[SOAP_DEVID] = {XML_SINGLE, 0, NULL, {{"Manufacturer", XML_STRING, 0, NULL}, {"OUI", XML_STRING, 0, NULL}, {"ProductClass", XML_STRING, 0, NULL}, {"SerialNumber", XML_STRING, 0, NULL}}},
|
[SOAP_DEVID] = {XML_SINGLE, 0, NULL, {{"Manufacturer", XML_STRING, 0, NULL}, {"OUI", XML_STRING, 0, NULL}, {"ProductClass", XML_STRING, 0, NULL}, {"SerialNumber", XML_STRING, 0, NULL}}},
|
||||||
[SOAP_DU_CHANGE_COMPLETE] = {XML_SINGLE, 0, NULL, {{"CommandKey", XML_STRING, 0, NULL}, {"Results", XML_REC, SOAP_CDU_RESULTS_REF, NULL}}},
|
[SOAP_DU_CHANGE_COMPLETE] = {XML_SINGLE, 0, NULL, {{"CommandKey", XML_STRING, 0, NULL}, {"Results", XML_REC, SOAP_CDU_RESULTS_REF, NULL}}},
|
||||||
[SOAP_CDU_RESULTS_REF] = {XML_LIST, 0, NULL, {{"OpResultStruct", XML_REC, SOAP_CDU_OPTS_REF, NULL}}},
|
[SOAP_CDU_RESULTS_REF] = {XML_LIST, SOAP_CDU_OPTS_REF, "OpResultStruct", {}},
|
||||||
[SOAP_CDU_OPTS_REF] = {XML_SINGLE, 0, NULL, {{"UUID", XML_STRING, 0, NULL}, {"DeploymentUnitRef", XML_STRING, 0, NULL}, {"Version", XML_STRING, 0, NULL}, {"CurrentState", XML_STRING, 0, NULL}, {"StartTime", XML_STRING, 0, NULL}, {"CompleteTime", XML_STRING, 0, NULL}, {"FaultStruct", XML_REC, SOAP_CWMP_FAULT, NULL}}},
|
[SOAP_CDU_OPTS_REF] = {XML_SINGLE, 0, NULL, {{"UUID", XML_STRING, 0, NULL}, {"DeploymentUnitRef", XML_STRING, 0, NULL}, {"Version", XML_STRING, 0, NULL}, {"CurrentState", XML_STRING, 0, NULL}, {"StartTime", XML_STRING, 0, NULL}, {"CompleteTime", XML_STRING, 0, NULL}, {"FaultStruct", XML_REC, SOAP_CWMP_FAULT, NULL}}},
|
||||||
[ATTR_PARAM_STRUCT] = {XML_SINGLE, 0, NULL, {{"xsi:type", XML_STRING, 0, NULL}}},
|
[ATTR_PARAM_STRUCT] = {XML_SINGLE, 0, NULL, {{"xsi:type", XML_STRING, 0, NULL}}},
|
||||||
[ATTR_SOAP_ENV] = {XML_SINGLE, 0, NULL, {{"xmlns:soap_env", XML_STRING, 0, NULL}, {"xmlns:soap_enc", XML_STRING, 0, NULL}, {"xmlns:xsd", XML_STRING, 0, NULL}, {"xmlns:xsi", XML_STRING, 0, NULL}}}
|
[ATTR_SOAP_ENV] = {XML_SINGLE, 0, NULL, {{"xmlns:soap_env", XML_STRING, 0, NULL}, {"xmlns:soap_enc", XML_STRING, 0, NULL}, {"xmlns:xsd", XML_STRING, 0, NULL}, {"xmlns:xsi", XML_STRING, 0, NULL}}}
|
||||||
|
|
@ -253,30 +253,33 @@ int load_change_du_state_operation(mxml_node_t *b, struct xml_data_struct *xml_a
|
||||||
int cdu_ref = 0;
|
int cdu_ref = 0;
|
||||||
int type = 0;
|
int type = 0;
|
||||||
|
|
||||||
|
if (xml_attrs->cdu_type == NULL) {
|
||||||
|
CWMP_LOG(ERROR, "Not able to load CDU operation");
|
||||||
|
return FAULT_CPE_INTERNAL_ERROR;
|
||||||
|
|
||||||
|
}
|
||||||
if (strcmp(operation, "cwmp:InstallOpStruct") == 0) {
|
if (strcmp(operation, "cwmp:InstallOpStruct") == 0) {
|
||||||
cdu_ref = SOAP_REQ_DU_INSTALL;
|
cdu_ref = SOAP_REQ_DU_INSTALL;
|
||||||
type = DU_INSTALL;
|
type = DU_INSTALL;
|
||||||
}
|
}
|
||||||
else if (strcmp(operation, "cwmp:UpdateOpStruct") == 0) {
|
else if (strcmp(operation, "cwmp:UpdateOpStruct") == 0) {
|
||||||
cdu_ref = SOAP_REQ_DU_INSTALL;
|
cdu_ref = SOAP_REQ_DU_UPDATE;
|
||||||
type = DU_UPDATE;
|
type = DU_UPDATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (strcmp(operation, "cwmp:UninstallOpStruct") == 0) {
|
else if (strcmp(operation, "cwmp:UninstallOpStruct") == 0) {
|
||||||
cdu_ref = SOAP_REQ_DU_INSTALL;
|
cdu_ref = SOAP_REQ_DU_UNINSTALL;
|
||||||
type = DU_UNINSTALL;
|
type = DU_UNINSTALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cppcheck-suppress autoVariables
|
*(xml_attrs->cdu_type) = type;
|
||||||
xml_attrs->cdu_type = &type;
|
|
||||||
|
|
||||||
if (cdu_ref == 0)
|
if (cdu_ref == 0)
|
||||||
return FAULT_CPE_INVALID_ARGUMENTS;
|
return FAULT_CPE_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
int fault = load_xml_node_data(cdu_ref, b, xml_attrs);
|
int fault = load_xml_node_data(cdu_ref, b, xml_attrs);
|
||||||
if (fault)
|
if (fault)
|
||||||
return fault;
|
return fault;
|
||||||
|
|
||||||
|
|
||||||
return FAULT_CPE_NO_FAULT;
|
return FAULT_CPE_NO_FAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -572,7 +575,6 @@ int load_single_xml_node_data(int node_ref, mxml_node_t *node, struct xml_data_s
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
b = mxmlWalkNext(b, node, MXML_DESCEND);
|
b = mxmlWalkNext(b, node, MXML_DESCEND);
|
||||||
}
|
}
|
||||||
|
|
@ -681,6 +683,11 @@ void event_container_list_to_xml_data_list(struct list_head *event_container_lis
|
||||||
struct event_container *event_container;
|
struct event_container *event_container;
|
||||||
|
|
||||||
list_for_each_entry (event_container, event_container_list, list) {
|
list_for_each_entry (event_container, event_container_list, list) {
|
||||||
|
// cppcheck-suppress uninitvar
|
||||||
|
if (cwmp_main->session->session_status.is_heartbeat && event_container->code != EVENT_IDX_14HEARTBEAT)
|
||||||
|
continue;
|
||||||
|
if ((!cwmp_main->session->session_status.is_heartbeat) && (event_container->code == EVENT_IDX_14HEARTBEAT))
|
||||||
|
continue;
|
||||||
struct xml_list_data *xml_data = calloc(1, sizeof(struct xml_list_data));
|
struct xml_list_data *xml_data = calloc(1, sizeof(struct xml_list_data));
|
||||||
list_add_tail(&xml_data->list, xml_data_list);
|
list_add_tail(&xml_data->list, xml_data_list);
|
||||||
xml_data->event_code = event_container->code;
|
xml_data->event_code = event_container->code;
|
||||||
|
|
@ -695,7 +702,6 @@ void get_xml_data_value_by_name(int type, int idx, struct xml_data_struct *xml_a
|
||||||
bool *bol;
|
bool *bol;
|
||||||
long int *lint;
|
long int *lint;
|
||||||
time_t *time;
|
time_t *time;
|
||||||
|
|
||||||
void **ptr = (void **)((char *)xml_attrs + idx * sizeof(char *));
|
void **ptr = (void **)((char *)xml_attrs + idx * sizeof(char *));
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case XML_STRING:
|
case XML_STRING:
|
||||||
|
|
@ -820,6 +826,10 @@ int build_xml_list_node_data(int node_ref, mxml_node_t *node, struct xml_data_st
|
||||||
xml_ref_data.fault_code = &xml_data->fault_code;
|
xml_ref_data.fault_code = &xml_data->fault_code;
|
||||||
xml_ref_data.current_state = &xml_data->current_state;
|
xml_ref_data.current_state = &xml_data->current_state;
|
||||||
xml_ref_data.du_ref = &xml_data->du_ref;
|
xml_ref_data.du_ref = &xml_data->du_ref;
|
||||||
|
xml_ref_data.uuid = &xml_data->uuid;
|
||||||
|
xml_ref_data.version = &xml_data->version;
|
||||||
|
xml_ref_data.start_time = &xml_data->start_time;
|
||||||
|
xml_ref_data.complete_time = &xml_data->complete_time;
|
||||||
|
|
||||||
int fault = build_xml_node_data(xml_nodes_data[node_ref].tag_node_ref, n, &xml_ref_data);
|
int fault = build_xml_node_data(xml_nodes_data[node_ref].tag_node_ref, n, &xml_ref_data);
|
||||||
|
|
||||||
|
|
@ -925,7 +935,6 @@ int xml_recreate_namespace(mxml_node_t *tree)
|
||||||
FREE(ns.xsd);
|
FREE(ns.xsd);
|
||||||
FREE(ns.xsi);
|
FREE(ns.xsi);
|
||||||
FREE(ns.cwmp);
|
FREE(ns.cwmp);
|
||||||
|
|
||||||
if (tree) {
|
if (tree) {
|
||||||
do {
|
do {
|
||||||
char *c;
|
char *c;
|
||||||
|
|
@ -957,7 +966,6 @@ int xml_recreate_namespace(mxml_node_t *tree)
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; cwmp_urls[i] != NULL; i++) {
|
for (i = 0; cwmp_urls[i] != NULL; i++) {
|
||||||
const char *cwmp_urn = cwmp_urls[i];
|
const char *cwmp_urn = cwmp_urls[i];
|
||||||
|
|
||||||
c = (char *)xml__get_attribute_name_by_value(b, cwmp_urn);
|
c = (char *)xml__get_attribute_name_by_value(b, cwmp_urn);
|
||||||
if (c && *(c + 5) == ':') {
|
if (c && *(c + 5) == ':') {
|
||||||
FREE(ns.cwmp);
|
FREE(ns.cwmp);
|
||||||
|
|
@ -966,10 +974,10 @@ int xml_recreate_namespace(mxml_node_t *tree)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ns.cwmp && ns.soap_env && ns.xsd && ns.soap_enc && ns.xsi)
|
||||||
|
return 0;
|
||||||
} while ((b = mxmlWalkNext(b, tree, MXML_DESCEND)));
|
} while ((b = mxmlWalkNext(b, tree, MXML_DESCEND)));
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -982,20 +990,19 @@ void xml_exit(void)
|
||||||
FREE(ns.cwmp);
|
FREE(ns.cwmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int xml_send_message(struct cwmp *cwmp, struct session *session, struct rpc *rpc)
|
int xml_send_message(struct rpc *rpc)
|
||||||
{
|
{
|
||||||
char *s, *msg_out = NULL, *msg_in = NULL;
|
char *s, *msg_out = NULL, *msg_in = NULL;
|
||||||
char c[512];
|
char c[512];
|
||||||
int msg_out_len = 0, f, r = 0;
|
int msg_out_len = 0, f, r = 0;
|
||||||
mxml_node_t *b;
|
mxml_node_t *b;
|
||||||
|
|
||||||
if (session->tree_out) {
|
if (cwmp_main->session->tree_out) {
|
||||||
unsigned char *zmsg_out;
|
unsigned char *zmsg_out;
|
||||||
msg_out = mxmlSaveAllocString(session->tree_out, whitespace_cb);
|
msg_out = mxmlSaveAllocString(cwmp_main->session->tree_out, whitespace_cb);
|
||||||
CWMP_LOG_XML_MSG(DEBUG, msg_out, XML_MSG_OUT);
|
CWMP_LOG_XML_MSG(DEBUG, msg_out, XML_MSG_OUT);
|
||||||
if (cwmp->conf.compression != COMP_NONE) {
|
if (cwmp_main->conf.compression != COMP_NONE) {
|
||||||
if (zlib_compress(msg_out, &zmsg_out, &msg_out_len, cwmp->conf.compression)) {
|
if (zlib_compress(msg_out, &zmsg_out, &msg_out_len, cwmp_main->conf.compression)) {
|
||||||
CWMP_LOG(ERROR,"zlib_compress failed");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
FREE(msg_out);
|
FREE(msg_out);
|
||||||
|
|
@ -1006,8 +1013,7 @@ int xml_send_message(struct cwmp *cwmp, struct session *session, struct rpc *rpc
|
||||||
}
|
}
|
||||||
while (1) {
|
while (1) {
|
||||||
f = 0;
|
f = 0;
|
||||||
if (icwmp_http_send_message(cwmp, msg_out, msg_out_len, &msg_in)) {
|
if (icwmp_http_send_message(msg_out, msg_out_len, &msg_in)) {
|
||||||
CWMP_LOG(ERROR,"Failed to icwmp_http_send_message");
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (msg_in) {
|
if (msg_in) {
|
||||||
|
|
@ -1035,34 +1041,32 @@ int xml_send_message(struct cwmp *cwmp, struct session *session, struct rpc *rpc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
session->tree_in = mxmlLoadString(NULL, msg_in, MXML_OPAQUE_CALLBACK);
|
cwmp_main->session->tree_in = mxmlLoadString(NULL, msg_in, MXML_OPAQUE_CALLBACK);
|
||||||
if (!session->tree_in)
|
if (!cwmp_main->session->tree_in)
|
||||||
goto error;
|
goto error;
|
||||||
|
if (xml_recreate_namespace(cwmp_main->session->tree_in) == -1) {
|
||||||
if (xml_recreate_namespace(session->tree_in) == -1) {
|
|
||||||
CWMP_LOG(ERROR, "Failed to get ns parameters");
|
CWMP_LOG(ERROR, "Failed to get ns parameters");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get NoMoreRequests or HolRequest*/
|
/* get NoMoreRequests or HolRequest*/
|
||||||
session->hold_request = false;
|
cwmp_main->session->hold_request = false;
|
||||||
|
|
||||||
if (snprintf(c, sizeof(c), "%s:%s", ns.cwmp, "NoMoreRequests") == -1)
|
if (snprintf(c, sizeof(c), "%s:%s", ns.cwmp, "NoMoreRequests") == -1)
|
||||||
goto error;
|
goto error;
|
||||||
b = mxmlFindElement(session->tree_in, session->tree_in, c, NULL, NULL, MXML_DESCEND);
|
b = mxmlFindElement(cwmp_main->session->tree_in, cwmp_main->session->tree_in, c, NULL, NULL, MXML_DESCEND);
|
||||||
if (b) {
|
if (b) {
|
||||||
b = mxmlWalkNext(b, session->tree_in, MXML_DESCEND_FIRST);
|
b = mxmlWalkNext(b, cwmp_main->session->tree_in, MXML_DESCEND_FIRST);
|
||||||
if (b && mxmlGetType(b) == MXML_OPAQUE && mxmlGetOpaque(b))
|
if (b && mxmlGetType(b) == MXML_OPAQUE && mxmlGetOpaque(b))
|
||||||
session->hold_request = atoi(mxmlGetOpaque(b));
|
cwmp_main->session->hold_request = atoi(mxmlGetOpaque(b));
|
||||||
} else {
|
} else {
|
||||||
if (snprintf(c, sizeof(c), "%s:%s", ns.cwmp, "HoldRequests") == -1)
|
if (snprintf(c, sizeof(c), "%s:%s", ns.cwmp, "HoldRequests") == -1)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
b = mxmlFindElement(session->tree_in, session->tree_in, c, NULL, NULL, MXML_DESCEND);
|
b = mxmlFindElement(cwmp_main->session->tree_in, cwmp_main->session->tree_in, c, NULL, NULL, MXML_DESCEND);
|
||||||
if (b) {
|
if (b) {
|
||||||
b = mxmlWalkNext(b, session->tree_in, MXML_DESCEND_FIRST);
|
b = mxmlWalkNext(b, cwmp_main->session->tree_in, MXML_DESCEND_FIRST);
|
||||||
if (b && mxmlGetType(b) == MXML_OPAQUE && mxmlGetOpaque(b))
|
if (b && mxmlGetType(b) == MXML_OPAQUE && mxmlGetOpaque(b))
|
||||||
session->hold_request = atoi(mxmlGetOpaque(b));
|
cwmp_main->session->hold_request = atoi(mxmlGetOpaque(b));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1077,39 +1081,37 @@ error:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xml_prepare_msg_out(struct session *session)
|
int xml_prepare_msg_out()
|
||||||
{
|
{
|
||||||
struct cwmp *cwmp = &cwmp_main;
|
struct config *conf = &(cwmp_main->conf);
|
||||||
struct config *conf;
|
|
||||||
conf = &(cwmp->conf);
|
|
||||||
mxml_node_t *n;
|
mxml_node_t *n;
|
||||||
|
|
||||||
load_response_xml_schema(&session->tree_out);
|
load_response_xml_schema(&cwmp_main->session->tree_out);
|
||||||
if (!session->tree_out)
|
if (!cwmp_main->session->tree_out)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
n = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
||||||
if (!n) {
|
if (!n) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mxmlElementSetAttr(n, "xmlns:cwmp", cwmp_urls[(conf->amd_version) - 1]);
|
mxmlElementSetAttr(n, "xmlns:cwmp", cwmp_urls[(conf->amd_version) - 1]);
|
||||||
if (!session->tree_out)
|
if (!cwmp_main->session->tree_out)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xml_set_cwmp_id(struct session *session)
|
int xml_set_cwmp_id()
|
||||||
{
|
{
|
||||||
char c[32];
|
char c[32];
|
||||||
mxml_node_t *b;
|
mxml_node_t *b;
|
||||||
|
|
||||||
/* define cwmp id */
|
/* define cwmp id */
|
||||||
if (snprintf(c, sizeof(c), "%u", ++(cwmp_main.cwmp_id)) == -1)
|
if (snprintf(c, sizeof(c), "%u", ++(cwmp_main->cwmp_id)) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
b = mxmlFindElement(session->tree_out, session->tree_out, "cwmp:ID", NULL, NULL, MXML_DESCEND);
|
b = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "cwmp:ID", NULL, NULL, MXML_DESCEND);
|
||||||
if (!b)
|
if (!b)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
@ -1120,7 +1122,7 @@ int xml_set_cwmp_id(struct session *session)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xml_set_cwmp_id_rpc_cpe(struct session *session)
|
int xml_set_cwmp_id_rpc_cpe()
|
||||||
{
|
{
|
||||||
char c[512];
|
char c[512];
|
||||||
mxml_node_t *b;
|
mxml_node_t *b;
|
||||||
|
|
@ -1129,16 +1131,16 @@ int xml_set_cwmp_id_rpc_cpe(struct session *session)
|
||||||
if (snprintf(c, sizeof(c), "%s:%s", ns.cwmp, "ID") == -1)
|
if (snprintf(c, sizeof(c), "%s:%s", ns.cwmp, "ID") == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
b = mxmlFindElement(session->tree_in, session->tree_in, c, NULL, NULL, MXML_DESCEND);
|
b = mxmlFindElement(cwmp_main->session->tree_in, cwmp_main->session->tree_in, c, NULL, NULL, MXML_DESCEND);
|
||||||
|
|
||||||
if (b) {
|
if (b) {
|
||||||
/* ACS send ID parameter */
|
/* ACS send ID parameter */
|
||||||
b = mxmlWalkNext(b, session->tree_in, MXML_DESCEND_FIRST);
|
b = mxmlWalkNext(b, cwmp_main->session->tree_in, MXML_DESCEND_FIRST);
|
||||||
if (!b || mxmlGetType(b) != MXML_OPAQUE || !mxmlGetOpaque(b))
|
if (!b || mxmlGetType(b) != MXML_OPAQUE || !mxmlGetOpaque(b))
|
||||||
return 0;
|
return 0;
|
||||||
snprintf(c, sizeof(c), "%s", mxmlGetOpaque(b));
|
snprintf(c, sizeof(c), "%s", mxmlGetOpaque(b));
|
||||||
|
|
||||||
b = mxmlFindElement(session->tree_out, session->tree_out, "cwmp:ID", NULL, NULL, MXML_DESCEND);
|
b = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "cwmp:ID", NULL, NULL, MXML_DESCEND);
|
||||||
if (!b)
|
if (!b)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
@ -1147,7 +1149,7 @@ int xml_set_cwmp_id_rpc_cpe(struct session *session)
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
/* ACS does not send ID parameter */
|
/* ACS does not send ID parameter */
|
||||||
int r = xml_set_cwmp_id(session);
|
int r = xml_set_cwmp_id();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1269,9 +1271,7 @@ error:
|
||||||
void load_notification_xml_schema(mxml_node_t **tree)
|
void load_notification_xml_schema(mxml_node_t **tree)
|
||||||
{
|
{
|
||||||
char declaration[1024] = {0};
|
char declaration[1024] = {0};
|
||||||
struct cwmp *cwmp = &cwmp_main;
|
struct config *conf = &(cwmp_main->conf);
|
||||||
struct config *conf;
|
|
||||||
conf = &(cwmp->conf);
|
|
||||||
char *c = NULL;
|
char *c = NULL;
|
||||||
|
|
||||||
if (tree == NULL)
|
if (tree == NULL)
|
||||||
|
|
@ -1351,7 +1351,7 @@ void load_notification_xml_schema(mxml_node_t **tree)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL == mxmlNewOpaque(oui, cwmp->deviceid.oui)) {
|
if (NULL == mxmlNewOpaque(oui, cwmp_main->deviceid.oui)) {
|
||||||
MXML_DELETE(xml);
|
MXML_DELETE(xml);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1362,7 +1362,7 @@ void load_notification_xml_schema(mxml_node_t **tree)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL == mxmlNewOpaque(pclass, cwmp->deviceid.productclass ? cwmp->deviceid.productclass : "")) {
|
if (NULL == mxmlNewOpaque(pclass, cwmp_main->deviceid.productclass ? cwmp_main->deviceid.productclass : "")) {
|
||||||
MXML_DELETE(xml);
|
MXML_DELETE(xml);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1373,7 +1373,7 @@ void load_notification_xml_schema(mxml_node_t **tree)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL == mxmlNewOpaque(slno, cwmp->deviceid.serialnumber ? cwmp->deviceid.serialnumber : "")) {
|
if (NULL == mxmlNewOpaque(slno, cwmp_main->deviceid.serialnumber ? cwmp_main->deviceid.serialnumber : "")) {
|
||||||
MXML_DELETE(xml);
|
MXML_DELETE(xml);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
src/xml.h
10
src/xml.h
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef __XML__H_
|
#ifndef __XML__H_
|
||||||
#define __XML__H_
|
#define __XML__H_
|
||||||
|
|
||||||
#include "xml_utils.h"
|
#include <mxml.h>
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
|
@ -221,13 +221,13 @@ struct xml_node_data {
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
extern const char *cwmp_urls[];
|
extern const char *cwmp_urls[];
|
||||||
int xml_prepare_msg_out(struct session *session);
|
int xml_prepare_msg_out();
|
||||||
int xml_prepare_lwnotification_message(char **msg_out);
|
int xml_prepare_lwnotification_message(char **msg_out);
|
||||||
int xml_set_cwmp_id_rpc_cpe(struct session *session);
|
int xml_set_cwmp_id_rpc_cpe();
|
||||||
int xml_recreate_namespace(mxml_node_t *tree);
|
int xml_recreate_namespace(mxml_node_t *tree);
|
||||||
const char *whitespace_cb(mxml_node_t *node, int where);
|
const char *whitespace_cb(mxml_node_t *node, int where);
|
||||||
int xml_set_cwmp_id(struct session *session);
|
int xml_set_cwmp_id();
|
||||||
int xml_send_message(struct cwmp *cwmp, struct session *session, struct rpc *rpc);
|
int xml_send_message(struct rpc *rpc);
|
||||||
mxml_node_t *mxmlFindElementOpaque(mxml_node_t *node, mxml_node_t *top, const char *text, int descend);
|
mxml_node_t *mxmlFindElementOpaque(mxml_node_t *node, mxml_node_t *top, const char *text, int descend);
|
||||||
char *xml__get_attribute_name_by_value(mxml_node_t *node, const char *value);
|
char *xml__get_attribute_name_by_value(mxml_node_t *node, const char *value);
|
||||||
char *xml_get_cwmp_version(int version);
|
char *xml_get_cwmp_version(int version);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
#ifndef __XML_UTILS
|
|
||||||
#define __XML_UTILS
|
|
||||||
#include <mxml.h>
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
LIB_LDFLAGS:= -luci -lblobmsg_json -lubox\
|
LIB_LDFLAGS:= -lmxml -luci -lblobmsg_json -lubox\
|
||||||
-ljson-c -lubus -lpthread -lcurl\
|
-ljson-c -lubus -lpthread -lcurl\
|
||||||
-lcrypto -lmxml
|
-lcrypto
|
||||||
|
|
||||||
LIB_CFLAGS:= -fPIC -I../../ -DLOPENSSL -g -O0
|
LIB_CFLAGS:= -fPIC -I../../ -DLOPENSSL -g -O0
|
||||||
UNIT_TESTS:= icwmp_unit_testd
|
UNIT_TESTS:= icwmp_unit_testd
|
||||||
|
|
|
||||||
|
|
@ -23,22 +23,30 @@
|
||||||
|
|
||||||
static struct cwmp cwmp_main_test = { 0 };
|
static struct cwmp cwmp_main_test = { 0 };
|
||||||
|
|
||||||
|
static int bkp_session_unit_tests_init(void **state)
|
||||||
|
{
|
||||||
|
cwmp_main = (struct cwmp*)calloc(1, sizeof(struct cwmp));
|
||||||
|
create_cwmp_session_structure();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int bkp_session_unit_tests_clean(void **state)
|
static int bkp_session_unit_tests_clean(void **state)
|
||||||
{
|
{
|
||||||
icwmp_cleanmem();
|
icwmp_cleanmem();
|
||||||
|
clean_cwmp_session_structure();
|
||||||
|
FREE(cwmp_main);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cwmp_backup_session_unit_test(void **state)
|
static void cwmp_backup_session_unit_test(void **state)
|
||||||
{
|
{
|
||||||
remove(CWMP_BKP_FILE);
|
remove(CWMP_BKP_FILE);
|
||||||
struct cwmp *cwmp_test = &cwmp_main_test;
|
|
||||||
mxml_node_t *backup_tree = NULL, *n = NULL;
|
mxml_node_t *backup_tree = NULL, *n = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Init backup session
|
* Init backup session
|
||||||
*/
|
*/
|
||||||
int error = cwmp_init_backup_session(cwmp_test, NULL, ALL);
|
int error = cwmp_init_backup_session(NULL, ALL);
|
||||||
assert_int_equal(error, 0);
|
assert_int_equal(error, 0);
|
||||||
bkp_session_save();
|
bkp_session_save();
|
||||||
FILE *pFile;
|
FILE *pFile;
|
||||||
|
|
@ -270,5 +278,5 @@ int icwmp_backup_session_test(void)
|
||||||
cmocka_unit_test(cwmp_backup_session_unit_test),
|
cmocka_unit_test(cwmp_backup_session_unit_test),
|
||||||
};
|
};
|
||||||
|
|
||||||
return cmocka_run_group_tests(tests, NULL, bkp_session_unit_tests_clean);
|
return cmocka_run_group_tests(tests, bkp_session_unit_tests_init, bkp_session_unit_tests_clean);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,17 +50,20 @@ static void restore_output()
|
||||||
|
|
||||||
static int cwmp_cli_unit_tests_init(void **state)
|
static int cwmp_cli_unit_tests_init(void **state)
|
||||||
{
|
{
|
||||||
cwmp_uci_init();
|
cwmp_main = (struct cwmp*)calloc(1, sizeof(struct cwmp));
|
||||||
|
create_cwmp_session_structure();
|
||||||
|
memcpy(&(cwmp_main->env), &cwmp_main, sizeof(struct env));
|
||||||
|
cwmp_session_init();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cwmp_cli_unit_tests_clean(void **state)
|
static int cwmp_cli_unit_tests_clean(void **state)
|
||||||
{
|
{
|
||||||
icwmp_cleanmem();
|
|
||||||
FREE(add_instance);
|
|
||||||
icwmp_free_list_services();
|
icwmp_free_list_services();
|
||||||
cwmp_uci_exit();
|
cwmp_session_exit();
|
||||||
|
FREE(cwmp_main->session);
|
||||||
|
FREE(cwmp_main);
|
||||||
|
FREE(add_instance);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,45 @@
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
static LIST_HEAD(list_set_param_value);
|
||||||
|
static LIST_HEAD(faults_array);
|
||||||
|
static LIST_HEAD(parameters_list);
|
||||||
|
|
||||||
|
static int dm_iface_unit_tests_init(void **state)
|
||||||
|
{
|
||||||
|
cwmp_main = (struct cwmp*)calloc(1, sizeof(struct cwmp));
|
||||||
|
create_cwmp_session_structure();
|
||||||
|
cwmp_session_init();
|
||||||
|
global_conf_init();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int dm_iface_unit_tests_clean(void **state)
|
static int dm_iface_unit_tests_clean(void **state)
|
||||||
{
|
{
|
||||||
icwmp_cleanmem();
|
icwmp_free_list_services();
|
||||||
|
clean_cwmp_session_structure();
|
||||||
|
FREE(cwmp_main->deviceid.manufacturer);
|
||||||
|
FREE(cwmp_main->deviceid.serialnumber);
|
||||||
|
FREE(cwmp_main->deviceid.productclass);
|
||||||
|
FREE(cwmp_main->deviceid.oui);
|
||||||
|
FREE(cwmp_main->deviceid.softwareversion);
|
||||||
|
FREE(cwmp_main->conf.lw_notification_hostname);
|
||||||
|
FREE(cwmp_main->conf.ip);
|
||||||
|
FREE(cwmp_main->conf.ipv6);
|
||||||
|
FREE(cwmp_main->conf.acsurl);
|
||||||
|
FREE(cwmp_main->conf.acs_userid);
|
||||||
|
FREE(cwmp_main->conf.acs_passwd);
|
||||||
|
FREE(cwmp_main->conf.interface);
|
||||||
|
FREE(cwmp_main->conf.cpe_userid);
|
||||||
|
FREE(cwmp_main->conf.cpe_passwd);
|
||||||
|
FREE(cwmp_main->conf.ubus_socket);
|
||||||
|
FREE(cwmp_main->conf.connection_request_path);
|
||||||
|
FREE(cwmp_main->conf.default_wan_iface);
|
||||||
|
FREE(cwmp_main->conf.custom_notify_json);
|
||||||
|
FREE(cwmp_main);
|
||||||
|
cwmp_free_all_list_param_fault(&faults_array);
|
||||||
|
cwmp_free_all_dm_parameter_list(&list_set_param_value);
|
||||||
|
cwmp_session_exit();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,7 +71,6 @@ static int dm_iface_unit_tests_clean(void **state)
|
||||||
static void dm_get_parameter_values_test(void **state)
|
static void dm_get_parameter_values_test(void **state)
|
||||||
{
|
{
|
||||||
char *fault = NULL;
|
char *fault = NULL;
|
||||||
LIST_HEAD(parameters_list);
|
|
||||||
/*
|
/*
|
||||||
* Test of valid parameter path
|
* Test of valid parameter path
|
||||||
*/
|
*/
|
||||||
|
|
@ -89,8 +124,6 @@ static void dm_set_multiple_parameter_values_test(void **state)
|
||||||
int fault_code = 0;
|
int fault_code = 0;
|
||||||
char *fault_name = NULL;
|
char *fault_name = NULL;
|
||||||
struct cwmp_param_fault *param_fault = NULL;
|
struct cwmp_param_fault *param_fault = NULL;
|
||||||
LIST_HEAD(list_set_param_value);
|
|
||||||
LIST_HEAD(faults_array);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test of one valid parameter
|
* Test of one valid parameter
|
||||||
|
|
@ -194,6 +227,7 @@ static void dm_set_multiple_parameter_values_test(void **state)
|
||||||
assert_int_equal(fault, 0);
|
assert_int_equal(fault, 0);
|
||||||
assert_in_set(flag, flag_values, 15);
|
assert_in_set(flag, flag_values, 15);
|
||||||
cwmp_transaction_commit();
|
cwmp_transaction_commit();
|
||||||
|
cwmp_free_all_list_param_fault(&faults_array);
|
||||||
cwmp_free_all_dm_parameter_list(&list_set_param_value);
|
cwmp_free_all_dm_parameter_list(&list_set_param_value);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -285,7 +319,6 @@ static void dm_delete_object_test(void **state)
|
||||||
static void dm_get_parameter_names_test(void **state)
|
static void dm_get_parameter_names_test(void **state)
|
||||||
{
|
{
|
||||||
char *fault = NULL;
|
char *fault = NULL;
|
||||||
LIST_HEAD(parameters_list);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Valid multi-instance object path
|
* Valid multi-instance object path
|
||||||
|
|
@ -331,5 +364,5 @@ int icwmp_datamodel_interface_test(void)
|
||||||
cmocka_unit_test(dm_get_parameter_names_test),
|
cmocka_unit_test(dm_get_parameter_names_test),
|
||||||
};
|
};
|
||||||
|
|
||||||
return cmocka_run_group_tests(tests, NULL, dm_iface_unit_tests_clean);
|
return cmocka_run_group_tests(tests, dm_iface_unit_tests_init, dm_iface_unit_tests_clean);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "notifications.h"
|
#include "notifications.h"
|
||||||
#include "cwmp_uci.h"
|
#include "cwmp_uci.h"
|
||||||
|
#include "session.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Common functions
|
* Common functions
|
||||||
*/
|
*/
|
||||||
|
|
@ -26,15 +28,21 @@ LIST_HEAD(parameters_list);
|
||||||
|
|
||||||
static int cwmp_notifications_unit_tests_init(void **state)
|
static int cwmp_notifications_unit_tests_init(void **state)
|
||||||
{
|
{
|
||||||
cwmp_uci_init();
|
cwmp_main = (struct cwmp*)calloc(1, sizeof(struct cwmp));
|
||||||
|
create_cwmp_session_structure();
|
||||||
|
memcpy(&(cwmp_main->env), &cwmp_main, sizeof(struct env));
|
||||||
|
cwmp_session_init();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cwmp_notifications_unit_tests_clean(void **state)
|
static int cwmp_notifications_unit_tests_clean(void **state)
|
||||||
{
|
{
|
||||||
icwmp_cleanmem();
|
clean_list_param_notify();
|
||||||
|
clean_list_value_change();
|
||||||
cwmp_free_all_dm_parameter_list(¶meters_list);
|
cwmp_free_all_dm_parameter_list(¶meters_list);
|
||||||
cwmp_uci_exit();
|
cwmp_session_exit();
|
||||||
|
FREE(cwmp_main->session);
|
||||||
|
FREE(cwmp_main);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -264,6 +272,7 @@ static void cwmp_check_value_change_1_unit_test(void **state)
|
||||||
assert_int_equal((int)list_empty(&list_value_change), 0);
|
assert_int_equal((int)list_empty(&list_value_change), 0);
|
||||||
assert_int_equal((int)list_empty(&list_lw_value_change), 1);
|
assert_int_equal((int)list_empty(&list_lw_value_change), 1);
|
||||||
assert_int_equal(get_parameter_in_list_value_change("Device.DeviceInfo.UpTime"), 1);
|
assert_int_equal(get_parameter_in_list_value_change("Device.DeviceInfo.UpTime"), 1);
|
||||||
|
clean_list_value_change();
|
||||||
}
|
}
|
||||||
|
|
||||||
int icwmp_notifications_test(void)
|
int icwmp_notifications_test(void)
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,8 @@
|
||||||
#include "xml.h"
|
#include "xml.h"
|
||||||
|
|
||||||
#include "icwmp_soap_msg_unit_test.h"
|
#include "icwmp_soap_msg_unit_test.h"
|
||||||
|
#include "cwmp_event.h"
|
||||||
|
|
||||||
static struct cwmp cwmp_main_test = { 0 };
|
|
||||||
static struct cwmp *cwmp_test;
|
|
||||||
static struct session *session_test = NULL;
|
|
||||||
static int instance = 0;
|
static int instance = 0;
|
||||||
|
|
||||||
#define INVALID_PARAM_KEY "ParameterKeyParameterKeyParameter"
|
#define INVALID_PARAM_KEY "ParameterKeyParameterKeyParameter"
|
||||||
|
|
@ -41,23 +39,23 @@ static int instance = 0;
|
||||||
*/
|
*/
|
||||||
static void clean_config()
|
static void clean_config()
|
||||||
{
|
{
|
||||||
FREE(cwmp_test->deviceid.manufacturer);
|
FREE(cwmp_main->deviceid.manufacturer);
|
||||||
FREE(cwmp_test->deviceid.serialnumber);
|
FREE(cwmp_main->deviceid.serialnumber);
|
||||||
FREE(cwmp_test->deviceid.productclass);
|
FREE(cwmp_main->deviceid.productclass);
|
||||||
FREE(cwmp_test->deviceid.oui);
|
FREE(cwmp_main->deviceid.oui);
|
||||||
FREE(cwmp_test->deviceid.softwareversion);
|
FREE(cwmp_main->deviceid.softwareversion);
|
||||||
FREE(cwmp_test->conf.lw_notification_hostname);
|
FREE(cwmp_main->conf.lw_notification_hostname);
|
||||||
FREE(cwmp_test->conf.ip);
|
FREE(cwmp_main->conf.ip);
|
||||||
FREE(cwmp_test->conf.ipv6);
|
FREE(cwmp_main->conf.ipv6);
|
||||||
FREE(cwmp_test->conf.acsurl);
|
FREE(cwmp_main->conf.acsurl);
|
||||||
FREE(cwmp_test->conf.acs_userid);
|
FREE(cwmp_main->conf.acs_userid);
|
||||||
FREE(cwmp_test->conf.acs_passwd);
|
FREE(cwmp_main->conf.acs_passwd);
|
||||||
FREE(cwmp_test->conf.interface);
|
FREE(cwmp_main->conf.interface);
|
||||||
FREE(cwmp_test->conf.cpe_userid);
|
FREE(cwmp_main->conf.cpe_userid);
|
||||||
FREE(cwmp_test->conf.cpe_passwd);
|
FREE(cwmp_main->conf.cpe_passwd);
|
||||||
FREE(cwmp_test->conf.ubus_socket);
|
FREE(cwmp_main->conf.ubus_socket);
|
||||||
FREE(cwmp_test->conf.connection_request_path);
|
FREE(cwmp_main->conf.connection_request_path);
|
||||||
FREE(cwmp_test->conf.default_wan_iface);
|
FREE(cwmp_main->conf.default_wan_iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clean_name_space()
|
static void clean_name_space()
|
||||||
|
|
@ -69,11 +67,11 @@ static void clean_name_space()
|
||||||
FREE(ns.cwmp);
|
FREE(ns.cwmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unit_test_remove_all_events_by_session(struct session *session)
|
static void unit_test_remove_all_session_events()
|
||||||
{
|
{
|
||||||
while (session->head_event_container.next != &(session->head_event_container)) {
|
while (cwmp_main->session->events.next != &(cwmp_main->session->events)) {
|
||||||
struct event_container *event_container;
|
struct event_container *event_container;
|
||||||
event_container = list_entry(session->head_event_container.next, struct event_container, list);
|
event_container = list_entry(cwmp_main->session->events.next, struct event_container, list);
|
||||||
free(event_container->command_key);
|
free(event_container->command_key);
|
||||||
cwmp_free_all_dm_parameter_list(&(event_container->head_dm_parameter));
|
cwmp_free_all_dm_parameter_list(&(event_container->head_dm_parameter));
|
||||||
list_del(&(event_container->list));
|
list_del(&(event_container->list));
|
||||||
|
|
@ -83,12 +81,7 @@ static void unit_test_remove_all_events_by_session(struct session *session)
|
||||||
|
|
||||||
static void unit_test_end_test_destruction()
|
static void unit_test_end_test_destruction()
|
||||||
{
|
{
|
||||||
struct session *session = NULL;
|
unit_test_remove_all_session_events();
|
||||||
while (cwmp_test->head_session_queue.next != &(cwmp_test->head_session_queue)) {
|
|
||||||
session = list_entry(cwmp_test->head_session_queue.next, struct session, list);
|
|
||||||
unit_test_remove_all_events_by_session(session);
|
|
||||||
cwmp_session_destructor(session);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -96,28 +89,22 @@ static void unit_test_end_test_destruction()
|
||||||
*/
|
*/
|
||||||
static int soap_unit_tests_init(void **state)
|
static int soap_unit_tests_init(void **state)
|
||||||
{
|
{
|
||||||
cwmp_test = &cwmp_main_test;
|
cwmp_main = (struct cwmp*)calloc(1, sizeof(struct cwmp));
|
||||||
INIT_LIST_HEAD(&(cwmp_test->head_session_queue));
|
create_cwmp_session_structure();
|
||||||
memcpy(&(cwmp_test->env), &cwmp_test, sizeof(struct env));
|
memcpy(&(cwmp_main->env), &cwmp_main, sizeof(struct env));
|
||||||
cwmp_uci_init();
|
cwmp_session_init();
|
||||||
log_set_severity_idx("DEBUG");
|
log_set_severity_idx("DEBUG");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int soap_unit_tests_clean(void **state)
|
static int soap_unit_tests_clean(void **state)
|
||||||
{
|
{
|
||||||
icwmp_cleanmem();
|
|
||||||
if (session_test != NULL) {
|
|
||||||
MXML_DELETE(session_test->tree_in);
|
|
||||||
MXML_DELETE(session_test->tree_out);
|
|
||||||
session_test->head_rpc_acs.next = NULL;
|
|
||||||
session_test->head_rpc_cpe.next = NULL;
|
|
||||||
cwmp_session_destructor(session_test);
|
|
||||||
}
|
|
||||||
icwmp_free_list_services();
|
icwmp_free_list_services();
|
||||||
clean_name_space();
|
clean_name_space();
|
||||||
clean_config();
|
clean_config();
|
||||||
cwmp_uci_exit();
|
cwmp_session_exit();
|
||||||
|
FREE(cwmp_main->session);
|
||||||
|
FREE(cwmp_main);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -126,51 +113,34 @@ static int soap_unit_tests_clean(void **state)
|
||||||
*/
|
*/
|
||||||
static void get_config_test(void **state)
|
static void get_config_test(void **state)
|
||||||
{
|
{
|
||||||
int error = get_preinit_config(&(cwmp_test->conf));
|
int error = get_preinit_config();
|
||||||
assert_int_equal(error, CWMP_OK);
|
assert_int_equal(error, CWMP_OK);
|
||||||
error = get_global_config(&(cwmp_test->conf));
|
error = get_global_config();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_deviceid_test(void **state)
|
static void get_deviceid_test(void **state)
|
||||||
{
|
{
|
||||||
int error = cwmp_get_deviceid(cwmp_test);
|
int error = cwmp_get_deviceid();
|
||||||
assert_int_equal(error, CWMP_OK);
|
assert_int_equal(error, CWMP_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_event_test(void **state)
|
static void add_event_test(void **state)
|
||||||
{
|
{
|
||||||
struct event_container *event_container;
|
struct event_container *event_container;
|
||||||
event_container = cwmp_add_event_container(cwmp_test, EVENT_IDX_1BOOT, "");
|
event_container = cwmp_add_event_container(EVENT_IDX_1BOOT, "");
|
||||||
assert_non_null(event_container);
|
assert_non_null(event_container);
|
||||||
assert_string_equal(EVENT_CONST[event_container->code].CODE, "1 BOOT");
|
assert_string_equal(EVENT_CONST[event_container->code].CODE, "1 BOOT");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int create_session(struct session **session)
|
|
||||||
{
|
|
||||||
*session = calloc(1, sizeof(struct session));
|
|
||||||
if (*session == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
list_add_tail(&((*session)->list), &(cwmp_test->head_session_queue));
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&((*session)->head_event_container));
|
|
||||||
*session = list_entry((&(cwmp_test->head_session_queue))->next, struct session, list);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void soap_inform_message_test(void **state)
|
static void soap_inform_message_test(void **state)
|
||||||
{
|
{
|
||||||
mxml_node_t *env = NULL, *n = NULL, *device_id = NULL, *cwmp_inform = NULL;
|
mxml_node_t *env = NULL, *n = NULL, *device_id = NULL, *cwmp_inform = NULL;
|
||||||
struct session *session = NULL;
|
|
||||||
struct rpc *rpc_acs;
|
struct rpc *rpc_acs;
|
||||||
|
|
||||||
create_session(&session);
|
rpc_acs = list_entry(&(cwmp_main->session->head_rpc_acs), struct rpc, list);
|
||||||
session_test = session;
|
cwmp_rpc_acs_prepare_message_inform(rpc_acs);
|
||||||
rpc_acs = list_entry(&(session->head_rpc_acs), struct rpc, list);
|
|
||||||
|
|
||||||
cwmp_rpc_acs_prepare_message_inform(cwmp_test, session, rpc_acs);
|
env = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
||||||
|
|
||||||
env = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
|
||||||
assert_non_null(env);
|
assert_non_null(env);
|
||||||
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
@ -200,33 +170,32 @@ static void soap_inform_message_test(void **state)
|
||||||
n = mxmlFindElement(cwmp_inform, cwmp_inform, "ParameterList", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(cwmp_inform, cwmp_inform, "ParameterList", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
||||||
MXML_DELETE(session->tree_in);
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
MXML_DELETE(session->tree_out);
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
|
|
||||||
unit_test_end_test_destruction();
|
unit_test_end_test_destruction();
|
||||||
clean_config();
|
clean_config();
|
||||||
session_test = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prepare_session_for_rpc_method_call(struct session *session)
|
static void prepare_session_for_rpc_method_call()
|
||||||
{
|
{
|
||||||
mxml_node_t *b;
|
mxml_node_t *b;
|
||||||
char *c;
|
char *c;
|
||||||
|
|
||||||
icwmp_asprintf(&c, "%s:%s", ns.soap_env, "Body");
|
icwmp_asprintf(&c, "%s:%s", ns.soap_env, "Body");
|
||||||
b = mxmlFindElement(session->tree_in, session->tree_in, c, NULL, NULL, MXML_DESCEND);
|
b = mxmlFindElement(cwmp_main->session->tree_in, cwmp_main->session->tree_in, c, NULL, NULL, MXML_DESCEND);
|
||||||
session->body_in = b;
|
cwmp_main->session->body_in = b;
|
||||||
xml_prepare_msg_out(session);
|
xml_prepare_msg_out();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prepare_gpv_soap_request(struct session *session, char *parameters[], int len)
|
static void prepare_gpv_soap_request(char *parameters[], int len)
|
||||||
{
|
{
|
||||||
mxml_node_t *params = NULL, *n = NULL;
|
mxml_node_t *params = NULL, *n = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
session->tree_in = mxmlLoadString(NULL, CWMP_GETPARAMETERVALUES_REQ, MXML_OPAQUE_CALLBACK);
|
cwmp_main->session->tree_in = mxmlLoadString(NULL, CWMP_GETPARAMETERVALUES_REQ, MXML_OPAQUE_CALLBACK);
|
||||||
xml_recreate_namespace(session->tree_in);
|
xml_recreate_namespace(cwmp_main->session->tree_in);
|
||||||
params = mxmlFindElement(session->tree_in, session->tree_in, "ParameterNames", NULL, NULL, MXML_DESCEND);
|
params = mxmlFindElement(cwmp_main->session->tree_in, cwmp_main->session->tree_in, "ParameterNames", NULL, NULL, MXML_DESCEND);
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
n = mxmlNewElement(params, "string");
|
n = mxmlNewElement(params, "string");
|
||||||
n = mxmlNewOpaque(n, parameters[i]);
|
n = mxmlNewOpaque(n, parameters[i]);
|
||||||
|
|
@ -235,27 +204,23 @@ static void prepare_gpv_soap_request(struct session *session, char *parameters[]
|
||||||
|
|
||||||
static void soap_get_param_value_message_test(void **state)
|
static void soap_get_param_value_message_test(void **state)
|
||||||
{
|
{
|
||||||
struct session *session = NULL;
|
|
||||||
mxml_node_t *env = NULL, *n = NULL, *name = NULL, *value = NULL;
|
mxml_node_t *env = NULL, *n = NULL, *name = NULL, *value = NULL;
|
||||||
struct rpc *rpc_cpe;
|
struct rpc *rpc_cpe;
|
||||||
|
|
||||||
create_session(&session);
|
rpc_cpe = list_entry(&(cwmp_main->session->head_rpc_cpe), struct rpc, list);
|
||||||
session_test = session;
|
|
||||||
|
|
||||||
rpc_cpe = list_entry(&(session->head_rpc_cpe), struct rpc, list);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Valid parameter path
|
* Valid parameter path
|
||||||
*/
|
*/
|
||||||
char *valid_parameters[1] = { "Device.ManagementServer.PeriodicInformEnable" };
|
char *valid_parameters[1] = { "Device.ManagementServer.PeriodicInformEnable" };
|
||||||
prepare_gpv_soap_request(session, valid_parameters, 1);
|
prepare_gpv_soap_request(valid_parameters, 1);
|
||||||
|
|
||||||
prepare_session_for_rpc_method_call(session);
|
prepare_session_for_rpc_method_call();
|
||||||
|
|
||||||
int ret = cwmp_handle_rpc_cpe_get_parameter_values(session, rpc_cpe);
|
int ret = cwmp_handle_rpc_cpe_get_parameter_values(rpc_cpe);
|
||||||
assert_int_equal(ret, 0);
|
assert_int_equal(ret, 0);
|
||||||
|
|
||||||
env = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
env = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(env);
|
assert_non_null(env);
|
||||||
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
@ -276,8 +241,8 @@ static void soap_get_param_value_message_test(void **state)
|
||||||
value = mxmlFindElement(n, n, "Value", NULL, NULL, MXML_DESCEND);
|
value = mxmlFindElement(n, n, "Value", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(value);
|
assert_non_null(value);
|
||||||
|
|
||||||
MXML_DELETE(session->tree_in);
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
MXML_DELETE(session->tree_out);
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wrong parameter path
|
* Wrong parameter path
|
||||||
|
|
@ -285,14 +250,14 @@ static void soap_get_param_value_message_test(void **state)
|
||||||
mxml_node_t *fault_code = NULL, *fault_string = NULL, *detail = NULL, *detail_code = NULL, *detail_string = NULL;
|
mxml_node_t *fault_code = NULL, *fault_string = NULL, *detail = NULL, *detail_code = NULL, *detail_string = NULL;
|
||||||
|
|
||||||
char *invalid_parameter[1] = { "Device.ManagementServereriodicInformEnable" };
|
char *invalid_parameter[1] = { "Device.ManagementServereriodicInformEnable" };
|
||||||
prepare_gpv_soap_request(session, invalid_parameter, 1);
|
prepare_gpv_soap_request(invalid_parameter, 1);
|
||||||
|
|
||||||
prepare_session_for_rpc_method_call(session);
|
prepare_session_for_rpc_method_call();
|
||||||
|
|
||||||
ret = cwmp_handle_rpc_cpe_get_parameter_values(session, rpc_cpe);
|
ret = cwmp_handle_rpc_cpe_get_parameter_values(rpc_cpe);
|
||||||
assert_int_equal(ret, 0);
|
assert_int_equal(ret, 0);
|
||||||
|
|
||||||
env = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
env = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(env);
|
assert_non_null(env);
|
||||||
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
@ -316,22 +281,21 @@ static void soap_get_param_value_message_test(void **state)
|
||||||
detail_string = mxmlFindElement(detail, detail, "FaultString", NULL, NULL, MXML_DESCEND);
|
detail_string = mxmlFindElement(detail, detail, "FaultString", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(detail_string);
|
assert_non_null(detail_string);
|
||||||
|
|
||||||
MXML_DELETE(session->tree_in);
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
MXML_DELETE(session->tree_out);
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
session->head_rpc_acs.next = NULL;
|
cwmp_main->session->head_rpc_acs.next = NULL;
|
||||||
|
|
||||||
unit_test_end_test_destruction();
|
unit_test_end_test_destruction();
|
||||||
clean_name_space();
|
clean_name_space();
|
||||||
session_test = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prepare_addobj_soap_request(struct session *session, char *object, char *parameter_key)
|
static void prepare_addobj_soap_request(char *object, char *parameter_key)
|
||||||
{
|
{
|
||||||
mxml_node_t *add_node = NULL, *n = NULL;
|
mxml_node_t *add_node = NULL, *n = NULL;
|
||||||
|
|
||||||
session->tree_in = mxmlLoadString(NULL, CWMP_ADDOBJECT_REQ, MXML_OPAQUE_CALLBACK);
|
cwmp_main->session->tree_in = mxmlLoadString(NULL, CWMP_ADDOBJECT_REQ, MXML_OPAQUE_CALLBACK);
|
||||||
xml_recreate_namespace(session->tree_in);
|
xml_recreate_namespace(cwmp_main->session->tree_in);
|
||||||
add_node = mxmlFindElement(session->tree_in, session->tree_in, "cwmp:AddObject", NULL, NULL, MXML_DESCEND);
|
add_node = mxmlFindElement(cwmp_main->session->tree_in, cwmp_main->session->tree_in, "cwmp:AddObject", NULL, NULL, MXML_DESCEND);
|
||||||
n = mxmlFindElement(add_node, add_node, "ObjectName", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(add_node, add_node, "ObjectName", NULL, NULL, MXML_DESCEND);
|
||||||
n = mxmlNewOpaque(n, object);
|
n = mxmlNewOpaque(n, object);
|
||||||
n = mxmlFindElement(add_node, add_node, "ParameterKey", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(add_node, add_node, "ParameterKey", NULL, NULL, MXML_DESCEND);
|
||||||
|
|
@ -340,23 +304,20 @@ static void prepare_addobj_soap_request(struct session *session, char *object, c
|
||||||
|
|
||||||
static void soap_add_object_message_test(void **state)
|
static void soap_add_object_message_test(void **state)
|
||||||
{
|
{
|
||||||
struct session *session = NULL;
|
|
||||||
mxml_node_t *env = NULL, *n = NULL, *add_resp = NULL;
|
mxml_node_t *env = NULL, *n = NULL, *add_resp = NULL;
|
||||||
struct rpc *rpc_cpe;
|
struct rpc *rpc_cpe;
|
||||||
|
|
||||||
create_session(&session);
|
rpc_cpe = list_entry(&(cwmp_main->session->head_rpc_cpe), struct rpc, list);
|
||||||
session_test = session;
|
|
||||||
rpc_cpe = list_entry(&(session->head_rpc_cpe), struct rpc, list);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Valid path & writable object
|
* Valid path & writable object
|
||||||
*/
|
*/
|
||||||
prepare_addobj_soap_request(session, "Device.WiFi.SSID.", "add_object_test");
|
prepare_addobj_soap_request("Device.WiFi.SSID.", "add_object_test");
|
||||||
prepare_session_for_rpc_method_call(session);
|
prepare_session_for_rpc_method_call();
|
||||||
|
|
||||||
int ret = cwmp_handle_rpc_cpe_add_object(session, rpc_cpe);
|
int ret = cwmp_handle_rpc_cpe_add_object(rpc_cpe);
|
||||||
assert_int_equal(ret, 0);
|
assert_int_equal(ret, 0);
|
||||||
env = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
env = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(env);
|
assert_non_null(env);
|
||||||
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
@ -372,21 +333,21 @@ static void soap_add_object_message_test(void **state)
|
||||||
n = mxmlFindElement(add_resp, add_resp, "Status", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(add_resp, add_resp, "Status", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
assert_string_equal(mxmlGetOpaque(mxmlGetFirstChild(n)), "1");
|
assert_string_equal(mxmlGetOpaque(mxmlGetFirstChild(n)), "1");
|
||||||
MXML_DELETE(session->tree_in);
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
MXML_DELETE(session->tree_out);
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wrong object path
|
* Wrong object path
|
||||||
*/
|
*/
|
||||||
mxml_node_t *cwmp_fault = NULL;
|
mxml_node_t *cwmp_fault = NULL;
|
||||||
|
|
||||||
prepare_addobj_soap_request(session, "Device.WiFi.SSI.", "add_object_test");
|
prepare_addobj_soap_request("Device.WiFi.SSI.", "add_object_test");
|
||||||
prepare_session_for_rpc_method_call(session);
|
prepare_session_for_rpc_method_call();
|
||||||
|
|
||||||
ret = cwmp_handle_rpc_cpe_add_object(session, rpc_cpe);
|
ret = cwmp_handle_rpc_cpe_add_object(rpc_cpe);
|
||||||
assert_int_equal(ret, 0);
|
assert_int_equal(ret, 0);
|
||||||
|
|
||||||
env = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
env = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(env);
|
assert_non_null(env);
|
||||||
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
@ -405,20 +366,20 @@ static void soap_add_object_message_test(void **state)
|
||||||
assert_string_equal(mxmlGetOpaque(mxmlGetFirstChild(n)), "9005");
|
assert_string_equal(mxmlGetOpaque(mxmlGetFirstChild(n)), "9005");
|
||||||
n = mxmlFindElement(cwmp_fault, cwmp_fault, "FaultString", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(cwmp_fault, cwmp_fault, "FaultString", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
MXML_DELETE(session->tree_in);
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
MXML_DELETE(session->tree_out);
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Not writable & Valid object path
|
* Not writable & Valid object path
|
||||||
*/
|
*/
|
||||||
cwmp_fault = NULL;
|
cwmp_fault = NULL;
|
||||||
prepare_addobj_soap_request(session, "Device.DeviceInfo.Processor.", "add_object_test");
|
prepare_addobj_soap_request("Device.DeviceInfo.Processor.", "add_object_test");
|
||||||
prepare_session_for_rpc_method_call(session);
|
prepare_session_for_rpc_method_call();
|
||||||
|
|
||||||
ret = cwmp_handle_rpc_cpe_add_object(session, rpc_cpe);
|
ret = cwmp_handle_rpc_cpe_add_object(rpc_cpe);
|
||||||
assert_int_equal(ret, 0);
|
assert_int_equal(ret, 0);
|
||||||
|
|
||||||
env = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
env = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(env);
|
assert_non_null(env);
|
||||||
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
@ -437,20 +398,20 @@ static void soap_add_object_message_test(void **state)
|
||||||
assert_string_equal(mxmlGetOpaque(mxmlGetFirstChild(n)), "9005");
|
assert_string_equal(mxmlGetOpaque(mxmlGetFirstChild(n)), "9005");
|
||||||
n = mxmlFindElement(cwmp_fault, cwmp_fault, "FaultString", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(cwmp_fault, cwmp_fault, "FaultString", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
MXML_DELETE(session->tree_in);
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
MXML_DELETE(session->tree_out);
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Invalid parameterkey
|
* Invalid parameterkey
|
||||||
*/
|
*/
|
||||||
cwmp_fault = NULL;
|
cwmp_fault = NULL;
|
||||||
prepare_addobj_soap_request(session, "Device.WiFi.SSID.", INVALID_PARAM_KEY);
|
prepare_addobj_soap_request("Device.WiFi.SSID.", INVALID_PARAM_KEY);
|
||||||
prepare_session_for_rpc_method_call(session);
|
prepare_session_for_rpc_method_call();
|
||||||
|
|
||||||
ret = cwmp_handle_rpc_cpe_add_object(session, rpc_cpe);
|
ret = cwmp_handle_rpc_cpe_add_object(rpc_cpe);
|
||||||
assert_int_equal(ret, 0);
|
assert_int_equal(ret, 0);
|
||||||
|
|
||||||
env = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
env = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(env);
|
assert_non_null(env);
|
||||||
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
@ -469,22 +430,21 @@ static void soap_add_object_message_test(void **state)
|
||||||
assert_string_equal(mxmlGetOpaque(mxmlGetFirstChild(n)), "9003");
|
assert_string_equal(mxmlGetOpaque(mxmlGetFirstChild(n)), "9003");
|
||||||
n = mxmlFindElement(cwmp_fault, cwmp_fault, "FaultString", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(cwmp_fault, cwmp_fault, "FaultString", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
MXML_DELETE(session->tree_in);
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
MXML_DELETE(session->tree_out);
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
|
|
||||||
session->head_rpc_acs.next = NULL;
|
cwmp_main->session->head_rpc_acs.next = NULL;
|
||||||
unit_test_end_test_destruction();
|
unit_test_end_test_destruction();
|
||||||
clean_name_space();
|
clean_name_space();
|
||||||
session_test = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prepare_delobj_soap_request(struct session *session, char *object, char *parameter_key)
|
static void prepare_delobj_soap_request(char *object, char *parameter_key)
|
||||||
{
|
{
|
||||||
mxml_node_t *del_node = NULL, *n = NULL;
|
mxml_node_t *del_node = NULL, *n = NULL;
|
||||||
|
|
||||||
session->tree_in = mxmlLoadString(NULL, CWMP_DELOBJECT_REQ, MXML_OPAQUE_CALLBACK);
|
cwmp_main->session->tree_in = mxmlLoadString(NULL, CWMP_DELOBJECT_REQ, MXML_OPAQUE_CALLBACK);
|
||||||
xml_recreate_namespace(session->tree_in);
|
xml_recreate_namespace(cwmp_main->session->tree_in);
|
||||||
del_node = mxmlFindElement(session->tree_in, session->tree_in, "cwmp:DeleteObject", NULL, NULL, MXML_DESCEND);
|
del_node = mxmlFindElement(cwmp_main->session->tree_in, cwmp_main->session->tree_in, "cwmp:DeleteObject", NULL, NULL, MXML_DESCEND);
|
||||||
n = mxmlFindElement(del_node, del_node, "ObjectName", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(del_node, del_node, "ObjectName", NULL, NULL, MXML_DESCEND);
|
||||||
n = mxmlNewOpaque(n, object);
|
n = mxmlNewOpaque(n, object);
|
||||||
n = mxmlFindElement(del_node, del_node, "ParameterKey", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(del_node, del_node, "ParameterKey", NULL, NULL, MXML_DESCEND);
|
||||||
|
|
@ -493,26 +453,22 @@ static void prepare_delobj_soap_request(struct session *session, char *object, c
|
||||||
|
|
||||||
static void soap_delete_object_message_test(void **state)
|
static void soap_delete_object_message_test(void **state)
|
||||||
{
|
{
|
||||||
struct session *session = NULL;
|
|
||||||
mxml_node_t *env = NULL, *n = NULL, *add_resp = NULL;
|
mxml_node_t *env = NULL, *n = NULL, *add_resp = NULL;
|
||||||
struct rpc *rpc_cpe;
|
struct rpc *rpc_cpe;
|
||||||
|
|
||||||
create_session(&session);
|
rpc_cpe = list_entry(&(cwmp_main->session->head_rpc_cpe), struct rpc, list);
|
||||||
session_test = session;
|
|
||||||
|
|
||||||
rpc_cpe = list_entry(&(session->head_rpc_cpe), struct rpc, list);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Valid path & writable object
|
* Valid path & writable object
|
||||||
*/
|
*/
|
||||||
char del_obj[32];
|
char del_obj[32];
|
||||||
snprintf(del_obj, sizeof(del_obj), "Device.WiFi.SSID.%d.", instance);
|
snprintf(del_obj, sizeof(del_obj), "Device.WiFi.SSID.%d.", instance);
|
||||||
prepare_delobj_soap_request(session, del_obj, "del_object_test");
|
prepare_delobj_soap_request(del_obj, "del_object_test");
|
||||||
prepare_session_for_rpc_method_call(session);
|
prepare_session_for_rpc_method_call();
|
||||||
|
|
||||||
int ret = cwmp_handle_rpc_cpe_delete_object(session, rpc_cpe);
|
int ret = cwmp_handle_rpc_cpe_delete_object(rpc_cpe);
|
||||||
assert_int_equal(ret, 0);
|
assert_int_equal(ret, 0);
|
||||||
env = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
env = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(env);
|
assert_non_null(env);
|
||||||
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
@ -525,21 +481,21 @@ static void soap_delete_object_message_test(void **state)
|
||||||
n = mxmlFindElement(add_resp, add_resp, "Status", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(add_resp, add_resp, "Status", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
assert_string_equal(mxmlGetOpaque(mxmlGetFirstChild(n)), "1");
|
assert_string_equal(mxmlGetOpaque(mxmlGetFirstChild(n)), "1");
|
||||||
MXML_DELETE(session->tree_in);
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
MXML_DELETE(session->tree_out);
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wrong object path
|
* Wrong object path
|
||||||
*/
|
*/
|
||||||
mxml_node_t *cwmp_fault = NULL;
|
mxml_node_t *cwmp_fault = NULL;
|
||||||
|
|
||||||
prepare_delobj_soap_request(session, "Device.WiFi.SID.1", "del_object_test");
|
prepare_delobj_soap_request("Device.WiFi.SID.1", "del_object_test");
|
||||||
prepare_session_for_rpc_method_call(session);
|
prepare_session_for_rpc_method_call();
|
||||||
|
|
||||||
ret = cwmp_handle_rpc_cpe_delete_object(session, rpc_cpe);
|
ret = cwmp_handle_rpc_cpe_delete_object(rpc_cpe);
|
||||||
assert_int_equal(ret, 0);
|
assert_int_equal(ret, 0);
|
||||||
|
|
||||||
env = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
env = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(env);
|
assert_non_null(env);
|
||||||
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
@ -558,20 +514,20 @@ static void soap_delete_object_message_test(void **state)
|
||||||
assert_string_equal(mxmlGetOpaque(mxmlGetFirstChild(n)), "9005");
|
assert_string_equal(mxmlGetOpaque(mxmlGetFirstChild(n)), "9005");
|
||||||
n = mxmlFindElement(cwmp_fault, cwmp_fault, "FaultString", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(cwmp_fault, cwmp_fault, "FaultString", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
MXML_DELETE(session->tree_in);
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
MXML_DELETE(session->tree_out);
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Not writable & Valid object path
|
* Not writable & Valid object path
|
||||||
*/
|
*/
|
||||||
cwmp_fault = NULL;
|
cwmp_fault = NULL;
|
||||||
prepare_delobj_soap_request(session, "Device.DeviceInfo.Processor.2.", "del_object_test");
|
prepare_delobj_soap_request("Device.DeviceInfo.Processor.2.", "del_object_test");
|
||||||
prepare_session_for_rpc_method_call(session);
|
prepare_session_for_rpc_method_call();
|
||||||
|
|
||||||
ret = cwmp_handle_rpc_cpe_delete_object(session, rpc_cpe);
|
ret = cwmp_handle_rpc_cpe_delete_object(rpc_cpe);
|
||||||
assert_int_equal(ret, 0);
|
assert_int_equal(ret, 0);
|
||||||
|
|
||||||
env = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
env = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(env);
|
assert_non_null(env);
|
||||||
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
@ -590,20 +546,20 @@ static void soap_delete_object_message_test(void **state)
|
||||||
assert_string_equal(mxmlGetOpaque(mxmlGetFirstChild(n)), "9005");
|
assert_string_equal(mxmlGetOpaque(mxmlGetFirstChild(n)), "9005");
|
||||||
n = mxmlFindElement(cwmp_fault, cwmp_fault, "FaultString", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(cwmp_fault, cwmp_fault, "FaultString", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
MXML_DELETE(session->tree_in);
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
MXML_DELETE(session->tree_out);
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Invalid parameterkey
|
* Invalid parameterkey
|
||||||
*/
|
*/
|
||||||
cwmp_fault = NULL;
|
cwmp_fault = NULL;
|
||||||
prepare_delobj_soap_request(session, "Device.WiFi.SSID.1.", INVALID_PARAM_KEY);
|
prepare_delobj_soap_request("Device.WiFi.SSID.1.", INVALID_PARAM_KEY);
|
||||||
prepare_session_for_rpc_method_call(session);
|
prepare_session_for_rpc_method_call();
|
||||||
|
|
||||||
ret = cwmp_handle_rpc_cpe_delete_object(session, rpc_cpe);
|
ret = cwmp_handle_rpc_cpe_delete_object(rpc_cpe);
|
||||||
assert_int_equal(ret, 0);
|
assert_int_equal(ret, 0);
|
||||||
|
|
||||||
env = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
env = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(env);
|
assert_non_null(env);
|
||||||
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
@ -622,22 +578,21 @@ static void soap_delete_object_message_test(void **state)
|
||||||
assert_string_equal(mxmlGetOpaque(mxmlGetFirstChild(n)), "9003");
|
assert_string_equal(mxmlGetOpaque(mxmlGetFirstChild(n)), "9003");
|
||||||
n = mxmlFindElement(cwmp_fault, cwmp_fault, "FaultString", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(cwmp_fault, cwmp_fault, "FaultString", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
MXML_DELETE(session->tree_in);
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
MXML_DELETE(session->tree_out);
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
|
|
||||||
session->head_rpc_acs.next = NULL;
|
cwmp_main->session->head_rpc_acs.next = NULL;
|
||||||
unit_test_end_test_destruction();
|
unit_test_end_test_destruction();
|
||||||
clean_name_space();
|
clean_name_space();
|
||||||
session_test = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prepare_gpa_soap_request(struct session *session, char *parameter)
|
static void prepare_gpa_soap_request(char *parameter)
|
||||||
{
|
{
|
||||||
mxml_node_t *n = NULL;
|
mxml_node_t *n = NULL;
|
||||||
|
|
||||||
session->tree_in = mxmlLoadString(NULL, CWMP_GETATTRIBUTES_REQ, MXML_OPAQUE_CALLBACK);
|
cwmp_main->session->tree_in = mxmlLoadString(NULL, CWMP_GETATTRIBUTES_REQ, MXML_OPAQUE_CALLBACK);
|
||||||
xml_recreate_namespace(session->tree_in);
|
xml_recreate_namespace(cwmp_main->session->tree_in);
|
||||||
n = mxmlFindElement(session->tree_in, session->tree_in, "cwmp:GetParameterAttributes", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(cwmp_main->session->tree_in, cwmp_main->session->tree_in, "cwmp:GetParameterAttributes", NULL, NULL, MXML_DESCEND);
|
||||||
n = mxmlFindElement(n, n, "ParameterNames", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(n, n, "ParameterNames", NULL, NULL, MXML_DESCEND);
|
||||||
n = mxmlNewElement(n, "string");
|
n = mxmlNewElement(n, "string");
|
||||||
n = mxmlNewOpaque(n, parameter);
|
n = mxmlNewOpaque(n, parameter);
|
||||||
|
|
@ -645,25 +600,21 @@ static void prepare_gpa_soap_request(struct session *session, char *parameter)
|
||||||
|
|
||||||
static void soap_get_parameter_attributes_message_test(void **state)
|
static void soap_get_parameter_attributes_message_test(void **state)
|
||||||
{
|
{
|
||||||
struct session *session = NULL;
|
|
||||||
mxml_node_t *env = NULL, *n = NULL, *param_attr = NULL;
|
mxml_node_t *env = NULL, *n = NULL, *param_attr = NULL;
|
||||||
struct rpc *rpc_cpe;
|
struct rpc *rpc_cpe;
|
||||||
|
|
||||||
create_session(&session);
|
rpc_cpe = list_entry(&(cwmp_main->session->head_rpc_cpe), struct rpc, list);
|
||||||
session_test = session;
|
|
||||||
|
|
||||||
rpc_cpe = list_entry(&(session->head_rpc_cpe), struct rpc, list);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Valid path
|
* Valid path
|
||||||
*/
|
*/
|
||||||
prepare_gpa_soap_request(session, "Device.DeviceInfo.UpTime");
|
prepare_gpa_soap_request("Device.DeviceInfo.UpTime");
|
||||||
prepare_session_for_rpc_method_call(session);
|
prepare_session_for_rpc_method_call();
|
||||||
|
|
||||||
int ret = cwmp_handle_rpc_cpe_get_parameter_attributes(session, rpc_cpe);
|
int ret = cwmp_handle_rpc_cpe_get_parameter_attributes(rpc_cpe);
|
||||||
assert_int_equal(ret, 0);
|
assert_int_equal(ret, 0);
|
||||||
|
|
||||||
env = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
env = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(env);
|
assert_non_null(env);
|
||||||
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
@ -685,8 +636,8 @@ static void soap_get_parameter_attributes_message_test(void **state)
|
||||||
n = mxmlFindElement(param_attr, param_attr, "AccessList", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(param_attr, param_attr, "AccessList", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
||||||
MXML_DELETE(session->tree_in);
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
MXML_DELETE(session->tree_out);
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Not Valid path
|
* Not Valid path
|
||||||
|
|
@ -694,14 +645,14 @@ static void soap_get_parameter_attributes_message_test(void **state)
|
||||||
mxml_node_t *fault_code = NULL, *fault_string = NULL, *detail = NULL, *detail_code = NULL, *detail_string = NULL;
|
mxml_node_t *fault_code = NULL, *fault_string = NULL, *detail = NULL, *detail_code = NULL, *detail_string = NULL;
|
||||||
|
|
||||||
char *invalid_parameter[1] = { "Device.DeviceInfo.pTime" };
|
char *invalid_parameter[1] = { "Device.DeviceInfo.pTime" };
|
||||||
prepare_gpv_soap_request(session, invalid_parameter, 1);
|
prepare_gpv_soap_request(invalid_parameter, 1);
|
||||||
|
|
||||||
prepare_session_for_rpc_method_call(session);
|
prepare_session_for_rpc_method_call();
|
||||||
|
|
||||||
ret = cwmp_handle_rpc_cpe_get_parameter_values(session, rpc_cpe);
|
ret = cwmp_handle_rpc_cpe_get_parameter_values(rpc_cpe);
|
||||||
assert_int_equal(ret, 0);
|
assert_int_equal(ret, 0);
|
||||||
|
|
||||||
env = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
env = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(env);
|
assert_non_null(env);
|
||||||
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
@ -724,22 +675,21 @@ static void soap_get_parameter_attributes_message_test(void **state)
|
||||||
assert_string_equal(mxmlGetOpaque(mxmlGetFirstChild(detail_code)), "9005");
|
assert_string_equal(mxmlGetOpaque(mxmlGetFirstChild(detail_code)), "9005");
|
||||||
detail_string = mxmlFindElement(detail, detail, "FaultString", NULL, NULL, MXML_DESCEND);
|
detail_string = mxmlFindElement(detail, detail, "FaultString", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(detail_string);
|
assert_non_null(detail_string);
|
||||||
MXML_DELETE(session->tree_in);
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
MXML_DELETE(session->tree_out);
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
|
|
||||||
session->head_rpc_acs.next = NULL;
|
cwmp_main->session->head_rpc_acs.next = NULL;
|
||||||
unit_test_end_test_destruction();
|
unit_test_end_test_destruction();
|
||||||
clean_name_space();
|
clean_name_space();
|
||||||
session_test = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prepare_spa_soap_request(struct session *session, char *parameter, char *notification, char *notification_change)
|
static void prepare_spa_soap_request(char *parameter, char *notification, char *notification_change)
|
||||||
{
|
{
|
||||||
mxml_node_t *n = NULL, *set_attr = NULL;
|
mxml_node_t *n = NULL, *set_attr = NULL;
|
||||||
|
|
||||||
session->tree_in = mxmlLoadString(NULL, CWMP_SETATTRIBUTES_REQ, MXML_OPAQUE_CALLBACK);
|
cwmp_main->session->tree_in = mxmlLoadString(NULL, CWMP_SETATTRIBUTES_REQ, MXML_OPAQUE_CALLBACK);
|
||||||
xml_recreate_namespace(session->tree_in);
|
xml_recreate_namespace(cwmp_main->session->tree_in);
|
||||||
set_attr = mxmlFindElement(session->tree_in, session->tree_in, "SetParameterAttributesStruct", NULL, NULL, MXML_DESCEND);
|
set_attr = mxmlFindElement(cwmp_main->session->tree_in, cwmp_main->session->tree_in, "SetParameterAttributesStruct", NULL, NULL, MXML_DESCEND);
|
||||||
n = mxmlFindElement(set_attr, set_attr, "Name", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(set_attr, set_attr, "Name", NULL, NULL, MXML_DESCEND);
|
||||||
n = mxmlNewOpaque(n, parameter);
|
n = mxmlNewOpaque(n, parameter);
|
||||||
n = mxmlFindElement(set_attr, set_attr, "Notification", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(set_attr, set_attr, "Notification", NULL, NULL, MXML_DESCEND);
|
||||||
|
|
@ -750,25 +700,21 @@ static void prepare_spa_soap_request(struct session *session, char *parameter, c
|
||||||
|
|
||||||
static void soap_set_parameter_attributes_message_test(void **state)
|
static void soap_set_parameter_attributes_message_test(void **state)
|
||||||
{
|
{
|
||||||
struct session *session = NULL;
|
|
||||||
mxml_node_t *env = NULL, *n = NULL;
|
mxml_node_t *env = NULL, *n = NULL;
|
||||||
struct rpc *rpc_cpe;
|
struct rpc *rpc_cpe;
|
||||||
|
|
||||||
create_session(&session);
|
rpc_cpe = list_entry(&(cwmp_main->session->head_rpc_cpe), struct rpc, list);
|
||||||
session_test = session;
|
|
||||||
|
|
||||||
rpc_cpe = list_entry(&(session->head_rpc_cpe), struct rpc, list);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Valid path
|
* Valid path
|
||||||
*/
|
*/
|
||||||
prepare_spa_soap_request(session, "Device.DeviceInfo.UpTime", "1", "true");
|
prepare_spa_soap_request("Device.DeviceInfo.UpTime", "1", "true");
|
||||||
prepare_session_for_rpc_method_call(session);
|
prepare_session_for_rpc_method_call();
|
||||||
|
|
||||||
int ret = cwmp_handle_rpc_cpe_set_parameter_attributes(session, rpc_cpe);
|
int ret = cwmp_handle_rpc_cpe_set_parameter_attributes(rpc_cpe);
|
||||||
assert_int_equal(ret, 0);
|
assert_int_equal(ret, 0);
|
||||||
|
|
||||||
env = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
env = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(env);
|
assert_non_null(env);
|
||||||
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
@ -779,20 +725,20 @@ static void soap_set_parameter_attributes_message_test(void **state)
|
||||||
n = mxmlFindElement(n, n, "cwmp:SetParameterAttributesResponse", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(n, n, "cwmp:SetParameterAttributesResponse", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
assert_null(mxmlGetFirstChild(n));
|
assert_null(mxmlGetFirstChild(n));
|
||||||
MXML_DELETE(session->tree_in);
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
MXML_DELETE(session->tree_out);
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Not Valid path
|
* Not Valid path
|
||||||
*/
|
*/
|
||||||
mxml_node_t *cwmp_fault = NULL;
|
mxml_node_t *cwmp_fault = NULL;
|
||||||
prepare_spa_soap_request(session, "Device.DeviceInfo.pTime", "1", "true");
|
prepare_spa_soap_request("Device.DeviceInfo.pTime", "1", "true");
|
||||||
prepare_session_for_rpc_method_call(session);
|
prepare_session_for_rpc_method_call();
|
||||||
|
|
||||||
ret = cwmp_handle_rpc_cpe_set_parameter_attributes(session, rpc_cpe);
|
ret = cwmp_handle_rpc_cpe_set_parameter_attributes(rpc_cpe);
|
||||||
assert_int_equal(ret, 0);
|
assert_int_equal(ret, 0);
|
||||||
|
|
||||||
env = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
env = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(env);
|
assert_non_null(env);
|
||||||
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
@ -812,19 +758,19 @@ static void soap_set_parameter_attributes_message_test(void **state)
|
||||||
n = mxmlFindElement(cwmp_fault, cwmp_fault, "FaultString", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(cwmp_fault, cwmp_fault, "FaultString", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
||||||
MXML_DELETE(session->tree_in);
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
MXML_DELETE(session->tree_out);
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Not Valid Notification value
|
* Not Valid Notification value
|
||||||
*/
|
*/
|
||||||
prepare_spa_soap_request(session, "Device.DeviceInfo.UpTime", "8", "true");
|
prepare_spa_soap_request("Device.DeviceInfo.UpTime", "8", "true");
|
||||||
prepare_session_for_rpc_method_call(session);
|
prepare_session_for_rpc_method_call();
|
||||||
|
|
||||||
ret = cwmp_handle_rpc_cpe_set_parameter_attributes(session, rpc_cpe);
|
ret = cwmp_handle_rpc_cpe_set_parameter_attributes(rpc_cpe);
|
||||||
assert_int_equal(ret, 0);
|
assert_int_equal(ret, 0);
|
||||||
|
|
||||||
env = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
env = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(env);
|
assert_non_null(env);
|
||||||
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
@ -844,20 +790,20 @@ static void soap_set_parameter_attributes_message_test(void **state)
|
||||||
n = mxmlFindElement(cwmp_fault, cwmp_fault, "FaultString", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(cwmp_fault, cwmp_fault, "FaultString", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
||||||
MXML_DELETE(session->tree_in);
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
MXML_DELETE(session->tree_out);
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Invalid Notification String
|
* Invalid Notification String
|
||||||
*/
|
*/
|
||||||
|
|
||||||
prepare_spa_soap_request(session, "Device.DeviceInfo.UpTime", "balabala", "true");
|
prepare_spa_soap_request("Device.DeviceInfo.UpTime", "balabala", "true");
|
||||||
prepare_session_for_rpc_method_call(session);
|
prepare_session_for_rpc_method_call();
|
||||||
|
|
||||||
ret = cwmp_handle_rpc_cpe_set_parameter_attributes(session, rpc_cpe);
|
ret = cwmp_handle_rpc_cpe_set_parameter_attributes(rpc_cpe);
|
||||||
assert_int_equal(ret, 0);
|
assert_int_equal(ret, 0);
|
||||||
|
|
||||||
env = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
env = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(env);
|
assert_non_null(env);
|
||||||
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
@ -877,20 +823,20 @@ static void soap_set_parameter_attributes_message_test(void **state)
|
||||||
n = mxmlFindElement(cwmp_fault, cwmp_fault, "FaultString", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(cwmp_fault, cwmp_fault, "FaultString", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
||||||
MXML_DELETE(session->tree_in);
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
MXML_DELETE(session->tree_out);
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Invalid NotificationChange
|
* Invalid NotificationChange
|
||||||
*/
|
*/
|
||||||
|
|
||||||
prepare_spa_soap_request(session, "Device.DeviceInfo.UpTime", "2", "5");
|
prepare_spa_soap_request("Device.DeviceInfo.UpTime", "2", "5");
|
||||||
prepare_session_for_rpc_method_call(session);
|
prepare_session_for_rpc_method_call();
|
||||||
|
|
||||||
ret = cwmp_handle_rpc_cpe_set_parameter_attributes(session, rpc_cpe);
|
ret = cwmp_handle_rpc_cpe_set_parameter_attributes(rpc_cpe);
|
||||||
assert_int_equal(ret, 0);
|
assert_int_equal(ret, 0);
|
||||||
|
|
||||||
env = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
env = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(env);
|
assert_non_null(env);
|
||||||
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(env, env, "soap_env:Header", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
@ -910,13 +856,12 @@ static void soap_set_parameter_attributes_message_test(void **state)
|
||||||
n = mxmlFindElement(cwmp_fault, cwmp_fault, "FaultString", NULL, NULL, MXML_DESCEND);
|
n = mxmlFindElement(cwmp_fault, cwmp_fault, "FaultString", NULL, NULL, MXML_DESCEND);
|
||||||
assert_non_null(n);
|
assert_non_null(n);
|
||||||
|
|
||||||
MXML_DELETE(session->tree_in);
|
MXML_DELETE(cwmp_main->session->tree_in);
|
||||||
MXML_DELETE(session->tree_out);
|
MXML_DELETE(cwmp_main->session->tree_out);
|
||||||
|
|
||||||
session->head_rpc_acs.next = NULL;
|
cwmp_main->session->head_rpc_acs.next = NULL;
|
||||||
unit_test_end_test_destruction();
|
unit_test_end_test_destruction();
|
||||||
clean_name_space();
|
clean_name_space();
|
||||||
session_test = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int icwmp_soap_msg_test(void)
|
int icwmp_soap_msg_test(void)
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ config acs 'acs'
|
||||||
option retry_interval_multiplier '2000'
|
option retry_interval_multiplier '2000'
|
||||||
option ipv6_enable '0'
|
option ipv6_enable '0'
|
||||||
option ip_version '4'
|
option ip_version '4'
|
||||||
|
|
||||||
|
|
||||||
config cpe 'cpe'
|
config cpe 'cpe'
|
||||||
option enable '1'
|
option enable '1'
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ case "$1" in
|
||||||
;;
|
;;
|
||||||
upgrade_start)
|
upgrade_start)
|
||||||
cat /tmp/rpc_sys.data 2>/dev/null
|
cat /tmp/rpc_sys.data 2>/dev/null
|
||||||
|
sleep 7
|
||||||
|
supervisorctl stop icwmpd >> ./funl-test-debug.log
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
|
|
|
||||||
7
test/script/test_seq.txt
Normal file
7
test/script/test_seq.txt
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
verify_download_method.sh
|
||||||
|
verify_add_method.sh
|
||||||
|
verify_delete_method.sh
|
||||||
|
verify_get_method.sh
|
||||||
|
verify_set_method.sh
|
||||||
|
verify_cmd_line.sh
|
||||||
|
|
||||||
|
|
@ -23,7 +23,9 @@ fi
|
||||||
remove_icwmp_log
|
remove_icwmp_log
|
||||||
echo "Restarting icwmpd in order to apply the new firmware" >> ./funl-test-debug.log
|
echo "Restarting icwmpd in order to apply the new firmware" >> ./funl-test-debug.log
|
||||||
supervisorctl stop icwmpd >> ./funl-test-debug.log
|
supervisorctl stop icwmpd >> ./funl-test-debug.log
|
||||||
check_valgrind_xml
|
sleep 20
|
||||||
|
cp memory-report.xml memory-report-download.xml
|
||||||
|
#check_valgrind_xml
|
||||||
supervisorctl start icwmpd >> ./funl-test-debug.log
|
supervisorctl start icwmpd >> ./funl-test-debug.log
|
||||||
check_cwmp_status
|
check_cwmp_status
|
||||||
sleep 5
|
sleep 5
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue