470 lines
14 KiB
C
470 lines
14 KiB
C
/*
|
||
sntp.c
|
||
|
||
Created on: 2014. 12. 15.
|
||
Author: Administrator
|
||
*/
|
||
|
||
|
||
#include <string.h>
|
||
|
||
#include "sntp.h"
|
||
#include "socket.h"
|
||
|
||
ntpformat NTPformat;
|
||
datetime Nowdatetime;
|
||
uint8_t ntpmessage[48];
|
||
uint8_t *data_buf;
|
||
uint8_t NTP_SOCKET;
|
||
uint8_t time_zone;
|
||
uint16_t ntp_retry_cnt = 0; //counting the ntp retry number
|
||
|
||
/*
|
||
00)UTC-12:00 Baker Island, Howland Island (both uninhabited)
|
||
01) UTC-11:00 American Samoa, Samoa
|
||
02) UTC-10:00 (Summer)French Polynesia (most), United States (Aleutian Islands, Hawaii)
|
||
03) UTC-09:30 Marquesas Islands
|
||
04) UTC-09:00 Gambier Islands;(Summer)United States (most of Alaska)
|
||
05) UTC-08:00 (Summer)Canada (most of British Columbia), Mexico (Baja California)
|
||
06) UTC-08:00 United States (California, most of Nevada, most of Oregon, Washington (state))
|
||
07) UTC-07:00 Mexico (Sonora), United States (Arizona); (Summer)Canada (Alberta)
|
||
08) UTC-07:00 Mexico (Chihuahua), United States (Colorado)
|
||
09) UTC-06:00 Costa Rica, El Salvador, Ecuador (Galapagos Islands), Guatemala, Honduras
|
||
10) UTC-06:00 Mexico (most), Nicaragua;(Summer)Canada (Manitoba, Saskatchewan), United States (Illinois, most of Texas)
|
||
11) UTC-05:00 Colombia, Cuba, Ecuador (continental), Haiti, Jamaica, Panama, Peru
|
||
12) UTC-05:00 (Summer)Canada (most of Ontario, most of Quebec)
|
||
13) UTC-05:00 United States (most of Florida, Georgia, Massachusetts, most of Michigan, New York, North Carolina, Ohio, Washington D.C.)
|
||
14) UTC-04:30 Venezuela
|
||
15) UTC-04:00 Bolivia, Brazil (Amazonas), Chile (continental), Dominican Republic, Canada (Nova Scotia), Paraguay,
|
||
16) UTC-04:00 Puerto Rico, Trinidad and Tobago
|
||
17) UTC-03:30 Canada (Newfoundland)
|
||
18) UTC-03:00 Argentina; (Summer) Brazil (Brasilia, Rio de Janeiro, Sao Paulo), most of Greenland, Uruguay
|
||
19) UTC-02:00 Brazil (Fernando de Noronha), South Georgia and the South Sandwich Islands
|
||
20) UTC-01:00 Portugal (Azores), Cape Verde
|
||
21) UTC±00:00 Cote d'Ivoire, Faroe Islands, Ghana, Iceland, Senegal; (Summer) Ireland, Portugal (continental and Madeira)
|
||
22) UTC±00:00 Spain (Canary Islands), Morocco, United Kingdom
|
||
23) UTC+01:00 Angola, Cameroon, Nigeria, Tunisia; (Summer)Albania, Algeria, Austria, Belgium, Bosnia and Herzegovina,
|
||
24) UTC+01:00 Spain (continental), Croatia, Czech Republic, Denmark, Germany, Hungary, Italy, Kinshasa, Kosovo,
|
||
25) UTC+01:00 Macedonia, France (metropolitan), the Netherlands, Norway, Poland, Serbia, Slovakia, Slovenia, Sweden, Switzerland
|
||
26) UTC+02:00 Libya, Egypt, Malawi, Mozambique, South Africa, Zambia, Zimbabwe, (Summer)Bulgaria, Cyprus, Estonia,
|
||
27) UTC+02:00 Finland, Greece, Israel, Jordan, Latvia, Lebanon, Lithuania, Moldova, Palestine, Romania, Syria, Turkey, Ukraine
|
||
28) UTC+03:00 Belarus, Djibouti, Eritrea, Ethiopia, Iraq, Kenya, Madagascar, Russia (Kaliningrad Oblast), Saudi Arabia,
|
||
29) UTC+03:00 South Sudan, Sudan, Somalia, South Sudan, Tanzania, Uganda, Yemen
|
||
30) UTC+03:30 (Summer)Iran
|
||
31) UTC+04:00 Armenia, Azerbaijan, Georgia, Mauritius, Oman, Russia (European), Seychelles, United Arab Emirates
|
||
32) UTC+04:30 Afghanistan
|
||
33) UTC+05:00 Kazakhstan (West), Maldives, Pakistan, Uzbekistan
|
||
34) UTC+05:30 India, Sri Lanka
|
||
35) UTC+05:45 Nepal
|
||
36) UTC+06:00 Kazakhstan (most), Bangladesh, Russia (Ural: Sverdlovsk Oblast, Chelyabinsk Oblast)
|
||
37) UTC+06:30 Cocos Islands, Myanmar
|
||
38) UTC+07:00 Jakarta, Russia (Novosibirsk Oblast), Thailand, Vietnam
|
||
39) UTC+08:00 China, Hong Kong, Russia (Krasnoyarsk Krai), Malaysia, Philippines, Singapore, Taiwan, most of Mongolia, Western Australia
|
||
40) UTC+09:00 Korea, East Timor, Russia (Irkutsk Oblast), Japan
|
||
41) UTC+09:30 Australia (Northern Territory);(Summer)Australia (South Australia))
|
||
42) UTC+10:00 Russia (Zabaykalsky Krai); (Summer)Australia (New South Wales, Queensland, Tasmania, Victoria)
|
||
43) UTC+10:30 Lord Howe Island
|
||
44) UTC+11:00 New Caledonia, Russia (Primorsky Krai), Solomon Islands
|
||
45) UTC+11:30 Norfolk Island
|
||
46) UTC+12:00 Fiji, Russia (Kamchatka Krai);(Summer)New Zealand
|
||
47) UTC+12:45 (Summer)New Zealand
|
||
48) UTC+13:00 Tonga
|
||
49) UTC+14:00 Kiribati (Line Islands)
|
||
*/
|
||
void get_seconds_from_ntp_server(uint8_t *buf, uint16_t idx) {
|
||
tstamp seconds = 0;
|
||
uint8_t i = 0;
|
||
for (i = 0; i < 4; i++) {
|
||
seconds = (seconds << 8) | buf[idx + i];
|
||
}
|
||
switch (time_zone) {
|
||
case 0:
|
||
seconds -= 12 * 3600;
|
||
break;
|
||
case 1:
|
||
seconds -= 11 * 3600;
|
||
break;
|
||
case 2:
|
||
seconds -= 10 * 3600;
|
||
break;
|
||
case 3:
|
||
seconds -= (9 * 3600 + 30 * 60);
|
||
break;
|
||
case 4:
|
||
seconds -= 9 * 3600;
|
||
break;
|
||
case 5:
|
||
case 6:
|
||
seconds -= 8 * 3600;
|
||
break;
|
||
case 7:
|
||
case 8:
|
||
seconds -= 7 * 3600;
|
||
break;
|
||
case 9:
|
||
case 10:
|
||
seconds -= 6 * 3600;
|
||
break;
|
||
case 11:
|
||
case 12:
|
||
case 13:
|
||
seconds -= 5 * 3600;
|
||
break;
|
||
case 14:
|
||
seconds -= (4 * 3600 + 30 * 60);
|
||
break;
|
||
case 15:
|
||
case 16:
|
||
seconds -= 4 * 3600;
|
||
break;
|
||
case 17:
|
||
seconds -= (3 * 3600 + 30 * 60);
|
||
break;
|
||
case 18:
|
||
seconds -= 3 * 3600;
|
||
break;
|
||
case 19:
|
||
seconds -= 2 * 3600;
|
||
break;
|
||
case 20:
|
||
seconds -= 1 * 3600;
|
||
break;
|
||
case 21: //<2F>?
|
||
case 22:
|
||
break;
|
||
case 23:
|
||
case 24:
|
||
case 25:
|
||
seconds += 1 * 3600;
|
||
break;
|
||
case 26:
|
||
case 27:
|
||
seconds += 2 * 3600;
|
||
break;
|
||
case 28:
|
||
case 29:
|
||
seconds += 3 * 3600;
|
||
break;
|
||
case 30:
|
||
seconds += (3 * 3600 + 30 * 60);
|
||
break;
|
||
case 31:
|
||
seconds += 4 * 3600;
|
||
break;
|
||
case 32:
|
||
seconds += (4 * 3600 + 30 * 60);
|
||
break;
|
||
case 33:
|
||
seconds += 5 * 3600;
|
||
break;
|
||
case 34:
|
||
seconds += (5 * 3600 + 30 * 60);
|
||
break;
|
||
case 35:
|
||
seconds += (5 * 3600 + 45 * 60);
|
||
break;
|
||
case 36:
|
||
seconds += 6 * 3600;
|
||
break;
|
||
case 37:
|
||
seconds += (6 * 3600 + 30 * 60);
|
||
break;
|
||
case 38:
|
||
seconds += 7 * 3600;
|
||
break;
|
||
case 39:
|
||
seconds += 8 * 3600;
|
||
break;
|
||
case 40:
|
||
seconds += 9 * 3600;
|
||
break;
|
||
case 41:
|
||
seconds += (9 * 3600 + 30 * 60);
|
||
break;
|
||
case 42:
|
||
seconds += 10 * 3600;
|
||
break;
|
||
case 43:
|
||
seconds += (10 * 3600 + 30 * 60);
|
||
break;
|
||
case 44:
|
||
seconds += 11 * 3600;
|
||
break;
|
||
case 45:
|
||
seconds += (11 * 3600 + 30 * 60);
|
||
break;
|
||
case 46:
|
||
seconds += 12 * 3600;
|
||
break;
|
||
case 47:
|
||
seconds += (12 * 3600 + 45 * 60);
|
||
break;
|
||
case 48:
|
||
seconds += 13 * 3600;
|
||
break;
|
||
case 49:
|
||
seconds += 14 * 3600;
|
||
break;
|
||
|
||
}
|
||
|
||
//calculation for date
|
||
calcdatetime(seconds);
|
||
}
|
||
|
||
void SNTP_init(uint8_t s, uint8_t *ntp_server, uint8_t tz, uint8_t *buf) {
|
||
NTP_SOCKET = s;
|
||
|
||
NTPformat.dstaddr[0] = ntp_server[0];
|
||
NTPformat.dstaddr[1] = ntp_server[1];
|
||
NTPformat.dstaddr[2] = ntp_server[2];
|
||
NTPformat.dstaddr[3] = ntp_server[3];
|
||
|
||
time_zone = tz;
|
||
|
||
data_buf = buf;
|
||
|
||
uint8_t Flag;
|
||
NTPformat.leap = 0; /* leap indicator */
|
||
NTPformat.version = 4; /* version number */
|
||
NTPformat.mode = 3; /* mode */
|
||
NTPformat.stratum = 0; /* stratum */
|
||
NTPformat.poll = 0; /* poll interval */
|
||
NTPformat.precision = 0; /* precision */
|
||
NTPformat.rootdelay = 0; /* root delay */
|
||
NTPformat.rootdisp = 0; /* root dispersion */
|
||
NTPformat.refid = 0; /* reference ID */
|
||
NTPformat.reftime = 0; /* reference time */
|
||
NTPformat.org = 0; /* origin timestamp */
|
||
NTPformat.rec = 0; /* receive timestamp */
|
||
NTPformat.xmt = 1; /* transmit timestamp */
|
||
|
||
Flag = (NTPformat.leap << 6) + (NTPformat.version << 3) + NTPformat.mode; //one byte Flag
|
||
memcpy(ntpmessage, (void const*)(&Flag), 1);
|
||
}
|
||
|
||
int8_t SNTP_run(datetime *time) {
|
||
uint16_t RSR_len;
|
||
uint32_t destip = 0;
|
||
uint16_t destport;
|
||
uint16_t startindex = 40; //last 8-byte of data_buf[size is 48 byte] is xmt, so the startindex should be 40
|
||
#if 1
|
||
// 20231019 taylor
|
||
uint8_t addr_len;
|
||
#endif
|
||
|
||
switch (getSn_SR(NTP_SOCKET)) {
|
||
case SOCK_UDP:
|
||
if ((RSR_len = getSn_RX_RSR(NTP_SOCKET)) > 0) {
|
||
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
|
||
}
|
||
#if 1
|
||
// 20231019 taylor//teddy 240122
|
||
#if ((_WIZCHIP_ == 6100) || (_WIZCHIP_ == 6300))
|
||
recvfrom(NTP_SOCKET, data_buf, RSR_len, (uint8_t *)&destip, &destport, &addr_len);
|
||
#else
|
||
recvfrom(NTP_SOCKET, data_buf, RSR_len, (uint8_t *)&destip, &destport);
|
||
#endif
|
||
#else
|
||
recvfrom(NTP_SOCKET, data_buf, RSR_len, (uint8_t *)&destip, &destport);
|
||
#endif
|
||
|
||
get_seconds_from_ntp_server(data_buf, startindex);
|
||
time->yy = Nowdatetime.yy;
|
||
time->mo = Nowdatetime.mo;
|
||
time->dd = Nowdatetime.dd;
|
||
time->hh = Nowdatetime.hh;
|
||
time->mm = Nowdatetime.mm;
|
||
time->ss = Nowdatetime.ss;
|
||
|
||
ntp_retry_cnt = 0;
|
||
close(NTP_SOCKET);
|
||
|
||
return 1;
|
||
}
|
||
|
||
if (ntp_retry_cnt < 0xFFFF) {
|
||
if (ntp_retry_cnt == 0) { //first send request, no need to wait
|
||
#if 1
|
||
// 20231016 taylor//teddy 240122
|
||
#if ((_WIZCHIP_ == 6100) || (_WIZCHIP_ == 6300))
|
||
sendto(NTP_SOCKET, ntpmessage, sizeof(ntpmessage), NTPformat.dstaddr, ntp_port, 4);
|
||
#else
|
||
sendto(NTP_SOCKET, ntpmessage, sizeof(ntpmessage), NTPformat.dstaddr, ntp_port);
|
||
#endif
|
||
#else
|
||
sendto(NTP_SOCKET, ntpmessage, sizeof(ntpmessage), NTPformat.dstaddr, ntp_port);
|
||
#endif
|
||
ntp_retry_cnt++;
|
||
} else { // send request again? it should wait for a while
|
||
if ((ntp_retry_cnt % 0xFFF) == 0) { //wait time
|
||
#if 1
|
||
// 20231016 taylor//teddy 240122
|
||
#if ((_WIZCHIP_ == 6100) || (_WIZCHIP_ == 6300))
|
||
sendto(NTP_SOCKET, ntpmessage, sizeof(ntpmessage), NTPformat.dstaddr, ntp_port, 4);
|
||
#else
|
||
sendto(NTP_SOCKET, ntpmessage, sizeof(ntpmessage), NTPformat.dstaddr, ntp_port);
|
||
#endif
|
||
#else
|
||
sendto(NTP_SOCKET, ntpmessage, sizeof(ntpmessage), NTPformat.dstaddr, ntp_port);
|
||
#endif
|
||
#ifdef _SNTP_DEBUG_
|
||
printf("ntp retry: %d\r\n", ntp_retry_cnt);
|
||
#endif
|
||
ntp_retry_cnt++;
|
||
}
|
||
}
|
||
} else { //ntp retry fail
|
||
ntp_retry_cnt = 0;
|
||
#ifdef _SNTP_DEBUG_
|
||
printf("ntp retry failed!\r\n");
|
||
#endif
|
||
close(NTP_SOCKET);
|
||
}
|
||
break;
|
||
case SOCK_CLOSED:
|
||
socket(NTP_SOCKET, Sn_MR_UDP, ntp_port, 0);
|
||
break;
|
||
}
|
||
// Return value
|
||
// 0 - failed / 1 - success
|
||
return 0;
|
||
}
|
||
|
||
void calcdatetime(tstamp seconds) {
|
||
uint8_t yf = 0;
|
||
uint8_t leap;
|
||
tstamp n = 0, d = 0, total_d = 0, rz = 0;
|
||
uint16_t y = 0, r = 0, yr = 0;
|
||
signed long long yd = 0;
|
||
|
||
n = seconds;
|
||
total_d = seconds / (SECS_PERDAY);
|
||
d = 0;
|
||
uint32_t p_year_total_sec = SECS_PERDAY * 365;
|
||
uint32_t r_year_total_sec = SECS_PERDAY * 366;
|
||
|
||
while (1) {
|
||
leap = 0;
|
||
if (((EPOCH + r) % 400 == 0) ||
|
||
(((EPOCH + r) % 100 != 0) && ((EPOCH + r) % 4 == 0))) {
|
||
leap = 1;
|
||
}
|
||
|
||
if (leap) {
|
||
if (n < r_year_total_sec) {
|
||
break;
|
||
}
|
||
n -= r_year_total_sec;
|
||
d += 366;
|
||
} else {
|
||
if (n < p_year_total_sec) {
|
||
break;
|
||
}
|
||
n -= p_year_total_sec;
|
||
d += 365;
|
||
}
|
||
|
||
r++;
|
||
y++;
|
||
}
|
||
|
||
y += EPOCH;
|
||
|
||
Nowdatetime.yy = y;
|
||
|
||
yd = 0;
|
||
yd = total_d - d;
|
||
|
||
yf = 1;
|
||
while (yd >= 28) {
|
||
|
||
if (yf == 1 || yf == 3 || yf == 5 || yf == 7 || yf == 8 || yf == 10 || yf == 12) {
|
||
yd -= 31;
|
||
if (yd < 0) {
|
||
break;
|
||
}
|
||
rz += 31;
|
||
}
|
||
|
||
if (yf == 2) {
|
||
if (y % 400 == 0 || (y % 100 != 0 && y % 4 == 0)) {
|
||
yd -= 29;
|
||
if (yd < 0) {
|
||
break;
|
||
}
|
||
rz += 29;
|
||
} else {
|
||
yd -= 28;
|
||
if (yd < 0) {
|
||
break;
|
||
}
|
||
rz += 28;
|
||
}
|
||
}
|
||
if (yf == 4 || yf == 6 || yf == 9 || yf == 11) {
|
||
yd -= 30;
|
||
if (yd < 0) {
|
||
break;
|
||
}
|
||
rz += 30;
|
||
}
|
||
yf += 1;
|
||
|
||
}
|
||
Nowdatetime.mo = yf;
|
||
yr = total_d - d - rz;
|
||
|
||
yr += 1;
|
||
|
||
Nowdatetime.dd = yr;
|
||
|
||
//calculation for time
|
||
seconds = seconds % SECS_PERDAY;
|
||
Nowdatetime.hh = seconds / 3600;
|
||
Nowdatetime.mm = (seconds % 3600) / 60;
|
||
Nowdatetime.ss = (seconds % 3600) % 60;
|
||
|
||
}
|
||
|
||
tstamp changedatetime_to_seconds(void) {
|
||
tstamp seconds = 0;
|
||
uint32_t total_day = 0;
|
||
uint16_t i = 0, run_year_cnt = 0, l = 0;
|
||
|
||
l = Nowdatetime.yy;//low
|
||
|
||
|
||
for (i = EPOCH; i < l; i++) {
|
||
if ((i % 400 == 0) || ((i % 100 != 0) && (i % 4 == 0))) {
|
||
run_year_cnt += 1;
|
||
}
|
||
}
|
||
|
||
total_day = (l - EPOCH - run_year_cnt) * 365 + run_year_cnt * 366;
|
||
|
||
for (i = 1; i <= Nowdatetime.mo; i++) {
|
||
if (i == 5 || i == 7 || i == 10 || i == 12) {
|
||
total_day += 30;
|
||
}
|
||
if (i == 3) {
|
||
if (l % 400 == 0 || l % 100 != 0 && l % 4 == 0) {
|
||
total_day += 29;
|
||
} else {
|
||
total_day += 28;
|
||
}
|
||
}
|
||
if (i == 2 || i == 4 || i == 6 || i == 8 || i == 9 || i == 11) {
|
||
total_day += 31;
|
||
}
|
||
}
|
||
|
||
seconds = (total_day + Nowdatetime.dd - 1) * 24 * 3600;
|
||
seconds += Nowdatetime.ss;//seconds
|
||
seconds += Nowdatetime.mm * 60; //minute
|
||
seconds += Nowdatetime.hh * 3600; //hour
|
||
|
||
return seconds;
|
||
}
|