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.
Dependencies: azure-iot-c-sdk-f767zi
Fork of samplemqtt 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 #include "NTPClient.h" 00021 00022 #include "UDPSocket.h" 00023 00024 #include "mbed.h" //time() and set_time() 00025 #include "def.h" 00026 00027 #define NTP_PORT 123 00028 #define NTP_CLIENT_PORT 0 //Random port 00029 #define NTP_TIMESTAMP_DELTA 2208988800ull //Diff btw a UNIX timestamp (Starting Jan, 1st 1970) and a NTP timestamp (Starting Jan, 1st 1900) 00030 00031 NTPClient::NTPClient(NetworkInterface *networkInterface) 00032 : m_sock(networkInterface), m_net(networkInterface) 00033 { 00034 } 00035 00036 NTPResult NTPClient::setTime(const char* host, uint16_t port, uint32_t timeout) 00037 { 00038 //Create & bind socket 00039 m_sock.set_blocking(false); 00040 m_sock.set_timeout(timeout); 00041 00042 struct NTPPacket pkt; 00043 00044 //Now ping the server and wait for response 00045 //Prepare NTP Packet: 00046 pkt.li = 0; //Leap Indicator : No warning 00047 pkt.vn = 4; //Version Number : 4 00048 pkt.mode = 3; //Client mode 00049 pkt.stratum = 0; //Not relevant here 00050 pkt.poll = 0; //Not significant as well 00051 pkt.precision = 0; //Neither this one is 00052 00053 pkt.rootDelay = 0; //Or this one 00054 pkt.rootDispersion = 0; //Or that one 00055 pkt.refId = 0; //... 00056 00057 pkt.refTm_s = 0; 00058 pkt.origTm_s = 0; 00059 pkt.rxTm_s = 0; 00060 pkt.txTm_s = htonl( NTP_TIMESTAMP_DELTA + time(NULL) ); //WARN: We are in LE format, network byte order is BE 00061 00062 pkt.refTm_f = pkt.origTm_f = pkt.rxTm_f = pkt.txTm_f = 0; 00063 00064 SocketAddress outEndpoint(host, port); 00065 00066 if(m_net->gethostbyname(host, &outEndpoint)!= 0) 00067 { 00068 m_sock.close(); 00069 return NTP_DNS; 00070 } 00071 00072 const char *ip = outEndpoint.get_ip_address(); 00073 //Set timeout, non-blocking and wait using select 00074 int ret = m_sock.sendto(outEndpoint, (char*)&pkt, sizeof(NTPPacket) ); 00075 if (ret < 0 ) 00076 { 00077 m_sock.close(); 00078 return NTP_CONN; 00079 } 00080 00081 SocketAddress recvAddress; 00082 recvAddress.set_ip_address(outEndpoint.get_ip_address()); 00083 recvAddress.set_port(port); 00084 ret = m_sock.recvfrom(&recvAddress, (char*)&pkt, sizeof(NTPPacket) ); //FIXME need a DNS Resolver to actually compare the incoming address with the DNS name 00085 if (ret > 0) 00086 { 00087 if (strcmp(outEndpoint.get_ip_address(), recvAddress.get_ip_address()) != 0) 00088 { 00089 m_sock.close(); 00090 return NTP_CONN; 00091 } 00092 } 00093 else 00094 { 00095 m_sock.close(); 00096 return NTP_CONN; 00097 } 00098 00099 if(ret < (int)sizeof(NTPPacket)) //TODO: Accept chunks 00100 { 00101 m_sock.close(); 00102 return NTP_PRTCL; 00103 } 00104 00105 if( pkt.stratum == 0) //Kiss of death message : Not good ! 00106 { 00107 m_sock.close(); 00108 return NTP_PRTCL; 00109 } 00110 00111 //Correct Endianness 00112 pkt.refTm_s = ntohl( pkt.refTm_s ); 00113 pkt.refTm_f = ntohl( pkt.refTm_f ); 00114 pkt.origTm_s = ntohl( pkt.origTm_s ); 00115 pkt.origTm_f = ntohl( pkt.origTm_f ); 00116 pkt.rxTm_s = ntohl( pkt.rxTm_s ); 00117 pkt.rxTm_f = ntohl( pkt.rxTm_f ); 00118 pkt.txTm_s = ntohl( pkt.txTm_s ); 00119 pkt.txTm_f = ntohl( pkt.txTm_f ); 00120 00121 //Compute offset, see RFC 4330 p.13 00122 uint32_t destTm_s = (NTP_TIMESTAMP_DELTA + time(NULL)); 00123 int64_t offset = ( (int64_t)( pkt.rxTm_s - pkt.origTm_s ) + (int64_t) ( pkt.txTm_s - destTm_s ) ) / 2; //Avoid overflow 00124 //Set time accordingly 00125 set_time( time(NULL) + offset ); 00126 00127 m_sock.close(); 00128 00129 return NTP_OK; 00130 } 00131
Generated on Sat Jul 16 2022 19:35:15 by
1.7.2
