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