Skip to content

Add get_time function to ESP8266 #12300

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions components/wifi/esp8266-driver/ESP8266/ESP8266.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1114,6 +1114,130 @@ void ESP8266::attach(Callback<void()> status_cb)
_conn_stat_cb = status_cb;
}

bool ESP8266::set_sntp_config(bool enable, int timezone, const char *server0,
const char *server1, const char *server2)
{
bool done = false;
_smutex.lock();
if ((server0 == nullptr || server0[0] == '\0')) {
done = _parser.send("AT+CIPSNTPCFG=%d,%d",
enable ? 1 : 0, timezone);
} else if ((server0 != nullptr || server0[0] != '\0')
&& (server1 == nullptr && server1[0] == '\0')) {
done = _parser.send("AT+CIPSNTPCFG=%d,%d,%s",
enable ? 1 : 0, timezone, server0);
} else if ((server0 != nullptr || server0[0] != '\0')
&& (server1 != nullptr && server1[0] != '\0')
&& (server2 == nullptr && server2[0] == '\0')) {
done = _parser.send("AT+CIPSNTPCFG=%d,%d,%s,%s",
enable ? 1 : 0, timezone, server0, server1);
} else {
done = _parser.send("AT+CIPSNTPCFG=%d,%d,%s,%s,%s",
enable ? 1 : 0, timezone, server0, server1, server2);
}
done &= _parser.recv("OK\n");
_smutex.unlock();
return done;
}

bool ESP8266::get_sntp_config(bool *enable, int *timezone, char *server0,
char *server1, char *server2)
{
_smutex.lock();
unsigned int tmp;
bool done = _parser.send("AT+CIPSNTPCFG?")
&& _parser.scanf("+CIPSNTPCFG:%d,%d,\"%32[^\"]\",\"%32[^\"]\",\"%32[^\"]\"",
&tmp, timezone, server0, server1, server2)
&& _parser.recv("OK\n");
_smutex.unlock();
*enable = tmp ? true : false;
return done;
}

bool ESP8266::get_sntp_time(std::tm *t)
{
_smutex.lock();
char buf[25]; // Thu Aug 04 14:48:05 2016 (always 24 chars + \0)
memset(buf, 0, 25);

bool done = _parser.send("AT+CIPSNTPTIME?")
&& _parser.scanf("+CIPSNTPTIME:%24c", &buf)
&& _parser.recv("OK\n");
_smutex.unlock();

if (!done) {
return false;
}

char wday[4] = "\0", mon[4] = "\0";
int mday = 0, hour = 0, min = 0, sec = 0, year = 0;
int ret = sscanf(buf, "%s %s %d %d:%d:%d %d",
wday, mon, &mday, &hour, &min, &sec, &year);
if (ret != 7) {
tr_debug("get_sntp_time(): sscanf returned %d", ret);
return false;
}

t->tm_sec = sec;
t->tm_min = min;
t->tm_hour = hour;
t->tm_mday = mday;

t->tm_wday = 0;
if (strcmp(wday, "Mon") == 0) {
t->tm_wday = 0;
} else if (strcmp(wday, "Tue") == 0) {
t->tm_wday = 1;
} else if (strcmp(wday, "Wed") == 0) {
t->tm_wday = 2;
} else if (strcmp(wday, "Thu") == 0) {
t->tm_wday = 3;
} else if (strcmp(wday, "Fri") == 0) {
t->tm_wday = 4;
} else if (strcmp(wday, "Sat") == 0) {
t->tm_wday = 5;
} else if (strcmp(wday, "Sun") == 0) {
t->tm_wday = 6;
} else {
tr_debug("get_sntp_time(): Invalid weekday: %s", wday);
return false;
}

t->tm_mon = 0;
if (strcmp(mon, "Jan") == 0) {
t->tm_mon = 0;
} else if (strcmp(mon, "Feb") == 0) {
t->tm_mon = 1;
} else if (strcmp(mon, "Mar") == 0) {
t->tm_mon = 2;
} else if (strcmp(mon, "Apr") == 0) {
t->tm_mon = 3;
} else if (strcmp(mon, "May") == 0) {
t->tm_mon = 4;
} else if (strcmp(mon, "Jun") == 0) {
t->tm_mon = 5;
} else if (strcmp(mon, "Jul") == 0) {
t->tm_mon = 6;
} else if (strcmp(mon, "Aug") == 0) {
t->tm_mon = 7;
} else if (strcmp(mon, "Sep") == 0) {
t->tm_mon = 8;
} else if (strcmp(mon, "Oct") == 0) {
t->tm_mon = 9;
} else if (strcmp(mon, "Nov") == 0) {
t->tm_mon = 10;
} else if (strcmp(mon, "Dec") == 0) {
t->tm_mon = 11;
} else {
tr_debug("get_sntp_time(): Invalid month: %s", mon);
return false;
}

t->tm_year = (year - 1900);

return true;
}

bool ESP8266::_recv_ap(nsapi_wifi_ap_t *ap)
{
int sec = NSAPI_SECURITY_UNKNOWN;
Expand Down
42 changes: 42 additions & 0 deletions components/wifi/esp8266-driver/ESP8266/ESP8266.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#if DEVICE_SERIAL && DEVICE_INTERRUPTIN && defined(MBED_CONF_EVENTS_PRESENT) && defined(MBED_CONF_NSAPI_PRESENT) && defined(MBED_CONF_RTOS_API_PRESENT)
#include <stdint.h>
#include <ctime>

#include "drivers/BufferedSerial.h"
#include "features/netsocket/nsapi_types.h"
Expand Down Expand Up @@ -354,6 +355,47 @@ class ESP8266 {
*/
void attach(mbed::Callback<void()> status_cb);

/**
* Configure SNTP (Simple Network Time Protocol)
*
* @param enable true to enable SNTP or false to disable it
* @param timezone timezone offset [-11,13] (0 by default)
* @param server0 optional parameter indicating the first SNTP server ("cn.ntp.org.cn" by default)
* @param server1 optional parameter indicating the second SNTP server ("ntp.sjtu.edu.cn" by default)
* @param server2 optional parameter indicating the third SNTP server ("us.pool.ntp.org" by default)
*
* @retval true if successful, false otherwise
*/
bool set_sntp_config(bool enable, int timezone = 0, const char *server0 = nullptr,
const char *server1 = nullptr, const char *server2 = nullptr);

/**
* Read out the configuration of SNTP (Simple Network Time Protocol)
*
* @param enable true if SNTP is enabled
* @param timezone timezone offset [-11,13]
* @param server0 name of the first SNTP server
* @param server1 name of the second SNTP server (optional, nullptr if not set)
* @param server2 name of the third SNTP server (optional, nullptr if not set)
*
* @retval true if successful, false otherwise
*/
bool get_sntp_config(bool *enable, int *timezone, char *server0,
char *server1, char *server2);

/**
* Read out SNTP time from ESP8266.
*
* @param t std::tm structure to be filled in
* @retval true on success, false otherwise
*
* @note ESP8266 must be connected and needs a couple of seconds
* before returning correct time. It may return 1 Jan 1970 if it is not ready.
*
* @note esp8266.sntp-enable must be set to true in mbed_app.json file.
*/
bool get_sntp_time(std::tm *t);

template <typename T, typename M>
void attach(T *obj, M method)
{
Expand Down
16 changes: 15 additions & 1 deletion components/wifi/esp8266-driver/ESP8266Interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,12 @@ const char *ESP8266Interface::get_netmask()
return _conn_stat != NSAPI_STATUS_DISCONNECTED ? _esp.netmask() : NULL;
}

nsapi_error_t ESP8266Interface::get_time(std::tm *t)
{
_init();
return _esp.get_sntp_time(t) ? NSAPI_ERROR_OK : NSAPI_ERROR_TIMEOUT;
}

char *ESP8266Interface::get_interface_name(char *interface_name)
{
memcpy(interface_name, ESP8266_WIFI_IF_NAME, sizeof(ESP8266_WIFI_IF_NAME));
Expand Down Expand Up @@ -709,7 +715,15 @@ nsapi_error_t ESP8266Interface::_init(void)
if (!_esp.startup(ESP8266::WIFIMODE_STATION)) {
return NSAPI_ERROR_DEVICE_ERROR;
}

#if MBED_CONF_ESP8266_SNTP_ENABLE
if (!_esp.set_sntp_config(MBED_CONF_ESP8266_SNTP_ENABLE,
MBED_CONF_ESP8266_SNTP_TIMEZONE,
MBED_CONF_ESP8266_SNTP_SERVER0,
MBED_CONF_ESP8266_SNTP_SERVER1,
MBED_CONF_ESP8266_SNTP_SERVER2)) {
return NSAPI_ERROR_DEVICE_ERROR;
}
#endif
_initialized = true;
}
return NSAPI_ERROR_OK;
Expand Down
9 changes: 9 additions & 0 deletions components/wifi/esp8266-driver/ESP8266Interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,15 @@ class ESP8266Interface : public NetworkStack, public WiFiInterface {
MBED_DEPRECATED_SINCE("mbed-os-5.15", "String-based APIs are deprecated")
virtual const char *get_netmask();

/** Get the current time.
*
* @retval NSAPI_ERROR_UNSUPPORTED if the function is not supported
* @retval NSAPI_ERROR_OK on success
*
* @note esp8266.sntp-enable must be set to true in mbed_app.json.
*/
nsapi_error_t get_time(std::tm *t);

/** Get the network interface name
*
* @return Null-terminated representation of the network interface name
Expand Down
24 changes: 22 additions & 2 deletions components/wifi/esp8266-driver/mbed_lib.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,36 @@
"value": null
},
"channel-start": {
"help": "the channel number to start at, 1 by default",
"help": "The channel number to start at, 1 by default",
"value": null
},
"channels": {
"help": "channel count, 13 by default",
"help": "Channel count, 13 by default",
"value": null
},
"built-in-dns": {
"help": "use built-in CIPDOMAIN AT command to resolve address to IP",
"value": false
},
"sntp-enable": {
"help": "Enable SNTP. This allows application to use get_sntp_time(). Only available from ESP8266 AT v1.5. This driver supports v1.7 and higher.",
"value": false
},
"sntp-timezone": {
"help": "SNTP timezone",
"value": 0
},
"sntp-server0": {
"help": "First SNTP server. Empty string will let ESP8266 use its default.",
"value": "\"\""
},
"sntp-server1": {
"help": "Second SNTP server. Empty string will let ESP8266 use its default.",
"value": "\"\""
},
"sntp-server2": {
"help": "Third SNTP server. Empty string will let ESP8266 use its default.",
"value": "\"\""
}
},
"target_overrides": {
Expand Down