Skip to content

Commit bcb0f08

Browse files
Add get_time function to Wifi interface and ESP8266
get_time function allows access to SNTP functionalities of WiFi modules. ESP8266 is the first module to offer this function in mbed-os.
1 parent ee1d998 commit bcb0f08

File tree

6 files changed

+154
-3
lines changed

6 files changed

+154
-3
lines changed

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

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,65 @@ void ESP8266::attach(Callback<void()> status_cb)
10841084
_conn_stat_cb = status_cb;
10851085
}
10861086

1087+
bool ESP8266::set_sntp_config(bool enable, int timezone, const char *server0,
1088+
const char *server1, const char *server2)
1089+
{
1090+
bool done = false;
1091+
_smutex.lock();
1092+
if ((server0 == nullptr || server0[0] == '\0')) {
1093+
done = _parser.send("AT+CIPSNTPCFG=%d,%d",
1094+
enable ? 1 : 0, timezone);
1095+
} else if ((server0 != nullptr || server0[0] != '\0')
1096+
&& (server1 == nullptr && server1[0] == '\0')) {
1097+
done = _parser.send("AT+CIPSNTPCFG=%d,%d,%s",
1098+
enable ? 1 : 0, timezone, server0);
1099+
} else if ((server0 != nullptr || server0[0] != '\0')
1100+
&& (server1 != nullptr && server1[0] != '\0')
1101+
&& (server2 == nullptr && server2[0] == '\0')) {
1102+
done = _parser.send("AT+CIPSNTPCFG=%d,%d,%s,%s",
1103+
enable ? 1 : 0, timezone, server0, server1);
1104+
} else {
1105+
done = _parser.send("AT+CIPSNTPCFG=%d,%d,%s,%s,%s",
1106+
enable ? 1 : 0, timezone, server0, server1, server2);
1107+
}
1108+
done &= _parser.recv("OK\n");
1109+
_smutex.unlock();
1110+
return done;
1111+
}
1112+
1113+
bool ESP8266::get_sntp_config(bool *enable, int *timezone, char *server0,
1114+
char *server1, char *server2)
1115+
{
1116+
_smutex.lock();
1117+
unsigned int tmp;
1118+
bool done = _parser.send("AT+CIPSNTPCFG?")
1119+
&& _parser.scanf("+CIPSNTPCFG:%d,%d,\"%32[^\"]\",\"%32[^\"]\",\"%32[^\"]\"",
1120+
&tmp, timezone, server0, server1, server2)
1121+
&& _parser.recv("OK\n");
1122+
_smutex.unlock();
1123+
*enable = tmp ? true : false;
1124+
return done;
1125+
}
1126+
1127+
bool ESP8266::get_sntp_time(std::tm *t)
1128+
{
1129+
_smutex.lock();
1130+
char buf[25]; // Thu Aug 04 14:48:05 2016 (always 24 chars + \0)
1131+
memset(buf, 0, 25);
1132+
bool done = _parser.send("AT+CIPSNTPTIME?")
1133+
&& _parser.scanf("+CIPSNTPTIME:%24c", &buf)
1134+
&& _parser.recv("OK\n");
1135+
_smutex.unlock();
1136+
1137+
std::istringstream ss(buf);
1138+
ss >> std::get_time(t, "%a %b %d %H:%M:%S %Y");
1139+
if (ss.fail()) {
1140+
return false;
1141+
} else {
1142+
return true;
1143+
}
1144+
}
1145+
10871146
bool ESP8266::_recv_ap(nsapi_wifi_ap_t *ap)
10881147
{
10891148
int sec = NSAPI_SECURITY_UNKNOWN;

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
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 <sstream>
23+
#include <iomanip>
2224

2325
#include "drivers/BufferedSerial.h"
2426
#include "features/netsocket/nsapi_types.h"
@@ -334,6 +336,47 @@ class ESP8266 {
334336
*/
335337
void attach(mbed::Callback<void()> status_cb);
336338

339+
/**
340+
* Configure SNTP (Simple Network Time Protocol)
341+
*
342+
* @param enable true to enable SNTP or false to disable it
343+
* @param timezone timezone offset [-11,13] (0 by default)
344+
* @param server0 optional parameter indicating the first SNTP server ("cn.ntp.org.cn" by default)
345+
* @param server1 optional parameter indicating the second SNTP server ("ntp.sjtu.edu.cn" by default)
346+
* @param server2 optional parameter indicating the third SNTP server ("us.pool.ntp.org" by default)
347+
*
348+
* @retval true if successful, false otherwise
349+
*/
350+
bool set_sntp_config(bool enable, int timezone = 0, const char *server0 = nullptr,
351+
const char *server1 = nullptr, const char *server2 = nullptr);
352+
353+
/**
354+
* Read out the configuration of SNTP (Simple Network Time Protocol)
355+
*
356+
* @param enable true if SNTP is enabled
357+
* @param timezone timezone offset [-11,13]
358+
* @param server0 name of the first SNTP server
359+
* @param server1 name of the second SNTP server (optional, nullptr if not set)
360+
* @param server2 name of the third SNTP server (optional, nullptr if not set)
361+
*
362+
* @retval true if successful, false otherwise
363+
*/
364+
bool get_sntp_config(bool *enable, int *timezone, char *server0,
365+
char *server1, char *server2);
366+
367+
/**
368+
* Read out SNTP time from ESP8266.
369+
*
370+
* @param t std::tm structure to be filled in
371+
* @retval true on success, false otherwise
372+
*
373+
* @note ESP8266 must be connected and needs a couple of seconds
374+
* before returning correct time. It may return 1 Jan 1970 if it is not ready.
375+
*
376+
* @note esp8266.sntp-enable must be set to true in mbed_app.json file.
377+
*/
378+
bool get_sntp_time(std::tm *t);
379+
337380
template <typename T, typename M>
338381
void attach(T *obj, M method)
339382
{

components/wifi/esp8266-driver/ESP8266Interface.cpp

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

599+
nsapi_error_t ESP8266Interface::get_time(std::tm *t)
600+
{
601+
_init();
602+
return _esp.get_sntp_time(t) ? NSAPI_ERROR_OK : NSAPI_ERROR_TIMEOUT;
603+
}
604+
599605
char *ESP8266Interface::get_interface_name(char *interface_name)
600606
{
601607
memcpy(interface_name, ESP8266_WIFI_IF_NAME, sizeof(ESP8266_WIFI_IF_NAME));
@@ -722,7 +728,13 @@ nsapi_error_t ESP8266Interface::_init(void)
722728
if (!_esp.startup(ESP8266::WIFIMODE_STATION)) {
723729
return NSAPI_ERROR_DEVICE_ERROR;
724730
}
725-
731+
if (!_esp.set_sntp_config(MBED_CONF_ESP8266_SNTP_ENABLE,
732+
MBED_CONF_ESP8266_SNTP_TIMEZONE,
733+
MBED_CONF_ESP8266_SNTP_SERVER0,
734+
MBED_CONF_ESP8266_SNTP_SERVER1,
735+
MBED_CONF_ESP8266_SNTP_SERVER2)) {
736+
return NSAPI_ERROR_DEVICE_ERROR;
737+
}
726738
_initialized = true;
727739
}
728740
return NSAPI_ERROR_OK;

components/wifi/esp8266-driver/ESP8266Interface.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,12 @@ 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+
/** @copydoc WiFiInterface::get_time
173+
*
174+
* @note esp8266.sntp-enable must be set to true in mbed_app.json.
175+
*/
176+
virtual nsapi_error_t get_time(std::tm *t);
177+
172178
/** Get the network interface name
173179
*
174180
* @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": {

features/netsocket/WiFiInterface.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#define WIFI_INTERFACE_H
2424

2525
#include <string.h>
26+
#include <ctime>
2627
#include "netsocket/NetworkInterface.h"
2728
#include "netsocket/WiFiAccessPoint.h"
2829

@@ -65,6 +66,16 @@ class WiFiInterface: public virtual NetworkInterface {
6566
*/
6667
virtual int8_t get_rssi() = 0;
6768

69+
/** Get the current time.
70+
*
71+
* @retval NSAPI_ERROR_UNSUPPORTED if the function is not supported
72+
* @retval NSAPI_ERROR_OK on success
73+
*/
74+
virtual nsapi_error_t get_time(std::tm *t)
75+
{
76+
return NSAPI_ERROR_UNSUPPORTED;
77+
}
78+
6879
/** Attempt to connect to a Wi-Fi network.
6980
*
7081
* @param ssid Name of the network to connect to.

0 commit comments

Comments
 (0)