diff --git a/docs/api/uci/cwmp.md b/docs/api/uci/cwmp.md index 4ecbd05..737d881 100644 --- a/docs/api/uci/cwmp.md +++ b/docs/api/uci/cwmp.md @@ -435,6 +435,15 @@
If set to 1, icwmp will keep the uci setting while doing firmware upgrade using Download RPC with '1 Firmware Upgrade Image'.
+ +
clock_sync_timeout
+
integer
+
no
+
128
+ +
The maximum time in seconds, icwmp should wait for the system clock to be synchronized with the time source before sending the initial inform message. Valid range is 0-180 seconds.
+ + diff --git a/src/common.h b/src/common.h index 67598ea..17d9d43 100644 --- a/src/common.h +++ b/src/common.h @@ -64,6 +64,7 @@ #define DEFAULT_INSTANCE_MODE 0 #define DEFAULT_SESSION_TIMEOUT 60 #define MAX_NBRE_SERVICES 256 +#define DEFAULT_SYNC_TIMEOUT 128 #define BUF_SIZE_8 (8 + 1) #define BUF_SIZE_16 (16 + 1) @@ -156,6 +157,7 @@ typedef struct config { unsigned int session_timeout; bool http_disable_100continue; int cr_timeout; + int clock_sync_timeout; bool force_ipv4; bool fw_upgrade_keep_settings; } config; diff --git a/src/cwmp.c b/src/cwmp.c index 2a99296..bc87a8e 100644 --- a/src/cwmp.c +++ b/src/cwmp.c @@ -215,6 +215,42 @@ end: return 0; } +static void wait_for_time_sync(void) +{ + struct cwmp_dm_parameter cwmp_dm_param = {0}; + + int loop_count = (cwmp_main->conf.clock_sync_timeout / 2); + + if (loop_count == 0) + return; + + while (loop_count) { + sleep(2); + + if (!cwmp_get_parameter_value("Device.Time.Status", &cwmp_dm_param)) { + CWMP_LOG(ERROR, "Failed to get TimeSync status"); + return; + } + + if (CWMP_STRCMP(cwmp_dm_param.value, "Disabled") == 0) { + CWMP_LOG(INFO, "TimeSync is disabled no need to wait more"); + return; + } + + if (CWMP_STRCMP(cwmp_dm_param.value, "Synchronized") != 0) { + CWMP_LOG(DEBUG, "Clock is unsynchronized, wait before sending inform"); + loop_count--; + continue; + } + + CWMP_LOG(INFO, "Clock is synchronized, ready to send inform"); + return; + } + + CWMP_LOG(ERROR, "Timeout occurred before clock sync or cwmp stopped"); + return; +} + static int cwmp_init(void) { openlog("cwmp", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1); @@ -250,6 +286,8 @@ static int cwmp_init(void) cwmp_config_load(); CWMP_LOG(DEBUG, "Successfully load icwmpd configuration"); + wait_for_time_sync(); + cwmp_main->prev_periodic_enable = cwmp_main->conf.periodic_enable; cwmp_main->prev_periodic_interval = cwmp_main->conf.period; cwmp_main->prev_periodic_time = cwmp_main->conf.time; diff --git a/src/uci_utils.c b/src/uci_utils.c index 4eb1f96..a5b64a4 100644 --- a/src/uci_utils.c +++ b/src/uci_utils.c @@ -238,6 +238,7 @@ static void config_get_cpe_elements(struct uci_section *s) UCI_CPE_FORCE_IPV4, UCI_CPE_KEEP_SETTINGS, UCI_CPE_DEFAULT_WAN_IFACE, + UCI_CPE_CLOCK_SYNC_TIMEOUT, __MAX_NUM_UCI_CPE_ATTRS, }; @@ -259,7 +260,8 @@ static void config_get_cpe_elements(struct uci_section *s) [UCI_CPE_CON_REQ_TIMEOUT] = { .name = "cr_timeout", .type = UCI_TYPE_STRING }, [UCI_CPE_FORCE_IPV4] = { .name = "force_ipv4", .type = UCI_TYPE_STRING }, [UCI_CPE_KEEP_SETTINGS] = { .name = "fw_upgrade_keep_settings", .type = UCI_TYPE_STRING }, - [UCI_CPE_DEFAULT_WAN_IFACE] = { .name = "default_wan_interface", .type = UCI_TYPE_STRING } + [UCI_CPE_DEFAULT_WAN_IFACE] = { .name = "default_wan_interface", .type = UCI_TYPE_STRING }, + [UCI_CPE_CLOCK_SYNC_TIMEOUT] = { .name = "clock_sync_timeout", .type = UCI_TYPE_STRING } }; struct uci_option *cpe_tb[__MAX_NUM_UCI_CPE_ATTRS]; @@ -377,6 +379,17 @@ static void config_get_cpe_elements(struct uci_section *s) memset(cwmp_main->net.interface, 0, sizeof(cwmp_main->net.interface)); } CWMP_LOG(DEBUG, "CWMP CONFIG - cpe default_wan_interface: %s", cwmp_main->conf.default_wan_iface); + + cwmp_main->conf.clock_sync_timeout = DEFAULT_SYNC_TIMEOUT; + char *sync_time = get_value_from_uci_option(cpe_tb[UCI_CPE_CLOCK_SYNC_TIMEOUT]); + if (CWMP_STRLEN(sync_time) != 0) { + int val = atoi(sync_time); + if (val >= 0 && val <= 180) { + cwmp_main->conf.clock_sync_timeout = val; + } + } + + CWMP_LOG(DEBUG, "CWMP CONFIG - cpe clock_sync_timeout: %d", cwmp_main->conf.clock_sync_timeout); } static void config_get_lwn_elements(struct uci_section *s)