NTP client to get UTC time from the internet time servers

Dependents:   NTPClient_HelloWorld

Fork of NTPClient by ST Expansion SW Team

Revision:
5:fe36718063a5
Parent:
4:881559865a93
Child:
6:510bffa8b3d9
--- a/NTPClient.cpp	Sun Aug 05 16:10:57 2012 +0000
+++ b/NTPClient.cpp	Wed Dec 14 16:23:38 2016 +0000
@@ -33,7 +33,7 @@
 #define ERR(x, ...) 
 
 #endif
-
+#include "NetworkStack.h"
 #include "NTPClient.h"
 
 #include "UDPSocket.h"
@@ -44,27 +44,73 @@
 #define NTP_CLIENT_PORT 0 //Random port
 #define NTP_TIMESTAMP_DELTA 2208988800ull //Diff btw a UNIX timestamp (Starting Jan, 1st 1970) and a NTP timestamp (Starting Jan, 1st 1900)
 
-NTPClient::NTPClient() : m_sock()
+/*NTPClient::NTPClient() : m_sock()
 {
 
+}*/
 
+NTPClient::NTPClient(NetworkStack & _m_intf) : m_intf(_m_intf)
+{
 }
 
+#ifdef htons
+#undef htons
+#endif /* htons */
+#ifdef htonl
+#undef htonl
+#endif /* htonl */
+#ifdef ntohs
+#undef ntohs
+#endif /* ntohs */
+#ifdef ntohl
+#undef ntohl
+#endif /* ntohl */
+
+
+#if ((__BYTE_ORDER__) == (__ORDER_LITTLE_ENDIAN__))
+
+#define htons(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
+#define ntohs(x) htons(x)
+#define htonl(x) ((((x) & 0xff) << 24) | \
+                     (((x) & 0xff00) << 8) | \
+                     (((x) & 0xff0000UL) >> 8) | \
+                     (((x) & 0xff000000UL) >> 24))
+#define ntohl(x) htonl(x)
+
+#else
+
+#define htons(x)  (x)
+#define htonl(x)  (x)
+#define ntohl(x)  (x)
+#define ntohs(x)  (x)
+
+#endif 
+
+
 NTPResult NTPClient::setTime(const char* host, uint16_t port, uint32_t timeout)
 {
 #ifdef __DEBUG__
   time_t ctTime;
   ctTime = time(NULL);
+  set_time(ctTime);
   DBG("Time is set to (UTC): %s", ctime(&ctTime));
 #endif
 
+  SocketAddress address(0, port);
+  int r = m_intf.gethostbyname(&address, host);  
+  if (r) {
+        printf("error: 'gethostbyname(\"%s\")' failed with code %d\r\n", host, r);
+  } else if (!address) {
+        printf("error: 'gethostbyname(\"%s\")' returned null IP address\r\n", host);
+  }  
+  //printf ("address: %s\n\r",address.get_ip_address());
+   
   //Create & bind socket
-  DBG("Binding socket");
-  m_sock.bind(0); //Bind to a random port
-  
-  m_sock.set_blocking(false, timeout); //Set not blocking
+  if (m_sock.open(&m_intf) < 0) printf ("ERROR sock open \n\r");  
+  m_sock.set_blocking(true); //Set blocking  LICIO
 
-  struct NTPPacket pkt;
+  struct NTPPacket pkt;  
+  memset (&pkt, 0, sizeof(NTPPacket));   
 
   //Now ping the server and wait for response
   DBG("Ping");
@@ -76,48 +122,24 @@
   pkt.poll = 0; //Not significant as well
   pkt.precision = 0; //Neither this one is
 
-  pkt.rootDelay = 0; //Or this one
-  pkt.rootDispersion = 0; //Or that one
-  pkt.refId = 0; //...
-
-  pkt.refTm_s = 0;
-  pkt.origTm_s = 0;
-  pkt.rxTm_s = 0;
-  pkt.txTm_s = htonl( NTP_TIMESTAMP_DELTA + time(NULL) ); //WARN: We are in LE format, network byte order is BE
-
-  pkt.refTm_f = pkt.origTm_f = pkt.rxTm_f = pkt.txTm_f = 0;
-
-  Endpoint outEndpoint;
-  
-  if( outEndpoint.set_address(host, port) < 0)
-  {
-    m_sock.close();
-    return NTP_DNS;
-  }
-  
-  //Set timeout, non-blocking and wait using select
-  int ret = m_sock.sendTo( outEndpoint, (char*)&pkt, sizeof(NTPPacket) );
+  int ret = m_sock.sendto(address, (char*)&pkt, sizeof(NTPPacket) ); 
   if (ret < 0 )
   {
-    ERR("Could not send packet");
+    ERR("Could not send packet %d", ret);
     m_sock.close();
     return NTP_CONN;
   }
 
   //Read response
-  Endpoint inEndpoint;
+  DBG("Pong");
 
-  DBG("Pong");
-  do
+  ret = m_sock.recvfrom(&address, (char*)&pkt, sizeof(NTPPacket) );  // LICIO
+  if(ret < 0)
   {
-    ret = m_sock.receiveFrom( inEndpoint, (char*)&pkt, sizeof(NTPPacket) ); //FIXME need a DNS Resolver to actually compare the incoming address with the DNS name
-    if(ret < 0)
-    {
-      ERR("Could not receive packet");
-      m_sock.close();
-      return NTP_CONN;
-    }
-  } while( strcmp(outEndpoint.get_address(), inEndpoint.get_address()) != 0 );
+    ERR("Could not receive packet %d", ret);
+    m_sock.close();
+    return NTP_CONN;
+  }
 
   if(ret < sizeof(NTPPacket)) //TODO: Accept chunks
   {
@@ -134,7 +156,7 @@
   }
 
   //Correct Endianness
-  pkt.refTm_s = ntohl( pkt.refTm_s );
+  pkt.refTm_s = ntohl( pkt.refTm_s ); 
   pkt.refTm_f = ntohl( pkt.refTm_f );
   pkt.origTm_s = ntohl( pkt.origTm_s );
   pkt.origTm_f = ntohl( pkt.origTm_f );
@@ -143,19 +165,14 @@
   pkt.txTm_s = ntohl( pkt.txTm_s );
   pkt.txTm_f = ntohl( pkt.txTm_f );
 
-  //Compute offset, see RFC 4330 p.13
-  uint32_t destTm_s = (NTP_TIMESTAMP_DELTA + time(NULL));
-  int64_t offset = ( (int64_t)( pkt.rxTm_s - pkt.origTm_s ) + (int64_t) ( pkt.txTm_s - destTm_s ) ) / 2; //Avoid overflow
-  DBG("Sent @%ul", pkt.txTm_s);
-  DBG("Offset: %lld", offset);
-  //Set time accordingly
-  set_time( time(NULL) + offset );
+  // see RFC 4330 p.13
+  time_t txTm = (time_t)(pkt.txTm_s - NTP_TIMESTAMP_DELTA);  
+  set_time(txTm); 
 
 #ifdef __DEBUG__
   ctTime = time(NULL);
   DBG("Time is now (UTC): %s", ctime(&ctTime));
 #endif
-
   m_sock.close();
 
   return NTP_OK;