OS5.15 complaint NTP library

Dependents:   Firebase-Example TCP-NTP-Server TCP-NTP-Server-OS5depreciated

Files at this revision

API Documentation at this revision

Comitter:
star297
Date:
Sun Mar 08 14:32:36 2020 +0000
Child:
1:a97d143dd94e
Commit message:
Deprecation updates

Changed in this revision

NTPclient.cpp Show annotated file Show diff for this revision Revisions of this file
NTPclient.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NTPclient.cpp	Sun Mar 08 14:32:36 2020 +0000
@@ -0,0 +1,125 @@
+
+#include "NTPclient.h"
+
+#define NTP_PORT 123
+#define NTP_CLIENT_PORT 0 //Random port
+#define timeout 3000
+#define NTP_TIMESTAMP_DELTA 2208988800ull 
+// Diff btw a UNIX timestamp (Starting Jan, 1st 1970)
+// and a NTP timestamp (Starting Jan, 1st 1900)
+
+NTPclient::NTPclient(NetworkInterface & _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 
+
+uint32_t NTPclient::getNTP(const char * NTPpool, uint32_t tzoffset, bool dst, bool setRTC)
+
+{
+  SocketAddress address(0, NTP_PORT);
+  int r = m_intf.gethostbyname(NTPpool, &address);  
+  if (r) {
+        printf("error: 'gethostbyname(\"%s\")' failed with code %d\r\n", NTPpool, r);
+    } else if (!address) {
+        printf("error: 'gethostbyname(\"%s\")' returned null IP address\r\n", NTPpool);
+    }  
+   
+  //Create & bind socket
+  if (m_sock.open(&m_intf) < 0) printf ("ERROR sock open \n\r");  
+  m_sock.set_timeout(timeout);  
+
+  struct NTPPacket pkt;  
+  memset (&pkt, 0, sizeof(NTPPacket));   
+
+  //Now ping the server and wait for response
+  //Prepare NTP Packet:
+  pkt.li = 0;           //Leap Indicator : No warning
+  pkt.vn = 4;           //Version Number : 4
+  pkt.mode = 3;         //Client mode
+  pkt.stratum = 0;      //Not relevant here
+  pkt.poll = 0;         //Not significant as well
+  pkt.precision = 0;    //Neither this one is
+
+    int ret = m_sock.sendto(address, (char*)&pkt, sizeof(NTPPacket) ); 
+    if (ret < 0 ){
+        m_sock.close();
+        return 0;
+    }
+    //Read response
+    ret = m_sock.recvfrom(&address, (char*)&pkt, sizeof(NTPPacket) );
+    if(ret < 0){
+        m_sock.close();
+        return 0;
+        }
+    if(ret < sizeof(NTPPacket)){
+        m_sock.close();
+        return 0;
+        }
+    //Correct Endianness
+    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 );
+    pkt.rxTm_s = ntohl( pkt.rxTm_s );
+    pkt.rxTm_f = ntohl( pkt.rxTm_f );
+    pkt.txTm_s = ntohl( pkt.txTm_s );
+    pkt.txTm_f = ntohl( pkt.txTm_f );
+    
+    
+    uint32_t CETtime = (time_t)(pkt.txTm_s - NTP_TIMESTAMP_DELTA + tzoffset); 
+    // check for DST time change, only valid for europe!!!
+    uint32_t DST=0;  
+    if(dst){
+        uint32_t dow,hour,day,month;             
+        char buffer[10];        
+        strftime(buffer, 2,"%H", localtime(&CETtime));                                
+        hour = atoi(buffer);
+        strftime(buffer, 2,"%w", localtime(&CETtime));                                
+        dow = atoi(buffer);
+        strftime(buffer, 2,"%e", localtime(&CETtime));                
+        day = atoi(buffer);
+        strftime(buffer, 2,"%m", localtime(&CETtime));
+        month = atoi(buffer);       
+        
+        uint32_t previousSunday = day - dow;
+        if (month > 2 && month < 9){DST=3600;}
+        // DST starts 2nd Sunday of March;  2am            
+        if (month == 2 && previousSunday >= 25 && hour >= 2){DST=3600;}
+        // DST ends 1st Sunday of November; 2am
+        if (month == 9 && previousSunday < 25 && hour >= 2){DST=0;}
+    }            
+    if(setRTC){set_time(CETtime+DST+1);} // add extra second here for processing         
+    m_sock.close();
+    return (CETtime+DST+1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NTPclient.h	Sun Mar 08 14:32:36 2020 +0000
@@ -0,0 +1,59 @@
+
+#include "mbed.h"
+ 
+#ifndef NTPCLIENT_H
+#define NTPCLIENT_H
+
+#include <stdint.h>
+#include "UDPSocket.h"
+#include "NetworkInterface.h"
+
+#define NTP_DEFAULT_PORT 123
+#define NTP_DEFAULT_TIMEOUT 4000
+#define NTP_DEFAULT_TIMEZONE_OFFSET 0
+
+class NTPclient
+{
+public:  
+    NTPclient(NetworkInterface & _m_intf);
+    // Returns current time in seconds (blocking)
+    // Update the time using the server host
+    // Blocks until completion
+    // NTPpool, NTP server IPv4 address or hostname (will be resolved via DNS)
+    // tzoffset, offset in seconds (3600 add 1 hour, -3600 subtract 1 hour)
+    // dst, adjust for DST 1= enabled, 0=dissabled 
+    // setRTC, set system RTC 1= enabled, 0=dissabled 
+
+    uint32_t getNTP(const char* NTPpool, uint32_t tzoffset, bool dst, bool setRTC); 
+
+private:
+    struct NTPPacket
+    {
+    //We are in LE Network is BE
+    //LSb first
+    unsigned mode : 3;
+    unsigned vn : 3;
+    unsigned li : 2;
+
+    uint8_t stratum;
+    uint8_t poll;
+    uint8_t precision;
+    
+    //32 bits header
+    uint32_t rootDelay;
+    uint32_t rootDispersion;
+    uint32_t refId;
+    uint32_t refTm_s;
+    uint32_t refTm_f;
+    uint32_t origTm_s;
+    uint32_t origTm_f;
+    uint32_t rxTm_s;
+    uint32_t rxTm_f;
+    uint32_t txTm_s;
+    uint32_t txTm_f;
+  } __attribute__ ((packed));
+  
+  NetworkInterface & m_intf;  // WiFi interface  
+  UDPSocket m_sock;
+};
+#endif /* NTPCLIENT_H_ */