D D / Mbed 2 deprecated DISCO_L475VG_IOT01-Telegram-BOT

Dependencies:   BSP_B-L475E-IOT01 mbed es_wifi jsmn

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 
00003 #include "stm32l475e_iot01_tsensor.h"
00004 #include "stm32l475e_iot01_hsensor.h"
00005 #include "stm32l475e_iot01_psensor.h"
00006 #include "es_wifi.h"
00007 #include "es_wifi_io.h"
00008 #include "jsmn.h"
00009 #include "TCPConnector.h"
00010 #include "HTTPHelper.h"
00011 
00012 
00013 #define WIFI_SSID ""
00014 #define WIFI_PASSWORD ""
00015 #define TELEGRAM_BOT_APIKEY ""
00016 #define WITH_ARDUCAM_2640 0
00017 
00018 #define CONNECTION_TRIAL_MAX 10
00019 
00020 // LED 
00021 DigitalOut g_alivenessLED(LED1);
00022 
00023 // secure tcp connector
00024 TCPConnector g_tcp_connector;
00025 // http parser utils
00026 HTTPHelper g_http_parser;
00027 // arducam driver
00028 #if WITH_ARDUCAM_2640
00029 #include "ArduCAM2640.h"
00030 ArduCAM2640 g_arducam;
00031 /* jpeg buffer */
00032 #define IMAGE_JPG_SIZE 16*1024
00033 uint8_t g_image_buffer[IMAGE_JPG_SIZE];
00034 #endif
00035 
00036 // http I/O buffer
00037 char g_http_io_buffer[ES_WIFI_DATA_SIZE];
00038 
00039 // Telegram json I/O buffer
00040 #define TBOT_JSON_BUFFER_SIZE 3 * 1024
00041 char g_json_io_buffer[TBOT_JSON_BUFFER_SIZE];
00042 
00043 // telegram REST API
00044 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";
00045 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";
00046 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";
00047 #if WITH_ARDUCAM_2640
00048 const char TELEGRAM_CUSTOM_KEYBOARD[] = "{\"keyboard\": [[\"Temperature\",\"Humidity\",\"Pressure\"],[\"Daily\",\"RTC\",\"Camera\"]],\"one_time_keyboard\": true}";
00049 #else
00050 const char TELEGRAM_CUSTOM_KEYBOARD[] = "{\"keyboard\": [[\"Temperature\",\"Humidity\",\"Pressure\"],[\"Daily\",\"RTC\"]],\"one_time_keyboard\": true}";
00051 #endif
00052 bool telegram_get_update(int32_t update_id);
00053 bool telegram_send_message(char *json_msg);
00054 bool telegram_send_photo(uint8_t *image, uint32_t image_size, int32_t chat_id, char *caption);
00055 #define TELEGRAM_BOT_INCOMING_CMD_SIZE 80
00056 char g_incoming_msg[TELEGRAM_BOT_INCOMING_CMD_SIZE];
00057 void telegram_bot();
00058 
00059 // now.httpbin.org
00060 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";
00061 bool set_rtc_from_network(void);
00062 
00063 // JSON parser
00064 #define JSON_MAX_TOKENS 128
00065 jsmn_parser g_json_parser;
00066 jsmntok_t g_json_tokens[JSON_MAX_TOKENS];
00067 bool jsoneq(const char *json, jsmntok_t *tok, const char *s,jsmntype_t type);
00068 
00069 // Data history 
00070 float g_daily_data_history_temp[24][60];
00071 float g_daily_data_history_pres[24][60];
00072 float g_daily_data_history_humi[24][60];
00073 void daily_history_update(int hour, int min,float t, float p, float h);
00074 int32_t daily_humidity_history_chart(char *report_buffer, uint32_t buffer_len);
00075 int32_t daily_temperature_history_chart(char *report_buffer, uint32_t buffer_len);
00076 int32_t daily_pressure_history_chart(char *report_buffer, uint32_t buffer_len);
00077 
00078 
00079 int main()
00080 {
00081 
00082     printf("> DISCO_L475VG_IOT01-Telegram-BOT started\r\n");
00083     
00084 #if WITH_ARDUCAM_2640
00085     /* Setup camera */
00086     I2C camI2C(PB_9,PB_8);
00087     SPI camSPI(PA_7,PA_6,PA_5);
00088     DigitalOut cam_spi_cs(PA_2);
00089 
00090     if( g_arducam.Setup( OV_RESOLUTION_CIF,92, &cam_spi_cs, &camSPI, &camI2C) == false)
00091     {
00092         printf("Arducam setup error \r\n");
00093         while(1);
00094     } 
00095 #endif
00096 
00097     /* Setup env sensors */
00098     BSP_TSENSOR_Init();
00099     BSP_HSENSOR_Init();
00100     BSP_PSENSOR_Init();
00101    
00102 
00103     /* start chatbot */
00104     telegram_bot();
00105 }
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 void telegram_bot()
00115 {
00116     int32_t update_id = 0;
00117     int32_t chat_id = 0;
00118     int json_results;
00119     bool well_done = false;
00120     time_t timestamp;
00121     struct tm *timestamp_tm;
00122     float temp,pres,humi;
00123     
00124 
00125     /* wifi connect */
00126     if(g_tcp_connector.wifi_connect(WIFI_SSID,WIFI_PASSWORD,CONNECTION_TRIAL_MAX))
00127     {
00128         printf("> Wifi connected\r\n");
00129     }
00130     else
00131     {
00132         NVIC_SystemReset();
00133     }
00134 
00135 
00136     /* set RTC */
00137     set_rtc_from_network();
00138     
00139     /* init data history */
00140     for(int i=0; i<24; i++)
00141     {
00142         for(int ii=0; ii<60; ii++)
00143         {
00144             g_daily_data_history_temp[i][ii]=0.0F;
00145             g_daily_data_history_pres[i][ii]=0.0F;
00146             g_daily_data_history_humi[i][ii]=0.0F;
00147         }
00148     }
00149     
00150 
00151     /* main loop */
00152     while (1)
00153     {
00154         g_alivenessLED = !g_alivenessLED;
00155         
00156         /* history update */
00157         timestamp = time(NULL);
00158         timestamp_tm = localtime(&timestamp);
00159         temp = BSP_TSENSOR_ReadTemp();
00160         pres = BSP_PSENSOR_ReadPressure();
00161         humi = BSP_HSENSOR_ReadHumidity();
00162         daily_history_update( timestamp_tm->tm_hour, timestamp_tm->tm_min, temp, pres, humi );
00163                                                             
00164         
00165         // Get updates -- API method getUpdates
00166         printf("> Get updates\r\n");
00167         g_json_io_buffer[0]=0;
00168         if (telegram_get_update(update_id + 1) == false)
00169         {
00170             printf("> ERROR telegram_get_update\r\n> Reset wifi connection\r\n");
00171             
00172             g_tcp_connector.wifi_connect(WIFI_SSID,WIFI_PASSWORD,CONNECTION_TRIAL_MAX);
00173             continue;
00174         }
00175         printf("> JSON content: %s\r\n", g_json_io_buffer);
00176        
00177         // Parsing json response
00178         jsmn_init(&g_json_parser);
00179         json_results = jsmn_parse(&g_json_parser,g_json_io_buffer,strlen(g_json_io_buffer),g_json_tokens,JSON_MAX_TOKENS);
00180         if(json_results < 4)
00181         {
00182             printf("> ERROR invalid json response\r\n");
00183             continue;
00184         }
00185 
00186         /* check ok */
00187         if( jsoneq(g_json_io_buffer,&g_json_tokens[1],"ok",JSMN_STRING) == false ) continue;
00188         if( jsoneq(g_json_io_buffer,&g_json_tokens[2],"true",JSMN_PRIMITIVE) == false ) continue;
00189 
00190         /* fetch update id */
00191         well_done = false;
00192         for(int i=3;i<json_results;i++)
00193         {
00194             if( jsoneq(g_json_io_buffer,&g_json_tokens[i],"update_id",JSMN_STRING) == true )
00195             {
00196                 g_json_io_buffer[g_json_tokens[i+1].end]=0;
00197                 update_id = atoi(g_json_io_buffer+g_json_tokens[i+1].start);
00198                 well_done = true;
00199             } 
00200         }
00201 
00202         // update_id not found ?
00203         if(well_done == false) continue;
00204 
00205         /* fetch chat id */
00206         well_done = false;
00207         for(int i=3;i<json_results;i++)
00208         {
00209             if( jsoneq(g_json_io_buffer,&g_json_tokens[i],"id",JSMN_STRING) == true )
00210             {
00211                 g_json_io_buffer[g_json_tokens[i+1].end]=0;
00212                 chat_id = atoi(g_json_io_buffer+g_json_tokens[i+1].start);
00213                 well_done = true;
00214             } 
00215         }
00216 
00217         // chat_id not found ?
00218         if(well_done == false) continue;
00219 
00220         /*fetch message */
00221         well_done = false;
00222         g_incoming_msg[0]=0;
00223         for(int i=3;i<json_results;i++)
00224         {
00225             if( jsoneq(g_json_io_buffer,&g_json_tokens[i],"text",JSMN_STRING) == true )
00226             {
00227                 int msg_len = g_json_tokens[i+1].end - g_json_tokens[i+1].start;
00228                 if( msg_len < TELEGRAM_BOT_INCOMING_CMD_SIZE)
00229                 {
00230                     memcpy(g_incoming_msg,g_json_io_buffer+g_json_tokens[i+1].start,msg_len);
00231                     g_incoming_msg[msg_len] = 0;
00232                     well_done = true;
00233                 }
00234                 break;
00235             } 
00236         }
00237 
00238         printf("> Incoming msg: %s\n\r",g_incoming_msg);
00239 
00240         // parse incoming message
00241         if( strstr(g_incoming_msg,"Temperature") != NULL)
00242         {
00243             snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"Temperature %.2f degC\",\"reply_markup\":%s}",
00244                      chat_id,temp,TELEGRAM_CUSTOM_KEYBOARD);
00245         }
00246         else if( strstr(g_incoming_msg,"Humidity") != NULL)
00247         {
00248             snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"Humidity %.2f %%\",\"reply_markup\":%s}",
00249                      chat_id,humi,TELEGRAM_CUSTOM_KEYBOARD);
00250         }
00251         else if( strstr(g_incoming_msg,"Pressure") != NULL)
00252         {
00253             snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"Pressure %.2f mBar\",\"reply_markup\":%s}",
00254                      chat_id,pres,TELEGRAM_CUSTOM_KEYBOARD);
00255         }
00256         else if( strstr(g_incoming_msg,"RTC") != NULL)
00257         {
00258             snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"%s UTC\",\"reply_markup\":%s}",
00259                      chat_id,ctime(&timestamp),TELEGRAM_CUSTOM_KEYBOARD);
00260         }
00261         else if( strstr(g_incoming_msg,"Daily") != NULL )
00262         {
00263             int pivot = snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"", chat_id); 
00264             pivot += daily_temperature_history_chart(   g_json_io_buffer + pivot, TBOT_JSON_BUFFER_SIZE - pivot );
00265             snprintf( g_json_io_buffer + pivot, TBOT_JSON_BUFFER_SIZE - pivot, "\"}");
00266             if( telegram_send_message(g_json_io_buffer) == false)
00267             {
00268                 printf("> ERROR telegram_send_message\r\n");
00269                 continue;
00270             }
00271             
00272             pivot = snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"", chat_id); 
00273             pivot += daily_humidity_history_chart(   g_json_io_buffer + pivot, TBOT_JSON_BUFFER_SIZE - pivot );
00274             snprintf( g_json_io_buffer + pivot, TBOT_JSON_BUFFER_SIZE - pivot, "\"}");
00275             if( telegram_send_message(g_json_io_buffer) == false)
00276             {
00277                 printf("> ERROR telegram_send_message\r\n");
00278                 continue;
00279             }
00280             
00281             pivot = snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"", chat_id); 
00282             pivot += daily_pressure_history_chart(   g_json_io_buffer + pivot, TBOT_JSON_BUFFER_SIZE - pivot );
00283             snprintf( g_json_io_buffer + pivot, TBOT_JSON_BUFFER_SIZE - pivot, "\",\"reply_markup\":%s}",TELEGRAM_CUSTOM_KEYBOARD);
00284             
00285             
00286         }
00287 #if WITH_ARDUCAM_2640
00288         else if( strstr(g_incoming_msg,"Camera") != NULL )
00289         {
00290             uint32_t image_size;
00291             uint32_t idx;
00292 
00293             snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"Sending photos ...\",\"reply_markup\":%s}",
00294                      chat_id,TELEGRAM_CUSTOM_KEYBOARD);
00295             if( telegram_send_message(g_json_io_buffer) == false)
00296             {
00297                 printf("> ERROR telegram_send_message\r\n");
00298                 continue;
00299             }
00300 
00301             for(int i=0; i<3; i++)
00302             {                     
00303                 image_size = g_arducam.CaptureImage(g_image_buffer,IMAGE_JPG_SIZE,&idx);
00304                 if( image_size == 0 || telegram_send_photo(g_image_buffer+idx, image_size, chat_id, "Images from space") == false )
00305                 {
00306                     printf("Photo failure %d\r\n",image_size);
00307                     break;
00308                 }
00309             }
00310 
00311             snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"Done.\",\"reply_markup\":%s}",
00312                      chat_id,TELEGRAM_CUSTOM_KEYBOARD);
00313         }
00314 #endif
00315         else
00316         {
00317             snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"Available commands\",\"reply_markup\":%s}",
00318                      chat_id,TELEGRAM_CUSTOM_KEYBOARD);
00319         }
00320         
00321         if( telegram_send_message(g_json_io_buffer) == false)
00322         {
00323             printf("> ERROR telegram_send_message\r\n");
00324             continue;
00325         }
00326         
00327         jsmn_init(&g_json_parser);
00328         json_results = jsmn_parse(&g_json_parser,g_json_io_buffer,strlen(g_json_io_buffer),g_json_tokens,JSON_MAX_TOKENS);
00329         if(json_results < 4)
00330         {
00331             printf("> ERROR invalid json response\r\n");
00332             continue;
00333         }
00334 
00335         /* check ok */
00336         if( jsoneq(g_json_io_buffer,&g_json_tokens[1],"ok",JSMN_STRING) == false ) continue;
00337         if( jsoneq(g_json_io_buffer,&g_json_tokens[2],"true",JSMN_PRIMITIVE) == false ) continue;
00338 
00339     }
00340 }
00341 
00342 /*****************************************************************************************
00343 *
00344 *
00345 * Daily history update
00346 *
00347 *
00348 ******************************************************************************************/
00349 void daily_history_update( int hour, int min, float t, float p, float h )
00350 {
00351     g_daily_data_history_temp[hour][min] = t;
00352     g_daily_data_history_pres[hour][min] = p;
00353     g_daily_data_history_humi[hour][min] = h;    
00354 }
00355 
00356 
00357 int32_t daily_temperature_history_chart(char *report_buffer, uint32_t buffer_len)
00358 {
00359     float sum;
00360     uint32_t num;
00361     int32_t pivot = 0;
00362     
00363     // temperature chart   
00364     pivot = snprintf(report_buffer,buffer_len,"Daily temperature chart\n\nhttps://image-charts.com/chart?chxt=x,y&chxr=1,0,%d&cht=lc&chd=t:",50);
00365     for(int i=0;i<24;i++)
00366     {
00367         sum = 0.0F;
00368         num = 0;
00369         for(int ii=0;ii<60;ii++)
00370         {
00371             if(g_daily_data_history_temp[i][ii] > 0.0F)
00372             {
00373                 num++;
00374                 sum += g_daily_data_history_temp[i][ii];
00375             }
00376         }
00377         pivot += snprintf(report_buffer+pivot,buffer_len-pivot,"%d,",(num>0)?(int32_t)sum/num:0);
00378     }
00379     pivot--;
00380     pivot += snprintf(report_buffer+pivot,buffer_len-pivot,"%s","&chco=76A4FB&chls=2.0&chs=600x300&chg=10,10");
00381     
00382     report_buffer[pivot]=0;
00383     return pivot;
00384 }
00385 
00386 int32_t daily_humidity_history_chart(char *report_buffer, uint32_t buffer_len)
00387 {
00388     float sum;
00389     uint32_t num;
00390     int32_t pivot = 0;
00391     
00392     // humidity chart 
00393     pivot += snprintf(report_buffer+pivot,buffer_len-pivot,"Daily humidity chart\n\nhttps://image-charts.com/chart?chxt=x,y&chxr=1,0,%d&cht=lc&chd=t:",100);
00394     for(int i=0;i<24;i++)
00395     {
00396         sum = 0.0F;
00397         num = 0;
00398         for(int ii=0;ii<60;ii++)
00399         {
00400             if(g_daily_data_history_humi[i][ii] > 0.0F)
00401             {
00402                 num++;
00403                 sum += g_daily_data_history_humi[i][ii];
00404             }
00405         }
00406         pivot += snprintf(report_buffer+pivot,buffer_len-pivot,"%d,",(num>0)?(int32_t)sum/num:0);
00407     }
00408     pivot--;
00409     pivot += snprintf(report_buffer+pivot,buffer_len-pivot,"%s","&chco=76A4FB&chls=2.0&chs=600x300&chg=10,10\n\n");
00410     
00411     report_buffer[pivot]=0;
00412     return pivot;
00413 }
00414 
00415     
00416 int32_t daily_pressure_history_chart(char *report_buffer, uint32_t buffer_len)
00417 {
00418     float sum;
00419     uint32_t num;
00420     int32_t pivot = 0;
00421     
00422     // pressure chart 
00423     pivot += snprintf(report_buffer+pivot,buffer_len-pivot,"Daily pressure chart\n\nhttps://image-charts.com/chart?chxt=x,y&chxr=1,%d,%d&cht=lc&chd=t:",900,1100);
00424     for(int i=0;i<24;i++)
00425     {
00426         sum = 0.0F;
00427         num = 0;
00428         for(int ii=0;ii<60;ii++)
00429         {
00430             if(g_daily_data_history_pres[i][ii] > 0.0F)
00431             {
00432                 num++;
00433                 sum += g_daily_data_history_pres[i][ii];
00434             }
00435         }
00436         pivot += snprintf(report_buffer+pivot,buffer_len-pivot,"%d,",(num>0)?(int32_t)sum/num:0);
00437     }
00438     pivot--;
00439     pivot += snprintf(report_buffer+pivot,buffer_len-pivot,"%s","&chco=76A4FB&chls=2.0&chs=600x300&chg=10,10&chds=a");
00440     
00441     report_buffer[pivot]=0;
00442     return pivot;
00443 }
00444 
00445 /*****************************************************************************************
00446  * 
00447  * 
00448  * update RTC using now.httpbin.org free service
00449  * 
00450  * 
00451  * ***************************************************************************************/
00452 
00453 #define HTTPBIN_EPOCH_TAG "epoch\":"
00454 bool set_rtc_from_network(void)
00455 {
00456     uint32_t http_content_len=0;
00457     bool http_ok = false;
00458 
00459     /* prepare http get header */
00460     strcpy(g_http_io_buffer,NOW_HTTPBIN_ORG);
00461 
00462     
00463     // CONNECT http://now.httpbin.org
00464     if( g_tcp_connector.tcp_connect(0x01,"now.httpbin.org",80,false,3) )
00465     {
00466         // send HTML GET 
00467         if( g_tcp_connector.tcp_write(0x01,g_http_io_buffer,strlen(g_http_io_buffer)))
00468         {
00469             // read json response
00470             if( g_http_parser.HttpParseResponse(&g_tcp_connector,0x01,g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,&http_ok,&http_content_len) )
00471             {
00472                 if(http_ok) 
00473                 {
00474                     g_json_io_buffer[http_content_len] = 0;
00475                 } 
00476             }
00477         }
00478     }
00479     g_tcp_connector.tcp_close(0x01);
00480 
00481     // parse and set time
00482     if( http_ok )
00483     {
00484         char *epoch = strstr(g_json_io_buffer,HTTPBIN_EPOCH_TAG);
00485         if(epoch == NULL) return false;
00486         epoch += sizeof( HTTPBIN_EPOCH_TAG );
00487         for(int i=0;i<20;i++)
00488         {
00489             if( epoch[i] == '.')
00490             {
00491                 epoch[i] = 0;
00492                 printf("> now.httpbin.org epoch: %s\r\n",epoch);
00493                 set_time( atoi(epoch) );
00494                 return true;
00495             }
00496         }
00497     }
00498 
00499     return false;
00500 
00501 }
00502 
00503 /*****************************************************************************************
00504 *
00505 *
00506 *   telegram rest api
00507 *
00508 *
00509 ******************************************************************************************/
00510 
00511 bool telegram_get_update(int32_t update_id)
00512 {
00513     uint32_t http_content_len=0;
00514     bool http_ok = false;
00515 
00516     /* prepare http get header */
00517     snprintf(g_http_io_buffer, ES_WIFI_PAYLOAD_SIZE, TELEGRAM_GETUPDATES, update_id);
00518 
00519 
00520     // CONNECT https://api.telegram.org
00521     if( g_tcp_connector.tcp_connect(0x01,"api.telegram.org",443,true,3) )
00522     {
00523         // send HTML GET getUpdates
00524         if( g_tcp_connector.tcp_write(0x01,g_http_io_buffer,strlen(g_http_io_buffer)))
00525         {
00526             // read json response
00527             if( g_http_parser.HttpParseResponse(&g_tcp_connector,0x01,g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,&http_ok,&http_content_len) )
00528             {
00529                 if(http_ok) 
00530                 {
00531                     g_json_io_buffer[http_content_len] = 0;
00532                 } 
00533             }
00534         }
00535         g_tcp_connector.tcp_close(0x01);
00536     }
00537 
00538     return http_ok;
00539 }
00540 
00541 
00542 
00543 bool telegram_send_message(char *json_msg)
00544 {
00545     uint32_t http_content_len=0,msg_len;
00546     bool http_ok = false;
00547     
00548     msg_len = strlen(json_msg);
00549 
00550     /* prepare http get header */
00551     snprintf(g_http_io_buffer, ES_WIFI_PAYLOAD_SIZE, TELEGRAM_SENDMESSAGE, msg_len);
00552 
00553    // CONNECT https://api.telegram.org
00554     if( g_tcp_connector.tcp_connect(0x01,"api.telegram.org",443,true,3) )
00555     {
00556         // send HTML GET sendMessage
00557         if( g_tcp_connector.tcp_write(0x01,g_http_io_buffer,strlen(g_http_io_buffer)))
00558         {
00559             // send payload
00560             if( g_tcp_connector.tcp_write(0x01,json_msg,msg_len) )
00561             {
00562                 // read json response
00563                 if( g_http_parser.HttpParseResponse(&g_tcp_connector,1,g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,&http_ok,&http_content_len) )
00564                 {
00565                     if(http_ok) 
00566                     {
00567                         g_json_io_buffer[http_content_len] = 0;
00568                     } 
00569                 }
00570             }
00571         }
00572         g_tcp_connector.tcp_close(0x01);
00573     }
00574 
00575     return http_ok;
00576 }
00577 
00578 
00579 bool telegram_send_photo(uint8_t *image, uint32_t image_size, int32_t chat_id, char *caption)
00580 {
00581     char chat_id_str[32];
00582     uint32_t content_len = 0;
00583     uint32_t http_content_len=0;
00584     bool http_ok = false;
00585 
00586         content_len = 383; // pre-calculated boundary len
00587         content_len += snprintf(chat_id_str,sizeof(chat_id_str),"%d",chat_id);
00588         content_len += strlen(caption);
00589         content_len += image_size;
00590 
00591         /* prepare http post header */
00592         snprintf(g_http_io_buffer, ES_WIFI_PAYLOAD_SIZE, TELEGRAM_SENDPHOTO, content_len);
00593         
00594         // CONNECT https://api.telegram.org
00595         if( g_tcp_connector.tcp_connect(0x01,"api.telegram.org",443,true,3) )
00596         {
00597             // send HTML POST sendMessage
00598             if( g_tcp_connector.tcp_write(0x01,g_http_io_buffer,strlen(g_http_io_buffer)))
00599             {
00600                 strcpy(g_http_io_buffer,"Content-Type: multipart/form-data; boundary=------------------------660d8ea934533f2b\r\n");
00601                 if( g_tcp_connector.tcp_write(0x01,g_http_io_buffer,strlen(g_http_io_buffer)))
00602                 {
00603                     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);
00604                     if( g_tcp_connector.tcp_write(0x01,g_http_io_buffer,strlen(g_http_io_buffer)))
00605                     {   
00606                         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);
00607                         if( g_tcp_connector.tcp_write(0x01,g_http_io_buffer,strlen(g_http_io_buffer)))
00608                         {   
00609                             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");
00610                             if( g_tcp_connector.tcp_write(0x01,g_http_io_buffer,strlen(g_http_io_buffer)))
00611                             {   
00612                                 if( g_tcp_connector.tcp_write(0x01,(char*)image,image_size))
00613                                 {   
00614                                     strcpy(g_http_io_buffer,"\r\n--------------------------660d8ea934533f2b--\r\n");
00615                                     if( g_tcp_connector.tcp_write(0x01,g_http_io_buffer,strlen(g_http_io_buffer)) )
00616                                     {
00617                                         // read json response
00618                                         if( g_http_parser.HttpParseResponse(&g_tcp_connector,0x01,g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,&http_ok,&http_content_len) )
00619                                         {
00620                                             if(http_ok) 
00621                                             {
00622                                                 g_json_io_buffer[http_content_len] = 0;
00623                                             } 
00624                                         }
00625                                     }
00626                                 }
00627                             }
00628                         }
00629                     }
00630                 }
00631             }
00632             g_tcp_connector.tcp_close(0x01);
00633         }
00634 
00635         return http_ok;        
00636 }
00637 
00638 /*****************************************************************************************
00639 *
00640 *
00641 *   JSON parsing
00642 *
00643 *
00644 ******************************************************************************************/
00645 
00646 bool jsoneq(const char *json, jsmntok_t *tok, const char *s,jsmntype_t type) 
00647 {
00648     if (tok->type == type && (int) strlen(s) == tok->end - tok->start &&
00649             strncmp(json + tok->start, s, tok->end - tok->start) == 0) {
00650         return true;
00651     }
00652     return false;
00653 }
00654 
00655