T#8244 Added support for AutonomousDUStateChangeComplPolicy

This commit is contained in:
Suvendhu Hansa 2022-10-07 08:02:58 +00:00 committed by Omar Kallel
parent 1b7b0e2918
commit 93d3710422
21 changed files with 792 additions and 143 deletions

View file

@ -37,7 +37,7 @@ ENDIF(WITH_MBEDTLS)
ADD_EXECUTABLE(icwmpd ${ICWMP_SOURCES})
TARGET_LINK_LIBRARIES(icwmpd pthread z m json-c uci ubox ubus blobmsg_json curl mxml ${SSL_LIBS} ${CRYPTO_LIBS})
TARGET_LINK_LIBRARIES(icwmpd pthread z m json-c uci ubox ubus blobmsg_json curl mxml uuid ${SSL_LIBS} ${CRYPTO_LIBS})
INSTALL(FILES icwmpd DESTINATION usr/sbin)

View file

@ -7,7 +7,7 @@ pwd
# install required packages
exec_cmd apt update
exec_cmd apt install -y mongodb jq
exec_cmd apt install -y mongodb jq uuid-dev
exec_cmd apt-get install -y libmxml-dev
# install genieacs
exec_cmd npm install -g genieacs@1.2.5

View file

@ -0,0 +1,238 @@
/*
* autonomous_complpolicy.c - CWMP autonomous notification methods
*
* Copyright (C) 2021-2022, IOPSYS Software Solutions AB.
*
* Author Suvendhu Hansa <suvendhu.hansa@iopsys.eu>
*
* See LICENSE file for license related information.
*
*/
#include "autonomous_complpolicy.h"
#include "cwmp_uci.h"
#include "cwmp_du_state.h"
#include "log.h"
#include <libubox/blobmsg_json.h>
#include "backupSession.h"
#include "common.h"
#include "session.h"
#include "event.h"
enum autonomous_notif_type {
DU_STATE_CHANGE,
__MAX_NOTIF_TYPE
};
typedef void (*autonomous_event_callback)(struct blob_attr *msg);
struct autonomous_event {
char name[2048];
autonomous_event_callback cb;
};
static bool filters_qualified(int type, void *data)
{
char *enable = NULL, *op_filter = NULL, *res_filter = NULL;
switch (type) {
case DU_STATE_CHANGE:
cwmp_uci_reinit();
uci_get_state_value(UCI_AUTONOMOUS_DU_STATE_ENABLE, &enable);
uci_get_state_value(UCI_AUTONOMOUS_DU_STATE_OPERATION, &op_filter);
uci_get_state_value(UCI_AUTONOMOUS_DU_STATE_RESULT, &res_filter);
auto_du_state_change_compl *p = (auto_du_state_change_compl *)data;
if (p == NULL)
return false;
if (enable == NULL || op_filter == NULL)
return false;
if (uci_str_to_bool(enable) == false || strlen(op_filter) == 0)
return false;
if (strstr(op_filter, p->operation) == NULL)
return false;
if (res_filter && strlen(res_filter) != 0 && strcmp(res_filter, "Both") != 0) {
if (strcmp(res_filter, "Failure") == 0 && strcmp(p->current_state, "Failed") != 0)
return false;
if (strcmp(res_filter, "Success") == 0 && strcmp(p->current_state, "Failed") == 0)
return false;
}
/* For now falut_code filter is not supported since usp-data-model
* only provides 7002, 7004, 7223, 7225, 7226, 7227 & 7229 but
* cwmp-data-model supports more fault-codes with more specific cause,
* so need to implement a mapping between usp FaultString & cwmp error code */
break;
default:
return false;
}
return true;
}
static void send_du_state_change_notif(struct blob_attr *msg)
{
(void)msg;
CWMP_LOG(INFO, "Received DU STATE CHANGE EVENT");
const struct blobmsg_policy p[2] = {
{ "name", BLOBMSG_TYPE_STRING },
{ "input", BLOBMSG_TYPE_TABLE }
};
const struct blobmsg_policy p1[9] = {
{ "UUID", BLOBMSG_TYPE_STRING },
{ "Version", BLOBMSG_TYPE_STRING },
{ "CurrentState", BLOBMSG_TYPE_STRING },
{ "Resolved", BLOBMSG_TYPE_INT8 },
{ "StartTime", BLOBMSG_TYPE_STRING },
{ "CompleteTime", BLOBMSG_TYPE_STRING },
{ "OperationPerformed", BLOBMSG_TYPE_STRING },
{ "Fault.FaultCode", BLOBMSG_TYPE_INT32 },
{ "Fault.FaultString", BLOBMSG_TYPE_STRING }
};
struct blob_attr *tb[2] = {NULL};
blobmsg_parse(p, 2, tb, blob_data(msg), blob_len(msg));
if (tb[1]) {
char *uuid = NULL, *oper = NULL;
CWMP_LOG(INFO, "%s\n", blobmsg_format_json_indent(tb[1], true, -1));
struct blob_attr *tb1[9] = {NULL};
blobmsg_parse(p1, 9, tb1, blobmsg_data(tb[1]), blobmsg_len(tb[1]));
if (tb1[0]) {
uuid = blobmsg_get_string(tb1[0]);
}
if (tb1[6]) {
oper = blobmsg_get_string(tb1[6]);
}
CWMP_LOG(INFO, "uuid: %s, oper: %s\n", uuid ? uuid : "", oper ? oper : "");
if (uuid == NULL || oper == NULL)
return;
if (exists_in_uuid_list(uuid, oper)) {
/* This DU operation was performed by cwmp */
remove_node_from_uuid_list(uuid, oper);
} else {
/* This DU operation was performed from outside */
auto_du_state_change_compl *data = calloc(1, sizeof(auto_du_state_change_compl));
if (data == NULL)
return;
data->uuid = strdup(uuid);
data->operation = strdup(oper);
if (tb1[1]) {
data->ver = strdup(blobmsg_get_string(tb1[1]));
}
if (tb1[2]) {
data->current_state = strdup(blobmsg_get_string(tb1[2]));
}
if (tb1[3]) {
data->resolved = blobmsg_get_u8(tb1[3]) ? 1 : 0;
}
if (tb1[4]) {
data->start_time = strdup(blobmsg_get_string(tb1[4]));
}
if (tb1[5]) {
data->complete_time = strdup(blobmsg_get_string(tb1[5]));
}
if (tb1[7]) {
//data->fault_code = blobmsg_get_u32(tb1[7]);
data->fault_code = 9001; // for now setting a generic code */
}
if (tb1[8]) {
data->fault_string = strdup(blobmsg_get_string(tb1[8]));
}
// Check autonomous_du_state_change_complpolicy filters
if (filters_qualified(DU_STATE_CHANGE, data) == false) {
CWMP_LOG(INFO, "autonomous du state change filters not matched");
FREE(data);
return;
}
bkp_session_insert_autonomous_du_state_change(data);
bkp_session_save();
CWMP_LOG(INFO, "autonomous du state change event added");
struct session_timer_event *ubus_inform_event = calloc(1, sizeof(struct session_timer_event));
ubus_inform_event->extra_data = data;
ubus_inform_event->session_timer_evt.cb = cwmp_schedule_session_with_event;
ubus_inform_event->event = EVENT_IDX_12AUTONOMOUS_DU_STATE_CHANGE_COMPLETE;
trigger_cwmp_session_timer_with_event(&ubus_inform_event->session_timer_evt);
}
}
}
static struct autonomous_event event_info[] = {
{ "Device.SoftwareModules.DUStateChange!", send_du_state_change_notif }
};
static void send_autonomous_notification(char *ev_name, struct blob_attr *msg)
{
int i;
if (!ev_name)
return;
int count = sizeof(event_info)/sizeof(struct autonomous_event);
for (i = 0; i < count; i++) {
if (strcmp(event_info[i].name, ev_name) == 0) {
autonomous_event_callback cb = event_info[i].cb;
cb(msg);
return;
}
}
}
void autonomous_notification_handler(struct ubus_context *ctx __attribute__((unused)),
struct ubus_event_handler *ev __attribute__((unused)),
const char *type __attribute__((unused)), struct blob_attr *msg)
{
if (!msg)
return;
size_t len = (size_t)blobmsg_data_len(msg);
struct blob_attr *attr;
__blob_for_each_attr(attr, blobmsg_data(msg), len) {
const char *attr_name = blobmsg_name(attr);
if (attr_name != NULL && strcmp(attr_name, "name") == 0) {
send_autonomous_notification(blobmsg_data(attr), msg);
break;
}
}
}
int cwmp_rpc_acs_destroy_data_autonomous_du_state_change_complete(struct rpc *rpc)
{
auto_du_state_change_compl *p = (auto_du_state_change_compl *)rpc->extra_data;
if (p) {
bkp_session_delete_autonomous_du_state_change(p);
FREE(p->uuid);
FREE(p->ver);
FREE(p->current_state);
FREE(p->start_time);
FREE(p->complete_time);
FREE(p->fault_string);
FREE(p->operation);
FREE(p);
}
return 0;
}

View file

@ -0,0 +1,23 @@
/*
* autonomous_complpolicy.h - CWMP autonomous notification header
*
* Copyright (C) 2021-2022, IOPSYS Software Solutions AB.
*
* Author Suvendhu Hansa <suvendhu.hansa@iopsys.eu>
*
* See LICENSE file for license related information.
*
*/
#ifndef __AUTONOMOUS_COMPL_H
#define __AUTONOMOUS_COMPL_H
#include "libubus.h"
#include "common.h"
void autonomous_notification_handler(struct ubus_context *ctx __attribute__((unused)),
struct ubus_event_handler *ev __attribute__((unused)),
const char *type __attribute__((unused)), struct blob_attr *msg);
int cwmp_rpc_acs_destroy_data_autonomous_du_state_change_complete(struct rpc *rpc);
#endif

View file

@ -67,6 +67,8 @@ struct backup_attributes_name_type bkp_attrs_names[] = { { "command_key", BKP_ST
{ "fault_code", BKP_INTEGER },
{ "resolved", BKP_BOOL },
{ "time", BKP_TIME },
{ "fault_string", BKP_STRING },
{ "operation", BKP_STRING },
{ "windowstart1", BKP_TIME },
{ "windowend1", BKP_TIME },
{ "windowstart2", BKP_TIME },
@ -100,6 +102,8 @@ struct backup_attributes {
int *fault_code;
bool *resolved;
time_t *time;
char **fault_string;
char **operation;
time_t *windowstart1;
time_t *windowend1;
time_t *windowstart2;
@ -568,6 +572,73 @@ void bkp_session_delete_upload(struct upload *pupload)
mxmlDelete(b);
}
void bkp_session_insert_autonomous_du_state_change(auto_du_state_change_compl *data)
{
char resolved[8], fault_code[8];
mxml_node_t *b;
if (data == NULL)
return;
snprintf(resolved, sizeof(resolved), "%d", data->resolved);
snprintf(fault_code, sizeof(fault_code), "%d", data->fault_code);
struct search_keywords keys[9] = {
{ "uuid", data->uuid },
{ "version", data->ver ? data->ver : "" },
{ "current_state", data->current_state ? data->current_state : "" },
{ "resolved", resolved },
{ "start_time", data->start_time ? data->start_time : "" },
{ "complete_time", data->complete_time ? data->complete_time : "" },
{ "fault_code", fault_code },
{ "fault_string", data->fault_string ? data->fault_string : "" },
{ "operation", data->operation ? data->operation : "" }
};
b = bkp_session_node_found(bkp_tree, "autonomous_du_state_change_complete", keys, 9);
if (!b) {
b = bkp_session_insert(bkp_tree, "autonomous_du_state_change_complete", NULL);
bkp_session_insert(b, "uuid", data->uuid);
bkp_session_insert(b, "version", data->ver ? data->ver : "");
bkp_session_insert(b, "current_state", data->current_state ? data->current_state : "");
bkp_session_insert(b, "resolved", resolved);
bkp_session_insert(b, "start_time", data->start_time ? data->start_time : "");
bkp_session_insert(b, "complete_time", data->complete_time ? data->complete_time : "");
bkp_session_insert(b, "fault_code", fault_code);
bkp_session_insert(b, "fault_string", data->fault_string ? data->fault_string : "");
bkp_session_insert(b, "operation", data->operation ? data->operation : "");
}
}
void bkp_session_delete_autonomous_du_state_change(auto_du_state_change_compl *data)
{
char resolved[8], fault_code[8];
mxml_node_t *b;
if (data == NULL)
return;
snprintf(resolved, sizeof(resolved), "%d", data->resolved);
snprintf(fault_code, sizeof(fault_code), "%d", data->fault_code);
struct search_keywords keys[9] = {
{ "uuid", data->uuid },
{ "version", data->ver ? data->ver : "" },
{ "current_state", data->current_state ? data->current_state : "" },
{ "resolved", resolved },
{ "start_time", data->start_time ? data->start_time : "" },
{ "complete_time", data->complete_time ? data->complete_time : "" },
{ "fault_code", fault_code },
{ "fault_string", data->fault_string ? data->fault_string : "" },
{ "operation", data->operation ? data->operation : "" }
};
b = bkp_session_node_found(bkp_tree, "autonomous_du_state_change_complete", keys, 9);
if (!b) {
mxmlDelete(b);
}
}
void bkp_session_insert_du_state_change_complete(struct du_state_change_complete *pdu_state_change_complete)
{
char schedule_time[128], resolved[8], fault_code[8];
@ -975,6 +1046,26 @@ void load_transfer_complete(mxml_node_t *tree)
sotfware_version_value_change(ptransfer_complete);
}
void load_autonomous_du_state_change_complete(mxml_node_t *tree)
{
auto_du_state_change_compl *p;
p = calloc(1, sizeof(auto_du_state_change_compl));
struct backup_attributes bkp_attrs = { .uuid = &p->uuid,
.version = &p->ver,
.current_state = &p->current_state,
.resolved = &p->resolved,
.start_time = &p->start_time,
.complete_time = &p->complete_time,
.fault_code = &p->fault_code,
.fault_string = &p->fault_string,
.operation = &p->operation };
load_specific_backup_attributes(tree, &bkp_attrs);
cwmp_root_cause_autonomous_cdu_complete(p);
}
void bkp_session_create_file()
{
FILE *pFile;
@ -1073,6 +1164,8 @@ int cwmp_load_saved_session(char **ret, enum backup_loading load)
load_du_state_change_complete(b);
} else if (ntype == MXML_ELEMENT && strcmp(elem_name, "schedule_download") == 0) {
load_schedule_download(b);
} else if (ntype == MXML_ELEMENT && strcmp(elem_name, "autonomous_du_state_change_complete") == 0) {
load_autonomous_du_state_change_complete(b);
}
}
b = mxmlWalkNext(b, bkp_tree, MXML_NO_DESCEND);

View file

@ -63,5 +63,7 @@ void bkp_session_insert_schedule_download(struct download *pschedule_download);
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_insert_du_state_change_complete(struct du_state_change_complete *pdu_state_change_complete);
void bkp_session_insert_autonomous_du_state_change(auto_du_state_change_compl *data);
void bkp_session_delete_autonomous_du_state_change(auto_du_state_change_compl *data);
void bkp_tree_clean(void);
#endif /* _BACKUPSESSION_H__ */

View file

@ -163,6 +163,7 @@ typedef struct cwmp {
time_t cwmp_periodic_time;
bool cwmp_periodic_enable;
bool custom_notify_active;
struct ubus_event_handler *ev;
} cwmp;
enum action {
@ -274,6 +275,7 @@ enum rpc_acs_methods_idx {
RPC_ACS_GET_RPC_METHODS,
RPC_ACS_TRANSFER_COMPLETE,
RPC_ACS_DU_STATE_CHANGE_COMPLETE,
RPC_ACS_AUTONOMOUS_DU_STATE_CHANGE_COMPLETE,
__RPC_ACS_MAX
};
@ -291,7 +293,9 @@ enum load_type {
enum dustate_type {
DU_INSTALL = 1,
DU_UPDATE, DU_UNINSTALL
DU_UPDATE,
DU_UNINSTALL,
__MAX_DU_STATE
};
enum fault_cpe_idx {
@ -432,6 +436,12 @@ typedef struct change_du_state {
struct list_head list_operation;
} change_du_state;
typedef struct du_operational_uuid {
struct list_head list;
char uuid[37];
char operation[10];
} du_op_uuid;
typedef struct operations {
struct list_head list;
int type;
@ -464,6 +474,18 @@ typedef struct transfer_complete {
int type;
} transfer_complete;
typedef struct autonomous_du_state_change_complete {
char *uuid;
char *ver;
char *current_state;
bool resolved;
char *start_time;
char *complete_time;
int fault_code;
char *fault_string;
char *operation;
} auto_du_state_change_compl;
typedef struct du_state_change_complete {
char *command_key;
time_t timeout;

View file

@ -43,6 +43,7 @@
bool g_firewall_restart = false;
struct list_head intf_reset_list;
struct list_head du_uuid_list;
static bool interface_reset_req(char *param_name, char *value)
{
@ -253,6 +254,8 @@ static int cwmp_init()
get_nonce_key();
memset(&intf_reset_list, 0, sizeof(struct list_head));
INIT_LIST_HEAD(&intf_reset_list);
memset(&du_uuid_list, 0, sizeof(struct list_head));
INIT_LIST_HEAD(&du_uuid_list);
cwmp_main->start_time = time(NULL);
cwmp_main->event_id = 0;
cwmp_main->cwmp_period = 0;
@ -306,6 +309,9 @@ void cwmp_exit()
uloop_timeout_cancel(&periodic_session_timer);
uloop_timeout_cancel(&session_timer);
uloop_timeout_cancel(&heartbeat_session_timer);
clean_autonomous_complpolicy();
clean_du_uuid_list();
FREE(cwmp_main->ev);
uloop_end();
shutdown(cwmp_main->cr_socket_desc, SHUT_RDWR);
FREE(global_session_event);
@ -362,6 +368,9 @@ int main(int argc, char **argv)
icwmp_uloop_ubus_init();
if (0 != initiate_autonomous_complpolicy())
return error;
trigger_cwmp_session_timer();
intiate_heartbeat_procedures();

View file

@ -20,44 +20,98 @@
#include "backupSession.h"
#include "event.h"
#include "session.h"
#include <uuid/uuid.h>
LIST_HEAD(list_change_du_state);
static char *generate_uuid(void)
{
uuid_t binuuid;
uuid_generate_random(binuuid);
char *uuid = malloc(37);
uuid_unparse(binuuid, uuid);
return uuid;
}
void ubus_du_state_callback(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg)
{
char **fault = (char **)req->priv;
const struct blobmsg_policy p[1] = { { "status", BLOBMSG_TYPE_BOOL } };
const struct blobmsg_policy p[1] = { { "Result", BLOBMSG_TYPE_ARRAY } };
struct blob_attr *tb[1] = { NULL };
blobmsg_parse(p, 1, tb, blobmsg_data(msg), blobmsg_len(msg));
if (tb[0] && blobmsg_get_bool(tb[0])) {
if (tb[0]) {
struct blob_attr *head = blobmsg_data(tb[0]);
int len = blobmsg_data_len(tb[0]);
struct blob_attr *attr;
__blob_for_each_attr(attr, head, len) {
struct blob_attr *data = blobmsg_data(attr);
int data_len = blobmsg_data_len(attr);
struct blob_attr *param;
__blob_for_each_attr(param, data, data_len) {
struct blobmsg_hdr *hdr = blob_data(attr);
if (hdr && hdr->name && strcmp((char*)hdr->name, "fault") == 0) {
*fault = strdup("9010");
return;
}
}
}
*fault = NULL;
} else {
*fault = strdup("9010");
}
}
static void prepare_blob_msg(struct blob_buf *b, char *url, char *uuid, char *user, char *pass, char *env_name, int env_id)
static void prepare_blob_msg(struct blob_buf *b, char *url, char *uuid, char *user, char *pass, char *path, char *env_ref, int op)
{
if (b == NULL)
return;
bb_add_string(b, "ee_name", env_name);
blobmsg_add_u32(b, "eeid", env_id);
bb_add_string(b, "url", url);
bb_add_string(b, "uuid", uuid);
bb_add_string(b, "username", user);
bb_add_string(b, "password", pass);
void *tbl;
bb_add_string(b, "path", path);
switch (op) {
case DU_INSTALL:
bb_add_string(b, "action", "InstallDU()");
tbl = blobmsg_open_table(b, "input");
bb_add_string(b, "UUID", uuid);
bb_add_string(b, "ExecutionEnvRef", env_ref ? env_ref : "");
bb_add_string(b, "URL", url ? url : "");
bb_add_string(b, "Username", user ? user : "");
bb_add_string(b, "Password", pass ? pass : "");
blobmsg_close_table(b, tbl);
break;
case DU_UPDATE:
bb_add_string(b, "action", "Update()");
tbl = blobmsg_open_table(b, "input");
bb_add_string(b, "URL", url ? url : "");
bb_add_string(b, "Username", user ? user : "");
bb_add_string(b, "Password", pass ? pass : "");
blobmsg_close_table(b, tbl);
break;
case DU_UNINSTALL:
bb_add_string(b, "action", "Uninstall()");
break;
default:
CWMP_LOG(ERROR, "Invalid DU operation");
}
}
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 *path, char *env_ref, char **fault_code)
{
int e;
struct blob_buf b = { 0 };
memset(&b, 0, sizeof(struct blob_buf));
blob_buf_init(&b, 0);
prepare_blob_msg(&b, url, uuid, user, pass, env_name, env_id);
e = icwmp_ubus_invoke("swmodules", "du_install", b.head, ubus_du_state_callback, fault_code);
int len = CWMP_STRLEN(env_ref);
if (len > 0 && env_ref[len - 1] == '.')
env_ref[len - 1] = '\0';
prepare_blob_msg(&b, url, uuid, user, pass, path, env_ref, DU_INSTALL);
e = icwmp_ubus_invoke("usp.raw", "operate", b.head, ubus_du_state_callback, fault_code);
blob_buf_free(&b);
if (e < 0) {
@ -67,15 +121,15 @@ int cwmp_du_install(char *url, char *uuid, char *user, char *pass, char *env_nam
return FAULT_CPE_NO_FAULT;
}
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 *user, char *pass, char *du_path, char **fault_code)
{
int e;
struct blob_buf b = { 0 };
memset(&b, 0, sizeof(struct blob_buf));
blob_buf_init(&b, 0);
prepare_blob_msg(&b, url, uuid, user, pass, env_name, env_id);
e = icwmp_ubus_invoke("swmodules", "du_update", b.head, ubus_du_state_callback, fault_code);
prepare_blob_msg(&b, url, 0, user, pass, du_path, "", DU_UPDATE);
e = icwmp_ubus_invoke("usp.raw", "operate", b.head, ubus_du_state_callback, fault_code);
blob_buf_free(&b);
if (e < 0) {
@ -85,18 +139,16 @@ int cwmp_du_update(char *url, char *uuid, char *user, char *pass, char *env_name
return FAULT_CPE_NO_FAULT;
}
int cwmp_du_uninstall(char *package_name, char *env_name, int env_id, char **fault_code)
int cwmp_du_uninstall(char *du_path, char **fault_code)
{
int e;
struct blob_buf b = { 0 };
memset(&b, 0, sizeof(struct blob_buf));
blob_buf_init(&b, 0);
bb_add_string(&b, "ee_name", env_name);
blobmsg_add_u32(&b, "eeid", env_id);
bb_add_string(&b, "du_name", package_name);
prepare_blob_msg(&b, "", 0, "", "", du_path, "", DU_UNINSTALL);
e = icwmp_ubus_invoke("swmodules", "du_uninstall", b.head, ubus_du_state_callback, fault_code);
e = icwmp_ubus_invoke("usp.raw", "operate", b.head, ubus_du_state_callback, fault_code);
blob_buf_free(&b);
if (e < 0) {
@ -187,19 +239,6 @@ char *get_deployment_unit_by_uuid(char *uuid)
return sw_by_uuid_instance;
}
static char *get_deployment_unit_reference(char *package_name, char *package_env)
{
LIST_HEAD(sw_parameters);
char *sw_by_name_env_instance = NULL, *deployment_unit_ref = NULL;
sw_by_name_env_instance = get_software_module_object_eq("Name", package_name, "ExecutionEnvRef", package_env, &sw_parameters);
cwmp_free_all_dm_parameter_list(&sw_parameters);
if (!sw_by_name_env_instance)
return NULL;
cwmp_asprintf(&deployment_unit_ref, "Device.SoftwareModules.DeploymentUnit.%s", sw_by_name_env_instance);
return deployment_unit_ref;
}
static bool environment_exists(char *environment_path)
{
LIST_HEAD(environment_list);
@ -211,58 +250,32 @@ static bool environment_exists(char *environment_path)
return true;
}
static char *get_exec_env_name(char *environment_path)
{
char env_param[256], *env_name = "";
LIST_HEAD(environment_list);
char *err = cwmp_get_parameter_values(environment_path, &environment_list);
if (err)
return strdup("");
struct cwmp_dm_parameter *param_value = NULL;
snprintf(env_param, sizeof(env_param), "%sName", environment_path);
list_for_each_entry (param_value, &environment_list, list) {
if (param_value->name && strcmp(param_value->name, env_param) == 0) {
env_name = strdup(param_value->value);
break;
}
}
cwmp_free_all_dm_parameter_list(&environment_list);
return env_name;
}
static int cwmp_launch_du_install(char *url, char *uuid, char *user, char *pass, char *env_name, int env_id, struct opresult **pchange_du_state_complete)
{
int error = FAULT_CPE_NO_FAULT;
char *fault_code = NULL;
(*pchange_du_state_complete)->start_time = strdup(get_time(time(NULL)));
cwmp_du_install(url, uuid, user, pass, env_name, env_id, &fault_code);
if (fault_code != NULL) {
if (fault_code[0] == '9') {
int i;
for (i = 1; i < __FAULT_CPE_MAX; i++) {
if (strcmp(FAULT_CPE_ARRAY[i].CODE, fault_code) == 0) {
error = i;
break;
}
}
}
free(fault_code);
}
return error;
}
static int cwmp_launch_du_update(char *uuid, char *url, char *user, char *pass, char *env_name, int env_id, struct opresult **pchange_du_state_complete)
static int cwmp_launch_du_install(char *url, char *uuid, char *user, char *pass, char *path, char *env_ref, struct opresult **pchange_du_state_complete)
{
int error = FAULT_CPE_NO_FAULT;
char *fault_code;
(*pchange_du_state_complete)->start_time = strdup(get_time(time(NULL)));
cwmp_du_update(url, uuid, user, pass, env_name, env_id, &fault_code);
if (uuid == NULL) {
return FAULT_CPE_INTERNAL_ERROR;
}
/* store uuid in list for du state change event */
du_op_uuid *node = (du_op_uuid *)malloc(sizeof(du_op_uuid));
if (node == NULL) {
return FAULT_CPE_INTERNAL_ERROR;
}
memset(node, 0, sizeof(du_op_uuid));
snprintf(node->uuid, sizeof(node->uuid), "%s", uuid);
snprintf(node->operation, sizeof(node->operation), "%s", "Install");
INIT_LIST_HEAD(&node->list);
list_add_tail(&node->list, &du_uuid_list);
cwmp_du_install(url, uuid, user, pass, path, env_ref, &fault_code);
if (fault_code != NULL) {
if (fault_code[0] == '9') {
int i;
@ -278,15 +291,31 @@ static int cwmp_launch_du_update(char *uuid, char *url, char *user, char *pass,
return error;
}
static int cwmp_launch_du_uninstall(char *package_name, char *env_name, int env_id, struct opresult **pchange_du_state_complete)
static int cwmp_launch_du_update(char *url, char *uuid, char *user, char *pass, char *du_path, struct opresult **pchange_du_state_complete)
{
int error = FAULT_CPE_NO_FAULT;
char *fault_code;
(*pchange_du_state_complete)->start_time = strdup(get_time(time(NULL)));
cwmp_du_uninstall(package_name, env_name, env_id, &fault_code);
if (uuid == NULL) {
return FAULT_CPE_INTERNAL_ERROR;
}
/* store uuid in list for du state change event */
du_op_uuid *node = (du_op_uuid *)malloc(sizeof(du_op_uuid));
if (node == NULL) {
return FAULT_CPE_INTERNAL_ERROR;
}
memset(node, 0, sizeof(du_op_uuid));
snprintf(node->uuid, sizeof(node->uuid), "%s", uuid);
snprintf(node->operation, sizeof(node->operation), "%s", "Update");
INIT_LIST_HEAD(&node->list);
list_add_tail(&node->list, &du_uuid_list);
cwmp_du_update(url, user, pass, du_path, &fault_code);
if (fault_code != NULL) {
if (fault_code[0] == '9') {
int i;
@ -302,11 +331,45 @@ static int cwmp_launch_du_uninstall(char *package_name, char *env_name, int env_
return error;
}
int get_exec_env_id(char *exec_env_ref)
static int cwmp_launch_du_uninstall(char *du_path, char *uuid, struct opresult **pchange_du_state_complete)
{
int id = 0;
sscanf(exec_env_ref, "Device.SoftwareModules.ExecEnv.%d", &id);
return id;
int error = FAULT_CPE_NO_FAULT;
char *fault_code;
(*pchange_du_state_complete)->start_time = strdup(get_time(time(NULL)));
if (uuid == NULL) {
return FAULT_CPE_INTERNAL_ERROR;
}
/* store uuid in list for du state change event */
du_op_uuid *node = (du_op_uuid *)malloc(sizeof(du_op_uuid));
if (node == NULL) {
return FAULT_CPE_INTERNAL_ERROR;
}
memset(node, 0, sizeof(du_op_uuid));
snprintf(node->uuid, sizeof(node->uuid), "%s", uuid);
snprintf(node->operation, sizeof(node->operation), "%s", "Uninstall");
INIT_LIST_HEAD(&node->list);
list_add_tail(&node->list, &du_uuid_list);
cwmp_du_uninstall(du_path, &fault_code);
if (fault_code != NULL) {
if (fault_code[0] == '9') {
int i;
for (i = 1; i < __FAULT_CPE_MAX; i++) {
if (strcmp(FAULT_CPE_ARRAY[i].CODE, fault_code) == 0) {
error = i;
break;
}
}
}
free(fault_code);
}
return error;
}
char *get_package_name_by_url(char *url)
@ -340,7 +403,16 @@ int change_du_state_fault(struct change_du_state *pchange_du_state, struct du_st
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);
// cppcheck-suppress uninitvar
if (CWMP_STRLEN(p->uuid) == 0) {
char *uuid = generate_uuid();
res->uuid = strdup(uuid);
FREE(uuid);
} else {
res->uuid = strdup(p->uuid);
}
res->version = strdup(p->version);
res->current_state = strdup("Failed");
res->start_time = strdup(get_time(time(NULL)));
@ -365,6 +437,8 @@ void change_du_state_execute(struct uloop_timeout *utimeout)
struct opresult *res;
struct du_state_change_complete *pdu_state_change_complete;
char *du_ref = NULL;
char du_path[2048] = {0};
//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);
@ -396,34 +470,45 @@ void change_du_state_execute(struct uloop_timeout *utimeout)
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;
if (CWMP_STRLEN(p->executionenvref) != 0) {
if (!environment_exists(p->executionenvref)) {
res->fault = FAULT_CPE_INTERNAL_ERROR; //TODO
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);
char *path = "Device.SoftwareModules.";
bool uuid_generated = false;
if (CWMP_STRLEN(p->uuid) == 0) {
FREE(p->uuid);
p->uuid = generate_uuid();
if (p->uuid == NULL) {
res->fault = FAULT_CPE_INTERNAL_ERROR;
break;
}
uuid_generated = true;
}
error = cwmp_launch_du_install(p->url, p->uuid, p->username, p->password, path, 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 : "");
if (error != FAULT_CPE_NO_FAULT) {
res->uuid = strdup(p->uuid);
res->current_state = strdup("Failed");
res->resolved = 0;
res->complete_time = strdup(get_time(time(NULL)));
res->fault = error;
/* du state change event will be scheduled here, so remove uuid from list */
remove_node_from_uuid_list(p->uuid, "Install");
}
res->complete_time = strdup(get_time(time(NULL)));
res->fault = error;
FREE(du_ref);
FREE(package_version);
if (uuid_generated)
FREE(p->uuid);
break;
case DU_UPDATE:
@ -433,61 +518,76 @@ void change_du_state_execute(struct uloop_timeout *utimeout)
}
du_ref = get_deployment_unit_by_uuid(p->uuid);
if (du_ref == NULL) {
if (CWMP_STRLEN(du_ref) == 0) {
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);
snprintf(du_path, sizeof(du_path), "Device.SoftwareModules.DeploymentUnit.%s.", du_ref);
res->uuid = strdup(p->uuid ? p->uuid : "");
error = cwmp_launch_du_update(p->url, p->uuid, p->username, p->password, du_path, &res);
res->uuid = strdup(p->uuid);
if (error == FAULT_CPE_NO_FAULT) {
res->current_state = strdup("Installed");
res->resolved = 1;
} else {
if (error != FAULT_CPE_NO_FAULT) {
res->current_state = strdup("Failed");
res->resolved = 0;
get_du_version(du_path, &package_version);
res->version = strdup(package_version ? package_version : "");
res->du_ref = strdup(du_path);
res->complete_time = strdup(get_time(time(NULL)));
res->fault = error;
/* du state change event will be scheduled here, so remove uuid from list */
remove_node_from_uuid_list(p->uuid, "Update");
}
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);
FREE(package_version);
break;
case DU_UNINSTALL:
if (p->uuid == NULL || *(p->uuid) == '\0' || !environment_exists(p->executionenvref)) {
if (p->uuid == NULL || *(p->uuid) == '\0') {
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') {
if (!package_name || *package_name == '\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;
unsigned int pkg_eeid = 0, req_eeid = 0;
if (CWMP_STRLEN(p->executionenvref) != 0) {
sscanf(p->executionenvref, "Device.SoftwareModules.ExecEnv.%u", &req_eeid);
sscanf(package_env, "Device.SoftwareModules.ExecEnv.%u", &pkg_eeid);
if (req_eeid != pkg_eeid) {
res->fault = FAULT_CPE_UNKNOWN_DEPLOYMENT_UNIT;
break;
}
}
du_ref = get_deployment_unit_by_uuid(p->uuid);
if (CWMP_STRLEN(du_ref) == 0) {
res->fault = FAULT_CPE_UNKNOWN_DEPLOYMENT_UNIT;
break;
}
snprintf(du_path, sizeof(du_path), "Device.SoftwareModules.DeploymentUnit.%s.", du_ref);
error = cwmp_launch_du_uninstall(du_path, p->uuid, &res);
if (error != FAULT_CPE_NO_FAULT) {
res->current_state = strdup("Installed");
res->resolved = 1;
res->du_ref = strdup(du_path);
res->uuid = strdup(p->uuid);
res->version = strdup(package_version ? package_version : "");
res->complete_time = strdup(get_time(time(NULL)));
res->fault = error;
/* du state change event will be scheduled here, so remove uuid from list */
remove_node_from_uuid_list(p->uuid, "Uninstall");
}
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);
@ -553,3 +653,41 @@ void apply_change_du_state()
uloop_timeout_set(&pchange_du_state->handler_timer, 10);
}
}
void remove_node_from_uuid_list(char *uuid, char *operation)
{
if (uuid == NULL || operation == NULL)
return;
du_op_uuid *tmp, *q;
list_for_each_entry_safe(tmp, q, &du_uuid_list, list) {
if (strcmp(tmp->uuid, uuid) == 0 && strcmp(tmp->operation, operation) == 0) {
list_del(&tmp->list);
free(tmp);
break;
}
}
}
bool exists_in_uuid_list(char *uuid, char *operation)
{
if (uuid == NULL || operation == NULL)
return false;
du_op_uuid *tmp, *q;
list_for_each_entry_safe(tmp, q, &du_uuid_list, list) {
if (strcmp(tmp->uuid, uuid) == 0 && strcmp(tmp->operation, operation) == 0)
return true;
}
return false;
}
void clean_du_uuid_list(void)
{
du_op_uuid *tmp, *q;
list_for_each_entry_safe(tmp, q, &du_uuid_list, list) {
list_del(&tmp->list);
free(tmp);
}
}

View file

@ -16,13 +16,17 @@
#define CDU_TIMEOUT 86400 //24 hours
extern struct list_head list_change_du_state;
extern struct list_head du_uuid_list;
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_uninstall(char *package_name, char *env_name, int env_id, char **fault_code);
int cwmp_du_install(char *url, char *uuid, char *user, char *pass, char *path, char *env_ref, char **fault_code);
int cwmp_du_update(char *url, char *user, char *pass, char *du_path, char **fault_code);
int cwmp_du_uninstall(char *du_path, char **fault_code);
int cwmp_rpc_acs_destroy_data_du_state_change_complete(struct rpc *rpc);
void *thread_cwmp_rpc_cpe_change_du_state(void *v);
int cwmp_free_change_du_state_request(struct change_du_state *change_du_state);
void change_du_state_execute(struct uloop_timeout *utimeout);
void apply_change_du_state();
void remove_node_from_uuid_list(char *uuid, char *operation);
bool exists_in_uuid_list(char *uuid, char *operation);
void clean_du_uuid_list(void);
#endif

View file

@ -14,6 +14,7 @@
#define __CWMPUCI_H
#include <uci.h>
#include <libubox/list.h>
//struct uci_context *cwmp_uci_ctx = ((void *)0);
@ -50,7 +51,9 @@
#define UCI_DHCP_CPE_PROV_CODE "cwmp.cpe.dhcp_provisioning_code"
#define UCI_DHCP_ACS_RETRY_MIN_WAIT_INTERVAL "cwmp.acs.dhcp_retry_min_wait_interval"
#define UCI_DHCP_ACS_RETRY_INTERVAL_MULTIPLIER "cwmp.acs.dhcp_retry_interval_multiplier"
#define UCI_AUTONOMOUS_DU_STATE_ENABLE "cwmp.du_state_change.enable"
#define UCI_AUTONOMOUS_DU_STATE_OPERATION "cwmp.du_state_change.operation_type"
#define UCI_AUTONOMOUS_DU_STATE_RESULT "cwmp.du_state_change.result_type"
#define UCI_CPE_FIREWALL_RESTART_STATE "cwmp.cpe.firewall_restart"
#define UCI_CONFIG_DIR "/etc/config/"

View file

@ -35,6 +35,7 @@ const struct EVENT_CONST_STRUCT EVENT_CONST[] = {[EVENT_IDX_0BOOTSTRAP] = { "0 B
[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_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_12AUTONOMOUS_DU_STATE_CHANGE_COMPLETE] = { "12 AUTONOMOUS DU STATE CHANGE COMPLETE", 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_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
[EVENT_IDX_M_Download] = { "M Download", EVENT_RETRY_AFTER_TRANSMIT_FAIL | EVENT_RETRY_AFTER_REBOOT },
@ -234,6 +235,25 @@ int cwmp_root_cause_transfer_complete(struct transfer_complete *p)
return CWMP_OK;
}
int cwmp_root_cause_autonomous_cdu_complete(auto_du_state_change_compl *p)
{
struct event_container *event_container;
struct rpc *rpc_acs;
event_container = cwmp_add_event_container(EVENT_IDX_12AUTONOMOUS_DU_STATE_CHANGE_COMPLETE, "");
if (event_container == NULL) {
CWMP_LOG(ERROR, "event %s: event_container is null", __FUNCTION__);
return CWMP_MEM_ERR;
}
if ((rpc_acs = cwmp_add_session_rpc_acs(RPC_ACS_AUTONOMOUS_DU_STATE_CHANGE_COMPLETE)) == NULL) {
CWMP_LOG(ERROR, "event %s: rpc_acs is null", __FUNCTION__);
return CWMP_MEM_ERR;
}
rpc_acs->extra_data = (void *)p;
return CWMP_OK;
}
int cwmp_root_cause_changedustate_complete(struct du_state_change_complete *p)
{
struct event_container *event_container;

View file

@ -50,6 +50,7 @@ enum event_idx_enum
EVENT_IDX_9REQUEST_DOWNLOAD,
EVENT_IDX_10AUTONOMOUS_TRANSFER_COMPLETE,
EVENT_IDX_11DU_STATE_CHANGE_COMPLETE,
EVENT_IDX_12AUTONOMOUS_DU_STATE_CHANGE_COMPLETE,
EVENT_IDX_M_Reboot,
EVENT_IDX_M_ScheduleInform,
EVENT_IDX_M_Download,
@ -77,4 +78,6 @@ int cwmp_root_cause_events();
int cwmp_root_cause_transfer_complete(struct transfer_complete *p);
int cwmp_root_cause_changedustate_complete(struct du_state_change_complete *p);
int cwmp_root_cause_schedule_inform(struct schedule_inform *schedule_inform);
int cwmp_root_cause_autonomous_cdu_complete(auto_du_state_change_compl *p);
#endif /* SRC_INC_EVENT_H_ */

View file

@ -27,6 +27,7 @@
#include "diagnostic.h"
#include "cwmp_uci.h"
#include "cwmp_event.h"
#include "autonomous_complpolicy.h"
#define PROCESSING_DELAY (1) // In download/upload the message enqueued before sending the response, which cause the download/upload
// to start just before the time. This delay is to compensate the time lapsed during the message enqueue and response
@ -55,7 +56,8 @@ const struct rpc_cpe_method rpc_cpe_methods[] = { [RPC_CPE_GET_RPC_METHODS] = {
struct rpc_acs_method rpc_acs_methods[] = { [RPC_ACS_INFORM] = { "Inform", cwmp_rpc_acs_prepare_message_inform, cwmp_rpc_acs_parse_response_inform, NULL, NOT_KNOWN },
[RPC_ACS_GET_RPC_METHODS] = { "GetRPCMethods", cwmp_rpc_acs_prepare_get_rpc_methods, cwmp_rpc_acs_parse_response_get_rpc_methods, NULL, NOT_KNOWN },
[RPC_ACS_TRANSFER_COMPLETE] = { "TransferComplete", cwmp_rpc_acs_prepare_transfer_complete, NULL, cwmp_rpc_acs_destroy_data_transfer_complete, NOT_KNOWN },
[RPC_ACS_DU_STATE_CHANGE_COMPLETE] = { "DUStateChangeComplete", cwmp_rpc_acs_prepare_du_state_change_complete, NULL, cwmp_rpc_acs_destroy_data_du_state_change_complete, NOT_KNOWN }
[RPC_ACS_DU_STATE_CHANGE_COMPLETE] = { "DUStateChangeComplete", cwmp_rpc_acs_prepare_du_state_change_complete, NULL, cwmp_rpc_acs_destroy_data_du_state_change_complete, NOT_KNOWN },
[RPC_ACS_AUTONOMOUS_DU_STATE_CHANGE_COMPLETE] = { "AutonomousDUStateChangeComplete", cwmp_rpc_acs_prepare_autonomous_du_state_change_complete, NULL, cwmp_rpc_acs_destroy_data_autonomous_du_state_change_complete, NOT_KNOWN }
};
char *forced_inform_parameters[] = {
@ -681,6 +683,56 @@ error:
return -1;
}
/*
* [RPC ACS]: AutonomousDUStateChangeComplete
*/
int cwmp_rpc_acs_prepare_autonomous_du_state_change_complete(struct rpc *rpc)
{
mxml_node_t *tree = NULL, *n;
auto_du_state_change_compl *p;
p = (auto_du_state_change_compl *)rpc->extra_data;
load_response_xml_schema(&tree);
if (!tree)
goto error;
n = mxmlFindElement(tree, tree, "soap_env:Envelope", NULL, NULL, MXML_DESCEND);
if (!n)
goto error;
mxmlElementSetAttr(n, "xmlns:cwmp", cwmp_urls[(cwmp_main->conf.amd_version) - 1]);
n = build_top_body_soap_request(tree, "AutonomousDUStateChangeComplete");
if (!n)
goto error;
struct xml_data_struct acdu_complete_xml_attrs = {0};
acdu_complete_xml_attrs.command_key = NULL;
if (p) {
acdu_complete_xml_attrs.start_time = &p->start_time;
acdu_complete_xml_attrs.complete_time = &p->complete_time;
acdu_complete_xml_attrs.fault_code = &p->fault_code;
acdu_complete_xml_attrs.fault_string = &p->fault_string;
acdu_complete_xml_attrs.version = &p->ver;
acdu_complete_xml_attrs.uuid = &p->uuid;
acdu_complete_xml_attrs.current_state = &p->current_state;
acdu_complete_xml_attrs.operation = &p->operation;
acdu_complete_xml_attrs.resolved = &p->resolved;
}
int fault = build_xml_node_data(SOAP_AUTONOMOUS_DU_CHANGE_COMPLETE, n, &acdu_complete_xml_attrs);
if (fault != CWMP_OK) {
goto error;
}
cwmp_main->session->tree_out = tree;
return 0;
error:
return -1;
}
/*
* [RPC CPE]: GetParameterValues
*/

View file

@ -46,6 +46,7 @@ int cwmp_rpc_acs_parse_response_get_rpc_methods(struct rpc *this);
int cwmp_rpc_acs_prepare_get_rpc_methods(struct rpc *rpc);
int cwmp_rpc_acs_prepare_transfer_complete(struct rpc *rpc);
int cwmp_rpc_acs_prepare_du_state_change_complete(struct rpc *rpc);
int cwmp_rpc_acs_prepare_autonomous_du_state_change_complete(struct rpc *rpc);
int xml_handle_message();
int cwmp_create_fault_message(struct rpc *rpc_cpe, int fault_code);

View file

@ -129,8 +129,10 @@ int cwmp_schedule_rpc()
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);
cwmp_session_rpc_destructor(rpc_acs);
continue;
}
if (!rpc_acs->type || cwmp_stop)
goto retry;
@ -432,6 +434,9 @@ void cwmp_schedule_session_with_event(struct uloop_timeout *timeout)
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 == EVENT_IDX_12AUTONOMOUS_DU_STATE_CHANGE_COMPLETE) {
auto_du_state_change_compl *data = (auto_du_state_change_compl *)session_event->extra_data;
cwmp_root_cause_autonomous_cdu_complete(data);
} else if (session_event->event >= 0) {
struct event_container *event_container = NULL;
event_container = cwmp_add_event_container(session_event->event, "");

View file

@ -16,6 +16,7 @@
#include "cwmp_uci.h"
#include "session.h"
#include "cwmp_event.h"
#include "autonomous_complpolicy.h"
typedef int (*callback)(struct blob_buf *b);
@ -415,3 +416,28 @@ int icwmp_ubus_invoke(const char *obj, const char *method, struct blob_attr *msg
return rc;
}
int initiate_autonomous_complpolicy(void)
{
cwmp_main->ev = (struct ubus_event_handler *)malloc(sizeof(struct ubus_event_handler));
if (cwmp_main->ev == NULL)
return -1;
memset(cwmp_main->ev, 0, sizeof(struct ubus_event_handler));
cwmp_main->ev->cb = autonomous_notification_handler;
int ret = ubus_register_event_handler(ubus_ctx, cwmp_main->ev, "usp.event");
if (ret) {
return -1;
}
return 0;
}
void clean_autonomous_complpolicy(void)
{
if (cwmp_main->ev == NULL)
return;
ubus_unregister_event_handler(ubus_ctx, cwmp_main->ev);
}

View file

@ -23,4 +23,6 @@ int icwmp_ubus_invoke(const char *obj, const char *method, struct blob_attr *msg
icwmp_ubus_cb icwmp_callback, void *callback_arg);
int icwmp_uloop_ubus_init();
void icwmp_uloop_ubus_exit();
int initiate_autonomous_complpolicy(void);
void clean_autonomous_complpolicy(void);
#endif /* __ICWMP_UBUS_UTILS_H__ */

View file

@ -88,8 +88,10 @@ 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_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_AUTONOMOUS_DU_CHANGE_COMPLETE] = {XML_SINGLE, 0, NULL, {{"Results", XML_REC, SOAP_ACDU_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_ACDU_OPTS_REF] = {XML_SINGLE, 0, NULL, {{"UUID", XML_STRING, 0, NULL}, {"Version", XML_STRING, 0, NULL}, {"CurrentState", XML_STRING, 0, NULL}, {"Resolved", XML_BOOL, 0, NULL}, {"StartTime", XML_STRING, 0, NULL}, {"CompleteTime", XML_STRING, 0, NULL}, {"FaultStruct", XML_REC, SOAP_CWMP_FAULT, NULL}, {"OperationPerformed", 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}}}
};
@ -113,6 +115,8 @@ char* xml_tags_names[] = {
"DeploymentUnitRef",
"CurrentState",
"Version",
"OperationPerformed",
"Resolved",
"WindowMode",
"UserMessage",
"StartTime",

View file

@ -68,7 +68,9 @@ enum soap_methods {
SOAP_INFORM_CWMP,
SOAP_DEVID,
SOAP_DU_CHANGE_COMPLETE,
SOAP_AUTONOMOUS_DU_CHANGE_COMPLETE,
SOAP_CDU_RESULTS_REF,
SOAP_ACDU_OPTS_REF,
SOAP_CDU_OPTS_REF,
ATTR_PARAM_STRUCT,
ATTR_SOAP_ENV,
@ -125,6 +127,8 @@ struct xml_data_struct {
char **du_ref;
char **current_state;
char **version;
char **operation;
bool *resolved;
char **window_mode;
char **user_message;
char **start_time;

View file

@ -1,7 +1,7 @@
LIB_LDFLAGS:= -lmxml -luci -lblobmsg_json -lubox\
-ljson-c -lubus -lpthread -lcurl\
-lcrypto
-lcrypto -luuid
LIB_CFLAGS:= -fPIC -I../../ -DLOPENSSL -g -O0
UNIT_TESTS:= icwmp_unit_testd