Add get_time function for ESP8266

get_time function allows access to SNTP functionalities of ESP8266
pull/12300/head
Michal Paszta 2020-01-16 10:52:30 +02:00
parent 539cf3fa63
commit 8175e32717
5 changed files with 210 additions and 3 deletions

View File

@ -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;

View File

@ -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"
@ -354,6 +355,47 @@ public:
*/
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)
{

View File

@ -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));
@ -709,7 +715,13 @@ nsapi_error_t ESP8266Interface::_init(void)
if (!_esp.startup(ESP8266::WIFIMODE_STATION)) {
return NSAPI_ERROR_DEVICE_ERROR;
}
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;
}
_initialized = true;
}
return NSAPI_ERROR_OK;

View File

@ -167,6 +167,15 @@ public:
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

View File

@ -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()",
"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": {