Skip to content

Commit 6426afe

Browse files
Add get_time function for ESP8266
get_time function allows access to SNTP functionalities of ESP8266
1 parent 8c51f4f commit 6426afe

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
@@ -1113,6 +1113,130 @@ void ESP8266::attach(Callback<void()> status_cb)
11131113
_conn_stat_cb = status_cb;
11141114
}
11151115

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

2020
#if DEVICE_SERIAL && DEVICE_INTERRUPTIN && defined(MBED_CONF_EVENTS_PRESENT) && defined(MBED_CONF_NSAPI_PRESENT) && defined(MBED_CONF_RTOS_API_PRESENT)
2121
#include <stdint.h>
22+
#include <ctime>
2223

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

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

components/wifi/esp8266-driver/ESP8266Interface.cpp

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

601+
nsapi_error_t ESP8266Interface::get_time(std::tm *t)
602+
{
603+
_init();
604+
return _esp.get_sntp_time(t) ? NSAPI_ERROR_OK : NSAPI_ERROR_TIMEOUT;
605+
}
606+
601607
char *ESP8266Interface::get_interface_name(char *interface_name)
602608
{
603609
memcpy(interface_name, ESP8266_WIFI_IF_NAME, sizeof(ESP8266_WIFI_IF_NAME));
@@ -724,7 +730,13 @@ nsapi_error_t ESP8266Interface::_init(void)
724730
if (!_esp.startup(ESP8266::WIFIMODE_STATION)) {
725731
return NSAPI_ERROR_DEVICE_ERROR;
726732
}
727-
733+
if (!_esp.set_sntp_config(MBED_CONF_ESP8266_SNTP_ENABLE,
734+
MBED_CONF_ESP8266_SNTP_TIMEZONE,
735+
MBED_CONF_ESP8266_SNTP_SERVER0,
736+
MBED_CONF_ESP8266_SNTP_SERVER1,
737+
MBED_CONF_ESP8266_SNTP_SERVER2)) {
738+
return NSAPI_ERROR_DEVICE_ERROR;
739+
}
728740
_initialized = true;
729741
}
730742
return NSAPI_ERROR_OK;

components/wifi/esp8266-driver/ESP8266Interface.h

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

172+
/** Get the current time.
173+
*
174+
* @retval NSAPI_ERROR_UNSUPPORTED if the function is not supported
175+
* @retval NSAPI_ERROR_OK on success
176+
*
177+
* @note esp8266.sntp-enable must be set to true in mbed_app.json.
178+
*/
179+
nsapi_error_t get_time(std::tm *t);
180+
172181
/** Get the network interface name
173182
*
174183
* @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)