Modify to work with Ethernet Interface on NUCLEO F746ZG
Fork of NTPClient by
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 "EthernetInterface.h" // #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(EthernetInterface & _m_intf) : m_intf(_m_intf) // NTPClient::NTPClient(NetworkInterface & _m_intf) : m_intf(_m_intf) 00053 { 00054 } 00055 00056 #ifdef htons 00057 #undef htons 00058 #endif /* htons */ 00059 #ifdef htonl 00060 #undef htonl 00061 #endif /* htonl */ 00062 #ifdef ntohs 00063 #undef ntohs 00064 #endif /* ntohs */ 00065 #ifdef ntohl 00066 #undef ntohl 00067 #endif /* ntohl */ 00068 00069 00070 #if ((__BYTE_ORDER__) == (__ORDER_LITTLE_ENDIAN__)) 00071 00072 #define htons(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8)) 00073 #define ntohs(x) htons(x) 00074 #define htonl(x) ((((x) & 0xff) << 24) | \ 00075 (((x) & 0xff00) << 8) | \ 00076 (((x) & 0xff0000UL) >> 8) | \ 00077 (((x) & 0xff000000UL) >> 24)) 00078 #define ntohl(x) htonl(x) 00079 00080 #else 00081 00082 #define htons(x) (x) 00083 #define htonl(x) (x) 00084 #define ntohl(x) (x) 00085 #define ntohs(x) (x) 00086 00087 #endif 00088 00089 00090 NTPResult NTPClient::setTime(const char* host, uint16_t port, uint32_t timeout) 00091 { 00092 #ifdef __DEBUG__ 00093 time_t ctTime; 00094 ctTime = time(NULL); 00095 set_time(ctTime); 00096 DBG("Time is set to (UTC): %s", ctime(&ctTime)); 00097 #endif 00098 00099 SocketAddress address(0, port); 00100 int r = m_intf.gethostbyname( host, &address); 00101 if (r) { 00102 printf("error: 'gethostbyname(\"%s\")' failed with code %d\r\n", host, r); 00103 } else if (!address) { 00104 printf("error: 'gethostbyname(\"%s\")' returned null IP address\r\n", host); 00105 } 00106 //printf ("address: %s\n\r",address.get_ip_address()); 00107 00108 //Create & bind socket 00109 if (m_sock.open(&m_intf) < 0) printf ("ERROR sock open \n\r"); 00110 m_sock.set_timeout(timeout); 00111 00112 struct NTPPacket pkt; 00113 memset (&pkt, 0, sizeof(NTPPacket)); 00114 00115 //Now ping the server and wait for response 00116 DBG("Ping"); 00117 //Prepare NTP Packet: 00118 pkt.li = 0; //Leap Indicator : No warning 00119 pkt.vn = 4; //Version Number : 4 00120 pkt.mode = 3; //Client mode 00121 pkt.stratum = 0; //Not relevant here 00122 pkt.poll = 0; //Not significant as well 00123 pkt.precision = 0; //Neither this one is 00124 00125 int ret = m_sock.sendto(address, (char*)&pkt, sizeof(NTPPacket) ); 00126 if (ret < 0 ) 00127 { 00128 ERR("Could not send packet %d", ret); 00129 m_sock.close(); 00130 return NTP_CONN; 00131 } 00132 00133 //Read response 00134 DBG("Pong"); 00135 00136 ret = m_sock.recvfrom(&address, (char*)&pkt, sizeof(NTPPacket) ); // LICIO 00137 if(ret < 0) 00138 { 00139 ERR("Could not receive packet %d", ret); 00140 m_sock.close(); 00141 return NTP_CONN; 00142 } 00143 00144 if(ret < sizeof(NTPPacket)) //TODO: Accept chunks 00145 { 00146 ERR("Receive packet size does not match"); 00147 m_sock.close(); 00148 return NTP_PRTCL; 00149 } 00150 00151 if( pkt.stratum == 0) //Kiss of death message : Not good ! 00152 { 00153 ERR("Kissed to death!"); 00154 m_sock.close(); 00155 return NTP_PRTCL; 00156 } 00157 00158 //Correct Endianness 00159 pkt.refTm_s = ntohl( pkt.refTm_s ); 00160 pkt.refTm_f = ntohl( pkt.refTm_f ); 00161 pkt.origTm_s = ntohl( pkt.origTm_s ); 00162 pkt.origTm_f = ntohl( pkt.origTm_f ); 00163 pkt.rxTm_s = ntohl( pkt.rxTm_s ); 00164 pkt.rxTm_f = ntohl( pkt.rxTm_f ); 00165 pkt.txTm_s = ntohl( pkt.txTm_s ); 00166 pkt.txTm_f = ntohl( pkt.txTm_f ); 00167 00168 // see RFC 4330 p.13 00169 time_t txTm = (time_t)(pkt.txTm_s - NTP_TIMESTAMP_DELTA); 00170 set_time(txTm); 00171 00172 #ifdef __DEBUG__ 00173 ctTime = time(NULL); 00174 DBG("Time is now (UTC): %s", ctime(&ctTime)); 00175 #endif 00176 m_sock.close(); 00177 00178 return NTP_OK; 00179 } 00180
Generated on Wed Jul 20 2022 19:28:34 by 1.7.2