try use cjson, too much heap usage

This commit is contained in:
2023-12-10 21:47:36 +01:00
parent f062b492fc
commit 1ab009feef
7 changed files with 191 additions and 94 deletions

View File

@@ -1,3 +1,3 @@
idf_component_register(SRCS "main.c" "font.c" "display.c" "text.c" "wlan.c" "https.c"
idf_component_register(SRCS "main.c" "font.c" "display.c" "text.c" "wlan.c" "https.c" "cJSON/cJSON.c"
REQUIRES esp_driver_gpio esp_wifi nvs_flash esp_timer esp-tls
INCLUDE_DIRS "")

1
main/cJSON Submodule

Submodule main/cJSON added at cb8693b058

View File

@@ -1,5 +1,8 @@
#include "esp_tls.h"
#include "esp_log.h"
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
@@ -7,27 +10,36 @@
static const char *TAG = "https";
#define WEB_SERVER "bsvg.efa.de"
//#define WEB_SERVER "bsvg.efa.de"
//#define WEB_PORT "443"
//#define WEB_URL "/bsvagstd/XML_DM_REQUEST?outputFormat=JSON&stateless=1&locationServerActive=1&type_dm=stop&name_dm=\"Freiastr,Braunschweig\"&mode=direct&ptOptionsActive=1&useRealtime=0"
#define WEB_SERVER "mustbehax.de"
#define WEB_PORT "443"
#define WEB_URL "/bsvagstd/XML_DM_REQUEST?outputFormat=JSON&stateless=1&locationServerActive=1&type_dm=stop&name_dm=\"Freiastr,Braunschweig\"&mode=direct&ptOptionsActive=1&useRealtime=1"
#define WEB_URL "/web/reduced.json"
static const char HOWSMYSSL_REQUEST[] = "GET " WEB_URL " HTTP/1.1\r\n"
static const char REQUEST[] = "GET " WEB_URL " HTTP/1.1\r\n"
"Host: "WEB_SERVER"\r\n"
"User-Agent: esp-idf/1.0 esp32\r\n"
"\r\n";
static void https_get_request(esp_tls_cfg_t cfg, const char *WEB_SERVER_URL, const char *REQUEST)
esp_err_t https_get_request_using_crt_bundle(char* buf, size_t bufsize)
{
char buf[47000];
memset(buf, 0, bufsize);
ESP_LOGI(TAG, "https_request using crt bundle");
esp_tls_cfg_t cfg = {
.crt_bundle_attach = esp_crt_bundle_attach,
};
//https_get_request(cfg, "https://"WEB_SERVER""WEB_URL, HOWSMYSSL_REQUEST);
//char buf[47000];
int ret, len;
esp_tls_t *tls = esp_tls_init();
if (!tls) {
ESP_LOGE(TAG, "Failed to allocate esp_tls handle!");
goto exit;
return -1;
}
if (esp_tls_conn_http_new_sync(WEB_SERVER_URL, &cfg, tls) == 1) {
if (esp_tls_conn_http_new_sync("https://"WEB_SERVER""WEB_URL, &cfg, tls) == 1) {
ESP_LOGI(TAG, "Connection established...");
} else {
ESP_LOGE(TAG, "Connection failed...");
@@ -39,7 +51,8 @@ static void https_get_request(esp_tls_cfg_t cfg, const char *WEB_SERVER_URL, con
if (ret == ESP_OK) {
ESP_LOGE(TAG, "TLS error = -0x%x, TLS flags = -0x%x", esp_tls_code, esp_tls_flags);
}
goto cleanup;
esp_tls_conn_destroy(tls);
return -2;
}
#ifdef CONFIG_EXAMPLE_CLIENT_SESSION_TICKETS
@@ -60,15 +73,20 @@ static void https_get_request(esp_tls_cfg_t cfg, const char *WEB_SERVER_URL, con
written_bytes += ret;
} else if (ret != ESP_TLS_ERR_SSL_WANT_READ && ret != ESP_TLS_ERR_SSL_WANT_WRITE) {
ESP_LOGE(TAG, "esp_tls_conn_write returned: [0x%02X](%s)", ret, esp_err_to_name(ret));
goto cleanup;
esp_tls_conn_destroy(tls);
return -3;
}
} while (written_bytes < strlen(REQUEST));
uint32_t write_offset = 0;
memset(buf, 0x00, bufsize);
ESP_LOGI(TAG, "Reading HTTP response...");
do {
len = sizeof(buf) - 1;
memset(buf, 0x00, sizeof(buf));
ret = esp_tls_conn_read(tls, (char *)buf, len);
len = bufsize - write_offset - 1;
if(len > 6000)
len = 6000;
ret = esp_tls_conn_read(tls, &buf[write_offset], len);
if (ret == ESP_TLS_ERR_SSL_WANT_WRITE || ret == ESP_TLS_ERR_SSL_WANT_READ) {
continue;
@@ -79,30 +97,27 @@ static void https_get_request(esp_tls_cfg_t cfg, const char *WEB_SERVER_URL, con
ESP_LOGI(TAG, "connection closed");
break;
}
write_offset += ret;
len = ret;
ESP_LOGD(TAG, "%d bytes read", len);
/* Print response directly to stdout as it is read */
for (int i = 0; i < len; i++) {
putchar(buf[i]);
}
putchar('\n'); // JSON output doesn't have a newline at end
ESP_LOGI(TAG, "%d bytes read", len);
if(!strstr(buf, "departureList")){
ESP_LOGI(TAG,"tossing ... strstr: %ld", (uint32_t)strstr(buf, "departureList"));
write_offset=0;
}else
ESP_LOGI(TAG,"keeping ... strstr: %ld", (uint32_t)strstr(buf, "departureList"));
} while (1);
cleanup:
esp_tls_conn_destroy(tls);
exit:
for (int countdown = 10; countdown >= 0; countdown--) {
ESP_LOGI(TAG, "%d...", countdown);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
return 0;
///* Print response directly to stdout as it is read */
//for (int i = 0; i < sizeof(buf); i++) {
// putchar(buf[i]);
// if(i%100 == 0)
// vTaskDelay(1);
//}
//putchar('\n'); // JSON output doesn't have a newline at end
void https_get_request_using_crt_bundle(void)
{
ESP_LOGI(TAG, "https_request using crt bundle");
esp_tls_cfg_t cfg = {
.crt_bundle_attach = esp_crt_bundle_attach,
};
https_get_request(cfg, "https://"WEB_SERVER""WEB_URL, HOWSMYSSL_REQUEST);
}

View File

@@ -1 +1,4 @@
void https_get_request_using_crt_bundle(void);
#include <stddef.h>
#include "esp_err.h"
esp_err_t https_get_request_using_crt_bundle(char* buf, size_t bufsize);

View File

@@ -6,7 +6,9 @@
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
@@ -20,6 +22,9 @@
#include "wlan.h"
#include "https.h"
#include "cJSON/cJSON.h"
#include "esp_heap_caps.h"
#ifdef CONFIG_IDF_TARGET_ESP32
#define CHIP_NAME "ESP32"
#endif
@@ -28,37 +33,117 @@
#define CHIP_NAME "ESP32-S2 Beta"
#endif
const esp_timer_create_args_t periodic_timer_args = {
.callback = &display_cycle,
};
uint8_t buf_ok = 0;
char bsvg_buf[33000];
static void https_request_task(void *pvparameters){
while(https_get_request_using_crt_bundle(bsvg_buf, sizeof(bsvg_buf)) != 0){
ESP_LOGE("bsvg", "Failed to get data from server. Retrying...");
vTaskDelay(1);
}
buf_ok = 1;
vTaskDelete(NULL);
}
uint8_t json_ok = 0;
cJSON *departureList;
static void json_parse_task(void *pvparameters){
//uint16_t start_ptr = 0;
//while(buf[start_ptr] != '{' && start_ptr < sizeof(buf))
// start_ptr++;
char *start = strstr(bsvg_buf, "\"departureList\"") + 17;
ESP_LOGI("bsvg", "start at %ld: \"%.10s\"", (uint32_t)start, start);
departureList = cJSON_Parse(start);
printf("free heap: %d\n", heap_caps_get_free_size( MALLOC_CAP_DEFAULT) );
json_ok = 1;
vTaskDelete(NULL);
}
void app_main(void)
{
printf("Hello world!\n");
printf("free heap: %d\n", heap_caps_get_free_size( MALLOC_CAP_DEFAULT) );
ESP_LOGI("bsvg", "display init");
display_init();
printf("free heap: %d\n", heap_caps_get_free_size( MALLOC_CAP_DEFAULT) );
esp_timer_handle_t periodic_timer;
ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));
ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, 500));
put_line(fb, 1, "MauMau", 1, 1);
put_line(fb, 1, "Moin", 1, 1);
wlan_init();
put_line(fb, 2, "wifi", 1, 1);
////xTaskCreate(&http_get_task, "http_get_task", 4096, NULL, 5, NULL);
//char buf[RCV_BUFSIZE];
//bzero(buf, RCV_BUFSIZE);
//http_request(buf);
//for(uint32_t i=0; i<RCV_BUFSIZE; i++){
// if(buf[i] == 0)
// break;
// putchar(buf[i]);
//}
https_get_request_using_crt_bundle();
printf("free heap: %d\n", heap_caps_get_free_size( MALLOC_CAP_DEFAULT) );
xTaskCreate(&https_request_task, "https_get_task", 8192, NULL, 5, NULL);
while (!buf_ok) {
vTaskDelay(1);
}
printf("free heap: %d\n", heap_caps_get_free_size( MALLOC_CAP_DEFAULT) );
ESP_LOGI("bsvg", "got from https server:");
for(uint32_t i=0; i<sizeof(bsvg_buf); i++){
putchar(bsvg_buf[i]);
if(i%1000==0)
vTaskDelay(1);
}
putchar('\n');
printf("free heap: %d\n", heap_caps_get_free_size( MALLOC_CAP_DEFAULT) );
put_line(fb, 3, "https", 1, 1);
xTaskCreate(&json_parse_task, "json_parse_task", 8192, NULL, 5, NULL);
ESP_LOGI("bsvg", "Parsing JSON...");
while (!json_ok) {
printf("free heap: %d\n", heap_caps_get_free_size( MALLOC_CAP_DEFAULT) );
vTaskDelay(1);
}
ESP_LOGI("bsvg", "Done");
if (departureList == NULL)
{
ESP_LOGI("bsvg", "did not get list");
const char *error_ptr = cJSON_GetErrorPtr();
heap_caps_print_heap_info(MALLOC_CAP_DEFAULT);
if (error_ptr != NULL)
{
fprintf(stderr, "Error at %ld: %.10s\n", (uint32_t)error_ptr-(uint32_t)bsvg_buf, error_ptr);
fprintf(stderr, "%.100s%.100s\n", error_ptr-100, error_ptr);
fprintf(stderr, " ^\n");
}
else {
fprintf(stderr, "did not get err ptr\n");
}
}else{
ESP_LOGI("bsvg", "got list");
printf("free heap: %d\n", heap_caps_get_free_size( MALLOC_CAP_DEFAULT) );
ESP_LOGI("bsvg", "type: %d", departureList->type);
ESP_LOGI("bsvg", "child: %ld", (uint32_t)departureList->child);
if(cJSON_IsArray(departureList)){
ESP_LOGI("bsvg", "is Array");
const cJSON *departure = NULL;
cJSON_ArrayForEach(departure, departureList){
cJSON *number = cJSON_GetObjectItemCaseSensitive(cJSON_GetObjectItemCaseSensitive(departure, "servingLine"), "number");;
if(number == NULL)
ESP_LOGI("bsvg", "cant get number");
else if(cJSON_IsNumber(number))
ESP_LOGI("bsvg", "number (int): %d\n", number->valueint);
else if(cJSON_IsString(number))
ESP_LOGI("bsvg", "number (str): %.3s\n", number->valuestring);
else
ESP_LOGI("bsvg", "cant get number value");
}
}
}
put_line(fb, 3, "http", 1, 1);
for (;;) {
vTaskDelay(1);