Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
NTPClient.cpp
00001 /* NTPClient.cpp */ 00002 /* Copyright (C) 2012 mbed.org, MIT License 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00005 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00006 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00007 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00008 * furnished to do so, subject to the following conditions: 00009 * 00010 * The above copyright notice and this permission notice shall be included in all copies or 00011 * substantial portions of the Software. 00012 * 00013 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00014 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00015 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00016 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00017 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00018 */ 00019 00020 //Debug is disabled by default 00021 #if 0 00022 //Enable debug 00023 #define __DEBUG__ 00024 #include <cstdio> 00025 #define DBG(x, ...) std::printf("[NTPClient : DBG]"x"\r\n", ##__VA_ARGS__); 00026 #define WARN(x, ...) std::printf("[NTPClient : WARN]"x"\r\n", ##__VA_ARGS__); 00027 #define ERR(x, ...) std::printf("[NTPClient : ERR]"x"\r\n", ##__VA_ARGS__); 00028 00029 #else 00030 //Disable debug 00031 #define DBG(x, ...) 00032 #define WARN(x, ...) 00033 #define ERR(x, ...) 00034 00035 #endif 00036 #include "NetworkInterface.h" 00037 #include "NTPClient.h" 00038 00039 #include "UDPSocket.h" 00040 00041 #include "mbed.h" //time() and set_time() 00042 00043 #define NTP_PORT 123 00044 #define NTP_CLIENT_PORT 0 //Random port 00045 #define NTP_TIMESTAMP_DELTA 2208988800ull //Diff btw a UNIX timestamp (Starting Jan, 1st 1970) and a NTP timestamp (Starting Jan, 1st 1900) 00046 00047 /*NTPClient::NTPClient() : m_sock() 00048 { 00049 00050 }*/ 00051 00052 NTPClient::NTPClient(NetworkInterface * _m_intf, int utcOffset) 00053 : m_intf(_m_intf), 00054 utc_offset(utcOffset) 00055 { 00056 } 00057 00058 #ifdef htons 00059 #undef htons 00060 #endif /* htons */ 00061 #ifdef htonl 00062 #undef htonl 00063 #endif /* htonl */ 00064 #ifdef ntohs 00065 #undef ntohs 00066 #endif /* ntohs */ 00067 #ifdef ntohl 00068 #undef ntohl 00069 #endif /* ntohl */ 00070 00071 00072 #if ((__BYTE_ORDER__) == (__ORDER_LITTLE_ENDIAN__)) 00073 00074 #define htons(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8)) 00075 #define ntohs(x) htons(x) 00076 #define htonl(x) ((((x) & 0xff) << 24) | \ 00077 (((x) & 0xff00) << 8) | \ 00078 (((x) & 0xff0000UL) >> 8) | \ 00079 (((x) & 0xff000000UL) >> 24)) 00080 #define ntohl(x) htonl(x) 00081 00082 #else 00083 00084 #define htons(x) (x) 00085 #define htonl(x) (x) 00086 #define ntohl(x) (x) 00087 #define ntohs(x) (x) 00088 00089 #endif 00090 00091 00092 NTPResult NTPClient::setTime(const char* host, uint16_t port, uint32_t timeout) 00093 { 00094 #ifdef __DEBUG__ 00095 time_t ctTime; 00096 ctTime = time(NULL); 00097 set_time(ctTime); 00098 DBG("Time is set to (UTC): %s", ctime(&ctTime)); 00099 #endif 00100 00101 00102 SocketAddress address(0, port); 00103 int r = m_intf->gethostbyname(host, &address); 00104 if (r) { 00105 printf("error: 'gethostbyname(\"%s\")' failed with code %d\r\n", host, r); 00106 } else if (!address) { 00107 printf("error: 'gethostbyname(\"%s\")' returned null IP address\r\n", host); 00108 } 00109 //printf ("address: %s\n\r",address.get_ip_address()); 00110 00111 //Create & bind socket 00112 if (m_sock.open(m_intf) < 0) printf ("ERROR sock open \n\r"); 00113 m_sock.set_timeout(timeout); 00114 00115 struct NTPPacket pkt; 00116 memset (&pkt, 0, sizeof(NTPPacket)); 00117 00118 //Now ping the server and wait for response 00119 DBG("Ping"); 00120 //Prepare NTP Packet: 00121 pkt.li = 0; //Leap Indicator : No warning 00122 pkt.vn = 4; //Version Number : 4 00123 pkt.mode = 3; //Client mode 00124 pkt.stratum = 0; //Not relevant here 00125 pkt.poll = 0; //Not significant as well 00126 pkt.precision = 0; //Neither this one is 00127 00128 int ret = m_sock.sendto(address, (char*)&pkt, sizeof(NTPPacket) ); 00129 if (ret < 0 ) 00130 { 00131 ERR("Could not send packet %d", ret); 00132 m_sock.close(); 00133 return NTP_CONN; 00134 } 00135 00136 //Read response 00137 DBG("Pong"); 00138 00139 ret = m_sock.recvfrom(&address, (char*)&pkt, sizeof(NTPPacket) ); // LICIO 00140 if(ret < 0) 00141 { 00142 ERR("Could not receive packet %d", ret); 00143 m_sock.close(); 00144 return NTP_CONN; 00145 } 00146 00147 if(ret < sizeof(NTPPacket)) //TODO: Accept chunks 00148 { 00149 ERR("Receive packet size does not match"); 00150 m_sock.close(); 00151 return NTP_PRTCL; 00152 } 00153 00154 if( pkt.stratum == 0) //Kiss of death message : Not good ! 00155 { 00156 ERR("Kissed to death!"); 00157 m_sock.close(); 00158 return NTP_PRTCL; 00159 } 00160 00161 //Correct Endianness 00162 pkt.refTm_s = ntohl( pkt.refTm_s ); 00163 pkt.refTm_f = ntohl( pkt.refTm_f ); 00164 pkt.origTm_s = ntohl( pkt.origTm_s ); 00165 pkt.origTm_f = ntohl( pkt.origTm_f ); 00166 pkt.rxTm_s = ntohl( pkt.rxTm_s ); 00167 pkt.rxTm_f = ntohl( pkt.rxTm_f ); 00168 pkt.txTm_s = ntohl( pkt.txTm_s ); 00169 pkt.txTm_f = ntohl( pkt.txTm_f ); 00170 00171 // see RFC 4330 p.13 00172 int timeoffset = utc_offset * 60 * 60; 00173 time_t txTm = (time_t)((pkt.txTm_s - NTP_TIMESTAMP_DELTA) + timeoffset); 00174 00175 set_time(txTm); 00176 00177 #ifdef __DEBUG__ 00178 ctTime = time(NULL); 00179 DBG("Time is now (UTC): %s", ctime(&ctTime)); 00180 #endif 00181 m_sock.close(); 00182 00183 return NTP_OK; 00184 } 00185
Generated on Tue Jul 12 2022 18:06:46 by
1.7.2