OS5.15 complaint NTP library

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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NTPclient.cpp Source File

NTPclient.cpp

00001 
00002 #include "NTPclient.h"
00003 
00004 #define NTP_PORT 123
00005 #define NTP_CLIENT_PORT 0 //Random port
00006 #define timeout 3000
00007 #define NTP_TIMESTAMP_DELTA 2208988800ull 
00008 // Diff btw a UNIX timestamp (Starting Jan, 1st 1970)
00009 // and a NTP timestamp (Starting Jan, 1st 1900)
00010 
00011 NTPclient::NTPclient(NetworkInterface & _m_intf) : m_intf(_m_intf)
00012 {
00013 }
00014 #ifdef htons
00015 #undef htons
00016 #endif /* htons */
00017 #ifdef htonl
00018 #undef htonl
00019 #endif /* htonl */
00020 #ifdef ntohs
00021 #undef ntohs
00022 #endif /* ntohs */
00023 #ifdef ntohl
00024 #undef ntohl
00025 #endif /* ntohl */
00026 
00027 
00028 #if ((__BYTE_ORDER__) == (__ORDER_LITTLE_ENDIAN__))
00029 
00030 #define htons(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
00031 #define ntohs(x) htons(x)
00032 #define htonl(x) ((((x) & 0xff) << 24) | \
00033                      (((x) & 0xff00) << 8) | \
00034                      (((x) & 0xff0000UL) >> 8) | \
00035                      (((x) & 0xff000000UL) >> 24))
00036 #define ntohl(x) htonl(x)
00037 
00038 #else
00039 
00040 #define htons(x)  (x)
00041 #define htonl(x)  (x)
00042 #define ntohl(x)  (x)
00043 #define ntohs(x)  (x)
00044 
00045 #endif 
00046 
00047 uint32_t NTPclient::getNTP(const char * NTPpool, uint32_t tzoffset, bool dst, bool setRTC)
00048 
00049 {
00050   SocketAddress address(0, NTP_PORT);
00051   int r = m_intf.gethostbyname(NTPpool, &address);  
00052   if (r) {
00053         printf("error: 'gethostbyname(\"%s\")' failed with code %d\r\n", NTPpool, r);
00054     } else if (!address) {
00055         printf("error: 'gethostbyname(\"%s\")' returned null IP address\r\n", NTPpool);
00056     }  
00057    
00058   //Create & bind socket
00059   if (m_sock.open(&m_intf) < 0) printf ("ERROR sock open \n\r");  
00060   m_sock.set_timeout(timeout);  
00061 
00062   struct NTPPacket pkt;  
00063   memset (&pkt, 0, sizeof(NTPPacket));   
00064 
00065   //Now ping the server and wait for response
00066   //Prepare NTP Packet:
00067   pkt.li = 0;           //Leap Indicator : No warning
00068   pkt.vn = 4;           //Version Number : 4
00069   pkt.mode = 3;         //Client mode
00070   pkt.stratum = 0;      //Not relevant here
00071   pkt.poll = 0;         //Not significant as well
00072   pkt.precision = 0;    //Neither this one is
00073 
00074     int ret = m_sock.sendto(address, (char*)&pkt, sizeof(NTPPacket) ); 
00075     if (ret < 0 ){
00076         m_sock.close();
00077         return 0;
00078     }
00079     //Read response
00080     ret = m_sock.recvfrom(&address, (char*)&pkt, sizeof(NTPPacket) );
00081     if(ret < 0){
00082         m_sock.close();
00083         return 0;
00084         }
00085     if(ret < sizeof(NTPPacket)){
00086         m_sock.close();
00087         return 0;
00088         }
00089     //Correct Endianness
00090     pkt.refTm_s = ntohl( pkt.refTm_s ); 
00091     pkt.refTm_f = ntohl( pkt.refTm_f );
00092     pkt.origTm_s = ntohl( pkt.origTm_s );
00093     pkt.origTm_f = ntohl( pkt.origTm_f );
00094     pkt.rxTm_s = ntohl( pkt.rxTm_s );
00095     pkt.rxTm_f = ntohl( pkt.rxTm_f );
00096     pkt.txTm_s = ntohl( pkt.txTm_s );
00097     pkt.txTm_f = ntohl( pkt.txTm_f );
00098     
00099     
00100     uint32_t CETtime = (time_t)(pkt.txTm_s - NTP_TIMESTAMP_DELTA + tzoffset); 
00101     // check for DST time change, only valid for europe!!!
00102     uint32_t DST=0;  
00103     if(dst){
00104         uint32_t dow,hour,day,month;             
00105         char buffer[10];        
00106         strftime(buffer, 2,"%H", localtime(&CETtime));                                
00107         hour = atoi(buffer);
00108         strftime(buffer, 2,"%w", localtime(&CETtime));                                
00109         dow = atoi(buffer);
00110         strftime(buffer, 2,"%e", localtime(&CETtime));                
00111         day = atoi(buffer);
00112         strftime(buffer, 2,"%m", localtime(&CETtime));
00113         month = atoi(buffer);       
00114         
00115         uint32_t previousSunday = day - dow;
00116         if (month > 2 && month < 9){DST=3600;}
00117         // DST starts last Sunday of March; 2am (1am UTC)          
00118         if (month == 3 && previousSunday >= 25 && hour >= 2){DST=3600;}
00119         // DST ends last Sunday of october; 2am (1am UTC)
00120         if (month == 9 && previousSunday < 25 && hour >= 2){DST=0;}
00121     }            
00122     if(setRTC){set_time(CETtime+DST);}         
00123     m_sock.close();
00124     return (CETtime+DST+1);
00125 }