diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d3e033d..38f0e52 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,5 @@ variables: - CFLAGS: "-DBBF_VENDOR_PREFIX=\\\"X_IOWRT_EU_\\\"" + CFLAGS: "-DBBF_VENDOR_PREFIX=\\\"X_IOWRT_EU_\\\" -DICWMP_ENABLE_OPCONF_SUPPORT -DICWMP_ENABLE_VENDOR_EXTN -DICWMP_ENABLE_SMM_SUPPORT" #VERBOSE: true SOURCE_FOLDER: "." COMPILATION_FIXUP: "cmake ." diff --git a/gitlab-ci/shared.sh b/gitlab-ci/shared.sh index 3f5bffc..a83afce 100644 --- a/gitlab-ci/shared.sh +++ b/gitlab-ci/shared.sh @@ -133,7 +133,7 @@ function build_icwmp() # compile icwmp mkdir -p build cd build - cmake ../ -DCMAKE_C_FLAGS="$COV_CFLAGS -DICWMP_ENABLE_VENDOR_EXTN" -DCMAKE_EXE_LINKER_FLAGS="$COV_LDFLAGS" -DCMAKE_INSTALL_PREFIX=/ -DBBF_VENDOR_PREFIX="$VENDOR_PREFIX" + cmake ../ -DCMAKE_C_FLAGS="$COV_CFLAGS -DICWMP_ENABLE_VENDOR_EXTN -DICWMP_ENABLE_SMM_SUPPORT -DICWMP_ENABLE_OPCONF_SUPPORT" -DCMAKE_EXE_LINKER_FLAGS="$COV_LDFLAGS" -DCMAKE_INSTALL_PREFIX=/ -DBBF_VENDOR_PREFIX="$VENDOR_PREFIX" exec_cmd make echo "installing icwmpd binary and libcwmpdm.so library" diff --git a/src/common.c b/src/common.c index 8117139..69d432d 100755 --- a/src/common.c +++ b/src/common.c @@ -101,10 +101,11 @@ const char *g_download_file_types[__MAX_DOWNLOAD_FILETYPE] = { [DOWNLOAD_FILETYPE_TONE_FILE] = "4 Tone File", [DOWNLOAD_FILETYPE_RINGER] = "5 Ringer File", [DOWNLOAD_FILETYPE_STORED_FIRMWARE_IMAGE] = "6 Stored Firmware Image", -#ifdef ICWMP_ENABLE_VENDOR_EXTN +#ifdef ICWMP_ENABLE_OPCONF_SUPPORT [DOWNLOAD_FILETYPE_UPGRADE_WITH_NOCONF] = "X GENEXIS-EU UPGRADE-WITH-NOCONF", [DOWNLOAD_FILETYPE_UPGRADE_WITH_USERCONF] = "X GENEXIS-EU UPGRADE-WITH-USERCONF", [DOWNLOAD_FILETYPE_UPGRADE_WITH_FULLCONF] = "X GENEXIS-EU UPGRADE-WITH-FULLCONF", + [DOWNLOAD_FILETYPE_OPERATOR_CONF_FILE] = "X GENEXIS-EU OPERATOR-CONFIGURATION-FILE", #endif }; @@ -550,12 +551,16 @@ void cwmp_reboot(const char *command_key) /* * FactoryReset */ -void cwmp_factory_reset() +void cwmp_factory_reset(bool is_soft_reset) { int code = 3; // Flawfinder: ignore - code = run_cmd("defaultreset", NULL, 0); + if (is_soft_reset) { + code = run_cmd("defaultreset -s", NULL, 0); + } else { + code = run_cmd("defaultreset", NULL, 0); + } if (code == 0) { // Wait before exit to avoid getting restarted by procd sleep(300); @@ -1464,3 +1469,51 @@ int get_random_cpe_port(void) return rand_port ? rand_port : DEFAULT_CONNECTION_REQUEST_PORT; } + +bool is_file_gzip(FILE *f) +{ + unsigned char sig[2]; + + fseek(f, 0, SEEK_SET); + if (fread(sig, 1, 2, f) != 2) { + return false; + } + + return (sig[0] == 0x1f && sig[1] == 0x8b); +} + +bool is_file_tar(FILE *f) +{ + char buf[6]; + + fseek(f, 257, SEEK_SET); + if (fread(buf, 1, 5, f) != 5) { + return false; + } + + buf[5] = '\0'; + return (strcmp(buf, "ustar") == 0); +} + +bool is_file_json(FILE *f) +{ + int c; + + fseek(f, 0, SEEK_SET); + while ((c = fgetc(f)) != EOF) { + if (!isspace(c)) { + return (c == '{' || c == '['); + } + } + + return false; +} + +void remove_file(const char *file) +{ +#ifdef DEBUG_KEEP_FILE + CWMP_LOG(ERROR, "Keeping the file [%s] for debugging", file); +#else + remove(file); +#endif +} diff --git a/src/common.h b/src/common.h index 3ff45d2..49444f3 100644 --- a/src/common.h +++ b/src/common.h @@ -471,10 +471,11 @@ enum download_filetypes { DOWNLOAD_FILETYPE_TONE_FILE = 4, DOWNLOAD_FILETYPE_RINGER = 5, DOWNLOAD_FILETYPE_STORED_FIRMWARE_IMAGE = 6, -#ifdef ICWMP_ENABLE_VENDOR_EXTN +#ifdef ICWMP_ENABLE_OPCONF_SUPPORT DOWNLOAD_FILETYPE_UPGRADE_WITH_NOCONF = 7, DOWNLOAD_FILETYPE_UPGRADE_WITH_USERCONF = 8, DOWNLOAD_FILETYPE_UPGRADE_WITH_FULLCONF = 9, + DOWNLOAD_FILETYPE_OPERATOR_CONF_FILE = 10, #endif __MAX_DOWNLOAD_FILETYPE }; @@ -684,7 +685,7 @@ void cwmp_free_all_list_param_fault(struct list_head *list_param_fault); bool folder_exists(const char *path); bool file_exists(const char *path); void cwmp_reboot(const char *command_key); -void cwmp_factory_reset(); +void cwmp_factory_reset(bool is_soft_reset); int download_file(const char *file_path, const char *url, const char *username, const char *password, const char *interface); unsigned int get_file_size(const char *file_name); int cwmp_check_image(); @@ -745,4 +746,10 @@ int get_random_cpe_port(void); void cwmp_add_modified_uci_list(const char *config_file); void cwmp_free_modified_uci_list(void); int run_cmd(const char *cmd, char *output, size_t out_len); + +bool is_file_gzip(FILE *f); +bool is_file_tar(FILE *f); +bool is_file_json(FILE *f); + +void remove_file(const char *file); #endif diff --git a/src/download.c b/src/download.c index 36a29ef..a780eae 100644 --- a/src/download.c +++ b/src/download.c @@ -26,6 +26,8 @@ #define BBF_VENDOR_PREFIX "X_IOWRT_EU_" #endif +#define MACRO_ENGINE "/sbin/macro_engine.sh" + LIST_HEAD(list_download); LIST_HEAD(list_schedule_download); @@ -424,16 +426,38 @@ static void ubus_get_opconf_status(struct ubus_request *req, int type __attribut *status = strdup(blobmsg_get_string(tb[0])); } -bool valid_opconf_file_name(char *download_file_name) +bool is_downloaded_file_opconf(char *file_name) { - char pattern[64] = {0}; + FILE *f; + bool is_opconf = false; - snprintf(pattern, sizeof(pattern), "^opconf[^/]*\\.(json|tar\\.gz)$"); + if (file_name == NULL) { + return false; + } - return match_reg_exp(pattern, download_file_name); + // cppcheck-suppress cert-MSC24-C + f = fopen(file_name, "rb"); + if (!f) { + CWMP_LOG(ERROR, "Failed to open downloaded config[%s] file", file_name); + return false; + } + + is_opconf = is_file_json(f); + if (is_opconf) + goto exit; + + is_opconf = is_file_tar(f); + if (is_opconf) + goto exit; + + is_opconf = is_file_gzip(f); +exit: + fclose(f); + return is_opconf; } -int cwmp_apply_opconf(char *filepath) +#ifdef ICWMP_ENABLE_OPCONF_SUPPORT +int cwmp_apply_opconf(char *filepath, enum download_filetypes filetype) { char file_url[520]; char *status = NULL; @@ -448,16 +472,21 @@ int cwmp_apply_opconf(char *filepath) blob_buf_init(&b, 0); blobmsg_add_string(&b, "url", file_url); + if (filetype == DOWNLOAD_FILETYPE_OPERATOR_CONF_FILE) { + blobmsg_add_u8(&b, "persistent", true); + } int err = icwmp_ubus_invoke("opconf", "install", b.head, ubus_get_opconf_status, &status); - if (CWMP_STRCMP(status, "OK") != 0) + if (CWMP_STRCMP(status, "OK") != 0) { err = -1; + } blob_buf_free(&b); FREE(status); return err; } +#endif void fw_upgrade_callback(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg) { @@ -504,7 +533,7 @@ static int cwmp_apply_multiple_firmware(enum download_filetypes filetype, bool a int bank_id = get_available_bank_id(); char buffer[32] = {0}; int keep_opconf = -1, keep_userconf = -1; - char *config_scope = NULL; + const char *config_scope = NULL; if (bank_id <= 0) return -1; @@ -539,7 +568,7 @@ static int cwmp_apply_multiple_firmware(enum download_filetypes filetype, bool a bb_add_string(&b, buffer, cwmp_ctx.conf.cpe_config_scope); config_scope = cwmp_ctx.conf.cpe_config_scope; } -#ifdef ICWMP_ENABLE_VENDOR_EXTN +#ifdef ICWMP_ENABLE_OPCONF_SUPPORT } else if (filetype == DOWNLOAD_FILETYPE_UPGRADE_WITH_USERCONF) { snprintf(buffer, sizeof(buffer), "%s%s", BBF_VENDOR_PREFIX, "ConfigScope"); bb_add_string(&b, buffer, "UserOnly"); @@ -566,7 +595,7 @@ static int cwmp_apply_multiple_firmware(enum download_filetypes filetype, bool a //set /var/state 'switch_bank' option set_uci_path_value(VARSTATE_CONFIG, "icwmp.cpe.switch_bank", "1"); -#ifdef ICWMP_ENABLE_VENDOR_EXTN +#ifdef ICWMP_ENABLE_OPCONF_SUPPORT if (keep_opconf != -1) { snprintf(buffer, sizeof(buffer), "%d", keep_opconf); set_uci_path_value(VARSTATE_CONFIG, "icwmp.cpe.KeepOpConf", buffer); @@ -630,67 +659,74 @@ int cwmp_launch_download(struct download *pdownload, char *download_file_name, e error = FAULT_CPE_INVALID_ARGUMENTS; snprintf(err_msg, sizeof(err_msg), "[%s:%d] File type [%d] is not a valid value", __func__, __LINE__, pdownload->filetype); goto end_download; - } else { - pdownload->filetype = get_download_filetype(pdownload->file_type); } - if ((pdownload->filetype == DOWNLOAD_FILETYPE_FIRMWARE_UPGRADE_IMAGE) - || (pdownload->filetype == DOWNLOAD_FILETYPE_STORED_FIRMWARE_IMAGE) -#ifdef ICWMP_ENABLE_VENDOR_EXTN - || (pdownload->filetype == DOWNLOAD_FILETYPE_UPGRADE_WITH_NOCONF) - || (pdownload->filetype == DOWNLOAD_FILETYPE_UPGRADE_WITH_USERCONF) - || (pdownload->filetype == DOWNLOAD_FILETYPE_UPGRADE_WITH_FULLCONF) + pdownload->filetype = get_download_filetype(pdownload->file_type); + switch (pdownload->filetype) { + case DOWNLOAD_FILETYPE_FIRMWARE_UPGRADE_IMAGE: + case DOWNLOAD_FILETYPE_STORED_FIRMWARE_IMAGE: +#ifdef ICWMP_ENABLE_OPCONF_SUPPORT + case DOWNLOAD_FILETYPE_UPGRADE_WITH_NOCONF: + case DOWNLOAD_FILETYPE_UPGRADE_WITH_USERCONF: + case DOWNLOAD_FILETYPE_UPGRADE_WITH_FULLCONF: #endif - ) { - rename(ICWMP_DOWNLOAD_FILE, FIRMWARE_UPGRADE_IMAGE); - int ret = cwmp_check_image(FIRMWARE_UPGRADE_IMAGE); + rename(ICWMP_DOWNLOAD_FILE, FIRMWARE_UPGRADE_IMAGE); + int ret = cwmp_check_image(FIRMWARE_UPGRADE_IMAGE); - if (ret == 0) { - unsigned int file_size = get_file_size(FIRMWARE_UPGRADE_IMAGE); - if (file_size > flashsize) { - error = FAULT_CPE_DOWNLOAD_FAILURE; - snprintf(err_msg, sizeof(err_msg), "File size: (%u) is larger than flash size: (%u)", file_size, flashsize);; - remove(FIRMWARE_UPGRADE_IMAGE); - goto end_download; + if (ret == 0) { + unsigned int file_size = get_file_size(FIRMWARE_UPGRADE_IMAGE); + + if (file_size > flashsize) { + error = FAULT_CPE_DOWNLOAD_FAILURE; + snprintf(err_msg, sizeof(err_msg), "File size: (%u) is larger than flash size: (%u)", file_size, flashsize);; + remove_file(FIRMWARE_UPGRADE_IMAGE); + goto end_download; + } else { + error = FAULT_CPE_NO_FAULT; + goto end_download; + } } else { - error = FAULT_CPE_NO_FAULT; - goto end_download; + error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED; + snprintf(err_msg, sizeof(err_msg), "Failed validation with %d of Downloaded file", ret); + remove_file(FIRMWARE_UPGRADE_IMAGE); } - } else { - error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED; - snprintf(err_msg, sizeof(err_msg), "Failed validation with %d of Downloaded file", ret); - remove(FIRMWARE_UPGRADE_IMAGE); - } - } else if (pdownload->filetype == DOWNLOAD_FILETYPE_WEB_CONTENT) { - if (download_file_name != NULL) { - char file_path[512]; - snprintf(file_path, sizeof(file_path), "/tmp/%s", download_file_name); - rename(ICWMP_DOWNLOAD_FILE, file_path); - } else - rename(ICWMP_DOWNLOAD_FILE, WEB_CONTENT_FILE); + break; + case DOWNLOAD_FILETYPE_WEB_CONTENT: + if (download_file_name != NULL) { + char file_path[512]; + snprintf(file_path, sizeof(file_path), "/tmp/%s", download_file_name); + rename(ICWMP_DOWNLOAD_FILE, file_path); + } else + rename(ICWMP_DOWNLOAD_FILE, WEB_CONTENT_FILE); - error = FAULT_CPE_NO_FAULT; - goto end_download; - } else if (pdownload->filetype == DOWNLOAD_FILETYPE_VENDOR_CONFIG) { - if (download_file_name != NULL) { - char file_path[512]; - snprintf(file_path, sizeof(file_path), "/tmp/%s", download_file_name); - rename(ICWMP_DOWNLOAD_FILE, file_path); - } else - rename(ICWMP_DOWNLOAD_FILE, VENDOR_CONFIG_FILE); + error = FAULT_CPE_NO_FAULT; + goto end_download; + break; + case DOWNLOAD_FILETYPE_VENDOR_CONFIG: +#ifdef ICWMP_ENABLE_OPCONF_SUPPORT + case DOWNLOAD_FILETYPE_OPERATOR_CONF_FILE: +#endif + if (download_file_name != NULL) { + char file_path[512]; + snprintf(file_path, sizeof(file_path), "/tmp/%s", download_file_name); + rename(ICWMP_DOWNLOAD_FILE, file_path); + } else { + rename(ICWMP_DOWNLOAD_FILE, VENDOR_CONFIG_FILE); + } - error = FAULT_CPE_NO_FAULT; - } else if (pdownload->filetype == DOWNLOAD_FILETYPE_TONE_FILE) { - //TODO Not Supported - error = FAULT_CPE_NO_FAULT; - } else if (pdownload->filetype == DOWNLOAD_FILETYPE_RINGER) { - //TODO Not Supported - error = FAULT_CPE_NO_FAULT; - - } else { - remove(ICWMP_DOWNLOAD_FILE); - error = FAULT_CPE_INVALID_ARGUMENTS; - snprintf(err_msg, sizeof(err_msg), "Invalid file type: (%s)", pdownload->file_type); + error = FAULT_CPE_NO_FAULT; + break; + case DOWNLOAD_FILETYPE_TONE_FILE: + case DOWNLOAD_FILETYPE_RINGER: + //TODO Not Supported, ignore the request + CWMP_LOG(ERROR, "Filetype [%s] not currently supported, removing downloaded file", pdownload->file_type); + error = FAULT_CPE_NO_FAULT; + remove_file(ICWMP_DOWNLOAD_FILE); + break; + default: + remove_file(ICWMP_DOWNLOAD_FILE); + error = FAULT_CPE_INVALID_ARGUMENTS; + snprintf(err_msg, sizeof(err_msg), "Invalid file type: (%s)", pdownload->file_type); } end_download: @@ -734,6 +770,7 @@ int apply_downloaded_file(struct download *pdownload, char *download_file_name, { int error = FAULT_CPE_NO_FAULT; char err_msg[256] = {0}; + char file_path[512] = {0}; if (pdownload->filetype == DOWNLOAD_FILETYPE_FIRMWARE_UPGRADE_IMAGE) { ptransfer_complete->old_software_version = cwmp_ctx.deviceid.softwareversion; @@ -747,107 +784,141 @@ int apply_downloaded_file(struct download *pdownload, char *download_file_name, } bkp_session_insert_transfer_complete(ptransfer_complete); bkp_session_save(); - if (pdownload->filetype == DOWNLOAD_FILETYPE_FIRMWARE_UPGRADE_IMAGE -#ifdef ICWMP_ENABLE_VENDOR_EXTN - || pdownload->filetype == DOWNLOAD_FILETYPE_UPGRADE_WITH_NOCONF - || pdownload->filetype == DOWNLOAD_FILETYPE_UPGRADE_WITH_USERCONF - || pdownload->filetype == DOWNLOAD_FILETYPE_UPGRADE_WITH_FULLCONF + + switch (pdownload->filetype) { + case DOWNLOAD_FILETYPE_FIRMWARE_UPGRADE_IMAGE: +#ifdef ICWMP_ENABLE_OPCONF_SUPPORT + case DOWNLOAD_FILETYPE_UPGRADE_WITH_NOCONF: + case DOWNLOAD_FILETYPE_UPGRADE_WITH_USERCONF: + case DOWNLOAD_FILETYPE_UPGRADE_WITH_FULLCONF: #endif - ) { - if (cwmp_apply_multiple_firmware(pdownload->filetype, true) == 0) { - cwmp_reboot("FirmwareUpgrade"); - if (error == FAULT_CPE_NO_FAULT) { - sleep(70); - error = FAULT_CPE_DOWNLOAD_FAIL_COMPLETE_DOWNLOAD; - snprintf(err_msg, sizeof(err_msg), "Failed to reboot after upgrade"); - CWMP_LOG(ERROR, "## Failed to reboot after upgrade"); - } - } else { - error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED; - snprintf(err_msg, sizeof(err_msg), "Failed in applying the downloaded firmware image, may be corrupted file"); - CWMP_LOG(ERROR, "Failed in applying the downloaded firmware image, may be corrupted file"); - } - - } else if (pdownload->filetype == DOWNLOAD_FILETYPE_WEB_CONTENT) { - // apply web content file - char file_path[512] = {0}; - if (download_file_name != NULL) { - snprintf(file_path, sizeof(file_path), "file:///tmp/%s", download_file_name); - } else { - snprintf(file_path, sizeof(file_path), "file://%s", WEB_CONTENT_FILE); - } - - if (cwmp_apply_web_content(file_path) == false) { - error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED; - snprintf(err_msg, sizeof(err_msg), "Failed in applying the downloaded web content, may be corrupted file"); - } else - error = FAULT_CPE_NO_FAULT; - - remove(file_path); - } else if (pdownload->filetype == DOWNLOAD_FILETYPE_VENDOR_CONFIG) { - int err = CWMP_OK; - if (download_file_name != NULL) { - char file_path[512]; - - snprintf(file_path, sizeof(file_path), "/tmp/%s", download_file_name); - - 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); + if (cwmp_apply_multiple_firmware(pdownload->filetype, true) == 0) { + cwmp_reboot("FirmwareUpgrade"); + if (error == FAULT_CPE_NO_FAULT) { + sleep(70); + error = FAULT_CPE_DOWNLOAD_FAIL_COMPLETE_DOWNLOAD; + snprintf(err_msg, sizeof(err_msg), "Failed to reboot after upgrade"); + CWMP_LOG(ERROR, "## Failed to reboot after upgrade"); + } } else { - err = import_uci_package(download_file_name, file_path); + error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED; + snprintf(err_msg, sizeof(err_msg), "Failed in applying the downloaded firmware image, may be corrupted file"); + CWMP_LOG(ERROR, "Failed in applying the downloaded firmware image, may be corrupted file"); + } + break; + case DOWNLOAD_FILETYPE_WEB_CONTENT: + // apply web content file + if (download_file_name != NULL) { + snprintf(file_path, sizeof(file_path), "file:///tmp/%s", download_file_name); + } else { + snprintf(file_path, sizeof(file_path), "file://%s", WEB_CONTENT_FILE); } - remove(file_path); - } else { - err = import_uci_package("vendor_conf_file", VENDOR_CONFIG_FILE); - remove(VENDOR_CONFIG_FILE); - } - - if (err == CWMP_OK) { - cwmp_reboot("VendorConfigApply"); - if (error == FAULT_CPE_NO_FAULT) { - sleep(70); - error = FAULT_CPE_DOWNLOAD_FAIL_COMPLETE_DOWNLOAD; - snprintf(err_msg, sizeof(err_msg), "Failed to reboot after config apply"); - CWMP_LOG(ERROR, "## Failed to reboot after config apply"); + if (cwmp_apply_web_content(file_path) == false) { + error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED; + snprintf(err_msg, sizeof(err_msg), "Failed in applying the downloaded web content, may be corrupted file"); + } else { + error = FAULT_CPE_NO_FAULT; } - } else if (err == CWMP_GEN_ERR) { - error = FAULT_CPE_INTERNAL_ERROR; - snprintf(err_msg, sizeof(err_msg), "Failed to commit the config file changes"); - } else if (err == -1) { - error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED; - snprintf(err_msg, sizeof(err_msg), "UCI operation failed, could not import config file"); - } - } else if (pdownload->filetype == DOWNLOAD_FILETYPE_TONE_FILE) { - //TODO Not Supported - error = FAULT_CPE_NO_FAULT; - } else if (pdownload->filetype == DOWNLOAD_FILETYPE_RINGER) { - //TODO Not Supported - error = FAULT_CPE_NO_FAULT; - } else if (pdownload->filetype == DOWNLOAD_FILETYPE_STORED_FIRMWARE_IMAGE) { - int err = cwmp_apply_multiple_firmware(pdownload->filetype, false); - if (err == CWMP_OK) + remove_file(file_path); + break; + case DOWNLOAD_FILETYPE_VENDOR_CONFIG: +#ifdef ICWMP_ENABLE_OPCONF_SUPPORT + case DOWNLOAD_FILETYPE_OPERATOR_CONF_FILE: +#endif + int err = CWMP_OK; + bool is_opconf = false; + + if (CWMP_STRLEN(download_file_name) != 0) { + snprintf(file_path, sizeof(file_path), "/tmp/%s", download_file_name); + } else { + snprintf(file_path, sizeof(file_path), "%s", VENDOR_CONFIG_FILE); + } + + is_opconf = is_downloaded_file_opconf(file_path); + if (is_opconf == false) { // handle normal uci download + char buffer[1024] = {0}; + + // First run the macro_engine.sh to resolve the macros in uci (if present) + if (file_exists(MACRO_ENGINE) == true) { + snprintf(buffer, sizeof(buffer), "%s %s", MACRO_ENGINE, file_path); + run_cmd(buffer, NULL, 0); + } + + // If the downloaded filename is one of the uci name, use named import + snprintf(buffer, sizeof(buffer), "/etc/config/%s", download_file_name); + if (file_exists(buffer) == true) { + err = import_uci_package(download_file_name, file_path); + } else { + err = import_uci_package(NULL, file_path); + } + + if (err == CWMP_GEN_ERR) { + error = FAULT_CPE_INTERNAL_ERROR; + snprintf(err_msg, sizeof(err_msg), "Failed to commit the config file changes"); + } else if (err == -1) { + error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED; + snprintf(err_msg, sizeof(err_msg), "UCI operation failed, could not import config file"); + } +#ifdef ICWMP_ENABLE_OPCONF_SUPPORT + } else { + err = cwmp_apply_opconf(file_path, pdownload->filetype); + if (err != CWMP_OK) { + snprintf(err_msg, sizeof(err_msg), "Failed to apply the opconf file"); + error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED; + } +#endif + } + remove_file(file_path); + // Trigger reboot/soft-reset only in case of its not operator default opconf file, + // operator will trigger factory reset to apply it latter, triggering factoryreset + // will break the DownloadRPC message flow +#ifdef ICWMP_ENABLE_OPCONF_SUPPORT + if (err == CWMP_OK && pdownload->filetype != DOWNLOAD_FILETYPE_OPERATOR_CONF_FILE) { +#else + if (err == CWMP_OK) { +#endif + if (is_opconf == true) { + CWMP_LOG(INFO, "Trigger Soft Factory Reset to apply the opconf"); + cwmp_factory_reset(true); + } else { + cwmp_reboot("VendorConfigApply"); + } + if (error == FAULT_CPE_NO_FAULT) { + sleep(70); + error = FAULT_CPE_DOWNLOAD_FAIL_COMPLETE_DOWNLOAD; + snprintf(err_msg, sizeof(err_msg), "Failed to reboot after config apply"); + CWMP_LOG(ERROR, "## Failed to reboot after config apply"); + } + } + break; + case DOWNLOAD_FILETYPE_TONE_FILE: + case DOWNLOAD_FILETYPE_RINGER: error = FAULT_CPE_NO_FAULT; - else { - error = FAULT_CPE_DOWNLOAD_FAILURE; - if (err == -1) - snprintf(err_msg, sizeof(err_msg), "Failed to get available bank id"); - else - snprintf(err_msg, sizeof(err_msg), "Failed in fwbank upgrade ubus method"); - } - } else { - error = FAULT_CPE_INVALID_ARGUMENTS; - snprintf(err_msg, sizeof(err_msg), "Invalid file type argument (%s)", pdownload->file_type); + break; + case DOWNLOAD_FILETYPE_STORED_FIRMWARE_IMAGE: + error = cwmp_apply_multiple_firmware(pdownload->filetype, false); + if (error != CWMP_OK) { + if (error == -1) + snprintf(err_msg, sizeof(err_msg), "Failed to get available bank id"); + else + snprintf(err_msg, sizeof(err_msg), "Failed in fwbank upgrade ubus method"); + + error = FAULT_CPE_DOWNLOAD_FAILURE; + } + break; + default: + error = FAULT_CPE_INVALID_ARGUMENTS; + snprintf(err_msg, sizeof(err_msg), "Invalid file type argument (%s)", pdownload->file_type); } if (error == FAULT_CPE_NO_FAULT) { set_rpc_parameter_key(pdownload->command_key); if (pdownload->filetype == DOWNLOAD_FILETYPE_WEB_CONTENT || +#ifdef ICWMP_ENABLE_OPCONF_SUPPORT + pdownload->filetype == DOWNLOAD_FILETYPE_OPERATOR_CONF_FILE || +#endif pdownload->filetype == DOWNLOAD_FILETYPE_STORED_FIRMWARE_IMAGE) { bkp_session_delete_element((ltype == TYPE_DOWNLOAD) ? "download" : "schedule_download", pdownload->id); diff --git a/src/rpc.c b/src/rpc.c index 592e63e..aa5a12b 100755 --- a/src/rpc.c +++ b/src/rpc.c @@ -1876,10 +1876,11 @@ static bool check_valid_download_filetypes(enum download_filetypes filetype) case DOWNLOAD_FILETYPE_TONE_FILE: case DOWNLOAD_FILETYPE_RINGER: case DOWNLOAD_FILETYPE_STORED_FIRMWARE_IMAGE: -#ifdef ICWMP_ENABLE_VENDOR_EXTN +#ifdef ICWMP_ENABLE_OPCONF_SUPPORT case DOWNLOAD_FILETYPE_UPGRADE_WITH_NOCONF: case DOWNLOAD_FILETYPE_UPGRADE_WITH_USERCONF: case DOWNLOAD_FILETYPE_UPGRADE_WITH_FULLCONF: + case DOWNLOAD_FILETYPE_OPERATOR_CONF_FILE: #endif res = true; break; diff --git a/src/session.c b/src/session.c index 10ca765..677b58e 100644 --- a/src/session.c +++ b/src/session.c @@ -813,7 +813,7 @@ int run_session_end_func(void) if (end_session_flag & END_SESSION_FACTORY_RESET) { CWMP_LOG(INFO, "Executing factory reset: end session request"); - cwmp_factory_reset(); + cwmp_factory_reset(false); exit(EXIT_SUCCESS); } diff --git a/src/upload.c b/src/upload.c index 7d89e83..9cba319 100644 --- a/src/upload.c +++ b/src/upload.c @@ -315,7 +315,7 @@ int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptrans error = FAULT_CPE_UPLOAD_FAILURE; snprintf(err_msg, sizeof(err_msg), "File upload failed (err_code: %d)", ret); } - remove(file_path); + remove_file(file_path); end_upload: p = calloc(1, sizeof(struct transfer_complete));