Can't create Https connection

manuel2258
Posts: 3
Joined: Fri Feb 14, 2020 3:35 pm

Can't create Https connection

Postby manuel2258 » Fri Feb 14, 2020 4:03 pm

Hello guys,
I'm new to ESP-IDF and currently trying to write a class in which I can schedule https requests.
As a base I took the wifi/getting-started and protocols/https-request example and merged them into a single class.
However when I try to initiate a new https connection I'm always getting an LoadProhibited Exception with the following stack-trace:

Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x400014e8 PS : 0x00060d30 A0 : 0x800faaf2 A1 : 0x3ffc8a20
A2 : 0x00000006 A3 : 0x00000004 A4 : 0x000000ff A5 : 0x0000ff00
A6 : 0x00ff0000 A7 : 0xff000000 A8 : 0x01000a01 A9 : 0x00000001
A10 : 0x3f40fc34 A11 : 0x00000000 A12 : 0x00000028 A13 : 0x00000000
A14 : 0x00000001 A15 : 0x00000000 SAR : 0x0000000a EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000004 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xfffffffd

ELF file SHA256: 2ece161e79310e5355193ee970340b93b83cef5b4a8d09a7b4fcb685a2f79d82

Backtrace: 0x400014e5:0x3ffc8a20 0x400faaef:0x3ffc8a30 0x400f8f31:0x3ffc8a50 0x400f90c4:0x3ffc8a90 0x400f85d2:0x3ffc8ac0 0x400f8774:0x3ffc8ae0 0x400f88e3:0x3ffc8b10 0x400f89a1:0x3ffc8b40 0x400d66c9:0x3ffc8b80 0x400d6fa6:0x3ffc8c00 0x400d5cec:0x3ffc8c30 0x400926f9:0x3ffc8c50
0x400faaef: mbedtls_ssl_conf_alpn_protocols at /home/manuel/esp-idf/components/mbedtls/mbedtls/library/ssl_tls.c:7575
0x400f8f31: set_client_config at /home/manuel/esp-idf/components/esp-tls/esp_tls_mbedtls.c:395
0x400f90c4: esp_create_mbedtls_handle at /home/manuel/esp-idf/components/esp-tls/esp_tls_mbedtls.c:56
0x400f85d2: create_ssl_handle at /home/manuel/esp-idf/components/esp-tls/esp_tls.c:73
0x400f8774: esp_tls_low_level_conn at /home/manuel/esp-idf/components/esp-tls/esp_tls.c:283
0x400f88e3: esp_tls_conn_new_sync at /home/manuel/esp-idf/components/esp-tls/esp_tls.c:347
0x400f89a1: esp_tls_conn_http_new at /home/manuel/esp-idf/components/esp-tls/esp_tls.c:402
0x400d66c9: network::HttpsRequester::make_request(network::Request*) at /home/manuel/Projects/espify/build/../main/src/network/HttpsRequester.cpp:103
0x400d6fa6: network::HttpsRequester::update() at /home/manuel/Projects/espify/build/../main/src/network/HttpsRequester.cpp:184
0x400d5cec: https_requester_update(void*) at /home/manuel/Projects/espify/build/../main/main.cpp:27 (discriminator 1)
0x400926f9: vPortTaskWrapper at /home/manuel/esp-idf/components/freertos/xtensa/port.c:143

First of all here is the merged class: https://github.com/manuel2258/espify/bl ... uester.cpp
Its Ctor initiates the wifi connection, then waits for the

Code: Select all

(event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)

Event after which it handles the queued requests.

So when making a requests I'm simply connecting to the host just like in the example:

Code: Select all

struct esp_tls *tls = esp_tls_conn_http_new(url_ptr->c_str(), tls_cfg);
while tls_cfg is a member of the class and defined like this:

Code: Select all

tls_cfg = new esp_tls_cfg_t;
tls_cfg->cacert_buf = server_root_cert_pem_start;
tls_cfg->cacert_bytes = server_root_cert_pem_end - server_root_cert_pem_start;
The server_root_cert.pem is loaded successfully, as I can print it out.

So I'm not quite sure what I'm doing wrong here. Is the Wifi-Connection not yet established right? Can't the esp_tls_cfg_t be a class member? Am I missing any necessary configs?

Using woflSSL instead of mbedTLS does't work either.

The used version is ESP-IDF v4.1-dev-2239-gc1d0daf36.

If there is any information missing please let me know.
Thanks a lot for your help and time in advance!

LG. Manuel

manuel2258
Posts: 3
Joined: Fri Feb 14, 2020 3:35 pm

Re: Can't create Https connection

Postby manuel2258 » Mon Feb 17, 2020 12:53 pm

I was able to resolve it myself.
The problem was that as the example uses designated initializer for the esp_tls_cfg_t struct.
Trying to port it to C++14 caused the issue.
I'm not sure why not initialized struct fields with a designated initializer differ from an "empty" struct, but somehow they do, so setting every struct field manually seems to fix the issue.

Code: Select all

tls_cfg = new esp_tls_cfg_t;
  tls_cfg->alpn_protos = new const char *(nullptr);
  tls_cfg->cacert_buf = server_root_cert_pem_start;
  tls_cfg->cacert_bytes = server_root_cert_pem_end - server_root_cert_pem_start;
  tls_cfg->clientcert_buf = NULL;
  tls_cfg->clientcert_bytes = 0;
  tls_cfg->clientkey_buf = NULL;
  tls_cfg->clientkey_bytes = 0;
  tls_cfg->clientkey_password = NULL;
  tls_cfg->clientkey_password_len = 0;
  tls_cfg->non_block = false;
  tls_cfg->timeout_ms = 1000;
  tls_cfg->use_global_ca_store = false;
  tls_cfg->common_name = NULL;
  tls_cfg->skip_common_name = true;
  tls_cfg->psk_hint_key = NULL;

zliudr
Posts: 357
Joined: Thu Oct 03, 2019 5:15 am

Re: Can't create Https connection

Postby zliudr » Thu Feb 27, 2020 10:03 pm

Manuel2258,

You saved me!

I upgraded from c to cpp recently and have been dealing with compilation issues all over the place.

FYI, if you're using ESP-DIF V3.3, the member names are different and there are less members.
Here are the V3.3 members:

Code: Select all

	esp_tls_cfg_t cfg;
	cfg.cacert_pem_buf = server_cert_pem_start;
	cfg.cacert_pem_bytes = server_cert_pem_end - server_cert_pem_start;
	cfg.alpn_protos = new const char *(nullptr);
	cfg.clientcert_pem_buf = NULL;
	cfg.clientcert_pem_bytes = 0;
	cfg.clientkey_pem_buf = NULL;
	cfg.clientkey_pem_bytes = 0;
	cfg.clientkey_password = NULL;
	cfg.clientkey_password_len = 0;
	cfg.non_block = false;
	cfg.timeout_ms = 1000;
	cfg.use_global_ca_store = false;

ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: Can't create Https connection

Postby ESP_Angus » Fri Feb 28, 2020 2:39 am

manuel2258 wrote:
Mon Feb 17, 2020 12:53 pm
I'm not sure why not initialized struct fields with a designated initializer differ from an "empty" struct, but somehow they do, so setting every struct field manually seems to fix the issue.
The reason is that a struct is what C++ calls a POD (not a class) and therefore has no constructor. So when you do this:
manuel2258 wrote:
Mon Feb 17, 2020 12:53 pm

Code: Select all

tls_cfg = new esp_tls_cfg_t;
All of the fields contain junk memory, uninitialized values - probably whatever was in those RAM addresses previously. This is a recipe for random crashes.

You should immediately call memset(tls_cfg, 0, sizeof(esp_tls_cfg_t); to zero the structure. Then it's no longer necessary to initialize every field, because any uninitialized field will be zero.

Calling memset() first is good even if you think you are setting every field, because in the future you update ESP-IDF and a new field may be added to the config structure. Having the memset() line in there means that field will automatically be set to zero, without you needing to do anything. Otherwise, that field will be junk memory.

If you don't need the config structure to be on the heap, another way to initialize it is like this:

Code: Select all

esp_tls_cfg_t tls_cfg = { 0 };
tls_cfg.cacert_buf = server_root_cert_pem_start;
// etc, etc
zliudr wrote:

Code: Select all

	esp_tls_cfg_t cfg;
	cfg.cacert_pem_buf = server_cert_pem_start;
Same applies here. With the declaration "esp_tls_cfg_t cfg;" then the contents of all this struct's fields are random junk memory. If you do "esp_tls_cfg_t cfg = { 0 };" then the contents of all fields are zero.

So it's strongly recommended to always do the second one, even if you think you're initializing all the fields.

zliudr
Posts: 357
Joined: Thu Oct 03, 2019 5:15 am

Re: Can't create Https connection

Postby zliudr » Fri Feb 28, 2020 3:29 am

ESP_Angus,

Excellent explanation and thank you! I'll use "={0}" and the list so I know what the struct has. So why is it working in C (only having to assign values for pem_bytes and pem_buf)?
My structs are variables, not pointers like Manuel. Still, not initializing it caused tls_new() to crash in one task, but not another. Dos C struct initializer do the memset 0 thing? I know that this C/C++ difference question sounds like it belongs to stackoverflow but there are rarely anybody there who aren't a self-centered ego-manic jerk on stackoverflow.

chegewara
Posts: 2207
Joined: Wed Jun 14, 2017 9:00 pm

Re: Can't create Https connection

Postby chegewara » Fri Feb 28, 2020 7:50 am

Recently i had task to fix issue with http connection in C++ code using esp-idf. From reading code all looks good:

Code: Select all

esp_http_client_config_t* conf = new esp_http_client_config_t;
Create new object and return its pointer. Except 1 small change and all problems gone:

Code: Select all

esp_http_client_config_t* conf = (esp_http_client_config_t*)calloc(sizeof(esp_http_client_config_t), 1);
Initializing C struct object in C++ may cause many problems, and i think that C++ only allocates memory for struct object with all garbage values that are in there. It may lead to situation where it may or may not work or even crash if you dont initialize all fields in struct or safer is to clean memory used by struct (set 0's).

zliudr
Posts: 357
Joined: Thu Oct 03, 2019 5:15 am

Re: Can't create Https connection

Postby zliudr » Sat Feb 29, 2020 5:25 am

Right, calloc. Haven't seen it in decades! That's one way to do it! Thanks.

zliudr
Posts: 357
Joined: Thu Oct 03, 2019 5:15 am

Re: Can't create Https connection

Postby zliudr » Sat Feb 29, 2020 6:08 am

Strangely, I found the uart_config struct to be just fine when I initialized it in the C syntax although this function is in a .cpp file. Why?

Code: Select all

void device_task(void *pvParameters)
{
    uart_config_t uart1_config = {
        .baud_rate = USB_HOST_BAUD,
        .data_bits = UART_DATA_8_BITS,
        .parity    = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
    };
}
ESP-IDF V3.3

ESP_Sprite
Posts: 8926
Joined: Thu Nov 26, 2015 4:08 am

Re: Can't create Https connection

Postby ESP_Sprite » Sat Feb 29, 2020 9:46 am

Iirc, it works (and only works) if you happen to feed in the parameters in the exact order the struct is defined in. Something to do with gcc being kind enough to ignore the named members, so it degrades to a normal initializer.

zliudr
Posts: 357
Joined: Thu Oct 03, 2019 5:15 am

Re: Can't create Https connection

Postby zliudr » Sun Mar 01, 2020 3:07 am

wow, I see. Thanks. I hope there's a white paper on C/C++ differences. I see bits of information on google search.

Who is online

Users browsing this forum: Baidu [Spider], Google [Bot] and 110 guests