From 13c8bed356f9a87621fbb873f250f4fb7d2a7f96 Mon Sep 17 00:00:00 2001 From: Suvendhu Hansa Date: Wed, 4 Jun 2025 16:22:36 +0530 Subject: [PATCH] Apply firmware via DM for '6 Stored Firmware Image' --- src/common.h | 1 + src/download.c | 80 ++++++++++++++++++++++++++---------------------- src/ubus_utils.c | 18 ++++++++++- src/ubus_utils.h | 2 ++ 4 files changed, 64 insertions(+), 37 deletions(-) diff --git a/src/common.h b/src/common.h index 343990e..9c07a34 100644 --- a/src/common.h +++ b/src/common.h @@ -65,6 +65,7 @@ #define DEFAULT_SESSION_TIMEOUT 60 #define MAX_NBRE_SERVICES 256 #define DEFAULT_SYNC_TIMEOUT 128 +#define DEFAULT_UBUS_TIMEOUT 60000 #define BUF_SIZE_8 (8 + 1) #define BUF_SIZE_16 (16 + 1) diff --git a/src/download.c b/src/download.c index 554d884..61be219 100644 --- a/src/download.c +++ b/src/download.c @@ -301,22 +301,6 @@ void ubus_get_bank_status_callback(struct ubus_request *req, int type __attribut bank->status = 0; } -int get_applied_firmware_status(struct fwbank_dump *bank) -{ - int e; - struct blob_buf b = { 0 }; - CWMP_MEMSET(&b, 0, sizeof(struct blob_buf)); - blob_buf_init(&b, 0); - - e = icwmp_ubus_invoke("fwbank", "dump", b.head, ubus_get_available_bank_callback, &bank); - - if (e != 0) { - CWMP_LOG(INFO, "fwbank dump ubus method failed: Ubus err code: %d", e); - } - blob_buf_free(&b); - return e; -} - /* * Apply the new firmware */ @@ -384,47 +368,71 @@ bool cwmp_apply_web_content(char *filepath) return status; } -void wait_firmware_to_be_applied(int bank_id) +void fw_upgrade_callback(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg) { - int count = 0; + char **fault = (char **)req->priv; + const struct blobmsg_policy p[1] = { { "results", BLOBMSG_TYPE_ARRAY } }; + struct blob_attr *tb[1] = { NULL }; + blobmsg_parse(p, 1, tb, blobmsg_data(msg), blobmsg_len(msg)); + if (tb[0]) { + struct blob_attr *attr = NULL; + int rem = 0; - do { - struct fwbank_dump bank = {.bank_id = bank_id, .status = 0}; - if (get_applied_firmware_status(&bank) != CWMP_OK) - continue; + blobmsg_for_each_attr(attr, tb[0], rem) { + const struct blobmsg_policy p1[1] = { { "output", BLOBMSG_TYPE_ARRAY } }; + struct blob_attr *tb1[1] = { NULL }; + blobmsg_parse(p1, 1, tb1, blobmsg_data(attr), blobmsg_len(attr)); - if (bank.status == 1) - break; + if (tb1[0]) { + struct blob_attr *param = NULL; + int len = 0; - sleep(2); - count++; - } while(count < 20); + blobmsg_for_each_attr(param, tb1[0], len) { + const struct blobmsg_policy p2[1] = { { "fault", BLOBMSG_TYPE_INT32 } }; + struct blob_attr *tb2[1] = { NULL }; + blobmsg_parse(p2, 1, tb2, blobmsg_data(param), blobmsg_len(param)); + + if (tb2[0]) { + *fault = strdup("9010"); + return; + } + } + } + } + *fault = NULL; + } else { + *fault = strdup("9010"); + } } int cwmp_apply_multiple_firmware() { + char *fault_code = NULL; int e; int bank_id = get_available_bank_id(); if (bank_id <= 0) return -1; + char path[128] = {0}, url[128] = {0}; + snprintf(path, sizeof(path), "Device.DeviceInfo.FirmwareImage.%d.Download()", bank_id); + snprintf(url, sizeof(url), "file://%s", FIRMWARE_UPGRADE_IMAGE); + struct blob_buf b = { 0 }; CWMP_MEMSET(&b, 0, sizeof(struct blob_buf)); blob_buf_init(&b, 0); - bb_add_string(&b, "path", FIRMWARE_UPGRADE_IMAGE); - blobmsg_add_u8(&b, "auto_activate", false); - blobmsg_add_u32(&b, "bank", bank_id); - blobmsg_add_u8(&b, "keep_settings", cwmp_ctx.conf.fw_upgrade_keep_settings); + bb_add_string(&b, "path", path); + void *tbl = blobmsg_open_table(&b, "input"); + bb_add_string(&b, "URL", url); + blobmsg_close_table(&b, tbl); - e = icwmp_ubus_invoke("fwbank", "upgrade", b.head, NULL, NULL); + e = icwmp_ubus_invoke_timeout(BBFDM_OBJECT_NAME, "operate", b.head, fw_upgrade_callback, &fault_code, 120000); blob_buf_free(&b); - if (e != 0) { - CWMP_LOG(INFO, "fwbank upgrade ubus method failed: Ubus err code: %d", e); + if (e != 0 || CWMP_STRLEN(fault_code) != 0) { + CWMP_LOG(INFO, "fwbank upgrade ubus method failed: Ubus err code: %d, fault code: %s", e, fault_code ? fault_code : ""); + FREE(fault_code); return -2; } - //wait until the apply completes - wait_firmware_to_be_applied(bank_id); //set /var/state 'switch_bank' option set_uci_path_value(VARSTATE_CONFIG, "icwmp.cpe.switch_bank", "1"); diff --git a/src/ubus_utils.c b/src/ubus_utils.c index 1ead5b4..4cff52f 100644 --- a/src/ubus_utils.c +++ b/src/ubus_utils.c @@ -23,6 +23,7 @@ typedef int (*callback)(struct blob_buf *b); static bool g_bbf_object_available = false; static struct ubus_context *ubus_ctx = NULL; struct uloop_timeout u_timeout; +static int ubus_timeout = DEFAULT_UBUS_TIMEOUT; static int icwmp_register_object(struct ubus_context *ctx); @@ -468,13 +469,28 @@ int icwmp_ubus_invoke(const char *obj, const char *method, struct blob_attr *msg } if (!ubus_lookup_id(ubus_ctx, obj, &id)) - rc = ubus_invoke(ubus_ctx, id, method, msg, icwmp_callback, callback_arg, 60000); + rc = ubus_invoke(ubus_ctx, id, method, msg, icwmp_callback, callback_arg, ubus_timeout); else rc = -1; return rc; } +int icwmp_ubus_invoke_timeout(const char *obj, const char *method, struct blob_attr *msg, + icwmp_ubus_cb icwmp_callback, void *callback_arg, int timeout) +{ + int rc = 0; + + if (timeout > DEFAULT_UBUS_TIMEOUT) + ubus_timeout = timeout; + + rc = icwmp_ubus_invoke(obj, method, msg, icwmp_callback, callback_arg); + + ubus_timeout = DEFAULT_UBUS_TIMEOUT; + + return rc; +} + int icwmp_ubus_invoke_async(const char *obj, const char *method, struct blob_attr *msg, icwmp_ubus_cb data_callback, icwmp_ubus_async_cb complete_callback) { diff --git a/src/ubus_utils.h b/src/ubus_utils.h index d28b1a2..a69721a 100644 --- a/src/ubus_utils.h +++ b/src/ubus_utils.h @@ -19,6 +19,8 @@ typedef void (*icwmp_ubus_async_cb)(struct ubus_request *req, int ret); void bb_add_string(struct blob_buf *bb, const char *name, const char *value); int icwmp_ubus_invoke(const char *obj, const char *method, struct blob_attr *msg, icwmp_ubus_cb icwmp_callback, void *callback_arg); +int icwmp_ubus_invoke_timeout(const char *obj, const char *method, struct blob_attr *msg, + icwmp_ubus_cb icwmp_callback, void *callback_arg, int timeout); int icwmp_ubus_invoke_async(const char *obj, const char *method, struct blob_attr *msg, icwmp_ubus_cb data_callback, icwmp_ubus_async_cb complete_callback); int icwmp_uloop_ubus_register(void);