@@ -126,18 +126,31 @@ enum ntpc_daemon_e
126126 NTP_STOPPED
127127};
128128
129+ enum ntpc_server_source_e
130+ {
131+ NTP_SERVER_SOURCE_NONE = 0 ,
132+ NTP_SERVER_SOURCE_CONFIG ,
133+ NTP_SERVER_SOURCE_DHCP ,
134+ NTP_SERVER_SOURCE_EXPLICIT
135+ };
136+
129137/* This type describes the state of the NTP client daemon. Only one
130138 * instance of the NTP daemon is permitted in this implementation.
131139 */
132140
133141struct ntpc_daemon_s
134142{
135- uint8_t state ; /* See enum ntpc_daemon_e */
136- sem_t lock ; /* Used to protect the whole structure */
137- sem_t sync ; /* Used to synchronize start and stop events */
138- pid_t pid ; /* Task ID of the NTP daemon */
139- sq_queue_t kod_list ; /* KoD excluded server addresses */
140- int family ; /* Allowed address family */
143+ uint8_t state ; /* See enum ntpc_daemon_e */
144+ uint8_t source ; /* See enum ntpc_server_source_e */
145+ sem_t lock ; /* Used to protect the whole structure */
146+ sem_t sync ; /* Used to synchronize start and stop events */
147+ pid_t pid ; /* Task ID of the NTP daemon */
148+ sq_queue_t kod_list ; /* KoD excluded server addresses */
149+ int family ; /* Allowed address family */
150+
151+ /* DHCP-provided server list */
152+
153+ FAR char * dhcp_servers ;
141154};
142155
143156union ntp_addr_u
@@ -194,11 +207,13 @@ struct ntp_kod_exclude_s
194207static struct ntpc_daemon_s g_ntpc_daemon =
195208{
196209 NTP_NOT_RUNNING ,
210+ NTP_SERVER_SOURCE_NONE ,
197211 SEM_INITIALIZER (1 ),
198212 SEM_INITIALIZER (0 ),
199213 -1 ,
200214 { NULL , NULL },
201215 AF_UNSPEC , /* Default is both IPv4 and IPv6 */
216+ NULL ,
202217};
203218
204219static struct ntp_sample_s g_last_samples
@@ -209,6 +224,73 @@ unsigned int g_last_nsamples = 0;
209224 * Private Functions
210225 ****************************************************************************/
211226
227+ static int ntpc_daemon (int argc , FAR char * * argv );
228+
229+ static FAR char * ntpc_dup_server_list (FAR const char * ntp_server_list )
230+ {
231+ if (ntp_server_list == NULL || ntp_server_list [0 ] == '\0' )
232+ {
233+ return NULL ;
234+ }
235+
236+ return strdup (ntp_server_list );
237+ }
238+
239+ static FAR const char * ntpc_select_server_list (FAR uint8_t * source )
240+ {
241+ if (CONFIG_NETUTILS_NTPCLIENT_SERVER [0 ] != '\0' )
242+ {
243+ * source = NTP_SERVER_SOURCE_CONFIG ;
244+ return CONFIG_NETUTILS_NTPCLIENT_SERVER ;
245+ }
246+
247+ if (g_ntpc_daemon .dhcp_servers != NULL &&
248+ g_ntpc_daemon .dhcp_servers [0 ] != '\0' )
249+ {
250+ * source = NTP_SERVER_SOURCE_DHCP ;
251+ return g_ntpc_daemon .dhcp_servers ;
252+ }
253+
254+ * source = NTP_SERVER_SOURCE_NONE ;
255+ return NULL ;
256+ }
257+
258+ static int ntpc_start_selected (FAR const char * ntp_server_list ,
259+ uint8_t source )
260+ {
261+ FAR char * task_argv [] =
262+ {
263+ (FAR char * )ntp_server_list ,
264+ NULL
265+ };
266+
267+ g_ntpc_daemon .state = NTP_STARTED ;
268+ g_ntpc_daemon .source = source ;
269+ g_ntpc_daemon .pid =
270+ task_create ("NTP daemon" , CONFIG_NETUTILS_NTPCLIENT_SERVERPRIO ,
271+ CONFIG_NETUTILS_NTPCLIENT_STACKSIZE , ntpc_daemon ,
272+ task_argv );
273+
274+ if (g_ntpc_daemon .pid < 0 )
275+ {
276+ int errval = errno ;
277+ DEBUGASSERT (errval > 0 );
278+
279+ g_ntpc_daemon .state = NTP_STOPPED ;
280+ g_ntpc_daemon .source = NTP_SERVER_SOURCE_NONE ;
281+ nerr ("ERROR: Failed to start the NTP daemon: %d\n" , errval );
282+ return - errval ;
283+ }
284+
285+ do
286+ {
287+ sem_wait (& g_ntpc_daemon .sync );
288+ }
289+ while (g_ntpc_daemon .state == NTP_STARTED );
290+
291+ return g_ntpc_daemon .pid ;
292+ }
293+
212294/****************************************************************************
213295 * Name: sample_cmp
214296 ****************************************************************************/
@@ -1490,46 +1572,23 @@ void ntpc_dualstack_family(int family)
14901572
14911573int ntpc_start_with_list (FAR const char * ntp_server_list )
14921574{
1493- FAR char * task_argv [] =
1575+ int ret ;
1576+
1577+ if (ntp_server_list == NULL || ntp_server_list [0 ] == '\0' )
14941578 {
1495- (FAR char * )ntp_server_list ,
1496- NULL
1497- };
1579+ return - EINVAL ;
1580+ }
14981581
14991582 /* Is the NTP in a non-running state? */
15001583
15011584 sem_wait (& g_ntpc_daemon .lock );
15021585 if (g_ntpc_daemon .state == NTP_NOT_RUNNING ||
15031586 g_ntpc_daemon .state == NTP_STOPPED )
15041587 {
1505- /* Start the NTP daemon */
1506-
1507- g_ntpc_daemon .state = NTP_STARTED ;
1508- g_ntpc_daemon .pid =
1509- task_create ("NTP daemon" , CONFIG_NETUTILS_NTPCLIENT_SERVERPRIO ,
1510- CONFIG_NETUTILS_NTPCLIENT_STACKSIZE , ntpc_daemon ,
1511- task_argv );
1512-
1513- /* Handle failures to start the NTP daemon */
1514-
1515- if (g_ntpc_daemon .pid < 0 )
1516- {
1517- int errval = errno ;
1518- DEBUGASSERT (errval > 0 );
1519-
1520- g_ntpc_daemon .state = NTP_STOPPED ;
1521- nerr ("ERROR: Failed to start the NTP daemon: %d\n" , errval );
1522- sem_post (& g_ntpc_daemon .lock );
1523- return - errval ;
1524- }
1525-
1526- /* Wait for any daemon state change */
1527-
1528- do
1529- {
1530- sem_wait (& g_ntpc_daemon .sync );
1531- }
1532- while (g_ntpc_daemon .state == NTP_STARTED );
1588+ ret = ntpc_start_selected (ntp_server_list ,
1589+ NTP_SERVER_SOURCE_EXPLICIT );
1590+ sem_post (& g_ntpc_daemon .lock );
1591+ return ret ;
15331592 }
15341593
15351594 sem_post (& g_ntpc_daemon .lock );
@@ -1550,7 +1609,79 @@ int ntpc_start_with_list(FAR const char *ntp_server_list)
15501609
15511610int ntpc_start (void )
15521611{
1553- return ntpc_start_with_list (CONFIG_NETUTILS_NTPCLIENT_SERVER );
1612+ FAR const char * ntp_server_list ;
1613+ uint8_t source ;
1614+ int ret ;
1615+
1616+ sem_wait (& g_ntpc_daemon .lock );
1617+ if (g_ntpc_daemon .state != NTP_NOT_RUNNING &&
1618+ g_ntpc_daemon .state != NTP_STOPPED )
1619+ {
1620+ ret = g_ntpc_daemon .pid ;
1621+ sem_post (& g_ntpc_daemon .lock );
1622+ return ret ;
1623+ }
1624+
1625+ ntp_server_list = ntpc_select_server_list (& source );
1626+ if (ntp_server_list == NULL )
1627+ {
1628+ sem_post (& g_ntpc_daemon .lock );
1629+ return - ENOENT ;
1630+ }
1631+
1632+ ret = ntpc_start_selected (ntp_server_list , source );
1633+ sem_post (& g_ntpc_daemon .lock );
1634+ return ret ;
1635+ }
1636+
1637+ int ntpc_set_dhcp_servers (FAR const char * ntp_server_list )
1638+ {
1639+ FAR char * new_servers ;
1640+ FAR char * old_servers ;
1641+ bool restart = false;
1642+ int ret = OK ;
1643+
1644+ new_servers = ntpc_dup_server_list (ntp_server_list );
1645+ if (ntp_server_list != NULL && ntp_server_list [0 ] != '\0' &&
1646+ new_servers == NULL )
1647+ {
1648+ return - ENOMEM ;
1649+ }
1650+
1651+ sem_wait (& g_ntpc_daemon .lock );
1652+
1653+ if ((g_ntpc_daemon .dhcp_servers == NULL && new_servers == NULL ) ||
1654+ (g_ntpc_daemon .dhcp_servers != NULL && new_servers != NULL &&
1655+ strcmp (g_ntpc_daemon .dhcp_servers , new_servers ) == 0 ))
1656+ {
1657+ sem_post (& g_ntpc_daemon .lock );
1658+ free (new_servers );
1659+ return OK ;
1660+ }
1661+
1662+ old_servers = g_ntpc_daemon .dhcp_servers ;
1663+ g_ntpc_daemon .dhcp_servers = new_servers ;
1664+
1665+ if (g_ntpc_daemon .source == NTP_SERVER_SOURCE_DHCP &&
1666+ (g_ntpc_daemon .state == NTP_STARTED ||
1667+ g_ntpc_daemon .state == NTP_RUNNING ))
1668+ {
1669+ restart = true;
1670+ }
1671+
1672+ sem_post (& g_ntpc_daemon .lock );
1673+ free (old_servers );
1674+
1675+ if (restart )
1676+ {
1677+ ret = ntpc_stop ();
1678+ if (ret >= 0 && new_servers != NULL )
1679+ {
1680+ ret = ntpc_start ();
1681+ }
1682+ }
1683+
1684+ return ret ;
15541685}
15551686
15561687/****************************************************************************
0 commit comments