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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SNTPClient.cpp Source File

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&#177;00:00 Cote d'Ivoire, Faroe Islands, Ghana, Iceland, Senegal; (Summer) Ireland, Portugal (continental and Madeira)
00121 22) UTC&#177;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 }