esp_http_client: Add support for esp_events

This commit is contained in:
Harshit Malpani
2022-11-16 17:31:07 +05:30
parent 745c06626d
commit 674fd8feb8
6 changed files with 97 additions and 1 deletions
+3 -1
View File
@@ -1,5 +1,7 @@
if(NOT ${IDF_TARGET} STREQUAL "linux")
set(req lwip)
set(req lwip esp_event)
else()
set(req esp_stubs)
endif()
idf_component_register(SRCS "esp_http_client.c"
@@ -25,6 +25,8 @@
#include "esp_transport_ssl.h"
#endif
ESP_EVENT_DEFINE_BASE(ESP_HTTP_CLIENT_EVENT);
static const char *TAG = "HTTP_CLIENT";
/**
@@ -183,6 +185,14 @@ static esp_err_t http_dispatch_event(esp_http_client_t *client, esp_http_client_
return ESP_OK;
}
static void http_dispatch_event_to_event_loop(int32_t event_id, const void* event_data, size_t event_data_size)
{
esp_err_t err = esp_event_post(ESP_HTTP_CLIENT_EVENT, event_id, event_data, event_data_size, portMAX_DELAY);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to post https_ota event: %"PRId32", error: %s", event_id, esp_err_to_name(err));
}
}
static int http_on_message_begin(http_parser *parser)
{
esp_http_client_t *client = parser->data;
@@ -211,6 +221,7 @@ static int http_on_header_event(esp_http_client_handle_t client)
client->event.header_key = client->current_header_key;
client->event.header_value = client->current_header_value;
http_dispatch_event(client, HTTP_EVENT_ON_HEADER, NULL, 0);
http_dispatch_event_to_event_loop(HTTP_EVENT_ON_HEADER, &client, sizeof(esp_http_client_handle_t));
free(client->current_header_key);
free(client->current_header_value);
client->current_header_key = NULL;
@@ -293,6 +304,10 @@ static int http_on_body(http_parser *parser, const char *at, size_t length)
client->response->data_process += length;
client->response->buffer->raw_len += length;
http_dispatch_event(client, HTTP_EVENT_ON_DATA, (void *)at, length);
esp_http_client_on_data_t evt_data = {};
evt_data.data_process = client->response->data_process;
evt_data.client = client;
http_dispatch_event_to_event_loop(HTTP_EVENT_ON_DATA, &evt_data, sizeof(esp_http_client_on_data_t));
return 0;
}
@@ -891,6 +906,11 @@ static esp_err_t esp_http_check_response(esp_http_client_handle_t client)
return ESP_FAIL;
};
}
esp_http_client_redirect_event_data_t evt_data = {
.status_code = client->response->status_code,
.client = client,
};
http_dispatch_event_to_event_loop(HTTP_EVENT_REDIRECT, &evt_data, sizeof(esp_http_client_redirect_event_data_t));
break;
case HttpStatus_Unauthorized:
esp_http_client_add_auth(client);
@@ -1138,6 +1158,7 @@ int esp_http_client_read(esp_http_client_handle_t client, char *buffer, int len)
if (rlen < 0 && ridx == 0 && !esp_http_client_is_complete_data_received(client)) {
http_dispatch_event(client, HTTP_EVENT_ERROR, esp_transport_get_error_handle(client->transport), 0);
http_dispatch_event_to_event_loop(HTTP_EVENT_ERROR, &client, sizeof(esp_http_client_handle_t));
return ESP_FAIL;
}
return ridx;
@@ -1172,6 +1193,7 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
return ESP_ERR_HTTP_EAGAIN;
}
http_dispatch_event(client, HTTP_EVENT_ERROR, esp_transport_get_error_handle(client->transport), 0);
http_dispatch_event_to_event_loop(HTTP_EVENT_ERROR, &client, sizeof(esp_http_client_handle_t));
return err;
}
/* falls through */
@@ -1181,6 +1203,7 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
return ESP_ERR_HTTP_EAGAIN;
}
http_dispatch_event(client, HTTP_EVENT_ERROR, esp_transport_get_error_handle(client->transport), 0);
http_dispatch_event_to_event_loop(HTTP_EVENT_ERROR, &client, sizeof(esp_http_client_handle_t));
return err;
}
/* falls through */
@@ -1190,6 +1213,7 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
return ESP_ERR_HTTP_EAGAIN;
}
http_dispatch_event(client, HTTP_EVENT_ERROR, esp_transport_get_error_handle(client->transport), 0);
http_dispatch_event_to_event_loop(HTTP_EVENT_ERROR, &client, sizeof(esp_http_client_handle_t));
return err;
}
/* falls through */
@@ -1209,9 +1233,11 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
ESP_LOGW(TAG, "Close connection due to FIN received");
esp_http_client_close(client);
http_dispatch_event(client, HTTP_EVENT_ERROR, esp_transport_get_error_handle(client->transport), 0);
http_dispatch_event_to_event_loop(HTTP_EVENT_ERROR, &client, sizeof(esp_http_client_handle_t));
return ESP_ERR_HTTP_CONNECTION_CLOSED;
}
http_dispatch_event(client, HTTP_EVENT_ERROR, esp_transport_get_error_handle(client->transport), 0);
http_dispatch_event_to_event_loop(HTTP_EVENT_ERROR, &client, sizeof(esp_http_client_handle_t));
return ESP_ERR_HTTP_FETCH_HEADER;
}
/* falls through */
@@ -1222,6 +1248,7 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
if ((err = esp_http_check_response(client)) != ESP_OK) {
ESP_LOGE(TAG, "Error response");
http_dispatch_event(client, HTTP_EVENT_ERROR, esp_transport_get_error_handle(client->transport), 0);
http_dispatch_event_to_event_loop(HTTP_EVENT_ERROR, &client, sizeof(esp_http_client_handle_t));
return err;
}
while (client->response->is_chunked && !client->is_chunk_complete) {
@@ -1243,6 +1270,7 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
}
}
http_dispatch_event(client, HTTP_EVENT_ON_FINISH, NULL, 0);
http_dispatch_event_to_event_loop(HTTP_EVENT_ON_FINISH, &client, sizeof(esp_http_client_handle_t));
client->response->buffer->raw_len = 0;
if (!http_should_keep_alive(client->parser)) {
@@ -1340,6 +1368,7 @@ static esp_err_t esp_http_client_connect(esp_http_client_handle_t client)
}
client->state = HTTP_STATE_CONNECTED;
http_dispatch_event(client, HTTP_EVENT_ON_CONNECTED, NULL, 0);
http_dispatch_event_to_event_loop(HTTP_EVENT_ON_CONNECTED, &client, sizeof(esp_http_client_handle_t));
}
return ESP_OK;
}
@@ -1439,6 +1468,7 @@ static esp_err_t esp_http_client_request_send(esp_http_client_handle_t client, i
client->data_written_index = 0;
client->data_write_left = client->post_len;
http_dispatch_event(client, HTTP_EVENT_HEADERS_SENT, NULL, 0);
http_dispatch_event_to_event_loop(HTTP_EVENT_HEADERS_SENT, &client, sizeof(esp_http_client_handle_t));
client->state = HTTP_STATE_REQ_COMPLETE_HEADER;
return ESP_OK;
}
@@ -1477,10 +1507,12 @@ esp_err_t esp_http_client_open(esp_http_client_handle_t client, int write_len)
esp_err_t err;
if ((err = esp_http_client_connect(client)) != ESP_OK) {
http_dispatch_event(client, HTTP_EVENT_ERROR, esp_transport_get_error_handle(client->transport), 0);
http_dispatch_event_to_event_loop(HTTP_EVENT_ERROR, &client, sizeof(esp_http_client_handle_t));
return err;
}
if ((err = esp_http_client_request_send(client, write_len)) != ESP_OK) {
http_dispatch_event(client, HTTP_EVENT_ERROR, esp_transport_get_error_handle(client->transport), 0);
http_dispatch_event_to_event_loop(HTTP_EVENT_ERROR, &client, sizeof(esp_http_client_handle_t));
return err;
}
return ESP_OK;
@@ -1510,6 +1542,7 @@ esp_err_t esp_http_client_close(esp_http_client_handle_t client)
{
if (client->state >= HTTP_STATE_INIT) {
http_dispatch_event(client, HTTP_EVENT_DISCONNECTED, esp_transport_get_error_handle(client->transport), 0);
http_dispatch_event_to_event_loop(HTTP_EVENT_DISCONNECTED, &client, sizeof(esp_http_client_handle_t));
client->state = HTTP_STATE_INIT;
return esp_transport_close(client->transport);
}
@@ -18,6 +18,9 @@ extern "C" {
#define DEFAULT_HTTP_BUF_SIZE (512)
#include "esp_event.h"
ESP_EVENT_DECLARE_BASE(ESP_HTTP_CLIENT_EVENT);
typedef struct esp_http_client *esp_http_client_handle_t;
typedef struct esp_http_client_event *esp_http_client_event_handle_t;
@@ -50,6 +53,21 @@ typedef struct esp_http_client_event {
char *header_value; /*!< For HTTP_EVENT_ON_HEADER event_id, it's store current http header value */
} esp_http_client_event_t;
/**
* @brief Argument structure for HTTP_EVENT_ON_DATA event
*/
typedef struct esp_http_client_on_data {
esp_http_client_handle_t client; /*!< Client handle */
int64_t data_process; /*!< Total data processed */
} esp_http_client_on_data_t;
/**
* @brief Argument structure for HTTP_EVENT_REDIRECT event
*/
typedef struct esp_http_client_redirect_event_data {
esp_http_client_handle_t client; /*!< Client handle */
int status_code; /*!< Status Code */
} esp_http_client_redirect_event_data_t;
/**
* @brief HTTP Client transport