Added support to download opconf

This commit is contained in:
Suvendhu Hansa 2025-09-22 19:07:06 +05:30
parent 7f4a159f6f
commit ca5227149c
4 changed files with 75 additions and 8 deletions

View file

@ -498,6 +498,7 @@ typedef struct download {
char *url;
char *username;
char *password;
char *target_file_name;
struct timewindow timewindowstruct[2];
} download;

View file

@ -368,6 +368,64 @@ bool cwmp_apply_web_content(char *filepath)
return status;
}
// Apply opconf
static void ubus_get_opconf_status(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg)
{
if (msg == NULL) {
CWMP_LOG(ERROR, "received msg is null");
return;
}
char **status = (char **)req->priv;
if (status == NULL)
return;
const struct blobmsg_policy p[1] = { { "Result", BLOBMSG_TYPE_STRING } };
struct blob_attr *tb[1] = { NULL };
blobmsg_parse(p, 1, tb, blobmsg_data(msg), blobmsg_len(msg));
if (tb[0] == NULL) {
CWMP_LOG(ERROR, "result not exists in received msg");
return;
}
*status = strdup(blobmsg_get_string(tb[0]));
}
bool valid_opconf_file_name(char *download_file_name)
{
char pattern[64] = {0};
snprintf(pattern, sizeof(pattern), "^opconf[^/]*\\.(json|tar\\.gz)$");
return match_reg_exp(pattern, download_file_name);
}
int cwmp_apply_opconf(char *filepath)
{
char file_url[520];
char *status = NULL;
if (CWMP_STRLEN(filepath) == 0)
return CWMP_GEN_ERR;
snprintf(file_url, sizeof(file_url), "file://%s", filepath);
struct blob_buf b = {0};
CWMP_MEMSET(&b, 0, sizeof(struct blob_buf));
blob_buf_init(&b, 0);
blobmsg_add_string(&b, "url", file_url);
int err = icwmp_ubus_invoke("opconf", "install", b.head, ubus_get_opconf_status, &status);
if (CWMP_STRCMP(status, "OK") != 0)
err = -1;
blob_buf_free(&b);
FREE(status);
return err;
}
void fw_upgrade_callback(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg)
{
char **fault = (char **)req->priv;
@ -619,11 +677,17 @@ int apply_downloaded_file(struct download *pdownload, char *download_file_name,
char file_path[512];
snprintf(file_path, sizeof(file_path), "/tmp/%s", download_file_name);
if (strstr(download_file_name, ".uci.conf") != NULL) {
if (CWMP_STRSTR(download_file_name, ".uci.conf") != NULL ||
CWMP_STRSTR(pdownload->target_file_name, ".uci.conf") != NULL) {
err = import_uci_package(NULL, file_path);
} else if (valid_opconf_file_name(download_file_name) ||
CWMP_STRCMP(pdownload->target_file_name, "opconf.json") == 0) {
err = cwmp_apply_opconf(file_path);
} else {
err = import_uci_package(download_file_name, file_path);
}
remove(file_path);
} else {
err = import_uci_package("vendor_conf_file", VENDOR_CONFIG_FILE);

View file

@ -1937,10 +1937,11 @@ int cwmp_handle_rpc_cpe_download(struct rpc *rpc)
download_xml_attrs.delay_seconds = (long int*)&download_delay;
download_xml_attrs.file_type = &download->file_type;
download_xml_attrs.file_size = &download->file_size;
download_xml_attrs.target_file_name = &download->target_file_name;
struct xml_tag_validation download_validation[] = {{"CommandKey", VALIDATE_STR_SIZE, 0, 32}, {"FileType", VALIDATE_STR_SIZE, 0, 64}, {"URL", VALIDATE_STR_SIZE, 0, 256}, {"Username", VALIDATE_STR_SIZE, 0, 256}, {"Password", VALIDATE_STR_SIZE, 0, 256}, {"FileSize", VALIDATE_UNINT, 0, 0}, {"DelaySeconds", VALIDATE_UNINT, 0, 0}};
struct xml_tag_validation download_validation[] = {{"CommandKey", VALIDATE_STR_SIZE, 0, 32}, {"FileType", VALIDATE_STR_SIZE, 0, 64}, {"URL", VALIDATE_STR_SIZE, 0, 256}, {"Username", VALIDATE_STR_SIZE, 0, 256}, {"Password", VALIDATE_STR_SIZE, 0, 256}, {"FileSize", VALIDATE_UNINT, 0, 0}, {"TargetFileName", VALIDATE_STR_SIZE, 0, 256}, {"DelaySeconds", VALIDATE_UNINT, 0, 0}};
download_xml_attrs.validations = download_validation;
download_xml_attrs.nbre_validations = 7;
download_xml_attrs.nbre_validations = 8;
error = load_xml_node_data(SOAP_REQ_DOWNLOAD, n, &download_xml_attrs);
@ -2080,10 +2081,11 @@ int cwmp_handle_rpc_cpe_schedule_download(struct rpc *rpc)
sched_download_xml_attrs.password = &schedule_download->password;
sched_download_xml_attrs.file_type = &schedule_download->file_type;
sched_download_xml_attrs.file_size = &schedule_download->file_size;
sched_download_xml_attrs.target_file_name = &schedule_download->target_file_name;
struct xml_tag_validation scheddownload_validation[] = {{"CommandKey", VALIDATE_STR_SIZE, 0, 32}, {"FileType", VALIDATE_STR_SIZE, 0, 64}, {"URL", VALIDATE_STR_SIZE, 0, 256}, {"Username", VALIDATE_STR_SIZE, 0, 256}, {"Password", VALIDATE_STR_SIZE, 0, 256}, {"FileSize", VALIDATE_UNINT, 0, 0}};
struct xml_tag_validation scheddownload_validation[] = {{"CommandKey", VALIDATE_STR_SIZE, 0, 32}, {"FileType", VALIDATE_STR_SIZE, 0, 64}, {"URL", VALIDATE_STR_SIZE, 0, 256}, {"Username", VALIDATE_STR_SIZE, 0, 256}, {"Password", VALIDATE_STR_SIZE, 0, 256}, {"FileSize", VALIDATE_UNINT, 0, 0}, {"TargetFileName", VALIDATE_STR_SIZE, 0, 256}};
sched_download_xml_attrs.validations = scheddownload_validation;
sched_download_xml_attrs.nbre_validations = 6;
sched_download_xml_attrs.nbre_validations = 7;
LIST_HEAD(time_window_intervals);
sched_download_xml_attrs.data_list = &time_window_intervals;

View file

@ -63,11 +63,11 @@ struct xml_node_data xml_nodes_data[] = {
[SOAP_REQ_ADDOBJ] = {XML_SINGLE, 0, NULL, {{"ObjectName", XML_STRING, 0, NULL}, {"ParameterKey", XML_STRING, 0, NULL}}},
[SOAP_REQ_DELOBJ] = {XML_SINGLE, 0, NULL, {{"ObjectName", XML_STRING, 0, NULL}, {"ParameterKey", XML_STRING, 0, NULL}}},
[SOAP_REQ_REBOOT] = {XML_SINGLE, 0, NULL, {{"CommandKey", XML_STRING, 0, NULL}}},
[SOAP_REQ_DOWNLOAD] = {XML_SINGLE, 0, NULL, {{"CommandKey", XML_STRING, 0, NULL}, {"FileType", XML_FUNC, 0, load_download_filetype}, {"URL", XML_STRING, 0, NULL}, {"Username", XML_STRING, 0, NULL}, {"Password", XML_STRING, 0, NULL}, {"FileSize", XML_INTEGER, 0, NULL}, {"DelaySeconds", XML_INTEGER, 0, NULL}}},
[SOAP_REQ_DOWNLOAD] = {XML_SINGLE, 0, NULL, {{"CommandKey", XML_STRING, 0, NULL}, {"FileType", XML_FUNC, 0, load_download_filetype}, {"URL", XML_STRING, 0, NULL}, {"Username", XML_STRING, 0, NULL}, {"Password", XML_STRING, 0, NULL}, {"FileSize", XML_INTEGER, 0, NULL}, {"TargetFileName", XML_STRING, 0, NULL}, {"DelaySeconds", XML_INTEGER, 0, NULL}}},
[SOAP_REQ_UPLOAD] = {XML_SINGLE, 0, NULL, {{"CommandKey", XML_STRING, 0, NULL}, {"FileType", XML_FUNC, 0, load_upload_filetype}, {"URL", XML_STRING, 0, NULL}, {"Username", XML_STRING, 0, NULL}, {"Password", XML_STRING, 0, NULL}, {"DelaySeconds", XML_INTEGER, 0, NULL}}},
[SOAP_REQ_CANCELTRANSFER] = {XML_SINGLE, 0, NULL, {{"CommandKey", XML_STRING, 0, NULL}}},
[SOAP_REQ_SCHEDINF] = {XML_SINGLE, 0, NULL, {{"CommandKey", XML_STRING, 0, NULL}, {"DelaySeconds", XML_INTEGER, 0, NULL}}},
[SOAP_REQ_SCHEDDOWN] = {XML_SINGLE, 0, NULL, {{"CommandKey", XML_STRING, 0, NULL}, {"FileType", XML_STRING, 0, NULL}, {"URL", XML_STRING, 0, NULL}, {"Username", XML_STRING, 0, NULL}, {"Password", XML_STRING, 0, NULL}, {"FileSize", XML_STRING, 0, NULL}, {"TimeWindowList", XML_REC, SOAP_TIMEWINDOW_REF, NULL}}},
[SOAP_REQ_SCHEDDOWN] = {XML_SINGLE, 0, NULL, {{"CommandKey", XML_STRING, 0, NULL}, {"FileType", XML_STRING, 0, NULL}, {"URL", XML_STRING, 0, NULL}, {"Username", XML_STRING, 0, NULL}, {"Password", XML_STRING, 0, NULL}, {"FileSize", XML_STRING, 0, NULL}, {"TargetFileName", XML_STRING, 0, NULL}, {"TimeWindowList", XML_REC, SOAP_TIMEWINDOW_REF, NULL}}},
[SOAP_REQ_CDU] = {XML_SINGLE, 0, NULL, {{"CommandKey", XML_STRING, 0, NULL}, {"Operations", XML_REC, SOAP_REQ_CDU_OPERATIONS, NULL}}},
[SOAP_REQ_SPV_LIST] = {XML_LIST, SOAP_REQ_SPV_LIST_REF, "ParameterValueStruct", {}},
[SOAP_REQ_SPV_LIST_REF] = {XML_SINGLE, 0, NULL, {{"Name", XML_STRING, 0, NULL}, {"Value", XML_STRING, 0, NULL}}},
@ -173,7 +173,7 @@ struct xml_node_data xml_nodes_data[] = {
[GET_RPC_ATTR] = {XML_SINGLE, 0, NULL, {{"xsi:type", XML_STRING, 0, NULL}, {"soap_enc:arrayType", XML_FUNC, 0, get_soap_enc_array_type}}}
};
struct xml_switch xml_nodes_names_switches[] = {{"URL", "url"}, {"UUID", "uuid"}, {"IsDownload", "isdownload"}, {"AnnounceURL", "announceurl"}, {"TransferURL", "transferurl"}, {"ExecutionEnvRef", "executionenvref"}, {"Resolved", "resolved"}, {"CurrentState", "uuid"}, {"FileType", "file_type"}, {"CommandKey", "command_key"}, {"Username", "username"}, {"Version", "version"}, {"Password", "password"}, {"StartTime", "start_time"}, {"CompleteTime", "complete_time"}, {"FileSize", "file_size"}, {"FaultCode", "fault_code"}, {"FaultString", "fault_string"}};
struct xml_switch xml_nodes_names_switches[] = {{"URL", "url"}, {"UUID", "uuid"}, {"IsDownload", "isdownload"}, {"AnnounceURL", "announceurl"}, {"TransferURL", "transferurl"}, {"ExecutionEnvRef", "executionenvref"}, {"Resolved", "resolved"}, {"CurrentState", "uuid"}, {"FileType", "file_type"}, {"CommandKey", "command_key"}, {"Username", "username"}, {"Version", "version"}, {"Password", "password"}, {"StartTime", "start_time"}, {"CompleteTime", "complete_time"}, {"FileSize", "file_size"}, {"TargetFileName", "target_file"}, {"FaultCode", "fault_code"}, {"FaultString", "fault_string"}};
char* xml_tags_names[] = {
"ParameterList",