Mercurial > flash_v2
changeset 1323:16a975af0355
* src/sntp.c: Added DHCP support for SNTP unicast mode.
* src/sntp.cdl: Added DHCP support for SNTP unicast mode.
* src/sntp.h: Removed UDP port constant.
* src/sntp1.c: Added test code for SNTP unicast mode.
* src/sntp.sgml: Added documentation for SNTP unicast mode.
| author | asl |
|---|---|
| date | Tue, 21 Oct 2003 17:51:51 +0000 |
| parents | 69a4719c04ad |
| children | f5a5cdd6afe0 |
| files | packages/net/sntp/current/ChangeLog packages/net/sntp/current/cdl/sntp.cdl packages/net/sntp/current/doc/sntp.sgml packages/net/sntp/current/include/sntp.h packages/net/sntp/current/src/sntp.c packages/net/sntp/current/tests/sntp1.c |
| diffstat | 6 files changed, 204 insertions(+), 57 deletions(-) [+] |
line wrap: on
line diff
--- a/packages/net/sntp/current/ChangeLog +++ b/packages/net/sntp/current/ChangeLog @@ -1,3 +1,12 @@ +2003-10-15 Dan Jakubiec <djakubiec@yahoo.com> + Andrew Lunn <andrew.lunn@ascom.ch> + + * src/sntp.c: Added DHCP support for SNTP unicast mode. + * src/sntp.cdl: Added DHCP support for SNTP unicast mode. + * src/sntp.h: Removed UDP port constant. + * src/sntp1.c: Added test code for SNTP unicast mode. + * src/sntp.sgml: Added documentation for SNTP unicast mode. + 2003-09-29 Dan Jakubiec <firstname.lastname@systech.com> * src/sntp.c: Added support for SNTP unicast mode.
--- a/packages/net/sntp/current/cdl/sntp.cdl +++ b/packages/net/sntp/current/cdl/sntp.cdl @@ -62,22 +62,35 @@ cdl_package CYGPKG_NET_SNTP { requires CYGSEM_LIBC_TIME_SETTIME_WORKING compile sntp.c + cdl_component CYGPKG_NET_SNTP_UNICAST { + display "Enable SNTP client unicast support" + flavor bool + default_value 0 + description " + This option enables SNTP unicast mode in + for the SNTP client. This mode will send + SNTP requests to NTP/SNTP servers in + addition to listening for SNTP broadcasts." + + cdl_option CYGNUM_NET_SNTP_UNICAST_MAXDHCP { + display "Maximum number of NTP servers to use from DHCP" + flavor booldata + requires CYGPKG_NET_DHCP + legal_values 1 to 8 + default_value 2 + description " + This option specifies the maximum number of + NTP servers to get from DHCP. These servers + are used to configure the unicast SNTP client. + Disabling this option disables DHCP usage." + } + } + cdl_component CYGPKG_NET_SNTP_OPTIONS { display "SNTP support build options" flavor none no_define - cdl_option CYGPKG_NET_SNTP_UNICAST { - display "Enable SNTP client unicast support" - flavor bool - default_value 0 - description " - This option enables SNTP unicast mode in - for the SNTP client. This mode will send - SNTP requests to NTP/SNTP servers in - addition to listening for SNTP broadcasts." - } - cdl_option CYGPKG_NET_SNTP_CFLAGS_ADD { display "Additional compiler flags" flavor data
--- a/packages/net/sntp/current/doc/sntp.sgml +++ b/packages/net/sntp/current/doc/sntp.sgml @@ -36,7 +36,8 @@ The SNTP package provides implementation of a client for RFC 2030, the Simple Network Time Protocol (SNTP). The client listens for broadcasts or IPv6 multicasts from an NTP server and uses the information received to -set the system clock. +set the system clock. It can also be configured to send SNTP time +requests to specific NTP servers using SNTP's unicast mode. </PARA> </PARTINTRO> <CHAPTER id="net-sntp"> @@ -45,16 +46,20 @@ set the system clock. <TITLE>Starting the SNTP client</TITLE> <para> The sntp client is implemented as a thread which listens for NTP -broadcasts and IPv6 multicasts. This thread is not automatically start by the -system. Instead it must be started by the user application. The header -file <filename>cyg/sntp/sntp.h</filename> declares the function to be +broadcasts and IPv6 multicasts, and optionally sends SNTP unicast +requests to specific NTP servers. This thread may be automatically +started by the system if it receives a list of (S)NTP servers from the +DHCP server and unicast mode is enabled. Otherwise it must be started +by the user application. The header file +<filename>cyg/sntp/sntp.h</filename> declares the function to be called. The thread is then started by calling the function: </para> <programlisting> void cyg_sntp_start(void); </programlisting> <para> -Once started, the thread will run forever. +It is safe to call this function multiple times. Once started, the +thread will run forever. </para> </sect1> @@ -62,8 +67,8 @@ Once started, the thread will run foreve <title>What it does</title> <para> The SNTP client listens for NTP IPv4 broadcasts from any NTP servers, -or IPv6 multicasts using the address fe0x:0X::101, where X can be 1 -(Node Local), 2 (Link Local), 5 (Site-Local) or 0xe (Global). Such +or IPv6 multicasts using the address fe0x:0X::101, where X can be +2 (Link Local), 5 (Site-Local) or 0xe (Global). Such packets contain a timestamp indicating the current time. The packet also contains information about where the server is in the hierarchy of time servers. A server at the root of the time server tree normally @@ -73,8 +78,19 @@ stratum 1 etc. The client will accept an servers using version 3 or 4 of the protocol. When receiving packets from multiple servers, it will use the packets from the server with the lowest stratum. However, if there are no packets from this server -for 10 minute and another server is sending packets, the client will -change server. +for 10 minutes and another server is sending packets, the client will +change servers. +</para> +<para> +If SNTP unicast mode is enabled via the CYGPKG_NET_SNTP_UNICAST +option, the SNTP client can additionally be configured with a list +of specific NTP servers to query. The general algorithm is as follows: if +the system clock has not yet been set via an NTP time update, then +the client will send out NTP requests every 30 seconds to all +configured NTP servers. Once an NTP time update has been received, +the client will send out additional NTP requests every 30 minutes +in order to update the system clock. These requests are resent +every 30 seconds until a response is received. </para> <para> The system clock in eCos is accurate to 1 second. The SNTP client will @@ -83,6 +99,53 @@ timestamp is greater than 2 seconds. The </para> </sect1> +<sect1 id="net-sntp-unicast"> +<title>Configuring the unicast list of NTP servers</title> +<para> +If SNTP unicast mode is enabled via the CYGPKG_NET_SNTP_UNICAST +option, the SNTP client can be configured with a list of +NTP servers to contact for time updates. +</para> +<para> +By default, this list is configured with NTP server information +received from DHCP. The number of NTP servers that are extracted +from DHCP can be configured with the CYGOPT_NET_SNTP_UNICAST_MAXDHCP +option. This option can also be used to disable DHCP usage entirely. +</para> +<para> +The list of NTP servers can be manually configured with the following +API function. Note that manual configuration will override any +servers that were automatically configured by DHCP. But later +reconfigurations by DHCP will override manual configurations. Hence it +is not recommended to manually configure servers when +CYGOPT_NET_SNTP_UNICAST is enabled. +</para> +<programlisting> +#include <cyg/sntp/sntp.h> + +void cyg_sntp_set_servers(struct sockaddr *server_list, cyg_uint32 num_servers); +</programlisting> +<para> +This function takes an array of sockaddr structures specifying the +IP address and UDP port of each NTP server to query. Currently, +both IPv4 and IPv6 sockaddr structures are supported. The +num_servers argument specifies how many sockaddr's are contained +in the array. The server_list array must be maintained by the caller. +Once the array is registered with this function, it must not be +modified by the caller until it is replaced or unregistered +by another call to this function. +</para> +<para> +Calling this function with a server_list of NULL and a num_servers +value of 0 unregisters any previously configured server_list array. +</para> +<para> +Finally, note that if this function is called with a non-empty server +list, it will implicitly start the SNTP client if it has not already +been started (i.e. it will call cyg_sntp_start()). +</para> +</sect1> + <sect1 id="net-sntp-warning"> <title>Warning: timestamp wrap around</title> <para> @@ -90,7 +153,7 @@ The timestamp in the NTP packet is a 32b the number of seconds after 00:00 01/01/1900. This 32bit number will wrap around at 06:28:16 Feb 7 2036. At this point in time, the eCos time will jump back to around 00:00:00 Jan 1 1900 when the next -NTP packett is received. +NTP packet is received. </para> <para> YOU HAVE BEEN WARNED! @@ -129,6 +192,16 @@ check the build date for the test. This else fails check that the computer used to build the test has the correct time. </para> +<para> +If SNTP unicast mode is enabled, the above tests are run twice. The +first time, the SNTP client is configured with NTP server addresses +from DHCP. The second time, unicast mode is disabled and only +multicasts are listened for. Note that the unicast test is partially +bogus in the sense that any multicast packet received will also make +the unicast test pass. To reduce the chance of this happening the +test will wait for a sorter time for replies. This is not ideal, but +it is the best that can be done with an automated test. +</para> </SECT1> </CHAPTER> -</PART> \ No newline at end of file +</PART>
--- a/packages/net/sntp/current/include/sntp.h +++ b/packages/net/sntp/current/include/sntp.h @@ -53,9 +53,6 @@ #include <pkgconf/net_sntp.h> #include <cyg/infra/cyg_type.h> -/* General Definitions */ -#define NTP_UDP_PORT 123 - // Multicast address used by IPv6 #define IN6ADDR_NTP_MULTICAST \ {{{ 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
--- a/packages/net/sntp/current/src/sntp.c +++ b/packages/net/sntp/current/src/sntp.c @@ -480,7 +480,6 @@ void cyg_sntp_start(void) { } #ifdef CYGPKG_NET_SNTP_UNICAST - /* * FUNCTION cyg_sntp_set_servers * @@ -497,8 +496,10 @@ void cyg_sntp_start(void) { * array can be unregistered by calling this * function again with different parameters. * - * NOTE: This function must be called AFTER - * cyg_sntp_start(). + * NOTE: If cyg_sntp_start() has not been called + * already, and this function is called with a + * list of 1 or more servers, then cyg_sntp_start() + * will be called by this function to start the client. * * PARAMETERS * server_list - Array of IPv4 and/or IPv6 sockaddr's @@ -510,9 +511,21 @@ void cyg_sntp_start(void) { void cyg_sntp_set_servers(struct sockaddr *server_list, cyg_uint32 num_servers) { - /* Get the server list mutex */ + /* If we haven't already started the SNTP client, then + * start it now. + */ if (!sntp_initialized) - return; + { + /* If we haven't started already and we don't + * have a list of servers, then don't start + * anything up. + */ + if (num_servers == 0) + return; + cyg_sntp_start(); + } + + /* Get the server list mutex */ cyg_mutex_lock(&sntp_mutex); /* Record the new server list */ @@ -526,3 +539,6 @@ void cyg_sntp_set_servers(struct sockadd } #endif /* CYGPKG_NET_SNTP_UNICAST */ + + +
--- a/packages/net/sntp/current/tests/sntp1.c +++ b/packages/net/sntp/current/tests/sntp1.c @@ -66,7 +66,7 @@ net_test(cyg_addrword_t param) int seconds; time_t now, build_time; struct tm tm={ 0,0,0,0,0,0,0,0,0 }; - int i; + int i, loop, waittime; char month[4]; char months[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", @@ -82,39 +82,78 @@ net_test(cyg_addrword_t param) cyg_sntp_start(); - for (seconds = 20; seconds > 0; seconds--) { + /* The SNTP client will try to obtain NTP time updates by + * listening for multicasts. It can also be configured + * to send unicast requests to specific NTP servers. By + * default, unicast NTP servers are obtained from DHCP. + * + * If unicast mode is enabled, the run the test loop twice. + * The first time, unicast requests will be sent. The + * second time, the unicast list will be unconfigured and + * the client will listen only for multicasts. + * + * Note that this test is somewhat bogus since multicast + * NTP packets will actually allow both test loops to + * pass. But it is the best we can do for the automated + * test, so consider this more of a usage example. + */ +#ifdef CYGPKG_NET_SNTP_UNICAST + loop = 2; +#else + loop = 1; +#endif + while (loop-- > 0) + { + if (loop == 1) { + CYG_TEST_INFO("Testing SNTP unicast mode."); + waittime=14; + } else { + CYG_TEST_INFO("Testing SNTP multicast mode."); + waittime=20; + } + for (seconds = waittime; seconds > 0; seconds--) { + now = time(NULL); + ctime_r(&now, time_info); + time_info[strlen(time_info)-1] = '\0'; // Strip \n + CYG_TEST_INFO(time_info); + cyg_thread_delay(100); + } + now = time(NULL); - ctime_r(&now, time_info); - time_info[strlen(time_info)-1] = '\0'; // Strip \n - CYG_TEST_INFO(time_info); - cyg_thread_delay(100); - } - - now = time(NULL); - if ( now < (5 * 60)) { - CYG_TEST_FAIL_FINISH("Nothing recieved from the SNTP server"); - } else { + if ( now < (5 * 60)) { + CYG_TEST_FAIL_FINISH("Nothing recieved from the SNTP server"); + } else { - i=sscanf(__DATE__, "%s %d %d",month,&tm.tm_mday,&tm.tm_year); - CYG_ASSERT(3==i,"sscanf did not return enough results"); - for (i=0; i < 12; i++) { - if (!strcmp(month,months[i])) - break; - } - tm.tm_mon = i; - tm.tm_year -= 1900; + i=sscanf(__DATE__, "%s %d %d",month,&tm.tm_mday,&tm.tm_year); + CYG_ASSERT(3==i,"sscanf did not return enough results"); + for (i=0; i < 12; i++) { + if (!strcmp(month,months[i])) + break; + } + tm.tm_mon = i; + tm.tm_year -= 1900; - build_time = mktime(&tm); - CYG_ASSERT(-1 != build_time,"mktime returned -1"); + build_time = mktime(&tm); + CYG_ASSERT(-1 != build_time,"mktime returned -1"); - if (build_time > time(NULL)) { - CYG_TEST_FAIL_FINISH("Build time is ahead of SNTP time"); - } else { - if ((build_time + 60 * 60 * 24 * 90) < time(NULL)) { - CYG_TEST_FAIL_FINISH("Build time is more than 90 days old"); + if (build_time > time(NULL)) { + CYG_TEST_FAIL_FINISH("Build time is ahead of SNTP time"); + } else { + if ((build_time + 60 * 60 * 24 * 90) < time(NULL)) { + CYG_TEST_FAIL_FINISH("Build time is more than 90 days old"); + } } } + +#ifdef CYGPKG_NET_SNTP_UNICAST + /* For the second pass of the test, we set the time + * back to epoch and unconfigure the list of SNTP + * unicast servers. This will test non-unicast mode. + */ + cyg_sntp_set_servers(NULL, 0); + cyg_libc_time_settime(0); +#endif } CYG_TEST_PASS_FINISH("sntp1 test is complete"); }
