summaryrefslogtreecommitdiff
path: root/ecos/packages/net/sntp
diff options
context:
space:
mode:
authorMichael Gielda <mgielda@antmicro.com>2014-04-03 14:53:04 +0200
committerMichael Gielda <mgielda@antmicro.com>2014-04-03 14:53:04 +0200
commitae1e4e08a1005a0c487f03ba189d7536e7fdcba6 (patch)
treef1c296f8a966a9a39876b0e98e16d9c5da1776dd /ecos/packages/net/sntp
parentf157da5337118d3c5cd464266796de4262ac9dbd (diff)
Added the OS files
Diffstat (limited to 'ecos/packages/net/sntp')
-rw-r--r--ecos/packages/net/sntp/current/ChangeLog96
-rw-r--r--ecos/packages/net/sntp/current/cdl/sntp.cdl126
-rwxr-xr-xecos/packages/net/sntp/current/doc/sntp.sgml205
-rw-r--r--ecos/packages/net/sntp/current/include/sntp.h68
-rw-r--r--ecos/packages/net/sntp/current/src/sntp.c548
-rw-r--r--ecos/packages/net/sntp/current/tests/sntp1.c188
6 files changed, 1231 insertions, 0 deletions
diff --git a/ecos/packages/net/sntp/current/ChangeLog b/ecos/packages/net/sntp/current/ChangeLog
new file mode 100644
index 0000000..92b8631
--- /dev/null
+++ b/ecos/packages/net/sntp/current/ChangeLog
@@ -0,0 +1,96 @@
+2009-03-09 John Dallaway <john@dallaway.org.uk>
+
+ * cdl/sntp.cdl: Reference test executable filenames for compatibility
+ with the eCos Configuration Tool.
+
+2006-11-08 Andre Mas <andrejohn.mas@gmail.com>
+
+ * src/sntp.c: Removed optional KeyIdentifer and MessageDigest
+ fields, which weren't being used, and caused certain servers
+ not to respond when these fields were included with null values.
+
+2005-07-30 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/sntp.c: Compiler warning fixes.
+
+2004-02-26 Yuxin Jiang <yjiang@matrics.com>
+
+ * src/sntp.c: When a new server is added to the list of unicast
+ servers don't wait 30 minutes before querying it for the first
+ time.
+
+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.
+ * src/sntp.h: Added support for SNTP unicast mode.
+ * src/sntp.cdl: Added support for SNTP unicast mode.
+
+2003-05-19 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/sntp.c: Added support for IPv6 multicast NTP packets.
+
+2003-04-09 Michael Checky <Michael_Checky@Thermoking.com>
+
+ * src/sntp.c: In function sntp_fn() changed 'version' to
+ 'new_srv.version' in the CYG_TRACE1() call.
+
+2003-02-25 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * include/sntp.h: Include <cyg/infra/cyg_type.h> for __externC.
+
+2003-02-25 Gary Thomas <gary@mlbassoc.com>
+
+ * tests/sntp1.c (net_test): Strip the trailing "\n" making it more
+ readable.
+
+2003-02-25 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * doc/sntp.sgml: Added license banner and added missing </para>
+ * include/sntp.h (cyg_sntp_start): C++ safe
+ * cdl/sntp.cdl: Stricture requirements and same description as in
+ ecos.db. Only build the test if CYGPKH_NET_BUILD_HW_TESTS
+ * tests/sntp1.c (net_test): Check we have the required
+ packages. Require the time to be within 90 days of the build
+ date of the test
+
+
+2003-02-16 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/sntp.c: First import of SNTP client code.
+ * include/sntp.c: Ditto
+ * test/sntp1.c: Ditto
+ * cdl/sntp.cdl: Ditto
+ * doc/sntp.sgml: Ditto
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/net/sntp/current/cdl/sntp.cdl b/ecos/packages/net/sntp/current/cdl/sntp.cdl
new file mode 100644
index 0000000..8d2ec7c
--- /dev/null
+++ b/ecos/packages/net/sntp/current/cdl/sntp.cdl
@@ -0,0 +1,126 @@
+# ====================================================================
+#
+# sntp.cdl
+#
+# Simple Network Time Protocol
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2003, 2009 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Andrew Lunn
+# Contributors:
+# Date: 2003-02-11
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_NET_SNTP {
+ display "Simple Network Time Protocol Client (SNTP)"
+ description "
+ This package provides a SNTP client which can recieve broadcast time
+ information and set the system clock."
+ doc ref/net-sntp.html
+ include_dir cyg/sntp
+
+ requires CYGPKG_NET
+ requires CYGPKG_LIBC_TIME
+ requires CYGSEM_LIBC_TIME_TIME_WORKING
+ 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_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the SNTP package.
+ These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_NET_SNTP_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the SNTP package. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+ cdl_option CYGPKG_NET_SNTP_TESTS {
+ display "sntp tests"
+ flavor data
+ no_define
+ calculated { CYGPKG_NET_BUILD_HW_TESTS ? "tests/sntp1" : "" }
+ }
+}
+
+# ====================================================================
+# EOF sntp.cdl
diff --git a/ecos/packages/net/sntp/current/doc/sntp.sgml b/ecos/packages/net/sntp/current/doc/sntp.sgml
new file mode 100755
index 0000000..d778b3e
--- /dev/null
+++ b/ecos/packages/net/sntp/current/doc/sntp.sgml
@@ -0,0 +1,205 @@
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- sntp.sgml -->
+<!-- -->
+<!-- Simple Network Time Protocol Client -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTBEGIN#### -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2003 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<PART ID="net-sntp-client">
+<TITLE>Simple Network Time Protocol Client</TITLE>
+<PARTINTRO>
+<PARA>
+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. 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">
+<TITLE>The SNTP Client</TITLE>
+<SECT1 id="sntp-starting">
+<TITLE>Starting the SNTP client</TITLE>
+<para>
+The sntp client is implemented as a thread which listens for NTP
+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>
+It is safe to call this function multiple times. Once started, the
+thread will run forever.
+</para>
+</sect1>
+
+<sect1 id="net-sntp-operation">
+<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
+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
+has an atomic clock. Such a server is said to be at stratum 0. A time
+server which is synchronised to a stratum 0 server is said to be at
+stratum 1 etc. The client will accept any NTP packets from
+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 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
+change the system clock when the time difference with the received
+timestamp is greater than 2 seconds. The change is made as a step.
+</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 &lt;cyg/sntp/sntp.h&gt;
+
+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>
+The timestamp in the NTP packet is a 32bit integer which represents
+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 packet is received.
+</para>
+<para>
+YOU HAVE BEEN WARNED!
+</para>
+</SECT1>
+<sect1 id="net-sntp-testing">
+<title>The SNTP test program</title>
+<para>
+The SNTP package contains a simple test program. Testing an SNTP
+client is not easy, so the test program should be considered as more a
+proof of concept. It shows that an NTP packet has been received,
+and is accurate to within a few days.
+</para>
+<para>
+The test program starts the network interfaces using the standard
+call. It then starts the SNTP thread. A loop is then entered printing
+the current system time every second for two minutes. When the client
+receives an NTP packet the time will jump from 1970 to hopefully the
+present day. Once the two minutes have expired, two simple tests are
+made. If the time is still less than 5 minutes since 00:00:00
+01/01/1970 the test fails. This indicates no NTP messages have
+been received. Check that the server is actually sending packet, using
+the correct port (123), correct IPv6 multicast address, and at a
+sufficiently frequent rate that the
+target has a chance to receive a message within the 2 minute
+interval. If all this is correct, assume the target is broken.
+</para>
+<para>
+The second test is that the current system time is compared with the
+build time as reported by the CPP macro __DATE__. If the build date is
+in the future relative to the system time, the test fails. If the
+build date is more than 90 days in the past relative to the system
+time the test also fails. If such failures are seen, use walk-clock
+time to verify the time printed during the test. If this seems correct
+check the build date for the test. This is printed at startup. If all
+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>
diff --git a/ecos/packages/net/sntp/current/include/sntp.h b/ecos/packages/net/sntp/current/include/sntp.h
new file mode 100644
index 0000000..66576a2
--- /dev/null
+++ b/ecos/packages/net/sntp/current/include/sntp.h
@@ -0,0 +1,68 @@
+#ifndef CYGONCE_SNTP_SNTP_H
+#define CYGONCE_SNTP_SNTP_H
+//=============================================================================
+//
+// sntp.h
+//
+// SNTP - Simple Network Time Protocol
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): andrew.lunn
+// Contributors:
+// Date: 2003-02-11
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/net_sntp.h>
+#include <cyg/infra/cyg_type.h>
+
+// Multicast address used by IPv6
+#define IN6ADDR_NTP_MULTICAST \
+ {{{ 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01 }}}
+
+/* Call this function to start the SNTP Client */
+__externC void
+cyg_sntp_start(void);
+
+#ifdef CYGPKG_NET_SNTP_UNICAST
+__externC void cyg_sntp_set_servers(struct sockaddr *server_list, cyg_uint32 num_servers);
+#endif
+
+#endif
diff --git a/ecos/packages/net/sntp/current/src/sntp.c b/ecos/packages/net/sntp/current/src/sntp.c
new file mode 100644
index 0000000..303a8fd
--- /dev/null
+++ b/ecos/packages/net/sntp/current/src/sntp.c
@@ -0,0 +1,548 @@
+//=============================================================================
+//
+// sntp.c
+//
+// Simple Network Time Protocol
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): andrew.lunn
+// Contributors:
+// Date: 2003-02-12
+// Description: Provides a Simple Network Time Protocol Client
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/net_sntp.h>
+#include <network.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/cyg_trac.h>
+#include <cyg/sntp/sntp.h>
+#include <time.h>
+
+/* NTP/SNTPv4 Packet Format (RFC2030) */
+typedef struct
+{
+ cyg_uint32 Seconds; /* Since 00:00:00 Jan 01 1900 */
+ cyg_uint32 Fraction;
+} NTP_TIMESTAMP;
+
+typedef struct
+{
+ /* Control combines LeapIndicator, Version, and Mode */
+ cyg_uint8 Control;
+ cyg_uint8 Stratum;
+ cyg_uint8 Poll;
+ cyg_uint8 Precision;
+
+ cyg_uint32 RootDelay;
+ cyg_uint32 RootDispersion;
+ cyg_uint32 ReferenceIdentifier;
+
+ NTP_TIMESTAMP ReferenceTimestamp;
+ NTP_TIMESTAMP OriginateTimestamp;
+ NTP_TIMESTAMP ReceiveTimestamp;
+ NTP_TIMESTAMP TransmitTimestamp;
+
+// cyg_uint32 KeyIdentifier; /* Optional */
+// cyg_uint8 MessageDigest[16]; /* Optional */
+} NTP_PACKET;
+#define NTP_PACKET_MINLEN 48 /* Packet size - optional fields */
+
+/* Leap Indicator Field [Bits 7:6] */
+#define NTP_LI_NOLEAP 0x00
+#define NTP_LI_61SECS 0x40
+#define NTP_LI_59SECS 0x80
+#define NTP_LI_ALARM 0xC0
+
+/* Version Field [Bits 5:3] */
+#define NTP_VERSION_GET(pkt) ((((pkt)->Control)>>3)&0x7)
+#define NTP_VERSION_SET(ver) (((ver)&0x7)<<3)
+
+/* Mode Field [Bits 2:0] */
+#define NTP_MODE_RESERVED 0
+#define NTP_MODE_SYMACTIVE 1 /* Symmetric Active */
+#define NTP_MODE_SYMPASSIVE 2 /* Symmetric Passive */
+#define NTP_MODE_CLIENT 3
+#define NTP_MODE_SERVER 4
+#define NTP_MODE_BROADCAST 5
+#define NTP_MODE_NTPCTRL 6 /* Reserved for NTP control message */
+#define NTP_MODE_PRIVATE 7 /* Reserved for private use */
+#define NTP_MODE_GET(pkt) (((pkt)->Control)&0x7)
+#define NTP_MODE_SET(mode) ((mode)&0x7)
+
+/* Time Base Conversion Macros
+ *
+ * The NTP timebase is 00:00 Jan 1 1900. The local
+ * time base is 00:00 Jan 1 1970. Convert between
+ * these two by added or substracting 70 years
+ * worth of time. Note that 17 of these years were
+ * leap years.
+ */
+#define TIME_BASEDIFF ((((cyg_uint32)70*365 + 17) * 24*3600))
+#define TIME_NTP_TO_LOCAL(t) ((t)-TIME_BASEDIFF)
+#define TIME_LOCAL_TO_NTP(t) ((t)+TIME_BASEDIFF)
+
+
+struct sntp_srv_s {
+ struct sockaddr addr;
+ int stratum;
+ int version;
+ cyg_uint32 timestamp;
+};
+static int sntp_initialized = 0;
+
+
+#ifdef CYGPKG_NET_SNTP_UNICAST
+/* When using SNTP unicast mode, sntp_servers
+ * points to an array of char pointers that
+ * specify NTP server addresses to send
+ * requests to. sntp_num_servers specifies
+ * the number of hostnames in the array.
+ */
+static struct sockaddr *sntp_servers = NULL;
+static cyg_uint32 sntp_num_servers = 0;
+static cyg_mutex_t sntp_mutex;
+static time_t NextTimeUpdate = 0;
+
+/* SNTP Timeouts
+ *
+ * SNTP_WAITPERIOD is the number of seconds to wait
+ * before retransmitting unanswered NTP requests
+ * whenever we are due for an update.
+ *
+ * SNTP_UPDATEPERIOD is the number of seconds to wait
+ * after we get a good time update before we feel
+ * like we should re-synchronize again with the
+ * time server.
+ */
+#define SNTP_WAITPERIOD 10 /* Wait period in seconds */
+#define SNTP_UPDATEPERIOD (30*60) /* Update period in seconds */
+
+#endif /* CYKPKG_NET_SNTP_UNICAST */
+
+#ifndef CYGNUM_SNTP_STACK_SIZE
+/* Use a stack size of at least CYGNUM_SNTP_STACK_SIZE_MIN, but not less than
+ * CYGNUM_HAL_STACK_SIZE_TYPICAL.
+ */
+#define CYGNUM_SNTP_STACK_SIZE_MIN 4096
+#if (CYGNUM_HAL_STACK_SIZE_TYPICAL < CYGNUM_SNTP_STACK_SIZE_MIN)
+#define CYGNUM_SNTP_STACK_SIZE CYGNUM_SNTP_STACK_SIZE_MIN
+#else
+#define CYGNUM_SNTP_STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+#endif
+#endif /* CYGNUM_SNTP_STACK_SIZE */
+
+/* Is the new server better than the current one? If its the same as
+ the current, its always better. If the stratum is lower its better.
+ If we have not heard from the old server for more than 10 minutes,
+ the new server is better. */
+
+static int is_better(struct sntp_srv_s *newer, struct sntp_srv_s *old) {
+
+ time_t last_time, diff;
+
+ if (!memcmp(&newer->addr, &old->addr, newer->addr.sa_len)) return 1;
+ if (newer->stratum < old->stratum) return 1;
+
+ if (old->timestamp != 0xffffffff) {
+ last_time = TIME_NTP_TO_LOCAL(old->timestamp);
+
+ diff = time(NULL) - last_time;
+ if (diff > 600) return 1;
+
+ return 0;
+ }
+ return 1;
+}
+
+const struct in6_addr in6addr_ntp_multicast = IN6ADDR_NTP_MULTICAST;
+
+static void sntp_fn(cyg_addrword_t data)
+{
+ int fd;
+ int ret;
+ struct sockaddr_in local;
+ struct servent *serv;
+ NTP_PACKET ntp_pkt;
+ struct sntp_srv_s new_srv;
+ struct sntp_srv_s best_srv;
+ int mode;
+ socklen_t len;
+ time_t new_time, current_time, diff;
+ fd_set readfds;
+ int n;
+#ifdef CYGPKG_NET_INET6
+ int fd6 = -1;
+ struct ipv6_mreq mreq;
+ struct sockaddr_in6 local6;
+#endif
+#ifdef CYGPKG_NET_SNTP_UNICAST
+ int i;
+ struct timeval timeout;
+#endif /* CYGPKG_NET_SNTP_UNICAST */
+ struct timeval *ptimeout = NULL;
+
+ memset(&best_srv,0xff,sizeof(best_srv));
+
+ fd = socket(AF_INET,SOCK_DGRAM,0);
+ CYG_ASSERT(-1 != fd,"Failed to open socket");
+
+ serv = getservbyname("ntp","udp");
+ CYG_ASSERT(serv,"getservbyname(sntp,udp)");
+
+ memset(&local,0,sizeof(local));
+ local.sin_family = AF_INET;
+ local.sin_len = sizeof(local);
+ local.sin_port = serv->s_port;
+ local.sin_addr.s_addr = INADDR_ANY;
+
+ ret=bind(fd,(struct sockaddr *)&local,sizeof(local));
+ CYG_ASSERT(0 == ret, "Bind failed");
+
+ n = fd;
+
+#ifdef CYGPKG_NET_INET6
+ fd6 = socket(AF_INET6, SOCK_DGRAM,0);
+ CYG_ASSERT(-1 != fd,"Failed to open socket");
+ mreq.ipv6mr_multiaddr = in6addr_ntp_multicast;
+ mreq.ipv6mr_interface = 0;
+
+ /* Join the well-known NTP multicast groups. We will
+ * try to join the link-local, site-local, and global
+ * unicast groups.
+ *
+ * Note that we skip the node-local group since it
+ * doesn't make any sense to join that group. If we
+ * had an NTP server running on the local node, we
+ * wouldn't need to have an NTP client get the time
+ * from it!
+ */
+#ifdef CYGHWR_NET_DRIVER_ETH0
+ // Link-Local
+ mreq.ipv6mr_multiaddr.s6_addr[1]=0x02;
+ mreq.ipv6mr_interface = if_nametoindex("eth0");
+ if (mreq.ipv6mr_interface != 0 ) {
+ ret = setsockopt(fd6, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq));
+ CYG_ASSERT(0 == ret, "setsockopt(IPV6_JOIN_GROUP) Link-Local eth0");
+ }
+#endif
+#ifdef CYGHWR_NET_DRIVER_ETH1
+ // Link-Local
+ mreq.ipv6mr_multiaddr.s6_addr[1]=0x02;
+ mreq.ipv6mr_interface = if_nametoindex("eth1");
+ if (mreq.ipv6mr_interface != 0 ) {
+ ret = setsockopt(fd6, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq));
+ CYG_ASSERT(0 == ret, "setsockopt(IPV6_JOIN_GROUP) Link-Local eth1");
+ }
+#endif
+
+ // Site-Local
+ mreq.ipv6mr_multiaddr.s6_addr[1]=0x05;
+ ret = setsockopt(fd6, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq));
+ CYG_ASSERT(0 == ret, "setsockopt(IPV6_JOIN_GROUP) Site-Local");
+
+ // Global
+ mreq.ipv6mr_multiaddr.s6_addr[1]=0x0e;
+ ret = setsockopt(fd6, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq));
+ CYG_ASSERT(0 == ret, "setsockopt(IPV6_JOIN_GROUP) Global");
+
+ memset(&local6,0,sizeof(local6));
+ local6.sin6_family = AF_INET6;
+ local6.sin6_len = sizeof(local6);
+ local6.sin6_port = serv->s_port;
+ local6.sin6_addr = in6addr_any;
+
+ ret = bind(fd6, (struct sockaddr *)&local6,sizeof(local6));
+ CYG_ASSERT(0 == ret, "Bind6 failed");
+
+ n = (n > fd6 ? n : fd6);
+#endif
+
+ while (1) {
+ FD_ZERO(&readfds);
+ FD_SET(fd,&readfds);
+#ifdef CYGPKG_NET_INET6
+ FD_SET(fd6,&readfds);
+#endif
+
+#ifdef CYGPKG_NET_SNTP_UNICAST
+ /* By default, we will let select() wait
+ * for SNTP_WAITPERIOD to receive a packet. This
+ * allows us to periodically wake up and check
+ * if new servers have been configured. However,
+ * if we are waiting to send an update request,
+ * we will set ptimeout to something more
+ * reasonable below.
+ */
+ timeout.tv_sec = SNTP_WAITPERIOD;
+ timeout.tv_usec = 0;
+ ptimeout = &timeout;
+
+ /* If we've already set the time, then
+ * check to see if it's time to try and
+ * update it.
+ */
+ if (NextTimeUpdate != 0)
+ {
+ current_time = time(NULL);
+ if (current_time < NextTimeUpdate)
+ {
+ /* Set the select() timeout to wake us
+ * up when it's time to send more
+ * requests.
+ */
+ timeout.tv_sec = (SNTP_WAITPERIOD > (NextTimeUpdate - current_time)?
+ (NextTimeUpdate - current_time):SNTP_WAITPERIOD);
+ } else {
+ /* It's already time for us to update our time */
+ NextTimeUpdate = 0;
+ }
+ }
+
+ /* If we need to update our time and we have
+ * a list of NTP servers, then send out some
+ * time requests.
+ */
+ if (NextTimeUpdate == 0 && (sntp_num_servers > 0))
+ {
+ /* Send an NTP request to each NTP server
+ * in our server list. Use version 3
+ * for v3 and v4 compatibility.
+ */
+ memset(&ntp_pkt, 0, sizeof(ntp_pkt));
+ ntp_pkt.Control =
+ NTP_LI_NOLEAP |
+ NTP_MODE_SET(NTP_MODE_CLIENT) |
+ NTP_VERSION_SET(3);
+
+ /* Send a request packet to each of our
+ * configured servers.
+ */
+ cyg_mutex_lock(&sntp_mutex);
+ for (i = 0; i < sntp_num_servers; i++)
+ {
+ /* Send the request packet using the
+ * appropriate protocol.
+ */
+ ntp_pkt.TransmitTimestamp.Seconds =
+ htonl(TIME_LOCAL_TO_NTP(time(NULL)));
+ if (sntp_servers[i].sa_family == AF_INET)
+ {
+ sendto(fd, &ntp_pkt, sizeof(ntp_pkt), 0,
+ &sntp_servers[i], sntp_servers[i].sa_len);
+#ifdef CYGPKG_NET_INET6
+ } else if (sntp_servers[i].sa_family == AF_INET6) {
+ sendto(fd6, &ntp_pkt, sizeof(ntp_pkt), 0,
+ &sntp_servers[i], sntp_servers[i].sa_len);
+#endif
+ }
+ }
+ cyg_mutex_unlock(&sntp_mutex);
+
+ /* Set the NextTimeUpdate so that we don't
+ * send any more requests until the next
+ * poll period. And we've already configured
+ * the select() timeout above to wait for
+ * replies.
+ */
+ NextTimeUpdate = time(NULL) + SNTP_WAITPERIOD;
+ }
+#endif /* CYGPKG_NET_SNTP_UNICAST */
+
+ ret = select(n+1, &readfds, NULL, NULL, ptimeout);
+ CYG_ASSERT(-1 != ret, "Select");
+
+#ifdef CYGPKG_NET_SNTP_UNICAST
+ /* If we timed out, then try resending requests */
+ if (ret == 0)
+ continue;
+#endif /* CYGPKG_NET_SNTP_UNICAST */
+
+ len = sizeof(new_srv.addr);
+ if (FD_ISSET(fd,&readfds)) {
+ ret=recvfrom(fd,&ntp_pkt,sizeof(ntp_pkt),0,(struct sockaddr *)&new_srv.addr,&len);
+ }
+#ifdef CYGPKG_NET_INET6
+ if (FD_ISSET(fd6,&readfds)) {
+ ret=recvfrom(fd6,&ntp_pkt,sizeof(ntp_pkt),0,(struct sockaddr *)&new_srv.addr,&len);
+ }
+#endif
+ CYG_ASSERT(0 < ret,"recvfrom");
+
+ /* We expect at least enough bytes to fill the buffer */
+ if (ret < NTP_PACKET_MINLEN)
+ continue;
+
+ new_srv.version = NTP_VERSION_GET(&ntp_pkt);
+ new_srv.stratum = ntp_pkt.Stratum;
+ new_srv.timestamp = ntohl(ntp_pkt.TransmitTimestamp.Seconds);
+ mode = NTP_MODE_GET(&ntp_pkt);
+
+ /* Only support protocol versions 3 or 4 */
+ if (new_srv.version < 3 || new_srv.version > 4) {
+ CYG_TRACE1(1, "Unsupported version of NTP. Version %d",new_srv.version);
+ continue;
+ }
+
+ /* Only process broadcast and server packets */
+ if (mode != NTP_MODE_BROADCAST && mode != NTP_MODE_SERVER)
+ continue;
+
+ /* Is the packet from a better server than our current one */
+ if (is_better(&new_srv,&best_srv)) {
+ best_srv = new_srv;
+
+ /* Work out the difference between server and our time.
+ * TODO: Implement RFC2030 recommendations for
+ * calculating propagation delay between the client
+ * and server.
+ */
+ new_time = TIME_NTP_TO_LOCAL(best_srv.timestamp);
+ current_time = time(NULL);
+ diff = current_time - new_time;
+
+ if (diff < 0)
+ diff = -diff;
+
+ if (diff > 2)
+ cyg_libc_time_settime(new_time);
+ }
+#ifdef CYGPKG_NET_SNTP_UNICAST
+ NextTimeUpdate = time(NULL) + SNTP_UPDATEPERIOD;
+#endif
+ }
+}
+
+/* Start the SNTP server */
+void cyg_sntp_start(void) {
+
+ static char sntp_stack[CYGNUM_SNTP_STACK_SIZE];
+ static cyg_thread sntp_thread_data;
+ static cyg_handle_t sntp_handle;
+
+ /* Only initialize things once */
+ if (sntp_initialized)
+ return;
+ sntp_initialized = 1;
+
+#ifdef CYGPKG_NET_SNTP_UNICAST
+ /* Initialize the SNTP mutex */
+ cyg_mutex_init(&sntp_mutex);
+#endif
+
+ cyg_thread_create(CYGPKG_NET_THREAD_PRIORITY+1,
+ sntp_fn, // entry
+ 0, // entry parameter
+ "SNTP Client", // Name
+ &sntp_stack, // stack
+ sizeof(sntp_stack), // stack size
+ &sntp_handle, // Handle
+ &sntp_thread_data); // Thread data structure
+
+ cyg_thread_resume(sntp_handle);
+}
+
+#ifdef CYGPKG_NET_SNTP_UNICAST
+/*
+ * FUNCTION cyg_sntp_set_servers
+ *
+ * DESCRIPTION
+ * Sets the list of SNTP/NTP servers to use
+ * for SNTP unicast requests. The list is
+ * specified as a list of sockaddr structures
+ * and can contain both IPv4 and IPv6
+ * addresses and UDP port numbers.
+ *
+ * The server_list array must be maintained
+ * by the caller and must not be modified after
+ * it is registered by this function. The
+ * array can be unregistered by calling this
+ * function again with different parameters.
+ *
+ * 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
+ * num_servers - Number of sockaddr's in array (0 to disable)
+ *
+ * RETURN VALUES
+ * None
+ */
+void cyg_sntp_set_servers(struct sockaddr *server_list,
+ cyg_uint32 num_servers)
+{
+ /* If we haven't already started the SNTP client, then
+ * start it now.
+ */
+ if (!sntp_initialized)
+ {
+ /* 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 */
+ sntp_num_servers = num_servers;
+ if (num_servers == 0) {
+ server_list = NULL;
+ } else {
+ /* reset the waiting time to force a new update <= SNTP_WAITPERIOD*/
+ NextTimeUpdate = 0;
+ }
+ sntp_servers = server_list;
+
+ /* Free the mutex */
+ cyg_mutex_unlock(&sntp_mutex);
+}
+#endif /* CYGPKG_NET_SNTP_UNICAST */
+
+
+
+
diff --git a/ecos/packages/net/sntp/current/tests/sntp1.c b/ecos/packages/net/sntp/current/tests/sntp1.c
new file mode 100644
index 0000000..ebef692
--- /dev/null
+++ b/ecos/packages/net/sntp/current/tests/sntp1.c
@@ -0,0 +1,188 @@
+//=================================================================
+//
+// sntp1.c
+//
+// Simple Network Time Protocol test 1
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Andrew Lunn
+// Contributors:
+// Date: 2003-02-11
+// Description: Tests the sntp client
+//####DESCRIPTIONEND####
+
+#include <pkgconf/isoinfra.h>
+#include <cyg/infra/testcase.h>
+
+#if defined(CYGINT_ISO_STDIO_FORMATTED_IO) && defined(CYGINT_ISO_STRING_STRFUNCS)
+#include <network.h>
+#include <time.h>
+#include <cyg/sntp/sntp.h>
+#include <stdio.h>
+
+#define SECONDSPERMINUTE (cyg_uint32)60
+#define SECONDSPERHOUR (cyg_uint32)(SECONDSPERMINUTE * 60)
+#define SECONDSPERDAY (cyg_uint32)(SECONDSPERHOUR * 24)
+#define SECONDSPERYEAR (cyg_uint32)(SECONDSPERDAY * 365)
+
+void
+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, loop, waittime;
+ char month[4];
+ char months[12][4] = { "Jan", "Feb", "Mar",
+ "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep",
+ "Oct", "Nov", "Dec" };
+ char time_info[32];
+
+ CYG_TEST_INIT();
+
+ CYG_TEST_INFO("sntp1 test build " __DATE__);
+
+ init_all_network_interfaces();
+
+ cyg_sntp_start();
+
+ /* 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);
+
+ 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;
+
+ 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");
+ }
+ }
+ }
+
+#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");
+}
+
+#define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL*2)
+static char thread_stack[STACK_SIZE];
+static cyg_thread thread_data;
+static cyg_handle_t thread_handle;
+
+void
+cyg_user_start(void)
+{
+ // Create a main thread, so we can run the scheduler and have time 'pass'
+ cyg_thread_create(10, // Priority - just a number
+ net_test, // entry
+ 0, // entry parameter
+ "Network test", // Name
+ thread_stack, // Stack
+ STACK_SIZE, // Size
+ &thread_handle, // Handle
+ &thread_data // Thread data structure
+ );
+ cyg_thread_resume(thread_handle); // Start it
+}
+
+#else //defined(CYGINT_ISO_STDIO_FORMATTED_IO) && defined(CYGINT_ISO_STRING_STRFUNCS)
+
+void cyg_user_start(void)
+{
+ CYG_TEST_NA("Not all the required packages are available");
+}
+
+#endif