Repository navigation
Expand file tree
/
Copy pathntp.cpp
More file actions
129 lines (105 loc) · 3.01 KB
/
Copy pathntp.cpp
File metadata and controls
129 lines (105 loc) · 3.01 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
#include "prog.h"
#include "ntp.h"
#include <Timezone.h>
const char* ntpServerName = "0.us.pool.ntp.org";
Toki toki = Toki();
IPAddress ntpServerIP;
time_t localTime;
unsigned long ntpPacketSentTime = 999000000L;
TimeChangeRule daylight = {"CDT", Second, Sun, Mar, 2, -300 };
TimeChangeRule standard = {"CST", First, Sun, Nov, 2, -360 };
Timezone* centralTimezone = new Timezone(daylight, standard);
WiFiUDP ntpUdp;
void Ntp::Connect() {
ntpConnected = ntpUdp.begin(ntpLocalPort);
}
time_t Ntp::GetLocalTime()
{
return localTime;
}
bool Ntp::IsTimeSet() {
return timeIsSet;
}
void Ntp::HandleTime() {
toki.millisecond();
toki.setTick();
if (toki.isTick()) //true only in the first loop after a new second started
{
UpdateLocalTime();
}
if (ntpConnected && millis() - ntpLastSyncTime > (1000*NTP_SYNC_INTERVAL) && WIFI_CONNECTED)
{
if (millis() - ntpPacketSentTime > 10000)
{
SendNTPPacket();
ntpPacketSentTime = millis();
}
if (CheckNTPResponse())
{
ntpLastSyncTime = millis();
}
}
}
void Ntp::SendNTPPacket()
{
if (!ntpServerIP.fromString(ntpServerName)) //see if server is IP or domain
{
WiFi.hostByName(ntpServerName, ntpServerIP, 750);
}
SERIAL_PRINTLN("send NTP");
byte pbuf[NTP_PACKET_SIZE];
memset(pbuf, 0, NTP_PACKET_SIZE);
pbuf[0] = 0b11100011; // LI, Version, Mode
pbuf[1] = 0; // Stratum, or type of clock
pbuf[2] = 6; // Polling Interval
pbuf[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
pbuf[12] = 49;
pbuf[13] = 0x4E;
pbuf[14] = 49;
pbuf[15] = 52;
ntpUdp.beginPacket(ntpServerIP, 123); //NTP requests are to port 123
ntpUdp.write(pbuf, NTP_PACKET_SIZE);
ntpUdp.endPacket();
}
bool Ntp::CheckNTPResponse()
{
int packetSize = ntpUdp.parsePacket();
if (!packetSize) return false;
uint32_t ntpPacketReceivedTime = millis();
SERIAL_PRINT("NTP recv, 1=");
SERIAL_PRINTLN(packetSize);
byte pbuf[NTP_PACKET_SIZE];
ntpUdp.read(pbuf, NTP_PACKET_SIZE); // read the packet into the buffer
Toki::Time arrived = toki.fromNTP(pbuf + 32);
Toki::Time departed = toki.fromNTP(pbuf + 40);
if (departed.sec == 0) return false;
//basic half roundtrip estimation
uint32_t serverDelay = toki.msDifference(arrived, departed);
uint32_t offset = (ntpPacketReceivedTime - ntpPacketSentTime - serverDelay) >> 1;
#ifdef DEBUG
//the time the packet departed the NTP server
toki.printTime(departed);
#endif
toki.adjust(departed, offset);
toki.setTime(departed, TOKI_TS_NTP);
#ifdef DEBUG
SERIAL_PRINT("Arrived: ");
toki.printTime(arrived);
SERIAL_PRINT("Time: ");
toki.printTime(departed);
SERIAL_PRINT("Roundtrip: ");
SERIAL_PRINTLN(ntpPacketReceivedTime - ntpPacketSentTime);
SERIAL_PRINT("Offset: ");
SERIAL_PRINTLN(offset);
SERIAL_PRINT("Serverdelay: ");
SERIAL_PRINTLN(serverDelay);
#endif
UpdateLocalTime();
timeIsSet = true;
return true;
}
void Ntp::UpdateLocalTime()
{
localTime = centralTimezone->toLocal(toki.second());
}