Skip to content

Commit 8175e32

Browse files
Add get_time function for ESP8266
get_time function allows access to SNTP functionalities of ESP8266
1 parent 539cf3f commit 8175e32

File tree

5 files changed

+210
-3
lines changed

5 files changed

+210
-3
lines changed

components/wifi/esp8266-driver/ESP8266/ESP8266.cpp

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,130 @@ void ESP8266::attach(Callback<void()> status_cb)
11141114
_conn_stat_cb = status_cb;
11151115
}
11161116

1117+
bool ESP8266::set_sntp_config(bool enable, int timezone, const char *server0,
1118+
const char *server1, const char *server2)
1119+
{
1120+
bool done = false;
1121+
_smutex.lock();
1122+
if ((server0 == nullptr || server0[0] == '\0')) {
1123+
done = _parser.send("AT+CIPSNTPCFG=%d,%d",
1124+
enable ? 1 : 0, timezone);
1125+
} else if ((server0 != nullptr || server0[0] != '\0')
1126+
&& (server1 == nullptr && server1[0] == '\0')) {
1127+
done = _parser.send("AT+CIPSNTPCFG=%d,%d,%s",
1128+
enable ? 1 : 0, timezone, server0);
1129+
} else if ((server0 != nullptr || server0[0] != '\0')
1130+
&& (server1 != nullptr && server1[0] != '\0')
1131+
&& (server2 == nullptr && server2[0] == '\0')) {
1132+
done = _parser.send("AT+CIPSNTPCFG=%d,%d,%s,%s",
1133+
enable ? 1 : 0, timezone, server0, server1);
1134+
} else {
1135+
done = _parser.send("AT+CIPSNTPCFG=%d,%d,%s,%s,%s",
1136+
enable ? 1 : 0, timezone, server0, server1, server2);
1137+
}
1138+
done &= _parser.recv("OK\n");
1139+
_smutex.unlock();
1140+
return done;
1141+
}
1142+
1143+
bool ESP8266::get_sntp_config(bool *enable, int *timezone, char *server0,
1144+
char *server1, char *server2)
1145+
{
1146+
_smutex.lock();
1147+
unsigned int tmp;
1148+
bool done = _parser.send("AT+CIPSNTPCFG?")
1149+
&& _parser.scanf("+CIPSNTPCFG:%d,%d,\"%32[^\"]\",\"%32[^\"]\",\"%32[^\"]\"",
1150+
&tmp, timezone, server0, server1, server2)
1151+
&& _parser.recv("OK\n");
1152+
_smutex.unlock();
1153+
*enable = tmp ? true : false;
1154+
return done;
1155+
}
1156+
1157+
bool ESP8266::get_sntp_time(std::tm *t)
1158+
{
1159+
_smutex.lock();
1160+
char buf[25]; // Thu Aug 04 14:48:05 2016 (always 24 chars + \0)
1161+
memset(buf, 0, 25);
1162+
1163+
bool done = _parser.send("AT+CIPSNTPTIME?")
1164+
&& _parser.scanf("+CIPSNTPTIME:%24c", &buf)
1165+
&& _parser.recv("OK\n");
1166+
_smutex.unlock();
1167+
1168+
if (!done) {
1169+
return false;
1170+
}
1171+
1172+
char wday[4] = "\0", mon[4] = "\0";
1173+
int mday = 0, hour = 0, min = 0, sec = 0, year = 0;
1174+
int ret = sscanf(buf, "%s %s %d %d:%d:%d %d",
1175+
wday, mon, &mday, &hour, &min, &sec, &year);
1176+
if (ret != 7) {
1177+
tr_debug("get_sntp_time(): sscanf returned %d", ret);
1178+
return false;
1179+
}
1180+
1181+
t->tm_sec = sec;
1182+
t->tm_min = min;
1183+
t->tm_hour = hour;
1184+
t->tm_mday = mday;
1185+
1186+
t->tm_wday = 0;
1187+
if (strcmp(wday, "Mon") == 0) {
1188+
t->tm_wday = 0;
1189+
} else if (strcmp(wday, "Tue") == 0) {
1190+
t->tm_wday = 1;
1191+
} else if (strcmp(wday, "Wed") == 0) {
1192+
t->tm_wday = 2;
1193+
} else if (strcmp(wday, "Thu") == 0) {
1194+
t->tm_wday = 3;
1195+
} else if (strcmp(wday, "Fri") == 0) {
1196+
t->tm_wday = 4;
1197+
} else if (strcmp(wday, "Sat") == 0) {
1198+
t->tm_wday = 5;
1199+
} else if (strcmp(wday, "Sun") == 0) {
1200+
t->tm_wday = 6;
1201+
} else {
1202+
tr_debug("get_sntp_time(): Invalid weekday: %s", wday);
1203+
return false;
1204+
}
1205+
1206+
t->tm_mon = 0;
1207+
if (strcmp(mon, "Jan") == 0) {
1208+
t->tm_mon = 0;
1209+
} else if (strcmp(mon, "Feb") == 0) {
1210+
t->tm_mon = 1;
1211+
} else if (strcmp(mon, "Mar") == 0) {
1212+
t->tm_mon = 2;
1213+
} else if (strcmp(mon, "Apr") == 0) {
1214+
t->tm_mon = 3;
1215+
} else if (strcmp(mon, "May") == 0) {
1216+
t->tm_mon = 4;
1217+
} else if (strcmp(mon, "Jun") == 0) {
1218+
t->tm_mon = 5;
1219+
} else if (strcmp(mon, "Jul") == 0) {
1220+
t->tm_mon = 6;
1221+
} else if (strcmp(mon, "Aug") == 0) {
1222+
t->tm_mon = 7;
1223+
} else if (strcmp(mon, "Sep") == 0) {
1224+
t->tm_mon = 8;
1225+
} else if (strcmp(mon, "Oct") == 0) {
1226+
t->tm_mon = 9;
1227+
} else if (strcmp(mon, "Nov") == 0) {
1228+
t->tm_mon = 10;
1229+
} else if (strcmp(mon, "Dec") == 0) {
1230+
t->tm_mon = 11;
1231+
} else {
1232+
tr_debug("get_sntp_time(): Invalid month: %s", mon);
1233+
return false;
1234+
}
1235+
1236+
t->tm_year = (year - 1900);
1237+
1238+
return true;
1239+
}
1240+
11171241
bool ESP8266::_recv_ap(nsapi_wifi_ap_t *ap)
11181242
{
11191243
int sec = NSAPI_SECURITY_UNKNOWN;

components/wifi/esp8266-driver/ESP8266/ESP8266.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#if DEVICE_SERIAL && DEVICE_INTERRUPTIN && defined(MBED_CONF_EVENTS_PRESENT) && defined(MBED_CONF_NSAPI_PRESENT) && defined(MBED_CONF_RTOS_API_PRESENT)
2222
#include <stdint.h>
23+
#include <ctime>
2324

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

358+
/**
359+
* Configure SNTP (Simple Network Time Protocol)
360+
*
361+
* @param enable true to enable SNTP or false to disable it
362+
* @param timezone timezone offset [-11,13] (0 by default)
363+
* @param server0 optional parameter indicating the first SNTP server ("cn.ntp.org.cn" by default)
364+
* @param server1 optional parameter indicating the second SNTP server ("ntp.sjtu.edu.cn" by default)
365+
* @param server2 optional parameter indicating the third SNTP server ("us.pool.ntp.org" by default)
366+
*
367+
* @retval true if successful, false otherwise
368+
*/
369+
bool set_sntp_config(bool enable, int timezone = 0, const char *server0 = nullptr,
370+
const char *server1 = nullptr, const char *server2 = nullptr);
371+
372+
/**
373+
* Read out the configuration of SNTP (Simple Network Time Protocol)
374+
*
375+
* @param enable true if SNTP is enabled
376+
* @param timezone timezone offset [-11,13]
377+
* @param server0 name of the first SNTP server
378+
* @param server1 name of the second SNTP server (optional, nullptr if not set)
379+
* @param server2 name of the third SNTP server (optional, nullptr if not set)
380+
*
381+
* @retval true if successful, false otherwise
382+
*/
383+
bool get_sntp_config(bool *enable, int *timezone, char *server0,
384+
char *server1, char *server2);
385+
386+
/**
387+
* Read out SNTP time from ESP8266.
388+
*
389+
* @param t std::tm structure to be filled in
390+
* @retval true on success, false otherwise
391+
*
392+
* @note ESP8266 must be connected and needs a couple of seconds
393+
* before returning correct time. It may return 1 Jan 1970 if it is not ready.
394+
*
395+
* @note esp8266.sntp-enable must be set to true in mbed_app.json file.
396+
*/
397+
bool get_sntp_time(std::tm *t);
398+
357399
template <typename T, typename M>
358400
void attach(T *obj, M method)
359401
{

components/wifi/esp8266-driver/ESP8266Interface.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,12 @@ const char *ESP8266Interface::get_netmask()
583583
return _conn_stat != NSAPI_STATUS_DISCONNECTED ? _esp.netmask() : NULL;
584584
}
585585

586+
nsapi_error_t ESP8266Interface::get_time(std::tm *t)
587+
{
588+
_init();
589+
return _esp.get_sntp_time(t) ? NSAPI_ERROR_OK : NSAPI_ERROR_TIMEOUT;
590+
}
591+
586592
char *ESP8266Interface::get_interface_name(char *interface_name)
587593
{
588594
memcpy(interface_name, ESP8266_WIFI_IF_NAME, sizeof(ESP8266_WIFI_IF_NAME));
@@ -709,7 +715,13 @@ nsapi_error_t ESP8266Interface::_init(void)
709715
if (!_esp.startup(ESP8266::WIFIMODE_STATION)) {
710716
return NSAPI_ERROR_DEVICE_ERROR;
711717
}
712-
718+
if (!_esp.set_sntp_config(MBED_CONF_ESP8266_SNTP_ENABLE,
719+
MBED_CONF_ESP8266_SNTP_TIMEZONE,
720+
MBED_CONF_ESP8266_SNTP_SERVER0,
721+
MBED_CONF_ESP8266_SNTP_SERVER1,
722+
MBED_CONF_ESP8266_SNTP_SERVER2)) {
723+
return NSAPI_ERROR_DEVICE_ERROR;
724+
}
713725
_initialized = true;
714726
}
715727
return NSAPI_ERROR_OK;

components/wifi/esp8266-driver/ESP8266Interface.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,15 @@ class ESP8266Interface : public NetworkStack, public WiFiInterface {
167167
MBED_DEPRECATED_SINCE("mbed-os-5.15", "String-based APIs are deprecated")
168168
virtual const char *get_netmask();
169169

170+
/** Get the current time.
171+
*
172+
* @retval NSAPI_ERROR_UNSUPPORTED if the function is not supported
173+
* @retval NSAPI_ERROR_OK on success
174+
*
175+
* @note esp8266.sntp-enable must be set to true in mbed_app.json.
176+
*/
177+
nsapi_error_t get_time(std::tm *t);
178+
170179
/** Get the network interface name
171180
*
172181
* @return Null-terminated representation of the network interface name

components/wifi/esp8266-driver/mbed_lib.json

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,36 @@
5959
"value": null
6060
},
6161
"channel-start": {
62-
"help": "the channel number to start at, 1 by default",
62+
"help": "The channel number to start at, 1 by default",
6363
"value": null
6464
},
6565
"channels": {
66-
"help": "channel count, 13 by default",
66+
"help": "Channel count, 13 by default",
6767
"value": null
6868
},
6969
"built-in-dns": {
7070
"help": "use built-in CIPDOMAIN AT command to resolve address to IP",
7171
"value": false
72+
},
73+
"sntp-enable": {
74+
"help": "Enable SNTP. This allows application to use get_sntp_time()",
75+
"value": false
76+
},
77+
"sntp-timezone": {
78+
"help": "SNTP timezone",
79+
"value": 0
80+
},
81+
"sntp-server0": {
82+
"help": "First SNTP server. Empty string will let ESP8266 use its default.",
83+
"value": "\"\""
84+
},
85+
"sntp-server1": {
86+
"help": "Second SNTP server. Empty string will let ESP8266 use its default.",
87+
"value": "\"\""
88+
},
89+
"sntp-server2": {
90+
"help": "Third SNTP server. Empty string will let ESP8266 use its default.",
91+
"value": "\"\""
7292
}
7393
},
7494
"target_overrides": {

0 commit comments

Comments
 (0)