A Telegram BOT for this awesome all-in-one board.
Dependencies: BSP_B-L475E-IOT01 mbed es_wifi jsmn
Telegram Bot for DISCO_L475VG_IOT01
This application embeds aTelegram chatbot into the DISCO_L475VG_IOT01 board.
The Bot answers to the users queries about:
- Real time environmental data taken from the on board sensors.
- Environmental data history of the latest 24 hours stored on board.
- Camera images taken from the Arducam-mini-2mp (optional).
This software uses:
- A modified version of the wifi library provided by ST in order to enable the TCP-SSL connection.
- An open source json parser jsmn (https://github.com/zserge/jsmn).
- A web service (http://now.http.org) to initialize the RTC.
- A web service (https://image-charts.com) to publish temperature,humidity and pressure charts.
- A modified version of the Arducam driver (https://os.mbed.com/users/dflet/)
Compilation
Import in your compiler and modify the following defines:
- WIFI_SSID
- WIFI_PASSWORD
- TELEGRAM_BOT_APIKEY
Please follow the Telegram bots documentation (https://core.telegram.org/bots) to better understand how the Telegram API works and how to create your bot.
In order to support the Arducam-Mini-2MP set WITH_ARDUCAM_2640 #define to 1.
Screenshots
Security
The Inventek wifi module creates the ssl connection but does not authenticate the server's certificate ( AT cmd P9=0 ).
For more details http://www.inventeksys.com/IWIN/programming-certificates-tcp-ssltls/
Diff: main.cpp
- Revision:
- 8:89fe332bc412
- Parent:
- 7:2b389a2e83c4
- Child:
- 9:d24842a5a468
--- a/main.cpp Tue Jan 30 10:23:41 2018 +0000 +++ b/main.cpp Thu Feb 15 14:31:15 2018 +0000 @@ -6,7 +6,9 @@ #include "es_wifi.h" #include "es_wifi_io.h" #include "jsmn.h" - +#include "ArduCAM2640.h" +#include "TCPConnector.h" +#include "HTTPHelper.h" #define WIFI_SSID "" @@ -14,8 +16,6 @@ #define TELEGRAM_BOT_APIKEY "" -#define WIFI_WRITE_TIMEOUT 10000 -#define WIFI_READ_TIMEOUT 25000 #define CONNECTION_TRIAL_MAX 10 @@ -23,36 +23,33 @@ DigitalOut g_alivenessLED(LED1); // wifi interfaces -ES_WIFIObject_t g_es_wifi_ctx; -bool wifi_connect(void); -bool open_tcp_connection(uint8_t socket, char *domain_name, uint16_t remote_port,bool secure); -bool close_tcp_connection(uint32_t socket); +TCPConnector g_tcp_connector; +HTTPHelper g_http_parser; +ArduCAM2640 g_arducam; // http I/O buffer char g_http_io_buffer[ES_WIFI_DATA_SIZE]; // Telegram json I/O buffer -#define TBOT_JSON_BUFFER_SIZE 5 * 1024 +#define TBOT_JSON_BUFFER_SIZE 3 * 1024 char g_json_io_buffer[TBOT_JSON_BUFFER_SIZE]; // telegram REST API const char TELEGRAM_GETUPDATES[] = "GET /bot" TELEGRAM_BOT_APIKEY "/getUpdates?offset=%d&timeout=20&limit=1 HTTP/1.1\r\nHost: api.telegram.org\r\nUser-Agent: curl/7.50.1\r\nAccept: */*\r\n\r\n"; const char TELEGRAM_SENDMESSAGE[] = "GET /bot" TELEGRAM_BOT_APIKEY "/sendMessage HTTP/1.1\r\nHost: api.telegram.org\r\nUser-Agent: curl/7.50.1\r\nAccept: */*\r\nContent-Type: application/json\r\nContent-Length: %d\r\n\r\n"; -const char TELEGRAM_CUSTOM_KEYBOARD[] = "{\"keyboard\": [[\"Temperature\",\"Humidity\",\"Pressure\"],[\"Daily\",\"RTC\"]],\"one_time_keyboard\": true}"; +const char TELEGRAM_SENDPHOTO[] = "POST /bot" TELEGRAM_BOT_APIKEY "/sendPhoto HTTP/1.1\r\nHost: api.telegram.org\r\nUser-Agent: curl/7.47.0\r\nAccept: */*\r\nContent-Length: %d\r\nConnection: close\r\n"; +const char TELEGRAM_CUSTOM_KEYBOARD[] = "{\"keyboard\": [[\"Temperature\",\"Humidity\",\"Pressure\"],[\"Daily\",\"RTC\",\"Camera\"]],\"one_time_keyboard\": true}"; bool telegram_get_update(int32_t update_id); -bool telegram_send_message(); +bool telegram_send_message(char *json_msg); +bool telegram_send_photo(uint8_t *image, uint32_t image_size, int32_t chat_id, char *caption); #define TELEGRAM_BOT_INCOMING_CMD_SIZE 80 char g_incoming_msg[TELEGRAM_BOT_INCOMING_CMD_SIZE]; -void telegram_bot(void); +void telegram_bot(); // now.httpbin.org const char NOW_HTTPBIN_ORG[] = "GET / HTTP/1.1\r\nHost: now.httpbin.org\r\nUser-Agent: curl/7.50.1\r\nAccept: */*\r\n\r\n"; bool set_rtc_from_network(void); -// HTTP util -bool http_request(char *http_server_domain,bool has_json_payload,bool secure); -bool http_parse_response(char *http_chunk, uint16_t http_chunk_len, bool *status_code_ok, uint16_t *content_len); - // JSON parser #define JSON_MAX_TOKENS 128 jsmn_parser g_json_parser; @@ -68,13 +65,26 @@ int32_t daily_temperature_history_chart(char *report_buffer, uint32_t buffer_len); int32_t daily_pressure_history_chart(char *report_buffer, uint32_t buffer_len); +/* jpeg buffer */ +#define IMAGE_JPG_SIZE 16*1024 +uint8_t g_image_buffer[IMAGE_JPG_SIZE]; int main() { - printf("> DISCO_L475VG_IOT01-Telegram-BOT started\r\n"); + printf("> DISCO_L475VG_IOT01-Telegram-Camera-BOT started\r\n"); + + /* Setup camera */ + I2C camI2C(PB_9,PB_8); + SPI camSPI(PA_7,PA_6,PA_5); + DigitalOut cam_spi_cs(PA_2); - + if( g_arducam.Setup( OV_RESOLUTION_CIF,92, &cam_spi_cs, &camSPI, &camI2C) == false) + { + printf("Arducam setup error \r\n"); + while(1); + } + /* Setup env sensors */ BSP_TSENSOR_Init(); BSP_HSENSOR_Init(); @@ -92,7 +102,7 @@ -void telegram_bot(void) +void telegram_bot() { int32_t update_id = 0; int32_t chat_id = 0; @@ -104,7 +114,7 @@ /* wifi connect */ - if(wifi_connect()) + if(g_tcp_connector.wifi_connect(WIFI_SSID,WIFI_PASSWORD,CONNECTION_TRIAL_MAX)) { printf("> Wifi connected\r\n"); } @@ -149,8 +159,8 @@ if (telegram_get_update(update_id + 1) == false) { printf("> ERROR telegram_get_update\r\n> Reset wifi connection\r\n"); - ES_WIFI_ResetModule(&g_es_wifi_ctx); - wifi_connect(); + + g_tcp_connector.wifi_connect(WIFI_SSID,WIFI_PASSWORD,CONNECTION_TRIAL_MAX); continue; } printf("> JSON content: %s\r\n", g_json_io_buffer); @@ -218,7 +228,6 @@ printf("> Incoming msg: %s\n\r",g_incoming_msg); - // parse incoming message if( strstr(g_incoming_msg,"Temperature") != NULL) { @@ -240,12 +249,12 @@ snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"%s UTC\",\"reply_markup\":%s}", chat_id,ctime(×tamp),TELEGRAM_CUSTOM_KEYBOARD); } - else if( strstr(g_incoming_msg,"Daily") != NULL) + else if( strstr(g_incoming_msg,"Daily") != NULL ) { int pivot = snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"", chat_id); pivot += daily_temperature_history_chart( g_json_io_buffer + pivot, TBOT_JSON_BUFFER_SIZE - pivot ); snprintf( g_json_io_buffer + pivot, TBOT_JSON_BUFFER_SIZE - pivot, "\"}"); - if( telegram_send_message() == false) + if( telegram_send_message(g_json_io_buffer) == false) { printf("> ERROR telegram_send_message\r\n"); continue; @@ -254,7 +263,7 @@ pivot = snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"", chat_id); pivot += daily_humidity_history_chart( g_json_io_buffer + pivot, TBOT_JSON_BUFFER_SIZE - pivot ); snprintf( g_json_io_buffer + pivot, TBOT_JSON_BUFFER_SIZE - pivot, "\"}"); - if( telegram_send_message() == false) + if( telegram_send_message(g_json_io_buffer) == false) { printf("> ERROR telegram_send_message\r\n"); continue; @@ -266,13 +275,39 @@ } + else if( strstr(g_incoming_msg,"Camera") != NULL ) + { + uint32_t image_size; + uint32_t idx; + + snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"Sending photos ...\",\"reply_markup\":%s}", + chat_id,TELEGRAM_CUSTOM_KEYBOARD); + if( telegram_send_message(g_json_io_buffer) == false) + { + printf("> ERROR telegram_send_message\r\n"); + continue; + } + + for(int i=0; i<3; i++) + { + image_size = g_arducam.CaptureImage(g_image_buffer,IMAGE_JPG_SIZE,&idx); + if( image_size == 0 || telegram_send_photo(g_image_buffer+idx, image_size, chat_id, "Images from space") == false ) + { + printf("Photo failure %d\r\n",image_size); + break; + } + } + + snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"Done.\",\"reply_markup\":%s}", + chat_id,TELEGRAM_CUSTOM_KEYBOARD); + } else { snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"Available commands\",\"reply_markup\":%s}", chat_id,TELEGRAM_CUSTOM_KEYBOARD); } - if( telegram_send_message() == false) + if( telegram_send_message(g_json_io_buffer) == false) { printf("> ERROR telegram_send_message\r\n"); continue; @@ -407,9 +442,33 @@ #define HTTPBIN_EPOCH_TAG "epoch\":" bool set_rtc_from_network(void) { + uint32_t http_content_len=0; + bool http_ok = false; + /* prepare http get header */ strcpy(g_http_io_buffer,NOW_HTTPBIN_ORG); - if( http_request("now.httpbin.org",false,false) ) + + + // CONNECT http://now.httpbin.org + if( g_tcp_connector.tcp_connect(0x01,"now.httpbin.org",80,false,3) ) + { + // send HTML GET + if( g_tcp_connector.tcp_write(0x01,g_http_io_buffer,strlen(g_http_io_buffer))) + { + // read json response + if( g_http_parser.HttpParseResponse(&g_tcp_connector,0x01,g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,&http_ok,&http_content_len) ) + { + if(http_ok) + { + g_json_io_buffer[http_content_len] = 0; + } + } + } + } + g_tcp_connector.tcp_close(0x01); + + // parse and set time + if( http_ok ) { char *epoch = strstr(g_json_io_buffer,HTTPBIN_EPOCH_TAG); if(epoch == NULL) return false; @@ -438,168 +497,132 @@ * ******************************************************************************************/ - bool telegram_get_update(int32_t update_id) { + uint32_t http_content_len=0; + bool http_ok = false; + /* prepare http get header */ snprintf(g_http_io_buffer, ES_WIFI_PAYLOAD_SIZE, TELEGRAM_GETUPDATES, update_id); - return http_request("api.telegram.org",false,true); + + + // CONNECT https://api.telegram.org + if( g_tcp_connector.tcp_connect(0x01,"api.telegram.org",443,true,3) ) + { + // send HTML GET getUpdates + if( g_tcp_connector.tcp_write(0x01,g_http_io_buffer,strlen(g_http_io_buffer))) + { + // read json response + if( g_http_parser.HttpParseResponse(&g_tcp_connector,0x01,g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,&http_ok,&http_content_len) ) + { + if(http_ok) + { + g_json_io_buffer[http_content_len] = 0; + } + } + } + g_tcp_connector.tcp_close(0x01); + } + + return http_ok; } -bool telegram_send_message() +bool telegram_send_message(char *json_msg) { - /* prepare http get header */ - snprintf(g_http_io_buffer, ES_WIFI_PAYLOAD_SIZE, TELEGRAM_SENDMESSAGE, strlen(g_json_io_buffer)); - return http_request("api.telegram.org",true,true); -} + uint32_t http_content_len=0,msg_len; + bool http_ok = false; + + msg_len = strlen(json_msg); -/************************************************************************************************** -* -* -* HTTP request transaction -* -* -***************************************************************************************************/ -bool http_request(char *http_server_domain,bool has_json_payload,bool secure) -{ - uint16_t io_s, tx_s; - ES_WIFI_Status_t io_status; - bool http_ok; - int32_t http_content_len; - char *http_content_pivot; - uint16_t content_chunk_size; - bool ret_val = false; - static uint8_t socket=0; + /* prepare http get header */ + snprintf(g_http_io_buffer, ES_WIFI_PAYLOAD_SIZE, TELEGRAM_SENDMESSAGE, msg_len); - /* open socket */ - socket++; - if(socket==4) socket=0; - io_status = ES_WIFI_STATUS_ERROR; - for (int i = 0; i < CONNECTION_TRIAL_MAX; i++) - { - printf("> Open TCP connection ...\r\n"); - if (open_tcp_connection(socket, http_server_domain,(secure)?443:80,secure)) - { - printf("> TCP Connection opened successfully.\r\n"); - io_status = ES_WIFI_STATUS_OK; - break; - } - } - - if (io_status != ES_WIFI_STATUS_OK) + // CONNECT https://api.telegram.org + if( g_tcp_connector.tcp_connect(0x01,"api.telegram.org",443,true,3) ) { - printf("> socket open error.\r\n"); - return false; - } - - - /* send http get header */ - tx_s = strlen(g_http_io_buffer); - // printf(g_http_io_buffer); - io_s = 0; - if (ES_WIFI_SendData(&g_es_wifi_ctx, socket, (uint8_t *)g_http_io_buffer, tx_s, &io_s, WIFI_WRITE_TIMEOUT) != ES_WIFI_STATUS_OK) - { - printf("> ERROR : CANNOT send data\r\n"); - goto happy_end; - } - if (io_s != tx_s) - { - printf("> ERROR Send %d of %d.\r\n", io_s, tx_s); - goto happy_end; + // send HTML GET sendMessage + if( g_tcp_connector.tcp_write(0x01,g_http_io_buffer,strlen(g_http_io_buffer))) + { + // send payload + if( g_tcp_connector.tcp_write(0x01,json_msg,msg_len) ) + { + // read json response + if( g_http_parser.HttpParseResponse(&g_tcp_connector,1,g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,&http_ok,&http_content_len) ) + { + if(http_ok) + { + g_json_io_buffer[http_content_len] = 0; + } + } + } + } + g_tcp_connector.tcp_close(0x01); } - /* send json payload */ - if(has_json_payload) - { - tx_s = strlen(g_json_io_buffer); - io_s = 0; - if (ES_WIFI_SendData(&g_es_wifi_ctx, socket, (uint8_t *)g_json_io_buffer, tx_s, &io_s, WIFI_WRITE_TIMEOUT) != ES_WIFI_STATUS_OK) - { - printf("> ERROR : CANNOT send data\r\n"); - goto happy_end; - } - if (io_s != tx_s) - { - printf("> ERROR Send %d of %d.\r\n", io_s, tx_s); - goto happy_end; - } - } - - /* from now on the http io buffer is reused */ - g_json_io_buffer[0]=0; - g_http_io_buffer[0]=0; - - /* fetch response */ - io_status = ES_WIFI_ReceiveData(&g_es_wifi_ctx, socket, (uint8_t *)g_http_io_buffer, ES_WIFI_PAYLOAD_SIZE, &io_s, WIFI_READ_TIMEOUT); - if (io_status != ES_WIFI_STATUS_OK) - { - printf("> ERROR : socket receive data\r\n"); - goto happy_end; - } - - /* parse http response for the status code and content len */ - http_ok = false; - http_content_len = 0; - g_http_io_buffer[io_s] = 0; - if (io_s == 0 || http_parse_response((char *)g_http_io_buffer, io_s, &http_ok, (uint16_t *)&http_content_len) == false) - { - printf("< Invalid response\r\n"); - for (int i = 0; i < io_s; i++) - printf("%c", g_http_io_buffer[i]); - printf("> Invalid response\r\n"); - goto happy_end; - } - printf("> HTTP OK = %d Content len = %d\r\n", http_ok, http_content_len); - - /* fetch json response */ - http_content_pivot = strstr((char *)g_http_io_buffer, "\r\n\r\n"); - if (http_content_pivot != NULL) - { - http_content_pivot += 4; - content_chunk_size = strlen(http_content_pivot); - if (content_chunk_size < TBOT_JSON_BUFFER_SIZE) - strcpy(g_json_io_buffer, http_content_pivot); - http_content_len -= content_chunk_size; - } - else - { - printf("< Invalid response\r\n"); - for (int i = 0; i < io_s; i++) - printf("%c", g_http_io_buffer[i]); - printf("> Invalid response\r\n"); - goto happy_end; - } - - /* continue to fetch json chunck */ - while (http_content_len > 0) - { - if (ES_WIFI_ReceiveData2(&g_es_wifi_ctx, (uint8_t *)g_http_io_buffer, ES_WIFI_PAYLOAD_SIZE, &io_s) != ES_WIFI_STATUS_OK) - { - printf("> ERROR : socket receive data\r\n"); - goto happy_end; - } - g_http_io_buffer[io_s] = 0; - http_content_len -= io_s; - if (http_content_len < 0 || io_s == 0) - { - printf("> ERROR : http content len overflow\r\n"); - goto happy_end; - } - strcat(g_json_io_buffer, g_http_io_buffer); - } - ret_val = http_ok; - -happy_end: - printf("> Close TCP connection...\r\n"); - close_tcp_connection(socket); - printf("> done.\r\n"); - return ret_val; + return http_ok; } +bool telegram_send_photo(uint8_t *image, uint32_t image_size, int32_t chat_id, char *caption) +{ + char chat_id_str[32]; + uint32_t content_len = 0; + uint32_t http_content_len=0; + bool http_ok = false; + content_len = 383; // pre-calculated boundary len + content_len += snprintf(chat_id_str,sizeof(chat_id_str),"%d",chat_id); + content_len += strlen(caption); + content_len += image_size; + + /* prepare http post header */ + snprintf(g_http_io_buffer, ES_WIFI_PAYLOAD_SIZE, TELEGRAM_SENDPHOTO, content_len); + + // CONNECT https://api.telegram.org + if( g_tcp_connector.tcp_connect(0x01,"api.telegram.org",443,true,3) ) + { + // send HTML POST sendMessage + if( g_tcp_connector.tcp_write(0x01,g_http_io_buffer,strlen(g_http_io_buffer))) + { + strcpy(g_http_io_buffer,"Content-Type: multipart/form-data; boundary=------------------------660d8ea934533f2b\r\n"); + if( g_tcp_connector.tcp_write(0x01,g_http_io_buffer,strlen(g_http_io_buffer))) + { + snprintf(g_http_io_buffer, ES_WIFI_PAYLOAD_SIZE, "\r\n--------------------------660d8ea934533f2b\r\nContent-Disposition: form-data; name=\"chat_id\"\r\n\r\n%s", chat_id_str); + if( g_tcp_connector.tcp_write(0x01,g_http_io_buffer,strlen(g_http_io_buffer))) + { + snprintf(g_http_io_buffer, ES_WIFI_PAYLOAD_SIZE, "\r\n--------------------------660d8ea934533f2b\r\nContent-Disposition: form-data; name=\"caption\"\r\n\r\n%s", caption); + if( g_tcp_connector.tcp_write(0x01,g_http_io_buffer,strlen(g_http_io_buffer))) + { + strcpy(g_http_io_buffer, "\r\n--------------------------660d8ea934533f2b\r\nContent-Disposition: form-data; name=\"photo\"; filename=\"acam2640.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n"); + if( g_tcp_connector.tcp_write(0x01,g_http_io_buffer,strlen(g_http_io_buffer))) + { + if( g_tcp_connector.tcp_write(0x01,(char*)image,image_size)) + { + strcpy(g_http_io_buffer,"\r\n--------------------------660d8ea934533f2b--\r\n"); + if( g_tcp_connector.tcp_write(0x01,g_http_io_buffer,strlen(g_http_io_buffer)) ) + { + // read json response + if( g_http_parser.HttpParseResponse(&g_tcp_connector,0x01,g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,&http_ok,&http_content_len) ) + { + if(http_ok) + { + g_json_io_buffer[http_content_len] = 0; + } + } + } + } + } + } + } + } + } + g_tcp_connector.tcp_close(0x01); + } + + return http_ok; +} /***************************************************************************************** * @@ -618,108 +641,4 @@ return false; } -/***************************************************************************************** -* -* -* HTTP parsing -* -* -******************************************************************************************/ -const char HTTP_200OK[] = "200 OK\r\n"; -const char HTTP_CL[] = "Content-Length: "; -bool http_parse_response(char *http_chunk, uint16_t http_chunk_len, bool *status_code_ok, uint16_t *content_len) -{ - char *line_pivot, *key_pivot; - - line_pivot = strstr(http_chunk, "\r\n"); - if (line_pivot == NULL) - return false; - - key_pivot = strstr(http_chunk, HTTP_200OK); - - if (key_pivot != NULL) - *status_code_ok = true; - else - *status_code_ok = false; - - while (1) - { - line_pivot = strstr(line_pivot + 2, "\r\n"); - if (line_pivot == NULL) - break; - key_pivot = strstr(http_chunk, HTTP_CL); - if (key_pivot == NULL) - continue; - if (key_pivot < line_pivot) - { - key_pivot += strlen(HTTP_CL); - *content_len = atoi((char const *)key_pivot); - return true; - } - } - - return false; -} - -/***************************************************************************************** -* -* -* WIFI -* -* -******************************************************************************************/ - -bool wifi_connect(void) -{ - /* HW setup */ - if (ES_WIFI_RegisterBusIO(&g_es_wifi_ctx, - SPI_WIFI_Init, - SPI_WIFI_DeInit, - SPI_WIFI_Delay, - SPI_WIFI_SendData, - SPI_WIFI_ReceiveData) != ES_WIFI_STATUS_OK) - return false; - - if (ES_WIFI_Init(&g_es_wifi_ctx) != ES_WIFI_STATUS_OK) - return false; - ES_WIFI_ResetToFactoryDefault(&g_es_wifi_ctx); - - /* JOIN AP */ - for (int i = 0; i < CONNECTION_TRIAL_MAX; i++) - { - if (ES_WIFI_Connect(&g_es_wifi_ctx, WIFI_SSID, WIFI_PASSWORD, ES_WIFI_SEC_WPA_WPA2) == ES_WIFI_STATUS_OK) - { - if (ES_WIFI_GetNetworkSettings(&g_es_wifi_ctx) == ES_WIFI_STATUS_OK) - return true; - else - return false; - } - wait_ms(1000); - } - - return false; -} - - -bool open_tcp_connection(uint8_t socket, char *domain_name, uint16_t remote_port,bool secure) -{ - ES_WIFI_Conn_t conn; - - conn.Number = socket; - conn.RemotePort = remote_port; - conn.LocalPort = 0; - conn.Type = (secure)?ES_WIFI_TCP_SSL_CONNECTION:ES_WIFI_TCP_CONNECTION; - strncpy((char *)conn.RemoteHost, domain_name, sizeof(conn.RemoteHost)); - return (ES_WIFI_ConnectToRemoteHost(&g_es_wifi_ctx, &conn) == ES_WIFI_STATUS_OK) ? true : false; -} - -bool close_tcp_connection(uint32_t socket) -{ - ES_WIFI_Conn_t conn; - conn.Number = socket; - - return (ES_WIFI_StopClientConnection(&g_es_wifi_ctx, &conn)== ES_WIFI_STATUS_OK); -} - -