Ticket refs #8243: bbf: Add AutonomousTransferCompletePolicy

This commit is contained in:
Omar Kallel 2022-10-27 11:26:06 +01:00
parent 280e2f2bc3
commit fe985fdfef
14 changed files with 301 additions and 10 deletions

View file

@ -76,6 +76,10 @@ static bool filters_qualified(int type, void *data)
static void send_du_state_change_notif(struct blob_attr *msg)
{
if (!cwmp_main->conf.auto_cdu_enable) {
CWMP_LOG(INFO, "Autonomous Change DU State is disabled");
return;
}
(void)msg;
CWMP_LOG(INFO, "Received DU STATE CHANGE EVENT");
const struct blobmsg_policy p[2] = {
@ -179,8 +183,93 @@ static void send_du_state_change_notif(struct blob_attr *msg)
}
}
static void send_transfer_complete_notif(struct blob_attr *msg)
{
if (!cwmp_main->conf.auto_tc_enable) {
CWMP_LOG(INFO, "Autonomous TransferComplete is disabled");
return;
}
(void)msg;
CWMP_LOG(INFO, "Received TRANSFER COMPLETE EVENT");
const struct blobmsg_policy p[2] = {
{ "name", BLOBMSG_TYPE_STRING },
{ "input", BLOBMSG_TYPE_TABLE }
};
const struct blobmsg_policy p1[10] = {
{ "AnnounceURL", BLOBMSG_TYPE_STRING },
{ "TransferURL", BLOBMSG_TYPE_STRING },
{ "TransferType", BLOBMSG_TYPE_STRING },
{ "FileType", BLOBMSG_TYPE_STRING },
{ "FileSize", BLOBMSG_TYPE_INT32 },
{ "TargetFileName", BLOBMSG_TYPE_STRING },
{ "StartTime", BLOBMSG_TYPE_STRING },
{ "CompleteTime", BLOBMSG_TYPE_STRING },
{ "Fault.FaultCode", BLOBMSG_TYPE_INT32 },
{ "Fault.FaultString", BLOBMSG_TYPE_STRING }
};
struct blob_attr *tb[2] = {NULL, NULL};
blobmsg_parse(p, 2, tb, blob_data(msg), blob_len(msg));
if (tb[1]) {
char *file_type = NULL;
CWMP_LOG(INFO, "%s\n", blobmsg_format_json_indent(tb[1], true, -1));
struct blob_attr *tb1[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
blobmsg_parse(p1, 10, tb1, blobmsg_data(tb[1]), blobmsg_len(tb[1]));
if (tb1[3]) {
file_type = blobmsg_get_string(tb1[3]);
}
CWMP_LOG(INFO, "file_type: %s\n", file_type);
if (file_type == NULL)
return;
auto_transfer_complete *data = calloc(1, sizeof(auto_transfer_complete));
if (data == NULL)
return;
data->file_type = strdup(file_type);
data->announce_url = strdup(tb1[0] ? blobmsg_get_string(tb1[0]) : "");
data->transfer_url = strdup(tb1[1] ? blobmsg_get_string(tb1[1]) : "");
data->is_download = (tb1[2] && strcmp(blobmsg_get_string(tb1[2]), "Download") == 0) ? true : false;
data->file_size = tb1[4] ? blobmsg_get_u32(tb1[4]) : 0;
data->target_file_name = strdup(tb1[5] ? blobmsg_get_string(tb1[5]) : "");
if (tb1[6]) {
data->start_time = strdup(blobmsg_get_string(tb1[6]));
}
if (tb1[7]) {
data->complete_time = strdup(blobmsg_get_string(tb1[7]));
}
if (tb1[8]) {
data->fault_code = tb1[8] ? blobmsg_get_u32(tb1[8]) : 0;
}
if (tb1[9]) {
data->fault_string = strdup(blobmsg_get_string(tb1[8]));
}
bkp_session_insert_autonomous_transfer_complete(data);
bkp_session_save();
CWMP_LOG(INFO, "autonomous transfer complete 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_10AUTONOMOUS_TRANSFER_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 }
{ "Device.SoftwareModules.DUStateChange!", send_du_state_change_notif },
{ "Device.LocalAgent.TransferComplete!", send_transfer_complete_notif }
};
static void send_autonomous_notification(char *ev_name, struct blob_attr *msg)
@ -236,3 +325,21 @@ int cwmp_rpc_acs_destroy_data_autonomous_du_state_change_complete(struct rpc *rp
return 0;
}
int cwmp_rpc_acs_destroy_data_autonomous_transfer_complete(struct rpc *rpc)
{
auto_transfer_complete *p = (auto_transfer_complete *)rpc->extra_data;
if (p) {
bkp_session_delete_autonomous_transfer_complete(p);
FREE(p->announce_url);
FREE(p->transfer_url);
FREE(p->file_type);
FREE(p->start_time);
FREE(p->complete_time);
FREE(p->fault_string);
FREE(p->target_file_name);
FREE(p);
}
return 0;
}

View file

@ -19,5 +19,6 @@ void autonomous_notification_handler(struct ubus_context *ctx __attribute__((unu
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);
int cwmp_rpc_acs_destroy_data_autonomous_transfer_complete(struct rpc *rpc);
#endif

View file

@ -590,18 +590,85 @@ void bkp_session_delete_autonomous_du_state_change(auto_du_state_change_compl *d
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 },
{ "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_autonomous_transfer_complete(auto_transfer_complete *data)
{
char is_download[8], fault_code[8], file_size[8];
mxml_node_t *b;
if (data == NULL)
return;
snprintf(is_download, sizeof(is_download), "%d", data->is_download);
snprintf(file_size, sizeof(is_download), "%d", data->file_size);
snprintf(fault_code, sizeof(fault_code), "%d", data->fault_code);
struct search_keywords keys[9] = {
{ "announceurl", data->announce_url ? data->announce_url : "" },
{ "transferurl", data->transfer_url ? data->transfer_url : "" },
{ "isdownload", is_download },
{ "filetype", data->file_type },
{ "filesize", file_size },
{ "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 : "" }
};
{ "fault_string", data->fault_string ? data->fault_string : "" }
};
b = bkp_session_node_found(bkp_tree, "autonomous_du_state_change_complete", keys, 9);
b = bkp_session_node_found(bkp_tree, "autonomous_transfer_complete", keys, 9);
if (!b) {
b = bkp_session_insert(bkp_tree, "autonomous_transfer_complete", NULL);
bkp_session_insert(b, "announceurl", data->announce_url ? data->announce_url : "");
bkp_session_insert(b, "transferurl", data->transfer_url ? data->transfer_url : "");
bkp_session_insert(b, "isdownload", is_download);
bkp_session_insert(b, "filetype", data->file_type);
bkp_session_insert(b, "filesize", file_size);
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 : "");
}
}
void bkp_session_delete_autonomous_transfer_complete(auto_transfer_complete *data)
{
if (data == NULL)
return;
char is_download[8], fault_code[8], file_size[8];
snprintf(is_download, sizeof(is_download), "%d", data->is_download);
snprintf(file_size, sizeof(file_size), "%d", data->file_size);
snprintf(fault_code, sizeof(fault_code), "%d", data->fault_code);
struct search_keywords keys[9] = {
{ "announceurl", data->announce_url ? data->announce_url : "" },
{ "transferurl", data->transfer_url ? data->transfer_url : "" },
{ "isdownload", is_download },
{ "filetype", data->file_type },
{ "filesize", file_size },
{ "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 : "" }
};
mxml_node_t *b = bkp_session_node_found(bkp_tree, "autonomous_transfer_complete", keys, 9);
if (!b) {
mxmlDelete(b);
}

View file

@ -63,5 +63,7 @@ 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_session_insert_autonomous_transfer_complete(auto_transfer_complete *data);
void bkp_session_delete_autonomous_transfer_complete(auto_transfer_complete *data);
void bkp_tree_clean(void);
#endif /* _BACKUPSESSION_H__ */

View file

@ -117,6 +117,8 @@ typedef struct config {
bool ipv6_enable;
bool heart_beat_enable;
bool acs_getrpc;
bool auto_tc_enable;
bool auto_cdu_enable;
int retry_min_wait_interval;
int retry_interval_multiplier;
bool lw_notification_enable;
@ -273,6 +275,7 @@ enum rpc_acs_methods_idx {
RPC_ACS_INFORM = 1,
RPC_ACS_GET_RPC_METHODS,
RPC_ACS_TRANSFER_COMPLETE,
RPC_ACS_AUTONOMOUS_TRANSFER_COMPLETE,
RPC_ACS_DU_STATE_CHANGE_COMPLETE,
RPC_ACS_AUTONOMOUS_DU_STATE_CHANGE_COMPLETE,
__RPC_ACS_MAX
@ -485,6 +488,20 @@ typedef struct autonomous_du_state_change_complete {
char *operation;
} auto_du_state_change_compl;
typedef struct autonomous_transfer_complete {
char *announce_url;
char *transfer_url;
char *file_type;
char *target_file_name;
char *start_time;
char *complete_time;
char *fault_string;
int fault_code;
bool is_download;
int file_size;
} auto_transfer_complete;
typedef struct du_state_change_complete {
char *command_key;
time_t timeout;

View file

@ -671,6 +671,20 @@ int get_global_config()
cwmp_main->conf.heart_time = 0;
}
if (uci_get_state_value(UCI_AUTONOMOUS_TC_ENABLE, &value) == CWMP_OK) {
cwmp_main->conf.auto_tc_enable = uci_str_to_bool(value);
FREE(value);
} else {
cwmp_main->conf.auto_tc_enable = 0;
}
if (uci_get_state_value(UCI_AUTONOMOUS_CDU_ENABLE, &value) == CWMP_OK) {
cwmp_main->conf.auto_cdu_enable = uci_str_to_bool(value);
FREE(value);
} else {
cwmp_main->conf.auto_cdu_enable = 0;
}
return CWMP_OK;
}

View file

@ -57,6 +57,9 @@
#define UCI_AUTONOMOUS_DU_STATE_RESULT "cwmp.du_state_change.result_type"
#define UCI_CPE_FIREWALL_RESTART_STATE "cwmp.cpe.firewall_restart"
#define UCI_AUTONOMOUS_TC_ENABLE "cwmp.transfer_complete.enable"
#define UCI_AUTONOMOUS_CDU_ENABLE "cwmp.du_state_change.enable"
#define UCI_CONFIG_DIR "/etc/config/"
#define LIB_DB_CONFIG "/lib/db/config"
#define ETC_DB_CONFIG "/etc/board-db/config"

View file

@ -212,6 +212,25 @@ int cwmp_root_cause_autonomous_cdu_complete(auto_du_state_change_compl *p)
return CWMP_OK;
}
int cwmp_root_cause_autonomous_transfer_complete(auto_transfer_complete *p)
{
struct event_container *event_container;
struct rpc *rpc_acs;
event_container = cwmp_add_event_container(EVENT_IDX_10AUTONOMOUS_TRANSFER_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_TRANSFER_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

@ -79,5 +79,5 @@ 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);
int cwmp_root_cause_autonomous_transfer_complete(auto_transfer_complete *p);
#endif /* SRC_INC_EVENT_H_ */

View file

@ -59,6 +59,7 @@ 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_AUTONOMOUS_TRANSFER_COMPLETE] = { "AutonomousTransferComplete", cwmp_rpc_acs_prepare_autonomous_transfer_complete, NULL, cwmp_rpc_acs_destroy_data_autonomous_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_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 }
};
@ -643,6 +644,52 @@ error:
return -1;
}
int cwmp_rpc_acs_prepare_autonomous_transfer_complete(struct rpc *rpc)
{
mxml_node_t *tree = NULL, *n;
auto_transfer_complete *p;
p = (auto_transfer_complete *)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, "AutonomousTransferComplete");
if (!n)
goto error;
struct xml_data_struct auto_trsfr_complete_xml_attrs = {0};
if (p) {
auto_trsfr_complete_xml_attrs.start_time = &p->start_time;
auto_trsfr_complete_xml_attrs.complete_time = &p->complete_time;
auto_trsfr_complete_xml_attrs.fault_code = &p->fault_code;
auto_trsfr_complete_xml_attrs.fault_string = &p->fault_string;
auto_trsfr_complete_xml_attrs.announce_url = &p->announce_url;
auto_trsfr_complete_xml_attrs.transfer_url = &p->transfer_url;
auto_trsfr_complete_xml_attrs.file_size = &p->file_size;
auto_trsfr_complete_xml_attrs.file_type = &p->file_type;
auto_trsfr_complete_xml_attrs.target_file_name = &p->target_file_name;
auto_trsfr_complete_xml_attrs.is_download = &p->is_download;
}
int fault = build_xml_node_data(SOAP_AUTONOMOUS_TRANSFER_COMPLETE, n, &auto_trsfr_complete_xml_attrs);
if (fault != CWMP_OK) {
goto error;
}
cwmp_main->session->tree_out = tree;
return 0;
error:
return -1;
}
/*
* [RPC ACS]: DUStateChangeComplete
*/

View file

@ -47,6 +47,7 @@ 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 cwmp_rpc_acs_prepare_autonomous_transfer_complete(struct rpc *rpc);
int xml_handle_message();
int cwmp_create_fault_message(struct rpc *rpc_cpe, int fault_code);

View file

@ -464,6 +464,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_10AUTONOMOUS_TRANSFER_COMPLETE) {
auto_transfer_complete *auto_trnsfr_complete = (auto_transfer_complete *)session_event->extra_data;
cwmp_root_cause_autonomous_transfer_complete(auto_trnsfr_complete);
} 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);

View file

@ -99,6 +99,7 @@ struct xml_node_data xml_nodes_data[] = {
[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_AUTONOMOUS_TRANSFER_COMPLETE] = {XML_SINGLE, 0, NULL, {{"AnnounceURL", XML_STRING, 0, NULL}, {"TransferURL", XML_STRING, 0, NULL}, {"IsDownload", XML_BOOL, 0, NULL}, {"FileType", XML_STRING, 0, NULL}, {"FileSize", XML_INTEGER, 0, NULL}, {"TargetFileName", XML_STRING, 0, NULL}, {"FaultStruct", XML_REC, SOAP_CWMP_FAULT, NULL}, {"StartTime", XML_STRING, 0, NULL}, {"CompleteTime", XML_STRING, 0, 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}}},
@ -123,6 +124,8 @@ char* xml_tags_names[] = {
"CommandKey",
"FileType",
"URL",
"AnnounceURL",
"TransferURL",
"Username",
"Password",
"UUID",
@ -147,6 +150,7 @@ char* xml_tags_names[] = {
"ProductClass",
"xsi:type",
"soap_enc:arrayType",
"TargetFileName",
"FileSize",
"Notification",
"MaxRetries",
@ -161,6 +165,7 @@ char* xml_tags_names[] = {
"NextLevel",
"NotificationChange",
"Writable",
"IsDownload"
};
int get_xml_tags_array_total_size(int tag_ref)

View file

@ -77,6 +77,7 @@ enum soap_methods {
SOAP_DEVID,
SOAP_DU_CHANGE_COMPLETE,
SOAP_AUTONOMOUS_DU_CHANGE_COMPLETE,
SOAP_AUTONOMOUS_TRANSFER_COMPLETE,
SOAP_CDU_RESULTS_REF,
SOAP_ACDU_OPTS_REF,
SOAP_CDU_OPTS_REF,
@ -129,6 +130,8 @@ struct xml_data_struct {
char **command_key;
char **file_type;
char **url;
char **announce_url;
char **transfer_url;
char **username;
char **password;
char **uuid;
@ -153,6 +156,7 @@ struct xml_data_struct {
char **product_class;
char **xsi_type;
char **soap_enc_array_type;
char **target_file_name;
int *file_size;
int *notification;
int *scheddown_max_retries;
@ -167,6 +171,7 @@ struct xml_data_struct {
bool *next_level;
bool *notification_change;
bool *writable;
bool *is_download;
mxml_node_t **xml_env;
struct list_head *data_list;