Skip to content

Commit

Permalink
Add SNTP get config
Browse files Browse the repository at this point in the history
  • Loading branch information
MaJerle committed Aug 3, 2023
1 parent 2c09735 commit 54f3421
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 60 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
- SNTP: Improve module comments, change timezone variable to `int16_t`
- SNTP: Implement global callback when command is to obtain current time
- SNTP: Add synchronization interval config, available with ESP AT `2.3.0` or later (ESP32-C3 only for the moment)
- SNTP: Add option for readin current SNTP configuration
- SNTP: Add option to automatically read SNTP data on `+TIME_UPDATED` event (requires ESP-AT v3.x or newer)
- ERR: Add option to get response to `ERR CODE:` message if command doesn't exist and put it to result of command execution
- Fix min at version for ESP32 to `2.2.0`
- Add `LWESP ` prefix for debug messages
Expand Down
1 change: 1 addition & 0 deletions lwesp/src/include/lwesp/lwesp_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ uint8_t lwespi_parse_cwjap(const char* str, lwesp_msg_t* msg);
uint8_t lwespi_parse_cwlif(const char* str, lwesp_msg_t* msg);
uint8_t lwespi_parse_cipdomain(const char* src, lwesp_msg_t* msg);
uint8_t lwespi_parse_cipsntptime(const char* str, lwesp_msg_t* msg);
uint8_t lwespi_parse_sntp_cfg(const char* str, lwesp_msg_t* msg);
uint8_t lwespi_parse_ping_time(const char* str, lwesp_msg_t* msg);
uint8_t lwespi_parse_hostname(const char* str, lwesp_msg_t* msg);
uint8_t lwespi_parse_link_conn(const char* str);
Expand Down
21 changes: 15 additions & 6 deletions lwesp/src/include/lwesp/lwesp_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,12 @@ typedef enum {
LWESP_CMD_TCPIP_CIPRECVLEN, /*!< Gets number of available bytes in connection to be read */
LWESP_CMD_TCPIP_CIUPDATE, /*!< Perform self-update */
#if LWESP_CFG_SNTP || __DOXYGEN__
LWESP_CMD_TCPIP_CIPSNTPCFG, /*!< Configure SNTP servers */
LWESP_CMD_TCPIP_CIPSNTPTIME, /*!< Get current time using SNTP */
LWESP_CMD_TCPIP_CIPSNTPINTV, /*!< Query/Set the SNTP time synchronization interval */
#endif /* LWESP_SNT || __DOXYGEN__ */
LWESP_CMD_TCPIP_CIPDINFO, /*!< Configure what data are received on +IPD statement */
LWESP_CMD_TCPIP_CIPSNTPCFG, /*!< Configure SNTP servers */
LWESP_CMD_TCPIP_CIPSNTPCFG_GET, /*!< Get SNTP config */
LWESP_CMD_TCPIP_CIPSNTPTIME, /*!< Get current time using SNTP */
LWESP_CMD_TCPIP_CIPSNTPINTV, /*!< Query/Set the SNTP time synchronization interval */
#endif /* LWESP_SNT || __DOXYGEN__ */
LWESP_CMD_TCPIP_CIPDINFO, /*!< Configure what data are received on +IPD statement */
#if LWESP_CFG_PING || __DOXYGEN__
LWESP_CMD_TCPIP_PING, /*!< Ping domain */
#endif /* LWESP_CFG_PING || __DOXYGEN__ */
Expand Down Expand Up @@ -481,12 +482,20 @@ typedef struct lwesp_msg {
#if LWESP_CFG_SNTP || __DOXYGEN__
struct {
uint8_t en; /*!< Status if SNTP is enabled or not */
int8_t tz; /*!< Timezone setup */
int16_t tz; /*!< Timezone setup */
const char* h1; /*!< Optional server 1 */
const char* h2; /*!< Optional server 2 */
const char* h3; /*!< Optional server 3 */
} tcpip_sntp_cfg; /*!< SNTP configuration */

struct {
uint8_t* en; /*!< Status if SNTP is enabled or not */
int16_t* tz; /*!< Timezone setup */
char* h1; /*!< Optional server 1 */
char* h2; /*!< Optional server 2 */
char* h3; /*!< Optional server 3 */
} tcpip_sntp_cfg_get; /*!< SNTP configuration read */

struct {
uint32_t interval; /*!< Time in units of seconds */
} tcpip_sntp_intv; /*!< SNTP interval configuration */
Expand Down
2 changes: 2 additions & 0 deletions lwesp/src/include/lwesp/lwesp_sntp.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ extern "C" {

lwespr_t lwesp_sntp_set_config(uint8_t en, int16_t tz, const char* h1, const char* h2, const char* h3,
const lwesp_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
lwespr_t lwesp_sntp_get_config(uint8_t* en, int16_t* tz, char* h1, char* h2, char* h3,
const lwesp_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
lwespr_t lwesp_sntp_set_interval(uint32_t interval, const lwesp_api_cmd_evt_fn evt_fn, void* const evt_arg,
const uint32_t blocking);
lwespr_t lwesp_sntp_gettime(struct tm* dt, const lwesp_api_cmd_evt_fn evt_fn, void* const evt_arg,
Expand Down
10 changes: 9 additions & 1 deletion lwesp/src/lwesp/lwesp_int.c
Original file line number Diff line number Diff line change
Expand Up @@ -957,7 +957,9 @@ lwespi_parse_received(lwesp_recv_t* rcv) {
#if LWESP_CFG_SNTP
} else if (CMD_IS_CUR(LWESP_CMD_TCPIP_CIPSNTPTIME) && !strncmp(rcv->data, "+CIPSNTPTIME", 12)) {
lwespi_parse_cipsntptime(rcv->data, esp.msg); /* Parse CIPSNTPTIME entry */
#endif /* LWESP_CFG_SNTP */
} else if (CMD_IS_CUR(LWESP_CMD_TCPIP_CIPSNTPCFG_GET) && !strncmp(rcv->data, "+CIPSNTPCFG", 11)) {
lwespi_parse_sntp_cfg(rcv->data, esp.msg); /* Parse CIPSNTPTIME entry */
#endif /* LWESP_CFG_SNTP */
#if LWESP_CFG_HOSTNAME
} else if (CMD_IS_CUR(LWESP_CMD_WIFI_CWHOSTNAME_GET) && !strncmp(rcv->data, "+CWHOSTNAME", 11)) {
lwespi_parse_hostname(rcv->data, esp.msg); /* Parse HOSTNAME entry */
Expand Down Expand Up @@ -2703,6 +2705,12 @@ lwespi_initiate_cmd(lwesp_msg_t* msg) {
AT_PORT_SEND_END_AT();
break;
}
case LWESP_CMD_TCPIP_CIPSNTPCFG_GET: { /* Get SNTP config */
AT_PORT_SEND_BEGIN_AT();
AT_PORT_SEND_CONST_STR("+CIPSNTPCFG?");
AT_PORT_SEND_END_AT();
break;
}
case LWESP_CMD_TCPIP_CIPSNTPTIME: { /* Get time over SNTP */
AT_PORT_SEND_BEGIN_AT();
AT_PORT_SEND_CONST_STR("+CIPSNTPTIME?");
Expand Down
94 changes: 48 additions & 46 deletions lwesp/src/lwesp/lwesp_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ int32_t
lwespi_parse_number(const char** str) {
int32_t val = 0;
uint8_t minus = 0;
const char* p = *str; /* */
const char* p = *str; /* */

INC_IF_CHAR_EQUAL(p, '"'); /* Skip leading quotes */
INC_IF_CHAR_EQUAL(p, ','); /* Skip leading comma */
Expand Down Expand Up @@ -92,7 +92,7 @@ lwespi_parse_port(const char** str) {
uint32_t
lwespi_parse_hexnumber(const char** str) {
int32_t val = 0;
const char* p = *str; /* */
const char* p = *str; /* */

INC_IF_CHAR_EQUAL(p, '"'); /* Skip leading quotes */
INC_IF_CHAR_EQUAL(p, ','); /* Skip leading comma */
Expand Down Expand Up @@ -161,7 +161,7 @@ lwespi_parse_ip(const char** src, lwesp_ip_t* ip) {
const char* p = *src;
#if LWESP_CFG_IPV6
char c;
#endif /* LWESP_CFG_IPV6 */
#endif /* LWESP_CFG_IPV6 */

INC_IF_CHAR_EQUAL(p, '"'); /* Skip leading quotes */

Expand Down Expand Up @@ -208,7 +208,7 @@ lwespi_parse_ip(const char** src, lwesp_ip_t* ip) {
}
INC_IF_CHAR_EQUAL(p, '"'); /* Skip trailing quotes */

*src = p; /* Set new pointer */
*src = p; /* Set new pointer */
return 1;
}

Expand Down Expand Up @@ -464,15 +464,15 @@ lwespi_parse_cwlap(const char* str, lwesp_msg_t* msg) {
#if LWESP_CFG_ACCESS_POINT_STRUCT_FULL_FIELDS
msg->msg.ap_list.aps[msg->msg.ap_list.apsi].scan_type = (uint8_t)lwespi_parse_number(&str); /* Scan type */
msg->msg.ap_list.aps[msg->msg.ap_list.apsi].scan_time_min =
(uint16_t)lwespi_parse_number(&str); /* Scan time minimum */
(uint16_t)lwespi_parse_number(&str); /* Scan time minimum */
msg->msg.ap_list.aps[msg->msg.ap_list.apsi].scan_time_max =
(uint16_t)lwespi_parse_number(&str); /* Scan time maximum */
(uint16_t)lwespi_parse_number(&str); /* Scan time maximum */
msg->msg.ap_list.aps[msg->msg.ap_list.apsi].freq_offset = (int16_t)lwespi_parse_number(&str); /* Freq offset */
msg->msg.ap_list.aps[msg->msg.ap_list.apsi].freq_cal = (int16_t)lwespi_parse_number(&str); /* Freqcal value */
msg->msg.ap_list.aps[msg->msg.ap_list.apsi].pairwise_cipher =
(lwesp_ap_cipher_t)lwespi_parse_number(&str); /* Pairwise cipher */
(lwesp_ap_cipher_t)lwespi_parse_number(&str); /* Pairwise cipher */
msg->msg.ap_list.aps[msg->msg.ap_list.apsi].group_cipher =
(lwesp_ap_cipher_t)lwespi_parse_number(&str); /* Group cipher */
(lwesp_ap_cipher_t)lwespi_parse_number(&str); /* Group cipher */
#else
/* Read and ignore values */
lwespi_parse_number(&str);
Expand Down Expand Up @@ -668,6 +668,33 @@ lwespi_parse_cipdomain(const char* str, lwesp_msg_t* msg) {

#if LWESP_CFG_SNTP || __DOXYGEN__

/**
* \brief Parse received message for SNTP configuration
* \param[in] str: Pointer to input string starting with +CWLAP
* \param[in] msg: Pointer to message
* \return `1` on success, `0` otherwise
*/
uint8_t
lwespi_parse_sntp_cfg(const char* str, lwesp_msg_t* msg) {
int32_t num;
if (!CMD_IS_DEF(LWESP_CMD_TCPIP_CIPSNTPCFG_GET)) {
return 0;
}
if (*str == '+') { /* Check input string */
str += 13;
}
num = lwespi_parse_number(&str);
if (msg->msg.tcpip_sntp_cfg_get.en != NULL) {
*msg->msg.tcpip_sntp_cfg_get.en = num;
}
num = lwespi_parse_number(&str);
if (msg->msg.tcpip_sntp_cfg_get.tz != NULL) {
*msg->msg.tcpip_sntp_cfg_get.tz = (int16_t)num;
}
/* TODO: Parse hostnames... */
return 1;
}

/**
* \brief Parse received message for SNTP time
* \param[in] str: Pointer to input string starting with +CWLAP
Expand All @@ -676,6 +703,9 @@ lwespi_parse_cipdomain(const char* str, lwesp_msg_t* msg) {
*/
uint8_t
lwespi_parse_cipsntptime(const char* str, lwesp_msg_t* msg) {
const char* days[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
const char* months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};

if (!CMD_IS_DEF(LWESP_CMD_TCPIP_CIPSNTPTIME)) {
return 0;
}
Expand All @@ -684,48 +714,20 @@ lwespi_parse_cipsntptime(const char* str, lwesp_msg_t* msg) {
}

/* Scan for day in a week */
if (!strncmp(str, "Mon", 3)) {
msg->msg.tcpip_sntp_time.dt->tm_mday = 0;
} else if (!strncmp(str, "Tue", 3)) {
msg->msg.tcpip_sntp_time.dt->tm_mday = 1;
} else if (!strncmp(str, "Wed", 3)) {
msg->msg.tcpip_sntp_time.dt->tm_mday = 2;
} else if (!strncmp(str, "Thu", 3)) {
msg->msg.tcpip_sntp_time.dt->tm_mday = 3;
} else if (!strncmp(str, "Fri", 3)) {
msg->msg.tcpip_sntp_time.dt->tm_mday = 4;
} else if (!strncmp(str, "Sat", 3)) {
msg->msg.tcpip_sntp_time.dt->tm_mday = 5;
} else if (!strncmp(str, "Sun", 3)) {
msg->msg.tcpip_sntp_time.dt->tm_mday = 6;
for (size_t i = 0; i < LWESP_ARRAYSIZE(days); ++i) {
if (!strncmp(str, days[i], 3)) {
msg->msg.tcpip_sntp_time.dt->tm_mday = (int)i;
break;
}
}
str += 4;

/* Scan for month in a year */
if (!strncmp(str, "Jan", 3)) {
msg->msg.tcpip_sntp_time.dt->tm_mon = 0;
} else if (!strncmp(str, "Feb", 3)) {
msg->msg.tcpip_sntp_time.dt->tm_mon = 1;
} else if (!strncmp(str, "Mar", 3)) {
msg->msg.tcpip_sntp_time.dt->tm_mon = 2;
} else if (!strncmp(str, "Apr", 3)) {
msg->msg.tcpip_sntp_time.dt->tm_mon = 3;
} else if (!strncmp(str, "May", 3)) {
msg->msg.tcpip_sntp_time.dt->tm_mon = 4;
} else if (!strncmp(str, "Jun", 3)) {
msg->msg.tcpip_sntp_time.dt->tm_mon = 5;
} else if (!strncmp(str, "Jul", 3)) {
msg->msg.tcpip_sntp_time.dt->tm_mon = 6;
} else if (!strncmp(str, "Aug", 3)) {
msg->msg.tcpip_sntp_time.dt->tm_mon = 7;
} else if (!strncmp(str, "Sep", 3)) {
msg->msg.tcpip_sntp_time.dt->tm_mon = 8;
} else if (!strncmp(str, "Oct", 3)) {
msg->msg.tcpip_sntp_time.dt->tm_mon = 9;
} else if (!strncmp(str, "Nov", 3)) {
msg->msg.tcpip_sntp_time.dt->tm_mon = 10;
} else if (!strncmp(str, "Dec", 3)) {
msg->msg.tcpip_sntp_time.dt->tm_mon = 11;
for (size_t i = 0; i < LWESP_ARRAYSIZE(months); ++i) {
if (!strncmp(str, months[i], 3)) {
msg->msg.tcpip_sntp_time.dt->tm_mon = (int)i;
break;
}
}
str += 4;
if (*str == ' ') { /* Numbers < 10 could have one more space */
Expand Down
34 changes: 34 additions & 0 deletions lwesp/src/lwesp/lwesp_sntp.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,40 @@ lwesp_sntp_set_config(uint8_t en, int16_t tz, const char* h1, const char* h2, co
return lwespi_send_msg_to_producer_mbox(&LWESP_MSG_VAR_REF(msg), lwespi_initiate_cmd, 1000);
}

/**
* \brief Get current SNTP configuration.
* \todo Parse response for hostnames, which is not done at the moment
*
* \param[in] en: Pointer to status variable
* \param[in] tz: Pointer to timezone
* \param[in] h1: Optional first SNTP server for time. Set to `NULL` if not used,
* otherwise value is copied into the pointer. Must be sufficient enough
* \param[in] h2: Optional second SNTP server for time. Set to `NULL` if not used
* otherwise value is copied into the pointer. Must be sufficient enough
* \param[in] h3: Optional third SNTP server for time. Set to `NULL` if not used
* otherwise value is copied into the pointer. Must be sufficient enough
* \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
* \param[in] evt_arg: Custom argument for event callback function
* \param[in] blocking: Status whether command should be blocking or not
* \return \ref lwespOK on success, member of \ref lwespr_t enumeration otherwise
*/
lwespr_t
lwesp_sntp_get_config(uint8_t* en, int16_t* tz, char* h1, char* h2, char* h3, const lwesp_api_cmd_evt_fn evt_fn,
void* const evt_arg, const uint32_t blocking) {
LWESP_MSG_VAR_DEFINE(msg);

LWESP_MSG_VAR_ALLOC(msg, blocking);
LWESP_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
LWESP_MSG_VAR_REF(msg).cmd_def = LWESP_CMD_TCPIP_CIPSNTPCFG_GET;
LWESP_MSG_VAR_REF(msg).msg.tcpip_sntp_cfg_get.en = en;
LWESP_MSG_VAR_REF(msg).msg.tcpip_sntp_cfg_get.tz = tz;
LWESP_MSG_VAR_REF(msg).msg.tcpip_sntp_cfg_get.h1 = h1;
LWESP_MSG_VAR_REF(msg).msg.tcpip_sntp_cfg_get.h2 = h2;
LWESP_MSG_VAR_REF(msg).msg.tcpip_sntp_cfg_get.h3 = h3;

return lwespi_send_msg_to_producer_mbox(&LWESP_MSG_VAR_REF(msg), lwespi_initiate_cmd, 1000);
}

/**
* \brief Set SNTP synchronization interval on Espressif device
* SNTP must be configured using \ref lwesp_sntp_set_config before you can use this function.
Expand Down
19 changes: 12 additions & 7 deletions snippets/netconn_client_ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ netconn_client_ssl_thread(void const* arg) {
client = lwesp_netconn_new(LWESP_NETCONN_TYPE_SSL);
if (client != NULL) {
struct tm dt;
uint8_t sntp_en;

/* Write data to coresponding manuf NVS */
res = lwesp_mfg_write(LWESP_MFG_NAMESPACE_CLIENT_CA, "client_ca.0", LWESP_MFG_VALTYPE_BLOB, client_ca,
Expand All @@ -76,14 +77,18 @@ netconn_client_ssl_thread(void const* arg) {
}

/* Ensure SNTP is enabled, time is required for SSL */
lwesp_sntp_set_config(1, 2, NULL, NULL, NULL, NULL, NULL, 1);
do {
lwesp_sntp_gettime(&dt, NULL, NULL, 1);
if (dt.tm_year > 100) {
break;
if (lwesp_sntp_get_config(&sntp_en, NULL, NULL, NULL, NULL, NULL, NULL, 1) == lwespOK) {
if (!sntp_en) {
lwesp_sntp_set_config(1, 2, NULL, NULL, NULL, NULL, NULL, 1);
}
lwesp_delay(1000);
} while (1);
do {
lwesp_sntp_gettime(&dt, NULL, NULL, 1);
if (dt.tm_year > 100) {
break;
}
lwesp_delay(1000);
} while (1);
}

/*
* Connect to external server as client
Expand Down

0 comments on commit 54f3421

Please sign in to comment.