Search code examples
c++cembeddedesp32

Trying to understand a parsing error when making an HTTP request with C++ on ESP32


I'm attempting to do an HTTPS PUT from C++ on an ESP-EYE. I started with the C esp_https_example code and had that working with the same PEM and URL. I started to transition to using this from C++ as part of a project that is primarily written in C++. My call looks like:

static const char *URL = "https://signal.unexpectedeof.casa/on-air";


void https_with_url(void)
{
    esp_http_client_config_t* config = (esp_http_client_config_t*)calloc(sizeof(esp_http_client_config_t), 1);
    config->url = URL;
    config->cert_pem = unexpectedeof_casa_root_cert_pem_start;
    config->event_handler = _http_event_handler;

    esp_http_client_handle_t client = esp_http_client_init(config);
    esp_http_client_set_method(client, HTTP_METHOD_PUT);
    esp_err_t err = esp_http_client_perform(client);

    if (err == ESP_OK) {
        ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %d",
                esp_http_client_get_status_code(client),
                esp_http_client_get_content_length(client));
    } else {
        ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
    }
    esp_http_client_close(client);
    esp_http_client_cleanup(client);
}

I believe the URL I'm providing isn't being copied or initialized correctly resulting in a url parsing error. When the function https_with_url is called I get this error:

E (13593) esp-tls: couldn't get hostname for :signal.unexpectedeof.casa:
E (13593) esp-tls: Failed to open new connection
E (13603) TRANS_SSL: Failed to open a new connection
E (13603) HTTP_CLIENT: Connection failed, sock < 0
E (13613) HTTPS_HANDLING: Error perform http request ESP_ERR_HTTP_CONNECT
I (13623) HTTPS_HANDLING: HTTP_EVENT_DISCONNECTED
I (13623) HTTPS_HANDLING: HTTP_EVENT_DISCONNECTED

Since I'm using C++ but the parse happens in the esp-idf C code I thought maybe I'm not passing the data correctly, but haven't made much progress. Switching from an inline string for the URL to the character array shown didn't make a difference.

esp-idf version 4.1.


Solution

  • Ended up being that I didn't handle the wifi event properly before the request was sent.

    static void wifi_event_handler(void* arg, esp_event_base_t event_base, 
                                    int32_t event_id, void* event_data)
    {
        if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
            esp_wifi_connect();
        } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
            if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {
                esp_wifi_connect();
                xEventGroupClearBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
                s_retry_num++;
                ESP_LOGI(LOGTAG, "retry to connect to the AP");
            }
            ESP_LOGI(LOGTAG,"connect to the AP fail");
        } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
            ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
            ESP_LOGI(LOGTAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
            s_retry_num = 0;
            xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
        }
    }
    
    void wifi_init_sta(void)
    {
        s_wifi_event_group = xEventGroupCreate();
    
        ESP_ERROR_CHECK(esp_netif_init());
    
        ESP_ERROR_CHECK(esp_event_loop_create_default());
        esp_netif_create_default_wifi_sta();
    
        wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
        ESP_ERROR_CHECK(esp_wifi_init(&cfg));
    
    
        ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));
        ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL));
    
        wifi_config_t wifi_config = { };
        strcpy((char*)wifi_config.sta.ssid, CONFIG_ESP_WIFI_SSID);
        strcpy((char*)wifi_config.sta.password, CONFIG_ESP_WIFI_PASSWORD);
        ESP_LOGI(LOGTAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
    
        ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
        ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
        ESP_ERROR_CHECK(esp_wifi_start() );
    
        ESP_LOGI(LOGTAG, "wifi_init_sta finished.");
    }
    

    Examples of this are in the esp-idf github repo under examples/protocols/wifi.