1 #ifndef ACE_TIME_NTP_TIME_PROVIDER_H 2 #define ACE_TIME_NTP_TIME_PROVIDER_H 4 #if defined(ESP8266) || defined(ESP32) 8 #include <ESP8266WiFi.h> 13 #include "../common/logger.h" 14 #include "TimeKeeper.h" 16 #ifndef ACE_TIME_NTP_TIME_PROVIDER_DEBUG 17 #define ACE_TIME_NTP_TIME_PROVIDER_DEBUG 0 36 class NtpTimeProvider:
public TimeProvider {
39 static const char kNtpServerName[];
42 static const uint16_t kLocalPort = 8888;
45 static const uint16_t kRequestTimeout = 1000;
55 explicit NtpTimeProvider(
56 const char* server = kNtpServerName,
57 uint16_t localPort = kLocalPort,
58 uint16_t requestTimeout = kRequestTimeout):
60 mLocalPort(localPort),
61 mRequestTimeout(requestTimeout) {}
64 void setup(
const char* ssid,
const char* password);
66 const char* getServer()
const {
return mServer; }
68 bool isSetup()
const {
return mIsSetUp; }
70 acetime_t getNow()
const override {
71 if (!mIsSetUp)
return kInvalidSeconds;
75 uint16_t startTime = millis();
76 while ((uint16_t) (millis() - startTime) < mRequestTimeout) {
77 if (isResponseReady()) {
78 return readResponse();
81 return kInvalidSeconds;
84 void sendRequest()
const override {
85 if (!mIsSetUp)
return;
88 while (mUdp.parsePacket() > 0) {}
97 IPAddress ntpServerIP;
98 WiFi.hostByName(mServer, ntpServerIP);
99 sendNtpPacket(ntpServerIP);
102 bool isResponseReady()
const override {
103 if (!mIsSetUp)
return false;
104 return mUdp.parsePacket() >= kNtpPacketSize;
107 acetime_t readResponse()
const override {
108 if (!mIsSetUp)
return kInvalidSeconds;
111 mUdp.read(mPacketBuffer, kNtpPacketSize);
114 uint32_t secsSince1900 = (uint32_t) mPacketBuffer[40] << 24;
115 secsSince1900 |= (uint32_t) mPacketBuffer[41] << 16;
116 secsSince1900 |= (uint32_t) mPacketBuffer[42] << 8;
117 secsSince1900 |= (uint32_t) mPacketBuffer[43];
119 return (secsSince1900 == 0)
121 : secsSince1900 - kSecondsSinceNtpEpoch;
126 static const uint8_t kNtpPacketSize = 48;
132 static const uint32_t kSecondsSinceNtpEpoch = 3155673600;
135 static const uint16_t kConnectTimeoutMillis = 5000;
138 void sendNtpPacket(
const IPAddress& address)
const {
139 #if ACE_TIME_NTP_TIME_PROVIDER_DEBUG == 1 140 uint16_t startTime = millis();
143 memset(mPacketBuffer, 0, kNtpPacketSize);
146 mPacketBuffer[0] = 0b11100011;
147 mPacketBuffer[1] = 0;
148 mPacketBuffer[2] = 6;
149 mPacketBuffer[3] = 0xEC;
151 mPacketBuffer[12] = 49;
152 mPacketBuffer[13] = 0x4E;
153 mPacketBuffer[14] = 49;
154 mPacketBuffer[15] = 52;
157 mUdp.beginPacket(address, 123);
158 mUdp.write(mPacketBuffer, kNtpPacketSize);
160 #if ACE_TIME_NTP_TIME_PROVIDER_DEBUG == 1 161 logging::println(
"NtpTimeProvider::sendNtpPacket(): %u ms",
162 (uint16_t) (millis() - startTime));
166 const char*
const mServer;
167 uint16_t
const mLocalPort;
168 uint16_t
const mRequestTimeout;
170 mutable WiFiUDP mUdp;
172 mutable uint8_t mPacketBuffer[kNtpPacketSize];
173 bool mIsSetUp =
false;
179 #endif // defined(ESP8266) || defined(ESP32)