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)