6 #ifndef ACE_TIME_NTP_TIME_PROVIDER_H 7 #define ACE_TIME_NTP_TIME_PROVIDER_H 9 #if defined(ESP8266) || defined(ESP32) 13 #include <ESP8266WiFi.h> 18 #include "../common/logger.h" 19 #include "TimeKeeper.h" 21 #ifndef ACE_TIME_NTP_TIME_PROVIDER_DEBUG 22 #define ACE_TIME_NTP_TIME_PROVIDER_DEBUG 0 41 class NtpTimeProvider:
public TimeProvider {
44 static const char kNtpServerName[];
47 static const uint16_t kLocalPort = 8888;
50 static const uint16_t kRequestTimeout = 1000;
60 explicit NtpTimeProvider(
61 const char* server = kNtpServerName,
62 uint16_t localPort = kLocalPort,
63 uint16_t requestTimeout = kRequestTimeout):
65 mLocalPort(localPort),
66 mRequestTimeout(requestTimeout) {}
69 void setup(
const char* ssid,
const char* password);
71 const char* getServer()
const {
return mServer; }
73 bool isSetup()
const {
return mIsSetUp; }
75 acetime_t getNow()
const override {
76 if (!mIsSetUp)
return kInvalidSeconds;
80 uint16_t startTime = millis();
81 while ((uint16_t) (millis() - startTime) < mRequestTimeout) {
82 if (isResponseReady()) {
83 return readResponse();
86 return kInvalidSeconds;
89 void sendRequest()
const override {
90 if (!mIsSetUp)
return;
93 while (mUdp.parsePacket() > 0) {}
102 IPAddress ntpServerIP;
103 WiFi.hostByName(mServer, ntpServerIP);
104 sendNtpPacket(ntpServerIP);
107 bool isResponseReady()
const override {
108 if (!mIsSetUp)
return false;
109 return mUdp.parsePacket() >= kNtpPacketSize;
112 acetime_t readResponse()
const override {
113 if (!mIsSetUp)
return kInvalidSeconds;
116 mUdp.read(mPacketBuffer, kNtpPacketSize);
119 uint32_t secsSince1900 = (uint32_t) mPacketBuffer[40] << 24;
120 secsSince1900 |= (uint32_t) mPacketBuffer[41] << 16;
121 secsSince1900 |= (uint32_t) mPacketBuffer[42] << 8;
122 secsSince1900 |= (uint32_t) mPacketBuffer[43];
124 return (secsSince1900 == 0)
126 : secsSince1900 - kSecondsSinceNtpEpoch;
131 static const uint8_t kNtpPacketSize = 48;
137 static const uint32_t kSecondsSinceNtpEpoch = 3155673600;
140 static const uint16_t kConnectTimeoutMillis = 5000;
143 void sendNtpPacket(
const IPAddress& address)
const {
144 #if ACE_TIME_NTP_TIME_PROVIDER_DEBUG == 1 145 uint16_t startTime = millis();
148 memset(mPacketBuffer, 0, kNtpPacketSize);
151 mPacketBuffer[0] = 0b11100011;
152 mPacketBuffer[1] = 0;
153 mPacketBuffer[2] = 6;
154 mPacketBuffer[3] = 0xEC;
156 mPacketBuffer[12] = 49;
157 mPacketBuffer[13] = 0x4E;
158 mPacketBuffer[14] = 49;
159 mPacketBuffer[15] = 52;
162 mUdp.beginPacket(address, 123);
163 mUdp.write(mPacketBuffer, kNtpPacketSize);
165 #if ACE_TIME_NTP_TIME_PROVIDER_DEBUG == 1 166 logging::println(
"NtpTimeProvider::sendNtpPacket(): %u ms",
167 (uint16_t) (millis() - startTime));
171 const char*
const mServer;
172 uint16_t
const mLocalPort;
173 uint16_t
const mRequestTimeout;
175 mutable WiFiUDP mUdp;
177 mutable uint8_t mPacketBuffer[kNtpPacketSize];
178 bool mIsSetUp =
false;
184 #endif // defined(ESP8266) || defined(ESP32)