Sample program that can send the recognition data from HVC-P2 to Fujitsu IoT Platform using REST (HTTP)
Dependencies: AsciiFont GR-PEACH_video GraphicsFramework LCD_shield_config R_BSP USBHost_custom easy-connect-gr-peach mbed-http picojson
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 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 00053 #if MBED_MAJOR_VERSION >= 5 00054 00055 #include <SocketAddress.h> 00056 #include <EthernetInterface.h> 00057 //extern EthernetInterface ei_; 00058 EthernetInterface ei_; 00059 00060 class Endpoint { 00061 SocketAddress sa_; 00062 public: 00063 Endpoint() : sa_() {} 00064 int set_address(const char* host, uint16_t port) 00065 { 00066 sa_.set_port(port); 00067 return nsapi_create_stack(&ei_)->gethostbyname(host, &sa_); 00068 } 00069 const char* get_address() const { return sa_.get_ip_address(); } 00070 operator const SocketAddress&() { return sa_; } 00071 operator SocketAddress*() { return &sa_; } 00072 }; 00073 00074 class LegacyUS { 00075 UDPSocket us_; 00076 public: 00077 LegacyUS() : us_() {} 00078 int bind(int port) 00079 { 00080 us_.open(&ei_); 00081 return us_.bind(port); 00082 } 00083 void set_blocking(bool blocking, unsigned int) 00084 { 00085 us_.set_blocking(blocking); 00086 } 00087 int close() { return us_.close(); } 00088 int sendTo(Endpoint& remote, char* packet, int length) 00089 { 00090 return us_.sendto(remote, packet, length); 00091 } 00092 int receiveFrom(Endpoint& remote, char* buffer, int length) 00093 { 00094 int ret = us_.recvfrom(remote, buffer, length); 00095 if( ret == NSAPI_ERROR_WOULD_BLOCK ) 00096 { 00097 wait(0.1); 00098 ret = 0; 00099 } 00100 return ret; 00101 } 00102 }; 00103 #define m_sock (*((LegacyUS*)&m_sock)) 00104 00105 #endif // MBED_MAJOR_VERSION >= 5 00106 00107 NTPResult NTPClient::setTime(const char* host, uint16_t port, uint32_t timeout) 00108 { 00109 #ifdef __DEBUG__ 00110 time_t ctTime; 00111 ctTime = time(NULL); 00112 DBG("Time is set to (UTC): %s", ctime(&ctTime)); 00113 #endif 00114 00115 //Create & bind socket 00116 DBG("Binding socket"); 00117 m_sock.bind(0); //Bind to a random port 00118 00119 m_sock.set_blocking(false, timeout); //Set not blocking 00120 00121 struct NTPPacket pkt; 00122 00123 //Now ping the server and wait for response 00124 DBG("Ping"); 00125 //Prepare NTP Packet: 00126 pkt.li = 0; //Leap Indicator : No warning 00127 pkt.vn = 4; //Version Number : 4 00128 pkt.mode = 3; //Client mode 00129 pkt.stratum = 0; //Not relevant here 00130 pkt.poll = 0; //Not significant as well 00131 pkt.precision = 0; //Neither this one is 00132 00133 pkt.rootDelay = 0; //Or this one 00134 pkt.rootDispersion = 0; //Or that one 00135 pkt.refId = 0; //... 00136 00137 pkt.refTm_s = 0; 00138 pkt.origTm_s = 0; 00139 pkt.rxTm_s = 0; 00140 pkt.txTm_s = htonl( NTP_TIMESTAMP_DELTA + time(NULL) ); //WARN: We are in LE format, network byte order is BE 00141 00142 pkt.refTm_f = pkt.origTm_f = pkt.rxTm_f = pkt.txTm_f = 0; 00143 00144 Endpoint outEndpoint; 00145 00146 if( outEndpoint.set_address(host, port) < 0) 00147 { 00148 m_sock.close(); 00149 return NTP_DNS; 00150 } 00151 00152 //Set timeout, non-blocking and wait using select 00153 int ret = m_sock.sendTo( outEndpoint, (char*)&pkt, sizeof(NTPPacket) ); 00154 if (ret < 0 ) 00155 { 00156 ERR("Could not send packet"); 00157 m_sock.close(); 00158 return NTP_CONN; 00159 } 00160 00161 //Read response 00162 Endpoint inEndpoint; 00163 // Set the inEndpoint address property 00164 inEndpoint.set_address(outEndpoint.get_address(), 0); 00165 DBG("Pong"); 00166 do 00167 { 00168 ret = m_sock.receiveFrom( inEndpoint, (char*)&pkt, sizeof(NTPPacket) ); //FIXME need a DNS Resolver to actually compare the incoming address with the DNS name 00169 if(ret < 0) 00170 { 00171 ERR("Could not receive packet"); 00172 m_sock.close(); 00173 return NTP_CONN; 00174 } 00175 } while( strcmp(outEndpoint.get_address(), inEndpoint.get_address()) != 0 ); 00176 00177 if(ret < sizeof(NTPPacket)) //TODO: Accept chunks 00178 { 00179 ERR("Receive packet size does not match"); 00180 m_sock.close(); 00181 return NTP_PRTCL; 00182 } 00183 00184 if( pkt.stratum == 0) //Kiss of death message : Not good ! 00185 { 00186 ERR("Kissed to death!"); 00187 m_sock.close(); 00188 return NTP_PRTCL; 00189 } 00190 00191 //Correct Endianness 00192 pkt.refTm_s = ntohl( pkt.refTm_s ); 00193 pkt.refTm_f = ntohl( pkt.refTm_f ); 00194 pkt.origTm_s = ntohl( pkt.origTm_s ); 00195 pkt.origTm_f = ntohl( pkt.origTm_f ); 00196 pkt.rxTm_s = ntohl( pkt.rxTm_s ); 00197 pkt.rxTm_f = ntohl( pkt.rxTm_f ); 00198 pkt.txTm_s = ntohl( pkt.txTm_s ); 00199 pkt.txTm_f = ntohl( pkt.txTm_f ); 00200 00201 //Compute offset, see RFC 4330 p.13 00202 uint32_t destTm_s = (NTP_TIMESTAMP_DELTA + time(NULL)); 00203 int64_t offset = ( (int64_t)( pkt.rxTm_s - pkt.origTm_s ) + (int64_t) ( pkt.txTm_s - destTm_s ) ) / 2; //Avoid overflow 00204 DBG("Sent @%ul", pkt.txTm_s); 00205 DBG("Offset: %lld", offset); 00206 //Set time accordingly 00207 set_time( time(NULL) + offset ); 00208 00209 #ifdef __DEBUG__ 00210 ctTime = time(NULL); 00211 DBG("Time is now (UTC): %s", ctime(&ctTime)); 00212 #endif 00213 00214 m_sock.close(); 00215 00216 return NTP_OK; 00217 } 00218 00219
Generated on Thu Jul 14 2022 06:34:38 by 1.7.2