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:

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

/media/uploads/dvddnr/screenshot_20180130-073732.png /media/uploads/dvddnr/screenshot_20180130-073703.png /media/uploads/dvddnr/arducam.jpeg /media/uploads/dvddnr/screenshot_20180216-102601.png

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/

Committer:
dvddnr
Date:
Fri Jan 26 15:27:26 2018 +0000
Revision:
6:94fc61e1cf40
Parent:
5:f204a47aa813
Child:
7:2b389a2e83c4
Added Bot response for RTC value

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dvddnr 0:1fc46da4a976 1 #include "mbed.h"
dvddnr 0:1fc46da4a976 2
dvddnr 0:1fc46da4a976 3 #include "stm32l475e_iot01_tsensor.h"
dvddnr 0:1fc46da4a976 4 #include "stm32l475e_iot01_hsensor.h"
dvddnr 0:1fc46da4a976 5 #include "stm32l475e_iot01_psensor.h"
dvddnr 1:60fbd0835b9d 6 #include "es_wifi.h"
dvddnr 1:60fbd0835b9d 7 #include "es_wifi_io.h"
dvddnr 1:60fbd0835b9d 8 #include "jsmn.h"
dvddnr 1:60fbd0835b9d 9
dvddnr 1:60fbd0835b9d 10
dvddnr 1:60fbd0835b9d 11
dvddnr 1:60fbd0835b9d 12 #define WIFI_SSID ""
dvddnr 1:60fbd0835b9d 13 #define WIFI_PASSWORD ""
dvddnr 1:60fbd0835b9d 14 #define TELEGRAM_BOT_APIKEY ""
dvddnr 1:60fbd0835b9d 15
dvddnr 6:94fc61e1cf40 16
dvddnr 1:60fbd0835b9d 17 #define WIFI_WRITE_TIMEOUT 10000
dvddnr 1:60fbd0835b9d 18 #define WIFI_READ_TIMEOUT 10000
dvddnr 1:60fbd0835b9d 19 #define CONNECTION_TRIAL_MAX 10
dvddnr 1:60fbd0835b9d 20
dvddnr 5:f204a47aa813 21
dvddnr 4:9926288a8703 22 // LED
dvddnr 4:9926288a8703 23 DigitalOut g_alivenessLED(LED1);
dvddnr 1:60fbd0835b9d 24
dvddnr 1:60fbd0835b9d 25 // wifi interfaces
dvddnr 1:60fbd0835b9d 26 ES_WIFIObject_t g_es_wifi_ctx;
dvddnr 1:60fbd0835b9d 27 bool wifi_connect(void);
dvddnr 5:f204a47aa813 28 bool open_tcp_connection(uint8_t socket, char *domain_name, uint16_t remote_port,bool secure);
dvddnr 5:f204a47aa813 29 bool close_tcp_connection(uint32_t socket);
dvddnr 0:1fc46da4a976 30
dvddnr 1:60fbd0835b9d 31 // http I/O buffer
dvddnr 1:60fbd0835b9d 32 char g_http_io_buffer[ES_WIFI_DATA_SIZE];
dvddnr 1:60fbd0835b9d 33
dvddnr 1:60fbd0835b9d 34 // Telegram json I/O buffer
dvddnr 1:60fbd0835b9d 35 #define TBOT_JSON_BUFFER_SIZE 5 * 1024
dvddnr 1:60fbd0835b9d 36 char g_json_io_buffer[TBOT_JSON_BUFFER_SIZE];
dvddnr 1:60fbd0835b9d 37
dvddnr 1:60fbd0835b9d 38 // telegram REST API
dvddnr 1:60fbd0835b9d 39 const char TELEGRAM_GETUPDATES[] = "GET /bot" TELEGRAM_BOT_APIKEY "/getUpdates?offset=%d&timeout=5&limit=1 HTTP/1.1\r\nHost: api.telegram.org\r\nUser-Agent: curl/7.50.1\r\nAccept: */*\r\n\r\n";
dvddnr 1:60fbd0835b9d 40 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";
dvddnr 6:94fc61e1cf40 41 const char TELEGRAM_CUSTOM_KEYBOARD[] = "{\"keyboard\": [[\"Temperature\"],[\"Humidity\"],[\"Pressure\"],[\"RTC\"]],\"one_time_keyboard\": true}";
dvddnr 1:60fbd0835b9d 42 bool telegram_get_update(int32_t update_id);
dvddnr 1:60fbd0835b9d 43 bool telegram_send_message();
dvddnr 1:60fbd0835b9d 44 #define TELEGRAM_BOT_INCOMING_CMD_SIZE 80
dvddnr 1:60fbd0835b9d 45 char g_incoming_msg[TELEGRAM_BOT_INCOMING_CMD_SIZE];
dvddnr 1:60fbd0835b9d 46 void telegram_bot(void);
dvddnr 1:60fbd0835b9d 47
dvddnr 5:f204a47aa813 48 // now.httpbin.org
dvddnr 5:f204a47aa813 49 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";
dvddnr 5:f204a47aa813 50 bool set_rtc_from_network(void);
dvddnr 1:60fbd0835b9d 51
dvddnr 1:60fbd0835b9d 52 // HTTP util
dvddnr 5:f204a47aa813 53 bool http_request(char *http_server_domain,bool has_json_payload,bool secure);
dvddnr 1:60fbd0835b9d 54 bool http_parse_response(char *http_chunk, uint16_t http_chunk_len, bool *status_code_ok, uint16_t *content_len);
dvddnr 1:60fbd0835b9d 55
dvddnr 1:60fbd0835b9d 56 // JSON parser
dvddnr 1:60fbd0835b9d 57 #define JSON_MAX_TOKENS 128
dvddnr 1:60fbd0835b9d 58 jsmn_parser g_json_parser;
dvddnr 1:60fbd0835b9d 59 jsmntok_t g_json_tokens[JSON_MAX_TOKENS];
dvddnr 1:60fbd0835b9d 60 bool jsoneq(const char *json, jsmntok_t *tok, const char *s,jsmntype_t type);
dvddnr 0:1fc46da4a976 61
dvddnr 0:1fc46da4a976 62 int main()
dvddnr 0:1fc46da4a976 63 {
dvddnr 1:60fbd0835b9d 64
dvddnr 4:9926288a8703 65 printf("> DISCO_L475VG_IOT01-Telegram-BOT started\r\n");
dvddnr 0:1fc46da4a976 66
dvddnr 1:60fbd0835b9d 67
dvddnr 1:60fbd0835b9d 68 /* Setup env sensors */
dvddnr 0:1fc46da4a976 69 BSP_TSENSOR_Init();
dvddnr 0:1fc46da4a976 70 BSP_HSENSOR_Init();
dvddnr 0:1fc46da4a976 71 BSP_PSENSOR_Init();
dvddnr 1:60fbd0835b9d 72
dvddnr 0:1fc46da4a976 73
dvddnr 1:60fbd0835b9d 74 /* start chatbot */
dvddnr 1:60fbd0835b9d 75 telegram_bot();
dvddnr 1:60fbd0835b9d 76 }
dvddnr 0:1fc46da4a976 77
dvddnr 1:60fbd0835b9d 78 void telegram_bot(void)
dvddnr 1:60fbd0835b9d 79 {
dvddnr 1:60fbd0835b9d 80 int32_t update_id = 0;
dvddnr 1:60fbd0835b9d 81 int32_t chat_id = 0;
dvddnr 1:60fbd0835b9d 82 int json_results;
dvddnr 1:60fbd0835b9d 83 bool well_done = false;
dvddnr 0:1fc46da4a976 84
dvddnr 5:f204a47aa813 85 /* wifi connect */
dvddnr 4:9926288a8703 86 if(wifi_connect())
dvddnr 5:f204a47aa813 87 {
dvddnr 4:9926288a8703 88 printf("> Wifi connected\r\n");
dvddnr 5:f204a47aa813 89 }
dvddnr 4:9926288a8703 90 else
dvddnr 4:9926288a8703 91 {
dvddnr 4:9926288a8703 92 NVIC_SystemReset();
dvddnr 4:9926288a8703 93 }
dvddnr 0:1fc46da4a976 94
dvddnr 5:f204a47aa813 95
dvddnr 5:f204a47aa813 96 /* set RTC */
dvddnr 5:f204a47aa813 97 set_rtc_from_network();
dvddnr 5:f204a47aa813 98
dvddnr 5:f204a47aa813 99
dvddnr 5:f204a47aa813 100 /* main loop */
dvddnr 1:60fbd0835b9d 101 while (1)
dvddnr 1:60fbd0835b9d 102 {
dvddnr 4:9926288a8703 103 g_alivenessLED = !g_alivenessLED;
dvddnr 4:9926288a8703 104
dvddnr 1:60fbd0835b9d 105 // Get updates -- API method getUpdates
dvddnr 1:60fbd0835b9d 106 printf("> Get updates\r\n");
dvddnr 1:60fbd0835b9d 107 g_json_io_buffer[0]=0;
dvddnr 1:60fbd0835b9d 108 if (telegram_get_update(update_id + 1) == false)
dvddnr 1:60fbd0835b9d 109 {
dvddnr 4:9926288a8703 110 printf("> ERROR telegram_get_update\r\n> Reset wifi connection\r\n");
dvddnr 4:9926288a8703 111 ES_WIFI_ResetModule(&g_es_wifi_ctx);
dvddnr 4:9926288a8703 112 wifi_connect();
dvddnr 1:60fbd0835b9d 113 continue;
dvddnr 1:60fbd0835b9d 114 }
dvddnr 1:60fbd0835b9d 115 printf("> JSON content: %s\r\n", g_json_io_buffer);
dvddnr 1:60fbd0835b9d 116
dvddnr 1:60fbd0835b9d 117 // Parsing json response
dvddnr 1:60fbd0835b9d 118 jsmn_init(&g_json_parser);
dvddnr 1:60fbd0835b9d 119 json_results = jsmn_parse(&g_json_parser,g_json_io_buffer,strlen(g_json_io_buffer),g_json_tokens,JSON_MAX_TOKENS);
dvddnr 1:60fbd0835b9d 120 if(json_results < 4)
dvddnr 1:60fbd0835b9d 121 {
dvddnr 1:60fbd0835b9d 122 printf("> ERROR invalid json response\r\n");
dvddnr 1:60fbd0835b9d 123 continue;
dvddnr 1:60fbd0835b9d 124 }
dvddnr 0:1fc46da4a976 125
dvddnr 1:60fbd0835b9d 126 /* check ok */
dvddnr 1:60fbd0835b9d 127 if( jsoneq(g_json_io_buffer,&g_json_tokens[1],"ok",JSMN_STRING) == false ) continue;
dvddnr 1:60fbd0835b9d 128 if( jsoneq(g_json_io_buffer,&g_json_tokens[2],"true",JSMN_PRIMITIVE) == false ) continue;
dvddnr 0:1fc46da4a976 129
dvddnr 1:60fbd0835b9d 130 /* fetch update id */
dvddnr 1:60fbd0835b9d 131 well_done = false;
dvddnr 1:60fbd0835b9d 132 for(int i=3;i<json_results;i++)
dvddnr 1:60fbd0835b9d 133 {
dvddnr 1:60fbd0835b9d 134 if( jsoneq(g_json_io_buffer,&g_json_tokens[i],"update_id",JSMN_STRING) == true )
dvddnr 1:60fbd0835b9d 135 {
dvddnr 1:60fbd0835b9d 136 g_json_io_buffer[g_json_tokens[i+1].end]=0;
dvddnr 1:60fbd0835b9d 137 update_id = atoi(g_json_io_buffer+g_json_tokens[i+1].start);
dvddnr 1:60fbd0835b9d 138 well_done = true;
dvddnr 1:60fbd0835b9d 139 }
dvddnr 1:60fbd0835b9d 140 }
dvddnr 0:1fc46da4a976 141
dvddnr 1:60fbd0835b9d 142 // update_id not found ?
dvddnr 1:60fbd0835b9d 143 if(well_done == false) continue;
dvddnr 0:1fc46da4a976 144
dvddnr 1:60fbd0835b9d 145 /* fetch chat id */
dvddnr 1:60fbd0835b9d 146 well_done = false;
dvddnr 1:60fbd0835b9d 147 for(int i=3;i<json_results;i++)
dvddnr 1:60fbd0835b9d 148 {
dvddnr 1:60fbd0835b9d 149 if( jsoneq(g_json_io_buffer,&g_json_tokens[i],"id",JSMN_STRING) == true )
dvddnr 1:60fbd0835b9d 150 {
dvddnr 1:60fbd0835b9d 151 g_json_io_buffer[g_json_tokens[i+1].end]=0;
dvddnr 1:60fbd0835b9d 152 chat_id = atoi(g_json_io_buffer+g_json_tokens[i+1].start);
dvddnr 1:60fbd0835b9d 153 well_done = true;
dvddnr 1:60fbd0835b9d 154 }
dvddnr 1:60fbd0835b9d 155 }
dvddnr 0:1fc46da4a976 156
dvddnr 1:60fbd0835b9d 157 // chat_id not found ?
dvddnr 1:60fbd0835b9d 158 if(well_done == false) continue;
dvddnr 0:1fc46da4a976 159
dvddnr 1:60fbd0835b9d 160 /*fetch message */
dvddnr 1:60fbd0835b9d 161 well_done = false;
dvddnr 1:60fbd0835b9d 162 g_incoming_msg[0]=0;
dvddnr 1:60fbd0835b9d 163 for(int i=3;i<json_results;i++)
dvddnr 1:60fbd0835b9d 164 {
dvddnr 1:60fbd0835b9d 165 if( jsoneq(g_json_io_buffer,&g_json_tokens[i],"text",JSMN_STRING) == true )
dvddnr 1:60fbd0835b9d 166 {
dvddnr 1:60fbd0835b9d 167 int msg_len = g_json_tokens[i+1].end - g_json_tokens[i+1].start;
dvddnr 1:60fbd0835b9d 168 if( msg_len < TELEGRAM_BOT_INCOMING_CMD_SIZE)
dvddnr 1:60fbd0835b9d 169 {
dvddnr 1:60fbd0835b9d 170 memcpy(g_incoming_msg,g_json_io_buffer+g_json_tokens[i+1].start,msg_len);
dvddnr 1:60fbd0835b9d 171 g_incoming_msg[msg_len] = 0;
dvddnr 1:60fbd0835b9d 172 well_done = true;
dvddnr 1:60fbd0835b9d 173 }
dvddnr 1:60fbd0835b9d 174 break;
dvddnr 1:60fbd0835b9d 175 }
dvddnr 1:60fbd0835b9d 176 }
dvddnr 1:60fbd0835b9d 177
dvddnr 1:60fbd0835b9d 178 printf("> Incoming msg: %s\n\r",g_incoming_msg);
dvddnr 1:60fbd0835b9d 179
dvddnr 0:1fc46da4a976 180
dvddnr 1:60fbd0835b9d 181 // parse incoming message
dvddnr 1:60fbd0835b9d 182 if( strstr(g_incoming_msg,"Temperature") != NULL)
dvddnr 1:60fbd0835b9d 183 {
dvddnr 1:60fbd0835b9d 184 snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"Temperature %.2f degC\",\"reply_markup\":%s}",
dvddnr 1:60fbd0835b9d 185 chat_id,BSP_TSENSOR_ReadTemp(),TELEGRAM_CUSTOM_KEYBOARD);
dvddnr 1:60fbd0835b9d 186 }
dvddnr 1:60fbd0835b9d 187 else if( strstr(g_incoming_msg,"Humidity") != NULL)
dvddnr 1:60fbd0835b9d 188 {
dvddnr 1:60fbd0835b9d 189 snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"Humidity %.2f %%\",\"reply_markup\":%s}",
dvddnr 1:60fbd0835b9d 190 chat_id,BSP_HSENSOR_ReadHumidity(),TELEGRAM_CUSTOM_KEYBOARD);
dvddnr 1:60fbd0835b9d 191 }
dvddnr 1:60fbd0835b9d 192 else if( strstr(g_incoming_msg,"Pressure") != NULL)
dvddnr 1:60fbd0835b9d 193 {
dvddnr 1:60fbd0835b9d 194 snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"Pressure %.2f mBar\",\"reply_markup\":%s}",
dvddnr 1:60fbd0835b9d 195 chat_id,BSP_PSENSOR_ReadPressure(),TELEGRAM_CUSTOM_KEYBOARD);
dvddnr 1:60fbd0835b9d 196 }
dvddnr 6:94fc61e1cf40 197 else if( strstr(g_incoming_msg,"RTC") != NULL)
dvddnr 6:94fc61e1cf40 198 {
dvddnr 6:94fc61e1cf40 199 time_t seconds = time(NULL);
dvddnr 6:94fc61e1cf40 200 snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"%s UTC\",\"reply_markup\":%s}",
dvddnr 6:94fc61e1cf40 201 chat_id,ctime(&seconds),TELEGRAM_CUSTOM_KEYBOARD);
dvddnr 6:94fc61e1cf40 202 }
dvddnr 1:60fbd0835b9d 203 else
dvddnr 1:60fbd0835b9d 204 {
dvddnr 1:60fbd0835b9d 205 snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"Available commands\",\"reply_markup\":%s}",
dvddnr 1:60fbd0835b9d 206 chat_id,TELEGRAM_CUSTOM_KEYBOARD);
dvddnr 1:60fbd0835b9d 207 }
dvddnr 1:60fbd0835b9d 208
dvddnr 1:60fbd0835b9d 209 if( telegram_send_message() == false)
dvddnr 1:60fbd0835b9d 210 {
dvddnr 1:60fbd0835b9d 211 printf("> ERROR telegram_send_message\r\n");
dvddnr 1:60fbd0835b9d 212 continue;
dvddnr 1:60fbd0835b9d 213 }
dvddnr 1:60fbd0835b9d 214
dvddnr 1:60fbd0835b9d 215 jsmn_init(&g_json_parser);
dvddnr 1:60fbd0835b9d 216 json_results = jsmn_parse(&g_json_parser,g_json_io_buffer,strlen(g_json_io_buffer),g_json_tokens,JSON_MAX_TOKENS);
dvddnr 1:60fbd0835b9d 217 if(json_results < 4)
dvddnr 1:60fbd0835b9d 218 {
dvddnr 1:60fbd0835b9d 219 printf("> ERROR invalid json response\r\n");
dvddnr 1:60fbd0835b9d 220 continue;
dvddnr 1:60fbd0835b9d 221 }
dvddnr 0:1fc46da4a976 222
dvddnr 1:60fbd0835b9d 223 /* check ok */
dvddnr 1:60fbd0835b9d 224 if( jsoneq(g_json_io_buffer,&g_json_tokens[1],"ok",JSMN_STRING) == false ) continue;
dvddnr 1:60fbd0835b9d 225 if( jsoneq(g_json_io_buffer,&g_json_tokens[2],"true",JSMN_PRIMITIVE) == false ) continue;
dvddnr 0:1fc46da4a976 226
dvddnr 0:1fc46da4a976 227 }
dvddnr 0:1fc46da4a976 228 }
dvddnr 1:60fbd0835b9d 229
dvddnr 1:60fbd0835b9d 230
dvddnr 1:60fbd0835b9d 231
dvddnr 5:f204a47aa813 232 /*****************************************************************************************
dvddnr 5:f204a47aa813 233 *
dvddnr 5:f204a47aa813 234 *
dvddnr 5:f204a47aa813 235 * update RTC using now.httpbin.org free service
dvddnr 5:f204a47aa813 236 *
dvddnr 5:f204a47aa813 237 *
dvddnr 5:f204a47aa813 238 * ***************************************************************************************/
dvddnr 5:f204a47aa813 239
dvddnr 5:f204a47aa813 240 #define HTTPBIN_EPOCH_TAG "epoch\":"
dvddnr 5:f204a47aa813 241 bool set_rtc_from_network(void)
dvddnr 5:f204a47aa813 242 {
dvddnr 5:f204a47aa813 243 /* prepare http get header */
dvddnr 5:f204a47aa813 244 strcpy(g_http_io_buffer,NOW_HTTPBIN_ORG);
dvddnr 5:f204a47aa813 245 if( http_request("now.httpbin.org",false,false) )
dvddnr 5:f204a47aa813 246 {
dvddnr 5:f204a47aa813 247 char *epoch = strstr(g_json_io_buffer,HTTPBIN_EPOCH_TAG);
dvddnr 5:f204a47aa813 248 if(epoch == NULL) return false;
dvddnr 5:f204a47aa813 249 epoch += sizeof( HTTPBIN_EPOCH_TAG );
dvddnr 5:f204a47aa813 250 for(int i=0;i<20;i++)
dvddnr 5:f204a47aa813 251 {
dvddnr 5:f204a47aa813 252 if( epoch[i] == '.')
dvddnr 5:f204a47aa813 253 {
dvddnr 5:f204a47aa813 254 epoch[i] = 0;
dvddnr 5:f204a47aa813 255 printf("> now.httpbin.org epoch: %s\r\n",epoch);
dvddnr 5:f204a47aa813 256 set_time( atoi(epoch) );
dvddnr 5:f204a47aa813 257 return true;
dvddnr 5:f204a47aa813 258 }
dvddnr 5:f204a47aa813 259 }
dvddnr 5:f204a47aa813 260 }
dvddnr 5:f204a47aa813 261
dvddnr 5:f204a47aa813 262 return false;
dvddnr 5:f204a47aa813 263
dvddnr 5:f204a47aa813 264 }
dvddnr 1:60fbd0835b9d 265
dvddnr 1:60fbd0835b9d 266 /*****************************************************************************************
dvddnr 1:60fbd0835b9d 267 *
dvddnr 1:60fbd0835b9d 268 *
dvddnr 1:60fbd0835b9d 269 * telegram rest api
dvddnr 1:60fbd0835b9d 270 *
dvddnr 1:60fbd0835b9d 271 *
dvddnr 1:60fbd0835b9d 272 ******************************************************************************************/
dvddnr 1:60fbd0835b9d 273
dvddnr 1:60fbd0835b9d 274
dvddnr 1:60fbd0835b9d 275 bool telegram_get_update(int32_t update_id)
dvddnr 1:60fbd0835b9d 276 {
dvddnr 1:60fbd0835b9d 277 /* prepare http get header */
dvddnr 1:60fbd0835b9d 278 snprintf(g_http_io_buffer, ES_WIFI_PAYLOAD_SIZE, TELEGRAM_GETUPDATES, update_id);
dvddnr 5:f204a47aa813 279 return http_request("api.telegram.org",false,true);
dvddnr 1:60fbd0835b9d 280 }
dvddnr 1:60fbd0835b9d 281
dvddnr 1:60fbd0835b9d 282
dvddnr 1:60fbd0835b9d 283
dvddnr 1:60fbd0835b9d 284 bool telegram_send_message()
dvddnr 1:60fbd0835b9d 285 {
dvddnr 1:60fbd0835b9d 286 /* prepare http get header */
dvddnr 1:60fbd0835b9d 287 snprintf(g_http_io_buffer, ES_WIFI_PAYLOAD_SIZE, TELEGRAM_SENDMESSAGE, strlen(g_json_io_buffer));
dvddnr 5:f204a47aa813 288 return http_request("api.telegram.org",true,true);
dvddnr 1:60fbd0835b9d 289 }
dvddnr 1:60fbd0835b9d 290
dvddnr 5:f204a47aa813 291 /**************************************************************************************************
dvddnr 5:f204a47aa813 292 *
dvddnr 5:f204a47aa813 293 *
dvddnr 5:f204a47aa813 294 * HTTP request transaction
dvddnr 5:f204a47aa813 295 *
dvddnr 5:f204a47aa813 296 *
dvddnr 5:f204a47aa813 297 ***************************************************************************************************/
dvddnr 5:f204a47aa813 298 bool http_request(char *http_server_domain,bool has_json_payload,bool secure)
dvddnr 1:60fbd0835b9d 299 {
dvddnr 1:60fbd0835b9d 300 uint16_t io_s, tx_s;
dvddnr 1:60fbd0835b9d 301 ES_WIFI_Status_t io_status;
dvddnr 1:60fbd0835b9d 302 bool http_ok;
dvddnr 1:60fbd0835b9d 303 int32_t http_content_len;
dvddnr 1:60fbd0835b9d 304 char *http_content_pivot;
dvddnr 1:60fbd0835b9d 305 uint16_t content_chunk_size;
dvddnr 1:60fbd0835b9d 306 bool ret_val = false;
dvddnr 1:60fbd0835b9d 307 static uint8_t socket=0;
dvddnr 1:60fbd0835b9d 308
dvddnr 1:60fbd0835b9d 309 /* open socket */
dvddnr 1:60fbd0835b9d 310 socket++;
dvddnr 1:60fbd0835b9d 311 if(socket==4) socket=0;
dvddnr 1:60fbd0835b9d 312 io_status = ES_WIFI_STATUS_ERROR;
dvddnr 1:60fbd0835b9d 313 for (int i = 0; i < CONNECTION_TRIAL_MAX; i++)
dvddnr 1:60fbd0835b9d 314 {
dvddnr 5:f204a47aa813 315 printf("> Open TCP connection ...\r\n");
dvddnr 5:f204a47aa813 316 if (open_tcp_connection(socket, http_server_domain,(secure)?443:80,secure))
dvddnr 1:60fbd0835b9d 317 {
dvddnr 5:f204a47aa813 318 printf("> TCP Connection opened successfully.\r\n");
dvddnr 1:60fbd0835b9d 319 io_status = ES_WIFI_STATUS_OK;
dvddnr 1:60fbd0835b9d 320 break;
dvddnr 1:60fbd0835b9d 321 }
dvddnr 1:60fbd0835b9d 322 }
dvddnr 1:60fbd0835b9d 323
dvddnr 1:60fbd0835b9d 324 if (io_status != ES_WIFI_STATUS_OK)
dvddnr 1:60fbd0835b9d 325 {
dvddnr 1:60fbd0835b9d 326 printf("> socket open error.\r\n");
dvddnr 1:60fbd0835b9d 327 return false;
dvddnr 1:60fbd0835b9d 328 }
dvddnr 1:60fbd0835b9d 329
dvddnr 1:60fbd0835b9d 330
dvddnr 1:60fbd0835b9d 331 /* send http get header */
dvddnr 1:60fbd0835b9d 332 tx_s = strlen(g_http_io_buffer);
dvddnr 1:60fbd0835b9d 333 // printf(g_http_io_buffer);
dvddnr 1:60fbd0835b9d 334 io_s = 0;
dvddnr 1:60fbd0835b9d 335 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)
dvddnr 1:60fbd0835b9d 336 {
dvddnr 1:60fbd0835b9d 337 printf("> ERROR : CANNOT send data\r\n");
dvddnr 1:60fbd0835b9d 338 goto happy_end;
dvddnr 1:60fbd0835b9d 339 }
dvddnr 1:60fbd0835b9d 340 if (io_s != tx_s)
dvddnr 1:60fbd0835b9d 341 {
dvddnr 1:60fbd0835b9d 342 printf("> ERROR Send %d of %d.\r\n", io_s, tx_s);
dvddnr 1:60fbd0835b9d 343 goto happy_end;
dvddnr 1:60fbd0835b9d 344 }
dvddnr 1:60fbd0835b9d 345
dvddnr 1:60fbd0835b9d 346 /* send json payload */
dvddnr 1:60fbd0835b9d 347 if(has_json_payload)
dvddnr 1:60fbd0835b9d 348 {
dvddnr 1:60fbd0835b9d 349 tx_s = strlen(g_json_io_buffer);
dvddnr 1:60fbd0835b9d 350 io_s = 0;
dvddnr 1:60fbd0835b9d 351 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)
dvddnr 1:60fbd0835b9d 352 {
dvddnr 1:60fbd0835b9d 353 printf("> ERROR : CANNOT send data\r\n");
dvddnr 1:60fbd0835b9d 354 goto happy_end;
dvddnr 1:60fbd0835b9d 355 }
dvddnr 1:60fbd0835b9d 356 if (io_s != tx_s)
dvddnr 1:60fbd0835b9d 357 {
dvddnr 1:60fbd0835b9d 358 printf("> ERROR Send %d of %d.\r\n", io_s, tx_s);
dvddnr 1:60fbd0835b9d 359 goto happy_end;
dvddnr 1:60fbd0835b9d 360 }
dvddnr 1:60fbd0835b9d 361 }
dvddnr 1:60fbd0835b9d 362
dvddnr 5:f204a47aa813 363 /* from now on the http io buffer is reused */
dvddnr 5:f204a47aa813 364 g_json_io_buffer[0]=0;
dvddnr 5:f204a47aa813 365 g_http_io_buffer[0]=0;
dvddnr 5:f204a47aa813 366
dvddnr 1:60fbd0835b9d 367 /* fetch response */
dvddnr 1:60fbd0835b9d 368 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);
dvddnr 1:60fbd0835b9d 369 if (io_status != ES_WIFI_STATUS_OK)
dvddnr 1:60fbd0835b9d 370 {
dvddnr 1:60fbd0835b9d 371 printf("> ERROR : socket receive data\r\n");
dvddnr 1:60fbd0835b9d 372 goto happy_end;
dvddnr 1:60fbd0835b9d 373 }
dvddnr 1:60fbd0835b9d 374
dvddnr 1:60fbd0835b9d 375 /* parse http response for the status code and content len */
dvddnr 1:60fbd0835b9d 376 http_ok = false;
dvddnr 1:60fbd0835b9d 377 http_content_len = 0;
dvddnr 1:60fbd0835b9d 378 g_http_io_buffer[io_s] = 0;
dvddnr 1:60fbd0835b9d 379 if (io_s == 0 || http_parse_response((char *)g_http_io_buffer, io_s, &http_ok, (uint16_t *)&http_content_len) == false)
dvddnr 1:60fbd0835b9d 380 {
dvddnr 1:60fbd0835b9d 381 printf("< Invalid response\r\n");
dvddnr 1:60fbd0835b9d 382 for (int i = 0; i < io_s; i++)
dvddnr 1:60fbd0835b9d 383 printf("%c", g_http_io_buffer[i]);
dvddnr 1:60fbd0835b9d 384 printf("> Invalid response\r\n");
dvddnr 1:60fbd0835b9d 385 goto happy_end;
dvddnr 1:60fbd0835b9d 386 }
dvddnr 5:f204a47aa813 387 printf("> HTTP OK = %d Content len = %d\r\n", http_ok, http_content_len);
dvddnr 1:60fbd0835b9d 388
dvddnr 1:60fbd0835b9d 389 /* fetch json response */
dvddnr 1:60fbd0835b9d 390 http_content_pivot = strstr((char *)g_http_io_buffer, "\r\n\r\n");
dvddnr 1:60fbd0835b9d 391 if (http_content_pivot != NULL)
dvddnr 1:60fbd0835b9d 392 {
dvddnr 1:60fbd0835b9d 393 http_content_pivot += 4;
dvddnr 1:60fbd0835b9d 394 content_chunk_size = strlen(http_content_pivot);
dvddnr 1:60fbd0835b9d 395 if (content_chunk_size < TBOT_JSON_BUFFER_SIZE)
dvddnr 1:60fbd0835b9d 396 strcpy(g_json_io_buffer, http_content_pivot);
dvddnr 1:60fbd0835b9d 397 http_content_len -= content_chunk_size;
dvddnr 1:60fbd0835b9d 398 }
dvddnr 1:60fbd0835b9d 399 else
dvddnr 1:60fbd0835b9d 400 {
dvddnr 1:60fbd0835b9d 401 printf("< Invalid response\r\n");
dvddnr 1:60fbd0835b9d 402 for (int i = 0; i < io_s; i++)
dvddnr 1:60fbd0835b9d 403 printf("%c", g_http_io_buffer[i]);
dvddnr 1:60fbd0835b9d 404 printf("> Invalid response\r\n");
dvddnr 1:60fbd0835b9d 405 goto happy_end;
dvddnr 1:60fbd0835b9d 406 }
dvddnr 1:60fbd0835b9d 407
dvddnr 1:60fbd0835b9d 408 /* continue to fetch json chunck */
dvddnr 1:60fbd0835b9d 409 while (http_content_len > 0)
dvddnr 1:60fbd0835b9d 410 {
dvddnr 1:60fbd0835b9d 411 if (ES_WIFI_ReceiveData2(&g_es_wifi_ctx, (uint8_t *)g_http_io_buffer, ES_WIFI_PAYLOAD_SIZE, &io_s) != ES_WIFI_STATUS_OK)
dvddnr 1:60fbd0835b9d 412 {
dvddnr 1:60fbd0835b9d 413 printf("> ERROR : socket receive data\r\n");
dvddnr 1:60fbd0835b9d 414 goto happy_end;
dvddnr 1:60fbd0835b9d 415 }
dvddnr 1:60fbd0835b9d 416 g_http_io_buffer[io_s] = 0;
dvddnr 1:60fbd0835b9d 417 http_content_len -= io_s;
dvddnr 1:60fbd0835b9d 418 if (http_content_len < 0 || io_s == 0)
dvddnr 1:60fbd0835b9d 419 {
dvddnr 1:60fbd0835b9d 420 printf("> ERROR : http content len overflow\r\n");
dvddnr 1:60fbd0835b9d 421 goto happy_end;
dvddnr 1:60fbd0835b9d 422 }
dvddnr 1:60fbd0835b9d 423 strcat(g_json_io_buffer, g_http_io_buffer);
dvddnr 1:60fbd0835b9d 424 }
dvddnr 1:60fbd0835b9d 425 ret_val = http_ok;
dvddnr 1:60fbd0835b9d 426
dvddnr 1:60fbd0835b9d 427 happy_end:
dvddnr 5:f204a47aa813 428 printf("> Close TCP connection...\r\n");
dvddnr 5:f204a47aa813 429 close_tcp_connection(socket);
dvddnr 1:60fbd0835b9d 430 printf("> done.\r\n");
dvddnr 1:60fbd0835b9d 431 return ret_val;
dvddnr 1:60fbd0835b9d 432 }
dvddnr 1:60fbd0835b9d 433
dvddnr 1:60fbd0835b9d 434
dvddnr 1:60fbd0835b9d 435
dvddnr 1:60fbd0835b9d 436
dvddnr 1:60fbd0835b9d 437 /*****************************************************************************************
dvddnr 1:60fbd0835b9d 438 *
dvddnr 1:60fbd0835b9d 439 *
dvddnr 1:60fbd0835b9d 440 * JSON parsing
dvddnr 1:60fbd0835b9d 441 *
dvddnr 1:60fbd0835b9d 442 *
dvddnr 1:60fbd0835b9d 443 ******************************************************************************************/
dvddnr 1:60fbd0835b9d 444
dvddnr 1:60fbd0835b9d 445 bool jsoneq(const char *json, jsmntok_t *tok, const char *s,jsmntype_t type)
dvddnr 1:60fbd0835b9d 446 {
dvddnr 1:60fbd0835b9d 447 if (tok->type == type && (int) strlen(s) == tok->end - tok->start &&
dvddnr 1:60fbd0835b9d 448 strncmp(json + tok->start, s, tok->end - tok->start) == 0) {
dvddnr 1:60fbd0835b9d 449 return true;
dvddnr 1:60fbd0835b9d 450 }
dvddnr 1:60fbd0835b9d 451 return false;
dvddnr 1:60fbd0835b9d 452 }
dvddnr 1:60fbd0835b9d 453
dvddnr 1:60fbd0835b9d 454 /*****************************************************************************************
dvddnr 1:60fbd0835b9d 455 *
dvddnr 1:60fbd0835b9d 456 *
dvddnr 1:60fbd0835b9d 457 * HTTP parsing
dvddnr 1:60fbd0835b9d 458 *
dvddnr 1:60fbd0835b9d 459 *
dvddnr 1:60fbd0835b9d 460 ******************************************************************************************/
dvddnr 1:60fbd0835b9d 461
dvddnr 1:60fbd0835b9d 462 const char HTTP_200OK[] = "200 OK\r\n";
dvddnr 1:60fbd0835b9d 463 const char HTTP_CL[] = "Content-Length: ";
dvddnr 1:60fbd0835b9d 464 bool http_parse_response(char *http_chunk, uint16_t http_chunk_len, bool *status_code_ok, uint16_t *content_len)
dvddnr 1:60fbd0835b9d 465 {
dvddnr 1:60fbd0835b9d 466 char *line_pivot, *key_pivot;
dvddnr 1:60fbd0835b9d 467
dvddnr 1:60fbd0835b9d 468 line_pivot = strstr(http_chunk, "\r\n");
dvddnr 1:60fbd0835b9d 469 if (line_pivot == NULL)
dvddnr 1:60fbd0835b9d 470 return false;
dvddnr 1:60fbd0835b9d 471
dvddnr 1:60fbd0835b9d 472 key_pivot = strstr(http_chunk, HTTP_200OK);
dvddnr 5:f204a47aa813 473
dvddnr 5:f204a47aa813 474 if (key_pivot != NULL)
dvddnr 1:60fbd0835b9d 475 *status_code_ok = true;
dvddnr 1:60fbd0835b9d 476 else
dvddnr 1:60fbd0835b9d 477 *status_code_ok = false;
dvddnr 1:60fbd0835b9d 478
dvddnr 1:60fbd0835b9d 479 while (1)
dvddnr 1:60fbd0835b9d 480 {
dvddnr 1:60fbd0835b9d 481 line_pivot = strstr(line_pivot + 2, "\r\n");
dvddnr 1:60fbd0835b9d 482 if (line_pivot == NULL)
dvddnr 1:60fbd0835b9d 483 break;
dvddnr 1:60fbd0835b9d 484 key_pivot = strstr(http_chunk, HTTP_CL);
dvddnr 1:60fbd0835b9d 485 if (key_pivot == NULL)
dvddnr 1:60fbd0835b9d 486 continue;
dvddnr 1:60fbd0835b9d 487 if (key_pivot < line_pivot)
dvddnr 1:60fbd0835b9d 488 {
dvddnr 1:60fbd0835b9d 489 key_pivot += strlen(HTTP_CL);
dvddnr 1:60fbd0835b9d 490 *content_len = atoi((char const *)key_pivot);
dvddnr 1:60fbd0835b9d 491 return true;
dvddnr 1:60fbd0835b9d 492 }
dvddnr 1:60fbd0835b9d 493 }
dvddnr 1:60fbd0835b9d 494
dvddnr 1:60fbd0835b9d 495 return false;
dvddnr 1:60fbd0835b9d 496 }
dvddnr 1:60fbd0835b9d 497
dvddnr 1:60fbd0835b9d 498 /*****************************************************************************************
dvddnr 1:60fbd0835b9d 499 *
dvddnr 1:60fbd0835b9d 500 *
dvddnr 1:60fbd0835b9d 501 * WIFI
dvddnr 1:60fbd0835b9d 502 *
dvddnr 1:60fbd0835b9d 503 *
dvddnr 1:60fbd0835b9d 504 ******************************************************************************************/
dvddnr 1:60fbd0835b9d 505
dvddnr 1:60fbd0835b9d 506 bool wifi_connect(void)
dvddnr 1:60fbd0835b9d 507 {
dvddnr 1:60fbd0835b9d 508 /* HW setup */
dvddnr 1:60fbd0835b9d 509 if (ES_WIFI_RegisterBusIO(&g_es_wifi_ctx,
dvddnr 1:60fbd0835b9d 510 SPI_WIFI_Init,
dvddnr 1:60fbd0835b9d 511 SPI_WIFI_DeInit,
dvddnr 1:60fbd0835b9d 512 SPI_WIFI_Delay,
dvddnr 1:60fbd0835b9d 513 SPI_WIFI_SendData,
dvddnr 1:60fbd0835b9d 514 SPI_WIFI_ReceiveData) != ES_WIFI_STATUS_OK)
dvddnr 1:60fbd0835b9d 515 return false;
dvddnr 1:60fbd0835b9d 516
dvddnr 1:60fbd0835b9d 517 if (ES_WIFI_Init(&g_es_wifi_ctx) != ES_WIFI_STATUS_OK)
dvddnr 1:60fbd0835b9d 518 return false;
dvddnr 1:60fbd0835b9d 519 ES_WIFI_ResetToFactoryDefault(&g_es_wifi_ctx);
dvddnr 1:60fbd0835b9d 520
dvddnr 1:60fbd0835b9d 521 /* JOIN AP */
dvddnr 1:60fbd0835b9d 522 for (int i = 0; i < CONNECTION_TRIAL_MAX; i++)
dvddnr 1:60fbd0835b9d 523 {
dvddnr 1:60fbd0835b9d 524 if (ES_WIFI_Connect(&g_es_wifi_ctx, WIFI_SSID, WIFI_PASSWORD, ES_WIFI_SEC_WPA_WPA2) == ES_WIFI_STATUS_OK)
dvddnr 1:60fbd0835b9d 525 {
dvddnr 1:60fbd0835b9d 526 if (ES_WIFI_GetNetworkSettings(&g_es_wifi_ctx) == ES_WIFI_STATUS_OK)
dvddnr 1:60fbd0835b9d 527 return true;
dvddnr 1:60fbd0835b9d 528 else
dvddnr 1:60fbd0835b9d 529 return false;
dvddnr 1:60fbd0835b9d 530 }
dvddnr 1:60fbd0835b9d 531 wait_ms(1000);
dvddnr 1:60fbd0835b9d 532 }
dvddnr 1:60fbd0835b9d 533
dvddnr 1:60fbd0835b9d 534 return false;
dvddnr 1:60fbd0835b9d 535 }
dvddnr 1:60fbd0835b9d 536
dvddnr 5:f204a47aa813 537
dvddnr 5:f204a47aa813 538 bool open_tcp_connection(uint8_t socket, char *domain_name, uint16_t remote_port,bool secure)
dvddnr 1:60fbd0835b9d 539 {
dvddnr 1:60fbd0835b9d 540 ES_WIFI_Conn_t conn;
dvddnr 1:60fbd0835b9d 541
dvddnr 1:60fbd0835b9d 542 conn.Number = socket;
dvddnr 1:60fbd0835b9d 543 conn.RemotePort = remote_port;
dvddnr 5:f204a47aa813 544 conn.LocalPort = 0;
dvddnr 5:f204a47aa813 545 conn.Type = (secure)?ES_WIFI_TCP_SSL_CONNECTION:ES_WIFI_TCP_CONNECTION;
dvddnr 5:f204a47aa813 546 strncpy((char *)conn.RemoteHost, domain_name, sizeof(conn.RemoteHost));
dvddnr 5:f204a47aa813 547 return (ES_WIFI_ConnectToRemoteHost(&g_es_wifi_ctx, &conn) == ES_WIFI_STATUS_OK) ? true : false;
dvddnr 1:60fbd0835b9d 548 }
dvddnr 1:60fbd0835b9d 549
dvddnr 5:f204a47aa813 550 bool close_tcp_connection(uint32_t socket)
dvddnr 1:60fbd0835b9d 551 {
dvddnr 1:60fbd0835b9d 552 ES_WIFI_Conn_t conn;
dvddnr 1:60fbd0835b9d 553 conn.Number = socket;
dvddnr 1:60fbd0835b9d 554
dvddnr 1:60fbd0835b9d 555 return (ES_WIFI_StopClientConnection(&g_es_wifi_ctx, &conn)== ES_WIFI_STATUS_OK);
dvddnr 1:60fbd0835b9d 556 }
dvddnr 1:60fbd0835b9d 557
dvddnr 1:60fbd0835b9d 558