OS5.15 complaint NTP library
Dependents: Firebase-Example TCP-NTP-Server TCP-NTP-Server-OS5depreciated
NTPclient.cpp@1:a97d143dd94e, 2020-06-01 (annotated)
- Committer:
- star297
- Date:
- Mon Jun 01 16:16:42 2020 +0000
- Revision:
- 1:a97d143dd94e
- Parent:
- 0:3854dc7bd4de
added DST
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
star297 | 0:3854dc7bd4de | 1 | |
star297 | 0:3854dc7bd4de | 2 | #include "NTPclient.h" |
star297 | 0:3854dc7bd4de | 3 | |
star297 | 0:3854dc7bd4de | 4 | #define NTP_PORT 123 |
star297 | 0:3854dc7bd4de | 5 | #define NTP_CLIENT_PORT 0 //Random port |
star297 | 0:3854dc7bd4de | 6 | #define timeout 3000 |
star297 | 0:3854dc7bd4de | 7 | #define NTP_TIMESTAMP_DELTA 2208988800ull |
star297 | 0:3854dc7bd4de | 8 | // Diff btw a UNIX timestamp (Starting Jan, 1st 1970) |
star297 | 0:3854dc7bd4de | 9 | // and a NTP timestamp (Starting Jan, 1st 1900) |
star297 | 0:3854dc7bd4de | 10 | |
star297 | 0:3854dc7bd4de | 11 | NTPclient::NTPclient(NetworkInterface & _m_intf) : m_intf(_m_intf) |
star297 | 0:3854dc7bd4de | 12 | { |
star297 | 0:3854dc7bd4de | 13 | } |
star297 | 0:3854dc7bd4de | 14 | #ifdef htons |
star297 | 0:3854dc7bd4de | 15 | #undef htons |
star297 | 0:3854dc7bd4de | 16 | #endif /* htons */ |
star297 | 0:3854dc7bd4de | 17 | #ifdef htonl |
star297 | 0:3854dc7bd4de | 18 | #undef htonl |
star297 | 0:3854dc7bd4de | 19 | #endif /* htonl */ |
star297 | 0:3854dc7bd4de | 20 | #ifdef ntohs |
star297 | 0:3854dc7bd4de | 21 | #undef ntohs |
star297 | 0:3854dc7bd4de | 22 | #endif /* ntohs */ |
star297 | 0:3854dc7bd4de | 23 | #ifdef ntohl |
star297 | 0:3854dc7bd4de | 24 | #undef ntohl |
star297 | 0:3854dc7bd4de | 25 | #endif /* ntohl */ |
star297 | 0:3854dc7bd4de | 26 | |
star297 | 0:3854dc7bd4de | 27 | |
star297 | 0:3854dc7bd4de | 28 | #if ((__BYTE_ORDER__) == (__ORDER_LITTLE_ENDIAN__)) |
star297 | 0:3854dc7bd4de | 29 | |
star297 | 0:3854dc7bd4de | 30 | #define htons(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8)) |
star297 | 0:3854dc7bd4de | 31 | #define ntohs(x) htons(x) |
star297 | 0:3854dc7bd4de | 32 | #define htonl(x) ((((x) & 0xff) << 24) | \ |
star297 | 0:3854dc7bd4de | 33 | (((x) & 0xff00) << 8) | \ |
star297 | 0:3854dc7bd4de | 34 | (((x) & 0xff0000UL) >> 8) | \ |
star297 | 0:3854dc7bd4de | 35 | (((x) & 0xff000000UL) >> 24)) |
star297 | 0:3854dc7bd4de | 36 | #define ntohl(x) htonl(x) |
star297 | 0:3854dc7bd4de | 37 | |
star297 | 0:3854dc7bd4de | 38 | #else |
star297 | 0:3854dc7bd4de | 39 | |
star297 | 0:3854dc7bd4de | 40 | #define htons(x) (x) |
star297 | 0:3854dc7bd4de | 41 | #define htonl(x) (x) |
star297 | 0:3854dc7bd4de | 42 | #define ntohl(x) (x) |
star297 | 0:3854dc7bd4de | 43 | #define ntohs(x) (x) |
star297 | 0:3854dc7bd4de | 44 | |
star297 | 0:3854dc7bd4de | 45 | #endif |
star297 | 0:3854dc7bd4de | 46 | |
star297 | 0:3854dc7bd4de | 47 | uint32_t NTPclient::getNTP(const char * NTPpool, uint32_t tzoffset, bool dst, bool setRTC) |
star297 | 0:3854dc7bd4de | 48 | |
star297 | 0:3854dc7bd4de | 49 | { |
star297 | 0:3854dc7bd4de | 50 | SocketAddress address(0, NTP_PORT); |
star297 | 0:3854dc7bd4de | 51 | int r = m_intf.gethostbyname(NTPpool, &address); |
star297 | 0:3854dc7bd4de | 52 | if (r) { |
star297 | 0:3854dc7bd4de | 53 | printf("error: 'gethostbyname(\"%s\")' failed with code %d\r\n", NTPpool, r); |
star297 | 0:3854dc7bd4de | 54 | } else if (!address) { |
star297 | 0:3854dc7bd4de | 55 | printf("error: 'gethostbyname(\"%s\")' returned null IP address\r\n", NTPpool); |
star297 | 0:3854dc7bd4de | 56 | } |
star297 | 0:3854dc7bd4de | 57 | |
star297 | 0:3854dc7bd4de | 58 | //Create & bind socket |
star297 | 0:3854dc7bd4de | 59 | if (m_sock.open(&m_intf) < 0) printf ("ERROR sock open \n\r"); |
star297 | 0:3854dc7bd4de | 60 | m_sock.set_timeout(timeout); |
star297 | 0:3854dc7bd4de | 61 | |
star297 | 0:3854dc7bd4de | 62 | struct NTPPacket pkt; |
star297 | 0:3854dc7bd4de | 63 | memset (&pkt, 0, sizeof(NTPPacket)); |
star297 | 0:3854dc7bd4de | 64 | |
star297 | 0:3854dc7bd4de | 65 | //Now ping the server and wait for response |
star297 | 0:3854dc7bd4de | 66 | //Prepare NTP Packet: |
star297 | 0:3854dc7bd4de | 67 | pkt.li = 0; //Leap Indicator : No warning |
star297 | 0:3854dc7bd4de | 68 | pkt.vn = 4; //Version Number : 4 |
star297 | 0:3854dc7bd4de | 69 | pkt.mode = 3; //Client mode |
star297 | 0:3854dc7bd4de | 70 | pkt.stratum = 0; //Not relevant here |
star297 | 0:3854dc7bd4de | 71 | pkt.poll = 0; //Not significant as well |
star297 | 0:3854dc7bd4de | 72 | pkt.precision = 0; //Neither this one is |
star297 | 0:3854dc7bd4de | 73 | |
star297 | 0:3854dc7bd4de | 74 | int ret = m_sock.sendto(address, (char*)&pkt, sizeof(NTPPacket) ); |
star297 | 0:3854dc7bd4de | 75 | if (ret < 0 ){ |
star297 | 0:3854dc7bd4de | 76 | m_sock.close(); |
star297 | 0:3854dc7bd4de | 77 | return 0; |
star297 | 0:3854dc7bd4de | 78 | } |
star297 | 0:3854dc7bd4de | 79 | //Read response |
star297 | 0:3854dc7bd4de | 80 | ret = m_sock.recvfrom(&address, (char*)&pkt, sizeof(NTPPacket) ); |
star297 | 0:3854dc7bd4de | 81 | if(ret < 0){ |
star297 | 0:3854dc7bd4de | 82 | m_sock.close(); |
star297 | 0:3854dc7bd4de | 83 | return 0; |
star297 | 0:3854dc7bd4de | 84 | } |
star297 | 0:3854dc7bd4de | 85 | if(ret < sizeof(NTPPacket)){ |
star297 | 0:3854dc7bd4de | 86 | m_sock.close(); |
star297 | 0:3854dc7bd4de | 87 | return 0; |
star297 | 0:3854dc7bd4de | 88 | } |
star297 | 0:3854dc7bd4de | 89 | //Correct Endianness |
star297 | 0:3854dc7bd4de | 90 | pkt.refTm_s = ntohl( pkt.refTm_s ); |
star297 | 0:3854dc7bd4de | 91 | pkt.refTm_f = ntohl( pkt.refTm_f ); |
star297 | 0:3854dc7bd4de | 92 | pkt.origTm_s = ntohl( pkt.origTm_s ); |
star297 | 0:3854dc7bd4de | 93 | pkt.origTm_f = ntohl( pkt.origTm_f ); |
star297 | 0:3854dc7bd4de | 94 | pkt.rxTm_s = ntohl( pkt.rxTm_s ); |
star297 | 0:3854dc7bd4de | 95 | pkt.rxTm_f = ntohl( pkt.rxTm_f ); |
star297 | 0:3854dc7bd4de | 96 | pkt.txTm_s = ntohl( pkt.txTm_s ); |
star297 | 0:3854dc7bd4de | 97 | pkt.txTm_f = ntohl( pkt.txTm_f ); |
star297 | 0:3854dc7bd4de | 98 | |
star297 | 0:3854dc7bd4de | 99 | |
star297 | 0:3854dc7bd4de | 100 | uint32_t CETtime = (time_t)(pkt.txTm_s - NTP_TIMESTAMP_DELTA + tzoffset); |
star297 | 0:3854dc7bd4de | 101 | // check for DST time change, only valid for europe!!! |
star297 | 0:3854dc7bd4de | 102 | uint32_t DST=0; |
star297 | 0:3854dc7bd4de | 103 | if(dst){ |
star297 | 0:3854dc7bd4de | 104 | uint32_t dow,hour,day,month; |
star297 | 0:3854dc7bd4de | 105 | char buffer[10]; |
star297 | 0:3854dc7bd4de | 106 | strftime(buffer, 2,"%H", localtime(&CETtime)); |
star297 | 0:3854dc7bd4de | 107 | hour = atoi(buffer); |
star297 | 0:3854dc7bd4de | 108 | strftime(buffer, 2,"%w", localtime(&CETtime)); |
star297 | 0:3854dc7bd4de | 109 | dow = atoi(buffer); |
star297 | 0:3854dc7bd4de | 110 | strftime(buffer, 2,"%e", localtime(&CETtime)); |
star297 | 0:3854dc7bd4de | 111 | day = atoi(buffer); |
star297 | 0:3854dc7bd4de | 112 | strftime(buffer, 2,"%m", localtime(&CETtime)); |
star297 | 0:3854dc7bd4de | 113 | month = atoi(buffer); |
star297 | 0:3854dc7bd4de | 114 | |
star297 | 0:3854dc7bd4de | 115 | uint32_t previousSunday = day - dow; |
star297 | 0:3854dc7bd4de | 116 | if (month > 2 && month < 9){DST=3600;} |
star297 | 1:a97d143dd94e | 117 | // DST starts last Sunday of March; 2am (1am UTC) |
star297 | 1:a97d143dd94e | 118 | if (month == 3 && previousSunday >= 25 && hour >= 2){DST=3600;} |
star297 | 1:a97d143dd94e | 119 | // DST ends last Sunday of october; 2am (1am UTC) |
star297 | 0:3854dc7bd4de | 120 | if (month == 9 && previousSunday < 25 && hour >= 2){DST=0;} |
star297 | 0:3854dc7bd4de | 121 | } |
star297 | 1:a97d143dd94e | 122 | if(setRTC){set_time(CETtime+DST);} |
star297 | 0:3854dc7bd4de | 123 | m_sock.close(); |
star297 | 0:3854dc7bd4de | 124 | return (CETtime+DST+1); |
star297 | 0:3854dc7bd4de | 125 | } |