Skip to content

Commit

Permalink
Fix NTP and network management issues.
Browse files Browse the repository at this point in the history
  • Loading branch information
mobizt committed Jan 22, 2023
1 parent ebe29a5 commit 60b3d7a
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 83 deletions.
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Firebase Arduino Client Library for ESP8266 and ESP32",
"version": "4.3.3",
"version": "4.3.4",
"keywords": "communication, REST, esp32, esp8266, arduino",
"description": "The library supports Firebase products e.g. Realtime database, Cloud Firestore database, Firebase Storage and Google Cloud Storage, Cloud Functions for Firebase and Cloud Messaging. The library also supported other Arduino devices using Clients interfaces e.g. WiFiClient, EthernetClient, and GSMClient.",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name=Firebase Arduino Client Library for ESP8266 and ESP32

version=4.3.3
version=4.3.4

author=Mobizt

Expand Down
78 changes: 57 additions & 21 deletions src/FB_Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
*
* This library supports Espressif ESP8266, ESP32 and Raspberry Pi Pico (RP2040)
*
* Created January 17, 2023
* Created January 21, 2023
*
* This work is a part of Firebase ESP Client library
* Copyright (c) 2023 K. Suwatchai (Mobizt)
Expand Down Expand Up @@ -54,7 +54,7 @@ namespace Utils
inline void idle()
{
#if defined(ARDUINO_ESP8266_MAJOR) && defined(ARDUINO_ESP8266_MINOR) && defined(ARDUINO_ESP8266_REVISION) && ((ARDUINO_ESP8266_MAJOR == 3 && ARDUINO_ESP8266_MINOR >= 1) || ARDUINO_ESP8266_MAJOR > 3)
esp_yield();
esp_yield();
#else
delay(0);
#endif
Expand Down Expand Up @@ -1705,14 +1705,58 @@ namespace TimeHelper
inline time_t getTime(uint32_t *mb_ts, uint32_t *mb_ts_offset)
{
uint32_t &tm = *mb_ts;

#if !defined(FB_ENABLE_EXTERNAL_CLIENT) && (defined(ESP8266) || defined(ESP32) || defined(PICO_RP2040))
#if defined(FB_ENABLE_EXTERNAL_CLIENT) || defined(PICO_RP2040)
tm = *mb_ts_offset + millis() / 1000;
#elif defined(ESP32) || defined(ESP8266)
tm = time(nullptr);
#endif
return tm;
}

inline int setTimestamp(time_t ts)
{
#if defined(ESP32) || defined(ESP8266)
struct timeval tm = {ts, 0}; // sec, us
return settimeofday((const timeval *)&tm, 0);
#endif
return -1;
}

inline bool setTime(time_t ts, uint32_t *mb_ts, uint32_t *mb_ts_offset)
{
bool ret = false;

#if defined(ESP32) || defined(ESP8266)
ret = TimeHelper::setTimestamp(ts) == 0;
*mb_ts = time(nullptr);
#else
tm = *mb_ts_offset + millis() / 1000;
if (ts > ESP_DEFAULT_TS)
{
*mb_ts_offset = ts - millis() / 1000;
*mb_ts = ts;
ret = true;
}
#endif

return tm;
return ret;
}

inline bool updateClock(MB_NTP *ntp, uint32_t *mb_ts, uint32_t *mb_ts_offset)
{
uint32_t ts = ntp->getTime(2000 /* wait 10000 ms */);
if (ts > 0)
*mb_ts_offset = ts - millis() / 1000;

time_t now = getTime(mb_ts, mb_ts_offset);

bool rdy = now > ESP_DEFAULT_TS;

#if defined(ESP32) || defined(ESP8266)
if (rdy && time(nullptr) < now)
setTime(now, mb_ts, mb_ts_offset);
#endif

return rdy;
}

inline bool syncClock(MB_NTP *ntp, uint32_t *mb_ts, uint32_t *mb_ts_offset, float gmtOffset, FirebaseConfig *config)
Expand All @@ -1739,19 +1783,20 @@ namespace TimeHelper

#if defined(FB_ENABLE_EXTERNAL_CLIENT)

if (*mb_ts_offset == 0)
{
*mb_ts_offset = ntp->getTime(2000 /* wait 2000 ms */);
if (*mb_ts_offset > 0)
*mb_ts_offset = *mb_ts_offset - millis() / 1000;
}
updateClock(ntp, mb_ts, mb_ts_offset);

#else

#if defined(ESP32) || defined(ESP8266) || defined(PICO_RP2040)

#if defined(PICO_RP2040)
NTP.begin("pool.ntp.org", "time.nist.gov");
NTP.waitSet();

now = time(nullptr);
if (now > ESP_DEFAULT_TS)
*mb_ts_offset = now - millis() / 1000;

#else
configTime(gmtOffset * 3600, 0, "pool.ntp.org", "time.nist.gov");
#endif
Expand All @@ -1771,15 +1816,6 @@ namespace TimeHelper
return config->internal.fb_clock_rdy;
}

inline int setTimestamp(time_t ts)
{
#if defined(ESP32) || defined(ESP8266)
struct timeval tm = {ts, 0}; // sec, us
return settimeofday((const timeval *)&tm, 0);
#endif
return -1;
}

};

namespace Utils
Expand Down
18 changes: 5 additions & 13 deletions src/Firebase_ESP_Client.h
Original file line number Diff line number Diff line change
@@ -1,25 +1,17 @@
#ifndef FIREBASE_CLIENT_VERSION
#define FIREBASE_CLIENT_VERSION "4.3.3"
#define FIREBASE_CLIENT_VERSION "4.3.4"
#endif

/**
* Google's Firebase ESP Client Main class, Firebase_ESP_Client.h v4.3.3
* Google's Firebase ESP Client Main class, Firebase_ESP_Client.h v4.3.4
*
* This library supports Espressif ESP8266 and ESP32 MCUs and Raspberry Pi RP2040 Pico MCUs.
*
* Created January 19, 2023
* Created January 22, 2023
*
* Updates:
* - Fix Firestore incomplete chunked response issue.
* - Fix chunked response handling issue for authentications.
* - Fix FCM HTTPv1 invalid message issue.
* - Fix Storage file openning locked issue.
* - Fix NTP client issue.
* - Fix Firebase.ready returns true when network disconnected.
* - Fix wdt reset in ESP8266 core v3.1.1 as delay(0) replaced by esp suspend.
* - Improve network (WiFi) resume task.
* - Add support non-ESP device WiFi resume.
* - Add support SDFS (ESP8266SdFat) filesystem for RP2040/Pico.
* - Fix NTP issue and update.
* - Fix netwok management task issue.
*
*
* This work is a part of Firebase ESP Client library
Expand Down
31 changes: 19 additions & 12 deletions src/MB_NTP.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Mobizt's UDP NTP Time Client, version 1.0.2
* Mobizt's UDP NTP Time Client, version 1.0.3
*
* The MIT License (MIT)
* Copyright (c) 2023 K. Suwatchai (Mobizt)
Expand Down Expand Up @@ -50,15 +50,14 @@ class MB_NTP
this->host = host;
this->port = port;
this->timeZoneOffset = timeZoneOffset;

return this->begin();
}

bool begin()
{
if (!this->udp || this->host.length() == 0 || this->port == 0)
return false;

if (!udpStarted)
udpStarted = udp->begin(intPort) > 0;

Expand All @@ -67,18 +66,23 @@ class MB_NTP

uint32_t getTime(uint16_t waitMillisec = 0)
{
if (ts == 0)
{
if (!udp)
return 0;

if (getResponse())
return ts;
if (getResponse())
return ts;

if (!sendRequest())
return 0;
if (!sendRequest())
return 0;

if (waitMillisec > 0)
delay(waitMillisec);
if (waitMillisec > 0)
delay(waitMillisec);

if (!getResponse())
return 0;
if (!getResponse())
return 0;
}

return ts;
}
Expand All @@ -98,7 +102,7 @@ class MB_NTP

bool sendRequest()
{
if (!udpStarted)
if (!udpStarted || !udp)
return false;

if (lastRequestMs == 0 || millis() - lastRequestMs > timeout)
Expand Down Expand Up @@ -136,6 +140,9 @@ class MB_NTP

bool getResponse()
{
if (!udp)
return false;

if (!udpStarted)
{
// We call begin again if network may not ready (e.g., WiFi)
Expand Down
49 changes: 15 additions & 34 deletions src/signer/Signer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,33 +283,7 @@ time_t Firebase_Signer::getTime()

bool Firebase_Signer::setTime(time_t ts)
{

#if !defined(FB_ENABLE_EXTERNAL_CLIENT) && (defined(ESP8266) || defined(ESP32) || defined(PICO_RP2040))

if (TimeHelper::setTimestamp(ts) == 0)
{
this->ts = time(nullptr);
*mb_ts = this->ts;
return true;
}
else
{
this->ts = time(nullptr);
*mb_ts = this->ts;
}

#else

if (ts > ESP_DEFAULT_TS)
{
*mb_ts_offset = ts - millis() / 1000;
this->ts = ts;
*mb_ts = this->ts;
}

#endif

return false;
return TimeHelper::setTime(ts, mb_ts, mb_ts_offset);
}

bool Firebase_Signer::isExpired()
Expand Down Expand Up @@ -585,12 +559,12 @@ void Firebase_Signer::freeJson()
resultPtr = nullptr;
}

bool Firebase_Signer::checkUDP(UDP *udp, bool &ret, bool &_token_processing_task_enable)
bool Firebase_Signer::checkUDP(UDP *udp, bool &ret, bool &_token_processing_task_enable, float gmtOffset)
{
#if defined(FB_ENABLE_EXTERNAL_CLIENT)

if (udp)
ntpClient.begin(udp, "pool.ntp.org" /* NTP host */, 123 /* NTP port */, gmtOffset /* timezone offset in seconds */);
ntpClient.begin(udp, "pool.ntp.org" /* NTP host */, 123 /* NTP port */, gmtOffset * 3600 /* timezone offset in seconds */);
else
{
config->signer.tokens.error.message.clear();
Expand Down Expand Up @@ -633,7 +607,7 @@ void Firebase_Signer::tokenProcessingTask()

while (!ret && config->signer.tokens.status != token_status_ready)
{
Utils::idle();
Utils::idle();
// check time if clock synching once set in the JWT token generating process (during beginning step)
// or valid time required for SSL handshake in ESP8266
if (!config->internal.fb_clock_rdy && (config->internal.fb_clock_synched || sslValidTime))
Expand All @@ -657,7 +631,7 @@ void Firebase_Signer::tokenProcessingTask()

// check or set time again

if (!checkUDP(udp, ret, _token_processing_task_enable))
if (!checkUDP(udp, ret, _token_processing_task_enable, config->time_zone))
continue;

TimeHelper::syncClock(&ntpClient, mb_ts, mb_ts_offset, config->time_zone, config);
Expand Down Expand Up @@ -695,7 +669,7 @@ void Firebase_Signer::tokenProcessingTask()
config->internal.fb_last_jwt_begin_step_millis == 0))
{
// time must be set first
if (!checkUDP(udp, ret, _token_processing_task_enable))
if (!checkUDP(udp, ret, _token_processing_task_enable, config->time_zone))
continue;

TimeHelper::syncClock(&ntpClient, mb_ts, mb_ts_offset, config->time_zone, config);
Expand Down Expand Up @@ -973,7 +947,7 @@ bool Firebase_Signer::handleTokenResponse(int &httpCode)

while (tcpClient->connected() && tcpClient->available() == 0)
{
Utils::idle();
Utils::idle();
if (!reconnect(tcpClient, nullptr, tcpHandler.dataTime))
return false;
}
Expand All @@ -986,7 +960,7 @@ bool Firebase_Signer::handleTokenResponse(int &httpCode)

while (tcpHandler.available() || !complete)
{
Utils::idle();
Utils::idle();

if (!reconnect(tcpClient, nullptr, tcpHandler.dataTime))
return false;
Expand Down Expand Up @@ -1803,6 +1777,11 @@ void Firebase_Signer::resumeWiFi(FB_TCP_CLIENT *client, bool &net_once_connected

bool Firebase_Signer::reconnect()
{
if (networkChecking)
return networkStatus;

networkChecking = true;

bool noClient = tcpClient == nullptr;
if (noClient)
newClient(&tcpClient);
Expand All @@ -1812,6 +1791,8 @@ bool Firebase_Signer::reconnect()
if (noClient)
freeClient(&tcpClient);

networkChecking = false;

return networkStatus;
}

Expand Down
3 changes: 2 additions & 1 deletion src/signer/Signer.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class Firebase_Signer
uint16_t wifi_reconnect_tmo = MIN_WIFI_RECONNECT_TIMEOUT;

volatile bool networkStatus = false;
bool networkChecking = false;

/* intitialize the class */
void begin(FirebaseConfig *config, FirebaseAuth *auth, MB_FS *mbfs, uint32_t *mb_ts, uint32_t *mb_ts_offset);
Expand Down Expand Up @@ -149,7 +150,7 @@ class Firebase_Signer
bool handleTokenResponse(int &httpCode);
/* process the tokens (generation, signing, request and refresh) */
void tokenProcessingTask();
bool checkUDP(UDP *udp, bool &ret, bool &_token_processing_task_enable);
bool checkUDP(UDP *udp, bool &ret, bool &_token_processing_task_enable, float gmtOffset);
/* encode and sign the JWT token */
bool createJWT();
/* verifying the user with email/passwod to get id token */
Expand Down

0 comments on commit 60b3d7a

Please sign in to comment.