Repository navigation
Expand file tree
/
Copy pathNTPClass.cpp
More file actions
142 lines (120 loc) · 4.7 KB
/
Copy pathNTPClass.cpp
File metadata and controls
142 lines (120 loc) · 4.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include <WiFiUdp.h>
#include <TimeLib.h>
#include <DS3231.h>
#include <Wire.h>
////////////////////////////////////////////////////////////////////////////////////////////////////
#include "NTPClass.h"
#include "SDLibs.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
NTPTime::NTPTime( int interval, char *server_name ) {
update_interval = interval;
update_interval2 = 1000; // One second
last_update = millis();
last_update2 = millis();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void NTPTime::begin() {
local_port = 2390; // local port to listen for UDP packets
NTP_time_update_needed = true;
NTP_time_syncronised = false;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void NTPTime::update() {
time_t epoch = 0UL;
int cb = 0;
char timestr[17] = {0};
char tmpstr[500];
if( NTP_time_update_needed == true ) {
udp.begin(local_port);
writeSDAuditLog( "sending NTP packet to %s", NTP_server_name);
// set all bytes in the buffer to 0
memset(NTP_buffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
NTP_buffer[0] = 0b11100011; // LI, Version, Mode
NTP_buffer[1] = 0; // Stratum, or type of clock
NTP_buffer[2] = 6; // Polling Interval
NTP_buffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
NTP_buffer[12] = 49;
NTP_buffer[13] = 0x4E;
NTP_buffer[14] = 49;
NTP_buffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
udp.beginPacket(NTP_server_name, 123); //NTP requests are to port 123
udp.write(NTP_buffer, NTP_PACKET_SIZE);
udp.endPacket();
NTP_last_request_millis = millis();
NTP_last_request_count = 0;
NTP_time_syncronised = false;
NTP_time_update_needed = false;
NTP_request_wait_interval = 1000;
} else if(( NTP_time_syncronised == false ) && (( millis() - NTP_last_request_millis) > NTP_request_wait_interval )){
cb = udp.parsePacket();
if (!cb) {
writeSDAuditLog( "no NTP packet received");
NTP_last_request_millis = millis();
NTP_request_wait_interval = 1000;
NTP_last_request_count ++;
if( NTP_last_request_count > 5 ) { // more that five goes and we send request again
NTP_time_update_needed = true;
writeSDAuditLog( "resending NTP request" );
}
} else {
writeSDAuditLog( "packet received, length=%d", cb );
// We've received a packet, read the data from it
udp.read(NTP_buffer, NTP_PACKET_SIZE); // read the packet into the buffer
//the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, extract the two words:
unsigned long highWord = word(NTP_buffer[40], NTP_buffer[41]);
unsigned long lowWord = word(NTP_buffer[42], NTP_buffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
udp.stop();
epoch = highWord << 16 | lowWord;
epoch -= 2208988800UL + localTimeOffset;
epoch += dst(epoch);
setTime(epoch);
writeSDAuditLog( "epoch = %d, last_NTP_update_time = %d (difference = %d)", epoch, last_NTP_update_time, epoch - last_NTP_update_time );
last_NTP_update_time = epoch;
NTP_time_syncronised = true;
NTP_time_update_needed = false;
}
} else if((millis() - last_update) > update_interval) {
last_update = millis();
NTP_time_update_needed = true;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
int NTPTime::dst (time_t t) { // calculate if summertime in Europe
tmElements_t te;
te.Year = year(t)-1970;
te.Month =3;
te.Day =1;
te.Hour = 0;
te.Minute = 0;
te.Second = 0;
time_t dstStart,dstEnd, current;
dstStart = makeTime(te);
dstStart = lastSunday(dstStart);
dstStart += 2*SECS_PER_HOUR; //2AM
te.Month=10;
dstEnd = makeTime(te);
dstEnd = lastSunday(dstEnd);
dstEnd += SECS_PER_HOUR; //1AM
if (t>=dstStart && t<dstEnd) {
return (3600); //Add back in one hours worth of seconds - DST in effect
} else {
return (0); //NonDST
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
time_t NTPTime::lastSunday(time_t t) {
t = nextSunday(t); //Once, first Sunday
if(day(t) < 4) {
return t += 4 * SECS_PER_WEEK;
} else {
return t += 3 * SECS_PER_WEEK;
}
}