sntp.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. /*
  2. * sntp.c
  3. *
  4. * Created on: 2014. 12. 15.
  5. * Author: Administrator
  6. */
  7. #include <string.h>
  8. #include "sntp.h"
  9. #include "socket.h"
  10. ntpformat NTPformat;
  11. datetime Nowdatetime;
  12. uint8_t ntpmessage[48];
  13. uint8_t *data_buf;
  14. uint8_t NTP_SOCKET;
  15. uint8_t time_zone;
  16. uint16_t ntp_retry_cnt=0; //counting the ntp retry number
  17. /*
  18. 00)UTC-12:00 Baker Island, Howland Island (both uninhabited)
  19. 01) UTC-11:00 American Samoa, Samoa
  20. 02) UTC-10:00 (Summer)French Polynesia (most), United States (Aleutian Islands, Hawaii)
  21. 03) UTC-09:30 Marquesas Islands
  22. 04) UTC-09:00 Gambier Islands;(Summer)United States (most of Alaska)
  23. 05) UTC-08:00 (Summer)Canada (most of British Columbia), Mexico (Baja California)
  24. 06) UTC-08:00 United States (California, most of Nevada, most of Oregon, Washington (state))
  25. 07) UTC-07:00 Mexico (Sonora), United States (Arizona); (Summer)Canada (Alberta)
  26. 08) UTC-07:00 Mexico (Chihuahua), United States (Colorado)
  27. 09) UTC-06:00 Costa Rica, El Salvador, Ecuador (Galapagos Islands), Guatemala, Honduras
  28. 10) UTC-06:00 Mexico (most), Nicaragua;(Summer)Canada (Manitoba, Saskatchewan), United States (Illinois, most of Texas)
  29. 11) UTC-05:00 Colombia, Cuba, Ecuador (continental), Haiti, Jamaica, Panama, Peru
  30. 12) UTC-05:00 (Summer)Canada (most of Ontario, most of Quebec)
  31. 13) UTC-05:00 United States (most of Florida, Georgia, Massachusetts, most of Michigan, New York, North Carolina, Ohio, Washington D.C.)
  32. 14) UTC-04:30 Venezuela
  33. 15) UTC-04:00 Bolivia, Brazil (Amazonas), Chile (continental), Dominican Republic, Canada (Nova Scotia), Paraguay,
  34. 16) UTC-04:00 Puerto Rico, Trinidad and Tobago
  35. 17) UTC-03:30 Canada (Newfoundland)
  36. 18) UTC-03:00 Argentina; (Summer) Brazil (Brasilia, Rio de Janeiro, Sao Paulo), most of Greenland, Uruguay
  37. 19) UTC-02:00 Brazil (Fernando de Noronha), South Georgia and the South Sandwich Islands
  38. 20) UTC-01:00 Portugal (Azores), Cape Verde
  39. 21) UTC&#177;00:00 Cote d'Ivoire, Faroe Islands, Ghana, Iceland, Senegal; (Summer) Ireland, Portugal (continental and Madeira)
  40. 22) UTC&#177;00:00 Spain (Canary Islands), Morocco, United Kingdom
  41. 23) UTC+01:00 Angola, Cameroon, Nigeria, Tunisia; (Summer)Albania, Algeria, Austria, Belgium, Bosnia and Herzegovina,
  42. 24) UTC+01:00 Spain (continental), Croatia, Czech Republic, Denmark, Germany, Hungary, Italy, Kinshasa, Kosovo,
  43. 25) UTC+01:00 Macedonia, France (metropolitan), the Netherlands, Norway, Poland, Serbia, Slovakia, Slovenia, Sweden, Switzerland
  44. 26) UTC+02:00 Libya, Egypt, Malawi, Mozambique, South Africa, Zambia, Zimbabwe, (Summer)Bulgaria, Cyprus, Estonia,
  45. 27) UTC+02:00 Finland, Greece, Israel, Jordan, Latvia, Lebanon, Lithuania, Moldova, Palestine, Romania, Syria, Turkey, Ukraine
  46. 28) UTC+03:00 Belarus, Djibouti, Eritrea, Ethiopia, Iraq, Kenya, Madagascar, Russia (Kaliningrad Oblast), Saudi Arabia,
  47. 29) UTC+03:00 South Sudan, Sudan, Somalia, South Sudan, Tanzania, Uganda, Yemen
  48. 30) UTC+03:30 (Summer)Iran
  49. 31) UTC+04:00 Armenia, Azerbaijan, Georgia, Mauritius, Oman, Russia (European), Seychelles, United Arab Emirates
  50. 32) UTC+04:30 Afghanistan
  51. 33) UTC+05:00 Kazakhstan (West), Maldives, Pakistan, Uzbekistan
  52. 34) UTC+05:30 India, Sri Lanka
  53. 35) UTC+05:45 Nepal
  54. 36) UTC+06:00 Kazakhstan (most), Bangladesh, Russia (Ural: Sverdlovsk Oblast, Chelyabinsk Oblast)
  55. 37) UTC+06:30 Cocos Islands, Myanmar
  56. 38) UTC+07:00 Jakarta, Russia (Novosibirsk Oblast), Thailand, Vietnam
  57. 39) UTC+08:00 China, Hong Kong, Russia (Krasnoyarsk Krai), Malaysia, Philippines, Singapore, Taiwan, most of Mongolia, Western Australia
  58. 40) UTC+09:00 Korea, East Timor, Russia (Irkutsk Oblast), Japan
  59. 41) UTC+09:30 Australia (Northern Territory);(Summer)Australia (South Australia))
  60. 42) UTC+10:00 Russia (Zabaykalsky Krai); (Summer)Australia (New South Wales, Queensland, Tasmania, Victoria)
  61. 43) UTC+10:30 Lord Howe Island
  62. 44) UTC+11:00 New Caledonia, Russia (Primorsky Krai), Solomon Islands
  63. 45) UTC+11:30 Norfolk Island
  64. 46) UTC+12:00 Fiji, Russia (Kamchatka Krai);(Summer)New Zealand
  65. 47) UTC+12:45 (Summer)New Zealand
  66. 48) UTC+13:00 Tonga
  67. 49) UTC+14:00 Kiribati (Line Islands)
  68. */
  69. void get_seconds_from_ntp_server(uint8_t *buf, uint16_t idx)
  70. {
  71. tstamp seconds = 0;
  72. uint8_t i=0;
  73. for (i = 0; i < 4; i++)
  74. {
  75. seconds = (seconds << 8) | buf[idx + i];
  76. }
  77. switch (time_zone)
  78. {
  79. case 0:
  80. seconds -= 12*3600;
  81. break;
  82. case 1:
  83. seconds -= 11*3600;
  84. break;
  85. case 2:
  86. seconds -= 10*3600;
  87. break;
  88. case 3:
  89. seconds -= (9*3600+30*60);
  90. break;
  91. case 4:
  92. seconds -= 9*3600;
  93. break;
  94. case 5:
  95. case 6:
  96. seconds -= 8*3600;
  97. break;
  98. case 7:
  99. case 8:
  100. seconds -= 7*3600;
  101. break;
  102. case 9:
  103. case 10:
  104. seconds -= 6*3600;
  105. break;
  106. case 11:
  107. case 12:
  108. case 13:
  109. seconds -= 5*3600;
  110. break;
  111. case 14:
  112. seconds -= (4*3600+30*60);
  113. break;
  114. case 15:
  115. case 16:
  116. seconds -= 4*3600;
  117. break;
  118. case 17:
  119. seconds -= (3*3600+30*60);
  120. break;
  121. case 18:
  122. seconds -= 3*3600;
  123. break;
  124. case 19:
  125. seconds -= 2*3600;
  126. break;
  127. case 20:
  128. seconds -= 1*3600;
  129. break;
  130. case 21: //ï¼?
  131. case 22:
  132. break;
  133. case 23:
  134. case 24:
  135. case 25:
  136. seconds += 1*3600;
  137. break;
  138. case 26:
  139. case 27:
  140. seconds += 2*3600;
  141. break;
  142. case 28:
  143. case 29:
  144. seconds += 3*3600;
  145. break;
  146. case 30:
  147. seconds += (3*3600+30*60);
  148. break;
  149. case 31:
  150. seconds += 4*3600;
  151. break;
  152. case 32:
  153. seconds += (4*3600+30*60);
  154. break;
  155. case 33:
  156. seconds += 5*3600;
  157. break;
  158. case 34:
  159. seconds += (5*3600+30*60);
  160. break;
  161. case 35:
  162. seconds += (5*3600+45*60);
  163. break;
  164. case 36:
  165. seconds += 6*3600;
  166. break;
  167. case 37:
  168. seconds += (6*3600+30*60);
  169. break;
  170. case 38:
  171. seconds += 7*3600;
  172. break;
  173. case 39:
  174. seconds += 8*3600;
  175. break;
  176. case 40:
  177. seconds += 9*3600;
  178. break;
  179. case 41:
  180. seconds += (9*3600+30*60);
  181. break;
  182. case 42:
  183. seconds += 10*3600;
  184. break;
  185. case 43:
  186. seconds += (10*3600+30*60);
  187. break;
  188. case 44:
  189. seconds += 11*3600;
  190. break;
  191. case 45:
  192. seconds += (11*3600+30*60);
  193. break;
  194. case 46:
  195. seconds += 12*3600;
  196. break;
  197. case 47:
  198. seconds += (12*3600+45*60);
  199. break;
  200. case 48:
  201. seconds += 13*3600;
  202. break;
  203. case 49:
  204. seconds += 14*3600;
  205. break;
  206. }
  207. //calculation for date
  208. calcdatetime(seconds);
  209. }
  210. void SNTP_init(uint8_t s, uint8_t *ntp_server, uint8_t tz, uint8_t *buf)
  211. {
  212. NTP_SOCKET = s;
  213. NTPformat.dstaddr[0] = ntp_server[0];
  214. NTPformat.dstaddr[1] = ntp_server[1];
  215. NTPformat.dstaddr[2] = ntp_server[2];
  216. NTPformat.dstaddr[3] = ntp_server[3];
  217. time_zone = tz;
  218. data_buf = buf;
  219. uint8_t Flag;
  220. NTPformat.leap = 0; /* leap indicator */
  221. NTPformat.version = 4; /* version number */
  222. NTPformat.mode = 3; /* mode */
  223. NTPformat.stratum = 0; /* stratum */
  224. NTPformat.poll = 0; /* poll interval */
  225. NTPformat.precision = 0; /* precision */
  226. NTPformat.rootdelay = 0; /* root delay */
  227. NTPformat.rootdisp = 0; /* root dispersion */
  228. NTPformat.refid = 0; /* reference ID */
  229. NTPformat.reftime = 0; /* reference time */
  230. NTPformat.org = 0; /* origin timestamp */
  231. NTPformat.rec = 0; /* receive timestamp */
  232. NTPformat.xmt = 1; /* transmit timestamp */
  233. Flag = (NTPformat.leap<<6)+(NTPformat.version<<3)+NTPformat.mode; //one byte Flag
  234. memcpy(ntpmessage,(void const*)(&Flag),1);
  235. }
  236. int8_t SNTP_run(datetime *time)
  237. {
  238. uint16_t RSR_len;
  239. uint32_t destip = 0;
  240. uint16_t destport;
  241. uint16_t startindex = 40; //last 8-byte of data_buf[size is 48 byte] is xmt, so the startindex should be 40
  242. switch(getSn_SR(NTP_SOCKET))
  243. {
  244. case SOCK_UDP:
  245. if ((RSR_len = getSn_RX_RSR(NTP_SOCKET)) > 0)
  246. {
  247. if (RSR_len > MAX_SNTP_BUF_SIZE) RSR_len = MAX_SNTP_BUF_SIZE; // if Rx data size is lager than TX_RX_MAX_BUF_SIZE
  248. recvfrom(NTP_SOCKET, data_buf, RSR_len, (uint8_t *)&destip, &destport);
  249. get_seconds_from_ntp_server(data_buf,startindex);
  250. time->yy = Nowdatetime.yy;
  251. time->mo = Nowdatetime.mo;
  252. time->dd = Nowdatetime.dd;
  253. time->hh = Nowdatetime.hh;
  254. time->mm = Nowdatetime.mm;
  255. time->ss = Nowdatetime.ss;
  256. ntp_retry_cnt=0;
  257. close(NTP_SOCKET);
  258. return 1;
  259. }
  260. if(ntp_retry_cnt<0xFFFF)
  261. {
  262. if(ntp_retry_cnt==0)//first send request, no need to wait
  263. {
  264. sendto(NTP_SOCKET,ntpmessage,sizeof(ntpmessage),NTPformat.dstaddr,ntp_port);
  265. ntp_retry_cnt++;
  266. }
  267. else // send request again? it should wait for a while
  268. {
  269. if((ntp_retry_cnt % 0xFFF) == 0) //wait time
  270. {
  271. sendto(NTP_SOCKET,ntpmessage,sizeof(ntpmessage),NTPformat.dstaddr,ntp_port);
  272. #ifdef _SNTP_DEBUG_
  273. printf("ntp retry: %d\r\n", ntp_retry_cnt);
  274. #endif
  275. ntp_retry_cnt++;
  276. }
  277. }
  278. }
  279. else //ntp retry fail
  280. {
  281. ntp_retry_cnt=0;
  282. #ifdef _SNTP_DEBUG_
  283. printf("ntp retry failed!\r\n");
  284. #endif
  285. close(NTP_SOCKET);
  286. }
  287. break;
  288. case SOCK_CLOSED:
  289. socket(NTP_SOCKET,Sn_MR_UDP,ntp_port,0);
  290. break;
  291. }
  292. // Return value
  293. // 0 - failed / 1 - success
  294. return 0;
  295. }
  296. void calcdatetime(tstamp seconds)
  297. {
  298. uint8_t yf=0;
  299. tstamp n=0,d=0,total_d=0,rz=0;
  300. uint16_t y=0,r=0,yr=0;
  301. signed long long yd=0;
  302. n = seconds;
  303. total_d = seconds/(SECS_PERDAY);
  304. d=0;
  305. uint32_t p_year_total_sec=SECS_PERDAY*365;
  306. uint32_t r_year_total_sec=SECS_PERDAY*366;
  307. while(n>=p_year_total_sec)
  308. {
  309. if((EPOCH+r)%400==0 || ((EPOCH+r)%100!=0 && (EPOCH+r)%4==0))
  310. {
  311. n = n -(r_year_total_sec);
  312. d = d + 366;
  313. }
  314. else
  315. {
  316. n = n - (p_year_total_sec);
  317. d = d + 365;
  318. }
  319. r+=1;
  320. y+=1;
  321. }
  322. y += EPOCH;
  323. Nowdatetime.yy = y;
  324. yd=0;
  325. yd = total_d - d;
  326. yf=1;
  327. while(yd>=28)
  328. {
  329. if(yf==1 || yf==3 || yf==5 || yf==7 || yf==8 || yf==10 || yf==12)
  330. {
  331. yd -= 31;
  332. if(yd<0)break;
  333. rz += 31;
  334. }
  335. if (yf==2)
  336. {
  337. if (y%400==0 || (y%100!=0 && y%4==0))
  338. {
  339. yd -= 29;
  340. if(yd<0)break;
  341. rz += 29;
  342. }
  343. else
  344. {
  345. yd -= 28;
  346. if(yd<0)break;
  347. rz += 28;
  348. }
  349. }
  350. if(yf==4 || yf==6 || yf==9 || yf==11 )
  351. {
  352. yd -= 30;
  353. if(yd<0)break;
  354. rz += 30;
  355. }
  356. yf += 1;
  357. }
  358. Nowdatetime.mo=yf;
  359. yr = total_d-d-rz;
  360. yr += 1;
  361. Nowdatetime.dd=yr;
  362. //calculation for time
  363. seconds = seconds%SECS_PERDAY;
  364. Nowdatetime.hh = seconds/3600;
  365. Nowdatetime.mm = (seconds%3600)/60;
  366. Nowdatetime.ss = (seconds%3600)%60;
  367. }
  368. tstamp changedatetime_to_seconds(void)
  369. {
  370. tstamp seconds=0;
  371. uint32_t total_day=0;
  372. uint16_t i=0,run_year_cnt=0,l=0;
  373. l = Nowdatetime.yy;//low
  374. for(i=EPOCH;i<l;i++)
  375. {
  376. if((i%400==0) || ((i%100!=0) && (i%4==0)))
  377. {
  378. run_year_cnt += 1;
  379. }
  380. }
  381. total_day=(l-EPOCH-run_year_cnt)*365+run_year_cnt*366;
  382. for(i=1;i<=Nowdatetime.mo;i++)
  383. {
  384. if(i==5 || i==7 || i==10 || i==12)
  385. {
  386. total_day += 30;
  387. }
  388. if (i==3)
  389. {
  390. if (l%400==0 && l%100!=0 && l%4==0)
  391. {
  392. total_day += 29;
  393. }
  394. else
  395. {
  396. total_day += 28;
  397. }
  398. }
  399. if(i==2 || i==4 || i==6 || i==8 || i==9 || i==11)
  400. {
  401. total_day += 31;
  402. }
  403. }
  404. seconds = (total_day+Nowdatetime.dd-1)*24*3600;
  405. seconds += Nowdatetime.ss;//seconds
  406. seconds += Nowdatetime.mm*60;//minute
  407. seconds += Nowdatetime.hh*3600;//hour
  408. return seconds;
  409. }