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.
Dependents: coap-example Borsch coap-example
Fork of NetworkServices by
SNTPClient.cpp
00001 #include "SNTPClient.h" 00002 #include "DNSClient.h" 00003 00004 #define MAX_TRY_WRITE 20 00005 #define MAX_TRY_READ 10 00006 00007 //Debug is disabled by default 00008 #ifdef _SNTP_DEBUG_ 00009 #define DBG(x, ...) std::printf("[SNTPClient : DBG]"x"\r\n", ##__VA_ARGS__); 00010 #define WARN(x, ...) std::printf("[SNTPClient : WARN]"x"\r\n", ##__VA_ARGS__); 00011 #define ERR(x, ...) std::printf("[SNTPClient : ERR]"x"\r\n", ##__VA_ARGS__); 00012 #else 00013 #define DBG(x, ...) 00014 #define WARN(x, ...) 00015 #define ERR(x, ...) 00016 #endif 00017 00018 #define INFO(x, ...) printf("[SNTPClient : INFO]"x"\r\n", ##__VA_ARGS__); 00019 00020 SNTPClient::SNTPClient(NetworkStack *ns, const char* url, uint8_t time_zone) { 00021 DNSClient dns(ns); 00022 00023 if (dns.lookup(url)) { 00024 const char* dns_addr = dns.get_ip_address(); 00025 memcpy(host, dns_addr, strlen(dns_addr)); 00026 host[strlen(dns_addr)] = '\0'; 00027 } else { 00028 memcpy(host, url, strlen(url)); 00029 host[strlen(url)] = '\0'; 00030 } 00031 00032 port = ntp_port; 00033 m_ns = ns; 00034 m_udp = NULL; 00035 tz = time_zone; 00036 } 00037 00038 bool SNTPClient::connect() { 00039 if (m_udp == NULL) { 00040 m_udp = new UDPSocket; 00041 m_udp->open(m_ns); 00042 } 00043 00044 m_udp->set_blocking(false); 00045 m_udp->set_timeout(3000); 00046 m_udp->bind(rand()&0x7fff); 00047 00048 sntp_server.set_ip_address(host); 00049 sntp_server.set_port(port); 00050 00051 nsapi_addr_t na = sntp_server.get_addr(); 00052 NTPformat.dstaddr[0] = na.bytes[0]; 00053 NTPformat.dstaddr[1] = na.bytes[1]; 00054 NTPformat.dstaddr[2] = na.bytes[2]; 00055 NTPformat.dstaddr[3] = na.bytes[3]; 00056 DBG("NTP Server: %s\r\n", sntp_server.get_ip_address()); 00057 00058 uint8_t Flag; 00059 NTPformat.leap = 0; /* leap indicator */ 00060 NTPformat.version = 4; /* version number */ 00061 NTPformat.mode = 3; /* mode */ 00062 NTPformat.stratum = 0; /* stratum */ 00063 NTPformat.poll = 0; /* poll interval */ 00064 NTPformat.precision = 0; /* precision */ 00065 NTPformat.rootdelay = 0; /* root delay */ 00066 NTPformat.rootdisp = 0; /* root dispersion */ 00067 NTPformat.refid = 0; /* reference ID */ 00068 NTPformat.reftime = 0; /* reference time */ 00069 NTPformat.org = 0; /* origin timestamp */ 00070 NTPformat.rec = 0; /* receive timestamp */ 00071 NTPformat.xmt = 1; /* transmit timestamp */ 00072 00073 Flag = (NTPformat.leap<<6)+(NTPformat.version<<3)+NTPformat.mode; //one byte Flag 00074 memcpy(ntpmessage,(void const*)(&Flag),1); 00075 00076 return true; 00077 } 00078 00079 bool SNTPClient::getTime(datetime *time) { 00080 if (!m_udp) return false; 00081 00082 uint16_t startindex = 40; //last 8-byte of data_buf[size is 48 byte] is xmt, so the startindex should be 40 00083 00084 int n = m_udp->sendto(sntp_server, (char *)ntpmessage, sizeof(ntpmessage)); 00085 00086 char in_buffer[MAX_SNTP_BUF_SIZE]; 00087 n = m_udp->recvfrom(&sntp_server, in_buffer, sizeof(in_buffer)); 00088 00089 if(n <= 0) { 00090 return false; 00091 } 00092 00093 get_seconds_from_ntp_server((uint8_t *)in_buffer,startindex); 00094 00095 time->yy = Nowdatetime.yy; 00096 time->mo = Nowdatetime.mo; 00097 time->dd = Nowdatetime.dd; 00098 time->hh = Nowdatetime.hh; 00099 time->mm = Nowdatetime.mm; 00100 time->ss = Nowdatetime.ss; 00101 00102 return true; 00103 } 00104 00105 bool SNTPClient::close() { 00106 if (m_udp) { 00107 delete m_udp; 00108 m_udp = NULL; 00109 } 00110 return true; 00111 } 00112 00113 char* SNTPClient::getHost() { 00114 return host; 00115 } 00116 00117 /* 00118 00)UTC-12:00 Baker Island, Howland Island (both uninhabited) 00119 01) UTC-11:00 American Samoa, Samoa 00120 02) UTC-10:00 (Summer)French Polynesia (most), United States (Aleutian Islands, Hawaii) 00121 03) UTC-09:30 Marquesas Islands 00122 04) UTC-09:00 Gambier Islands;(Summer)United States (most of Alaska) 00123 05) UTC-08:00 (Summer)Canada (most of British Columbia), Mexico (Baja California) 00124 06) UTC-08:00 United States (California, most of Nevada, most of Oregon, Washington (state)) 00125 07) UTC-07:00 Mexico (Sonora), United States (Arizona); (Summer)Canada (Alberta) 00126 08) UTC-07:00 Mexico (Chihuahua), United States (Colorado) 00127 09) UTC-06:00 Costa Rica, El Salvador, Ecuador (Galapagos Islands), Guatemala, Honduras 00128 10) UTC-06:00 Mexico (most), Nicaragua;(Summer)Canada (Manitoba, Saskatchewan), United States (Illinois, most of Texas) 00129 11) UTC-05:00 Colombia, Cuba, Ecuador (continental), Haiti, Jamaica, Panama, Peru 00130 12) UTC-05:00 (Summer)Canada (most of Ontario, most of Quebec) 00131 13) UTC-05:00 United States (most of Florida, Georgia, Massachusetts, most of Michigan, New York, North Carolina, Ohio, Washington D.C.) 00132 14) UTC-04:30 Venezuela 00133 15) UTC-04:00 Bolivia, Brazil (Amazonas), Chile (continental), Dominican Republic, Canada (Nova Scotia), Paraguay, 00134 16) UTC-04:00 Puerto Rico, Trinidad and Tobago 00135 17) UTC-03:30 Canada (Newfoundland) 00136 18) UTC-03:00 Argentina; (Summer) Brazil (Brasilia, Rio de Janeiro, Sao Paulo), most of Greenland, Uruguay 00137 19) UTC-02:00 Brazil (Fernando de Noronha), South Georgia and the South Sandwich Islands 00138 20) UTC-01:00 Portugal (Azores), Cape Verde 00139 21) UTC±00:00 Cote d'Ivoire, Faroe Islands, Ghana, Iceland, Senegal; (Summer) Ireland, Portugal (continental and Madeira) 00140 22) UTC±00:00 Spain (Canary Islands), Morocco, United Kingdom 00141 23) UTC+01:00 Angola, Cameroon, Nigeria, Tunisia; (Summer)Albania, Algeria, Austria, Belgium, Bosnia and Herzegovina, 00142 24) UTC+01:00 Spain (continental), Croatia, Czech Republic, Denmark, Germany, Hungary, Italy, Kinshasa, Kosovo, 00143 25) UTC+01:00 Macedonia, France (metropolitan), the Netherlands, Norway, Poland, Serbia, Slovakia, Slovenia, Sweden, Switzerland 00144 26) UTC+02:00 Libya, Egypt, Malawi, Mozambique, South Africa, Zambia, Zimbabwe, (Summer)Bulgaria, Cyprus, Estonia, 00145 27) UTC+02:00 Finland, Greece, Israel, Jordan, Latvia, Lebanon, Lithuania, Moldova, Palestine, Romania, Syria, Turkey, Ukraine 00146 28) UTC+03:00 Belarus, Djibouti, Eritrea, Ethiopia, Iraq, Kenya, Madagascar, Russia (Kaliningrad Oblast), Saudi Arabia, 00147 29) UTC+03:00 South Sudan, Sudan, Somalia, South Sudan, Tanzania, Uganda, Yemen 00148 30) UTC+03:30 (Summer)Iran 00149 31) UTC+04:00 Armenia, Azerbaijan, Georgia, Mauritius, Oman, Russia (European), Seychelles, United Arab Emirates 00150 32) UTC+04:30 Afghanistan 00151 33) UTC+05:00 Kazakhstan (West), Maldives, Pakistan, Uzbekistan 00152 34) UTC+05:30 India, Sri Lanka 00153 35) UTC+05:45 Nepal 00154 36) UTC+06:00 Kazakhstan (most), Bangladesh, Russia (Ural: Sverdlovsk Oblast, Chelyabinsk Oblast) 00155 37) UTC+06:30 Cocos Islands, Myanmar 00156 38) UTC+07:00 Jakarta, Russia (Novosibirsk Oblast), Thailand, Vietnam 00157 39) UTC+08:00 China, Hong Kong, Russia (Krasnoyarsk Krai), Malaysia, Philippines, Singapore, Taiwan, most of Mongolia, Western Australia 00158 40) UTC+09:00 Korea, East Timor, Russia (Irkutsk Oblast), Japan 00159 41) UTC+09:30 Australia (Northern Territory);(Summer)Australia (South Australia)) 00160 42) UTC+10:00 Russia (Zabaykalsky Krai); (Summer)Australia (New South Wales, Queensland, Tasmania, Victoria) 00161 43) UTC+10:30 Lord Howe Island 00162 44) UTC+11:00 New Caledonia, Russia (Primorsky Krai), Solomon Islands 00163 45) UTC+11:30 Norfolk Island 00164 46) UTC+12:00 Fiji, Russia (Kamchatka Krai);(Summer)New Zealand 00165 47) UTC+12:45 (Summer)New Zealand 00166 48) UTC+13:00 Tonga 00167 49) UTC+14:00 Kiribati (Line Islands) 00168 */ 00169 void SNTPClient::get_seconds_from_ntp_server(uint8_t *buf, uint16_t idx) 00170 { 00171 tstamp seconds = 0; 00172 uint8_t i=0; 00173 for (i = 0; i < 4; i++) 00174 { 00175 seconds = (seconds << 8) | buf[idx + i]; 00176 } 00177 switch (tz) // Time Zone 00178 { 00179 case 0: 00180 seconds -= 12*3600; 00181 break; 00182 case 1: 00183 seconds -= 11*3600; 00184 break; 00185 case 2: 00186 seconds -= 10*3600; 00187 break; 00188 case 3: 00189 seconds -= (9*3600+30*60); 00190 break; 00191 case 4: 00192 seconds -= 9*3600; 00193 break; 00194 case 5: 00195 case 6: 00196 seconds -= 8*3600; 00197 break; 00198 case 7: 00199 case 8: 00200 seconds -= 7*3600; 00201 break; 00202 case 9: 00203 case 10: 00204 seconds -= 6*3600; 00205 break; 00206 case 11: 00207 case 12: 00208 case 13: 00209 seconds -= 5*3600; 00210 break; 00211 case 14: 00212 seconds -= (4*3600+30*60); 00213 break; 00214 case 15: 00215 case 16: 00216 seconds -= 4*3600; 00217 break; 00218 case 17: 00219 seconds -= (3*3600+30*60); 00220 break; 00221 case 18: 00222 seconds -= 3*3600; 00223 break; 00224 case 19: 00225 seconds -= 2*3600; 00226 break; 00227 case 20: 00228 seconds -= 1*3600; 00229 break; 00230 case 21: //? 00231 case 22: 00232 break; 00233 case 23: 00234 case 24: 00235 case 25: 00236 seconds += 1*3600; 00237 break; 00238 case 26: 00239 case 27: 00240 seconds += 2*3600; 00241 break; 00242 case 28: 00243 case 29: 00244 seconds += 3*3600; 00245 break; 00246 case 30: 00247 seconds += (3*3600+30*60); 00248 break; 00249 case 31: 00250 seconds += 4*3600; 00251 break; 00252 case 32: 00253 seconds += (4*3600+30*60); 00254 break; 00255 case 33: 00256 seconds += 5*3600; 00257 break; 00258 case 34: 00259 seconds += (5*3600+30*60); 00260 break; 00261 case 35: 00262 seconds += (5*3600+45*60); 00263 break; 00264 case 36: 00265 seconds += 6*3600; 00266 break; 00267 case 37: 00268 seconds += (6*3600+30*60); 00269 break; 00270 case 38: 00271 seconds += 7*3600; 00272 break; 00273 case 39: 00274 seconds += 8*3600; 00275 break; 00276 case 40: 00277 seconds += 9*3600; 00278 break; 00279 case 41: 00280 seconds += (9*3600+30*60); 00281 break; 00282 case 42: 00283 seconds += 10*3600; 00284 break; 00285 case 43: 00286 seconds += (10*3600+30*60); 00287 break; 00288 case 44: 00289 seconds += 11*3600; 00290 break; 00291 case 45: 00292 seconds += (11*3600+30*60); 00293 break; 00294 case 46: 00295 seconds += 12*3600; 00296 break; 00297 case 47: 00298 seconds += (12*3600+45*60); 00299 break; 00300 case 48: 00301 seconds += 13*3600; 00302 break; 00303 case 49: 00304 seconds += 14*3600; 00305 break; 00306 00307 } 00308 00309 //calculation for date 00310 calcdatetime(seconds); 00311 } 00312 00313 void SNTPClient::calcdatetime(tstamp seconds) 00314 { 00315 uint8_t yf=0; 00316 tstamp n=0,d=0,total_d=0,rz=0; 00317 uint16_t y=0,r=0,yr=0; 00318 signed long long yd=0; 00319 00320 n = seconds; 00321 total_d = seconds/(SECS_PERDAY); 00322 d=0; 00323 uint32_t p_year_total_sec=SECS_PERDAY*365; 00324 uint32_t r_year_total_sec=SECS_PERDAY*366; 00325 while(n>=p_year_total_sec) 00326 { 00327 if((EPOCH+r)%400==0 || ((EPOCH+r)%100!=0 && (EPOCH+r)%4==0)) 00328 { 00329 n = n -(r_year_total_sec); 00330 d = d + 366; 00331 } 00332 else 00333 { 00334 n = n - (p_year_total_sec); 00335 d = d + 365; 00336 } 00337 r+=1; 00338 y+=1; 00339 00340 } 00341 00342 y += EPOCH; 00343 00344 Nowdatetime.yy = y; 00345 00346 yd=0; 00347 yd = total_d - d; 00348 00349 yf=1; 00350 while(yd>=28) 00351 { 00352 00353 if(yf==1 || yf==3 || yf==5 || yf==7 || yf==8 || yf==10 || yf==12) 00354 { 00355 yd -= 31; 00356 if(yd<0)break; 00357 rz += 31; 00358 } 00359 00360 if (yf==2) 00361 { 00362 if (y%400==0 || (y%100!=0 && y%4==0)) 00363 { 00364 yd -= 29; 00365 if(yd<0)break; 00366 rz += 29; 00367 } 00368 else 00369 { 00370 yd -= 28; 00371 if(yd<0)break; 00372 rz += 28; 00373 } 00374 } 00375 if(yf==4 || yf==6 || yf==9 || yf==11 ) 00376 { 00377 yd -= 30; 00378 if(yd<0)break; 00379 rz += 30; 00380 } 00381 yf += 1; 00382 00383 } 00384 Nowdatetime.mo=yf; 00385 yr = total_d-d-rz; 00386 00387 yr += 1; 00388 00389 Nowdatetime.dd=yr; 00390 00391 //calculation for time 00392 seconds = seconds%SECS_PERDAY; 00393 Nowdatetime.hh = seconds/3600; 00394 Nowdatetime.mm = (seconds%3600)/60; 00395 Nowdatetime.ss = (seconds%3600)%60; 00396 00397 } 00398 00399 tstamp SNTPClient::changedatetime_to_seconds(void) 00400 { 00401 tstamp seconds=0; 00402 uint32_t total_day=0; 00403 uint16_t i=0,run_year_cnt=0,l=0; 00404 00405 l = Nowdatetime.yy;//low 00406 00407 00408 for(i=EPOCH;i<l;i++) 00409 { 00410 if((i%400==0) || ((i%100!=0) && (i%4==0))) 00411 { 00412 run_year_cnt += 1; 00413 } 00414 } 00415 00416 total_day=(l-EPOCH-run_year_cnt)*365+run_year_cnt*366; 00417 00418 for(i=1;i<=Nowdatetime.mo;i++) 00419 { 00420 if(i==5 || i==7 || i==10 || i==12) 00421 { 00422 total_day += 30; 00423 } 00424 if (i==3) 00425 { 00426 if (l%400==0 && l%100!=0 && l%4==0) 00427 { 00428 total_day += 29; 00429 } 00430 else 00431 { 00432 total_day += 28; 00433 } 00434 } 00435 if(i==2 || i==4 || i==6 || i==8 || i==9 || i==11) 00436 { 00437 total_day += 31; 00438 } 00439 } 00440 00441 seconds = (total_day+Nowdatetime.dd-1)*24*3600; 00442 seconds += Nowdatetime.ss;//seconds 00443 seconds += Nowdatetime.mm*60;//minute 00444 seconds += Nowdatetime.hh*3600;//hour 00445 00446 return seconds; 00447 }
Generated on Fri Jul 15 2022 01:11:07 by
1.7.2
