Merge branch 'feature/esp_http_client_on_linux' into 'master'

Feature/esp http client on linux

Closes IDF-6564

See merge request espressif/esp-idf!21128
This commit is contained in:
Mahavir Jain
2023-01-05 14:55:02 +08:00
28 changed files with 200 additions and 83 deletions

View File

@@ -9,23 +9,30 @@ if(CONFIG_ESP_TLS_USING_WOLFSSL)
"esp_tls_wolfssl.c")
endif()
set(priv_req http_parser)
if(NOT ${IDF_TARGET} STREQUAL "linux")
list(APPEND priv_req lwip)
endif()
idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS . esp-tls-crypto
PRIV_INCLUDE_DIRS "private_include"
# mbedtls is public requirements becasue esp_tls.h
# includes mbedtls header files.
REQUIRES mbedtls
PRIV_REQUIRES lwip http_parser)
PRIV_REQUIRES ${priv_req})
if(CONFIG_ESP_TLS_USING_WOLFSSL)
idf_component_get_property(wolfssl esp-wolfssl COMPONENT_LIB)
target_link_libraries(${COMPONENT_LIB} PUBLIC ${wolfssl})
endif()
if(NOT ${IDF_TARGET} STREQUAL "linux")
# Increase link multiplicity to get some lwip symbols correctly resolved by the linker
# due to cyclic dependencies present in IDF for lwip/esp_netif/mbedtls
idf_component_get_property(lwip lwip COMPONENT_LIB)
set_property(TARGET ${lwip} APPEND PROPERTY LINK_INTERFACE_MULTIPLICITY 5)
endif()
if(CONFIG_ESP_TLS_USE_SECURE_ELEMENT)
idf_component_optional_requires(PRIVATE espressif__esp-cryptoauthlib esp-cryptoauthlib)

View File

@@ -17,6 +17,18 @@
#include "esp_tls_private.h"
#include "esp_tls_error_capture_internal.h"
#include <errno.h>
#if CONFIG_IDF_TARGET_LINUX
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <linux/if.h>
#include <sys/time.h>
#define ipaddr_ntoa(ipaddr) inet_ntoa(*ipaddr)
typedef struct in_addr ip_addr_t;
#endif
static const char *TAG = "esp-tls";
#ifdef CONFIG_ESP_TLS_USING_MBEDTLS

View File

@@ -7,6 +7,10 @@
#include "esp_tls.h"
#include "esp_tls_error_capture_internal.h"
#if CONFIG_IDF_TARGET_LINUX
#include "esp_linux_helper.h"
#endif
typedef struct esp_tls_error_storage {
struct esp_tls_last_error parent; /*!< standard esp-tls last error container */
int sock_errno; /*!< last socket error captured in esp-tls */

View File

@@ -226,7 +226,7 @@ ssize_t esp_mbedtls_read(esp_tls_t *tls, char *data, size_t datalen)
}
if (ret != ESP_TLS_ERR_SSL_WANT_READ && ret != ESP_TLS_ERR_SSL_WANT_WRITE) {
ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_MBEDTLS, -ret);
ESP_LOGE(TAG, "read error :-0x%04X:", -ret);
ESP_LOGE(TAG, "read error :-0x%04zX:", -ret);
mbedtls_print_error_msg(ret);
}
}
@@ -242,19 +242,19 @@ ssize_t esp_mbedtls_write(esp_tls_t *tls, const char *data, size_t datalen)
write_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
}
if (datalen > MBEDTLS_SSL_OUT_CONTENT_LEN) {
ESP_LOGD(TAG, "Fragmenting data of excessive size :%d, offset: %d, size %d", datalen, written, write_len);
ESP_LOGD(TAG, "Fragmenting data of excessive size :%zu, offset: %zu, size %zu", datalen, written, write_len);
}
ssize_t ret = mbedtls_ssl_write(&tls->ssl, (unsigned char*) data + written, write_len);
if (ret <= 0) {
if (ret != ESP_TLS_ERR_SSL_WANT_READ && ret != ESP_TLS_ERR_SSL_WANT_WRITE && ret != 0) {
ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_MBEDTLS, -ret);
ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_ESP, ESP_ERR_MBEDTLS_SSL_WRITE_FAILED);
ESP_LOGE(TAG, "write error :-0x%04X:", -ret);
ESP_LOGE(TAG, "write error :-0x%04zX:", -ret);
mbedtls_print_error_msg(ret);
return ret;
} else {
// Exiting the tls-write process as less than desired datalen are writable
ESP_LOGD(TAG, "mbedtls_ssl_write() returned -0x%04X, already written %d, exitting...", -ret, written);
ESP_LOGD(TAG, "mbedtls_ssl_write() returned -0x%04zX, already written %zu, exitting...", -ret, written);
mbedtls_print_error_msg(ret);
return (written > 0) ? written : ret;
}

View File

@@ -28,9 +28,11 @@ void setUp(void)
{
// Execute esp_sha operation to allocate internal SHA semaphore memory
// which is considered as leaked otherwise
#if SOC_SHA_SUPPORTED
const uint8_t input_buffer[64] = {0};
uint8_t output_buffer[64];
esp_sha(SHA_TYPE, input_buffer, sizeof(input_buffer), output_buffer);
#endif // SOC_SHA_SUPPORTED
test_utils_record_free_mem();
TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL));
TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_GENERAL));

View File

@@ -1,3 +1,7 @@
if(NOT ${IDF_TARGET} STREQUAL "linux")
set(req lwip)
endif()
idf_component_register(SRCS "esp_http_client.c"
"lib/http_auth.c"
"lib/http_header.c"
@@ -5,5 +9,5 @@ idf_component_register(SRCS "esp_http_client.c"
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "lib/include"
# lwip is a public requirement because esp_http_client.h includes sys/socket.h
REQUIRES lwip
REQUIRES ${req}
PRIV_REQUIRES tcp_transport http_parser)

View File

@@ -8,7 +8,6 @@
#include <string.h>
#include <inttypes.h>
#include "esp_system.h"
#include "esp_log.h"
#include "esp_check.h"
#include "http_parser.h"
@@ -20,6 +19,7 @@
#include "sdkconfig.h"
#include "esp_http_client.h"
#include "errno.h"
#include "esp_random.h"
#ifdef CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS
#include "esp_transport_ssl.h"
@@ -269,7 +269,7 @@ static int http_on_headers_complete(http_parser *parser)
static int http_on_body(http_parser *parser, const char *at, size_t length)
{
esp_http_client_t *client = parser->data;
ESP_LOGD(TAG, "http_on_body %d", length);
ESP_LOGD(TAG, "http_on_body %zu", length);
if (client->response->buffer->output_ptr) {
memcpy(client->response->buffer->output_ptr, (char *)at, length);
@@ -277,7 +277,7 @@ static int http_on_body(http_parser *parser, const char *at, size_t length)
} else {
/* Do not cache body when http_on_body is called from esp_http_client_perform */
if (client->state < HTTP_STATE_RES_ON_DATA_START && client->cache_data_in_fetch_hdr) {
ESP_LOGI(TAG, "Body received in fetch header state, %p, %d", at, length);
ESP_LOGI(TAG, "Body received in fetch header state, %p, %zu", at, length);
esp_http_buffer_t *res_buffer = client->response->buffer;
assert(res_buffer->orig_raw_data == res_buffer->raw_data);
res_buffer->orig_raw_data = (char *)realloc(res_buffer->orig_raw_data, res_buffer->raw_len + length);
@@ -298,7 +298,7 @@ static int http_on_body(http_parser *parser, const char *at, size_t length)
static int http_on_message_complete(http_parser *parser)
{
ESP_LOGD(TAG, "http_on_message_complete, parser=%x", (int)parser);
ESP_LOGD(TAG, "http_on_message_complete, parser=%p", parser);
esp_http_client_handle_t client = parser->data;
client->is_chunk_complete = true;
return 0;
@@ -1041,7 +1041,7 @@ static int esp_http_client_get_data(esp_http_client_handle_t client)
esp_http_buffer_t *res_buffer = client->response->buffer;
ESP_LOGD(TAG, "data_process=%lld, content_length=%lld", client->response->data_process, client->response->content_length);
ESP_LOGD(TAG, "data_process=%"PRId64", content_length=%"PRId64, client->response->data_process, client->response->content_length);
int rlen = esp_transport_read(client->transport, res_buffer->data, client->buffer_size_rx, client->timeout_ms);
if (rlen >= 0) {
@@ -1059,7 +1059,7 @@ bool esp_http_client_is_complete_data_received(esp_http_client_handle_t client)
}
} else {
if (client->response->data_process != client->response->content_length) {
ESP_LOGD(TAG, "Data processed %lld != Data specified in content length %lld", client->response->data_process, client->response->content_length);
ESP_LOGD(TAG, "Data processed %"PRId64" != Data specified in content length %"PRId64, client->response->data_process, client->response->content_length);
return false;
}
}
@@ -1092,7 +1092,7 @@ int esp_http_client_read(esp_http_client_handle_t client, char *buffer, int len)
} else {
is_data_remain = client->response->data_process < client->response->content_length;
}
ESP_LOGD(TAG, "is_data_remain=%d, is_chunked=%d, content_length=%lld", is_data_remain, client->response->is_chunked, client->response->content_length);
ESP_LOGD(TAG, "is_data_remain=%"PRId8", is_chunked=%d"PRId8", content_length=%"PRId64, is_data_remain, client->response->is_chunked, client->response->content_length);
if (!is_data_remain) {
break;
}
@@ -1279,7 +1279,7 @@ int64_t esp_http_client_fetch_headers(esp_http_client_handle_t client)
http_parser_execute(client->parser, client->parser_settings, buffer->data, buffer->len);
}
client->state = HTTP_STATE_RES_ON_DATA_START;
ESP_LOGD(TAG, "content_length = %lld", client->response->content_length);
ESP_LOGD(TAG, "content_length = %"PRId64, client->response->content_length);
if (client->response->content_length <= 0) {
client->response->is_chunked = true;
return 0;

View File

@@ -9,11 +9,10 @@
#include <stdio.h>
#include <stdarg.h>
#include "lwip/sockets.h"
#include "sys/socket.h"
#include "esp_rom_md5.h"
#include "esp_tls_crypto.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_check.h"
@@ -117,11 +116,21 @@ char *http_auth_digest(const char *username, const char *password, esp_http_auth
goto _digest_exit;
}
}
asprintf(&auth_str, "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", algorithm=\"MD5\", "
"response=\"%s\", qop=%s, nc=%08x, cnonce=\"%016llx\"",
int rc = asprintf(&auth_str, "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", algorithm=\"MD5\", "
"response=\"%s\", qop=%s, nc=%08x, cnonce=%016"PRIx64,
username, auth_data->realm, auth_data->nonce, auth_data->uri, digest, auth_data->qop, auth_data->nc, auth_data->cnonce);
if (rc < 0) {
ESP_LOGE(TAG, "asprintf() returned: %d", rc);
ret = ESP_FAIL;
goto _digest_exit;
}
if (auth_data->opaque) {
asprintf(&temp_auth_str, "%s, opaque=\"%s\"", auth_str, auth_data->opaque);
rc = asprintf(&temp_auth_str, "%s, opaque=\"%s\"", auth_str, auth_data->opaque);
if (rc < 0) {
ESP_LOGE(TAG, "asprintf() returned: %d", rc);
ret = ESP_FAIL;
goto _digest_exit;
}
free(auth_str);
auth_str = temp_auth_str;
}
@@ -134,18 +143,20 @@ _digest_exit:
char *http_auth_basic(const char *username, const char *password)
{
int out;
size_t out;
char *user_info = NULL;
char *digest = NULL;
esp_err_t ret = ESP_OK;
size_t n = 0;
asprintf(&user_info, "%s:%s", username, password);
if (asprintf(&user_info, "%s:%s", username, password) < 0) {
return NULL;
}
ESP_RETURN_ON_FALSE(user_info, NULL, TAG, "Memory exhausted");
esp_crypto_base64_encode(NULL, 0, &n, (const unsigned char *)user_info, strlen(user_info));
digest = calloc(1, 6 + n + 1);
ESP_GOTO_ON_FALSE(digest, ESP_FAIL, _basic_exit, TAG, "Memory exhausted");
strcpy(digest, "Basic ");
esp_crypto_base64_encode((unsigned char *)digest + 6, n, (size_t *)&out, (const unsigned char *)user_info, strlen(user_info));
esp_crypto_base64_encode((unsigned char *)digest + 6, n, &out, (const unsigned char *)user_info, strlen(user_info));
_basic_exit:
free(user_info);
return (ret == ESP_OK) ? digest : NULL;

View File

@@ -0,0 +1,20 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#if CONFIG_IDF_TARGET_LINUX
#define __containerof(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -1,11 +1,13 @@
idf_build_get_property(idf_target IDF_TARGET)
idf_build_get_property(python PYTHON)
if(NOT ${IDF_TARGET} STREQUAL "linux")
set(priv_requires soc esp_hw_support)
if(NOT BOOTLOADER_BUILD)
list(APPEND priv_requires esp_pm)
endif()
endif()
set(mbedtls_srcs "")
set(mbedtls_include_dirs "port/include" "mbedtls/include" "mbedtls/library")
@@ -120,6 +122,10 @@ set(mbedtls_target_sources ${mbedtls_target_sources}
"${COMPONENT_DIR}/port/dynamic/esp_ssl_tls.c")
endif()
if(${IDF_TARGET} STREQUAL "linux")
set(mbedtls_target_sources ${mbedtls_target_sources} "${COMPONENT_DIR}/port/net_sockets.c")
endif()
# net_sockets.c should only be compiled if BSD socket functions are available.
# Do this by checking if lwip component is included into the build.
idf_build_get_property(build_components BUILD_COMPONENTS)
@@ -180,7 +186,6 @@ endif()
target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_hardware.c"
"${COMPONENT_DIR}/port/esp_mem.c"
"${COMPONENT_DIR}/port/esp_timing.c"
"${COMPONENT_DIR}/port/sha/esp_sha.c"
)
if(CONFIG_SOC_AES_SUPPORTED)
@@ -191,7 +196,9 @@ if(CONFIG_SOC_AES_SUPPORTED)
endif()
if(CONFIG_SOC_SHA_SUPPORTED)
target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/sha.c")
target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/sha/esp_sha.c"
"${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/sha.c"
)
endif()
# CONFIG_ESP_TLS_USE_DS_PERIPHERAL can be enabled only for the supported targets.

View File

@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <esp_system.h>
#include <stdbool.h>
#include "esp_crt_bundle.h"
#include "esp_log.h"

View File

@@ -34,6 +34,8 @@
#include <stdio.h>
#include <time.h>
#include <stdint.h>
#include <fcntl.h>
#include <errno.h>
/*
* Prepare for using the sockets interface

View File

@@ -33,6 +33,7 @@ are tested as part of mbedTLS tests. Only esp_sha() is different.
#define TAG "sha_test"
#if SOC_SHA_SUPPORTED
TEST_CASE("Test esp_sha()", "[hw_crypto]")
{
const size_t BUFFER_SZ = 32 * 1024 + 6; // NB: not an exact multiple of SHA block size
@@ -136,3 +137,5 @@ TEST_CASE("Test esp_sha() function with long input", "[hw_crypto]")
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_espsha, sha512_mbedtls, sizeof(sha512_espsha), "SHA512 results should match");
#endif
}
#endif // SOC_SHA_SUPPORTED

View File

@@ -8,7 +8,12 @@ list(APPEND srcs
"transport_ws.c")
endif()
set(req esp-tls)
if(NOT ${IDF_TARGET} STREQUAL "linux")
list(APPEND req lwip)
endif()
idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "private_include"
REQUIRES esp-tls lwip)
REQUIRES ${req})

View File

@@ -6,6 +6,7 @@
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "esp_tls.h"
#include "esp_log.h"
@@ -13,6 +14,7 @@
#include "esp_transport.h"
#include "esp_transport_ssl.h"
#include "esp_transport_internal.h"
#include "errno.h"
#define INVALID_SOCKET (-1)

View File

@@ -6,6 +6,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/random.h>
#include <sys/socket.h>
@@ -16,6 +17,7 @@
#include "esp_transport_internal.h"
#include "errno.h"
#include "esp_tls_crypto.h"
#include <arpa/inet.h>
static const char *TAG = "transport_ws";
@@ -145,7 +147,11 @@ static int ws_connect(esp_transport_handle_t t, const char *host, int port, int
}
unsigned char random_key[16];
getrandom(random_key, sizeof(random_key), 0);
ssize_t rc;
if ((rc = getrandom(random_key, sizeof(random_key), 0)) < 0) {
ESP_LOGD(TAG, "getrandom() returned %zd", rc);
return -1;
}
// Size of base64 coded string is equal '((input_size * 4) / 3) + (input_size / 96) + 6' including Z-term
unsigned char client_key[28] = {0};
@@ -289,7 +295,11 @@ static int _ws_write(esp_transport_handle_t t, int opcode, int mask_flag, const
if (mask_flag) {
mask = &ws_header[header_len];
getrandom(ws_header + header_len, 4, 0);
ssize_t rc;
if ((rc = getrandom(ws_header + header_len, 4, 0)) < 0) {
ESP_LOGD(TAG, "getrandom() returned %zd", rc);
return -1;
}
header_len += 4;
for (i = 0; i < len; ++i) {

View File

@@ -2,9 +2,14 @@
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
if(${IDF_TARGET} STREQUAL "linux")
set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/freertos/"
"$ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs")
set(COMPONENTS main)
else()
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
endif()
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(esp_http_client_example)

View File

@@ -1,7 +1,12 @@
# Embed the server root certificate into the final binary
#
# (If this was a component, we would set COMPONENT_EMBED_TXTFILES here.)
set(requires "")
if(${IDF_TARGET} STREQUAL "linux")
list(APPEND requires esp_stubs esp-tls esp_http_client)
endif()
idf_component_register(SRCS "esp_http_client_example.c"
INCLUDE_DIRS "."
REQUIRES ${requires}
EMBED_TXTFILES howsmyssl_com_root_cert.pem
postman_root_cert.pem)

View File

@@ -9,10 +9,7 @@
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "esp_netif.h"
@@ -22,6 +19,12 @@
#include "esp_crt_bundle.h"
#endif
#if !CONFIG_IDF_TARGET_LINUX
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#endif
#include "esp_http_client.h"
#define MAX_HTTP_RECV_BUFFER 512
@@ -144,7 +147,7 @@ static void http_rest_with_url(void)
// GET
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -160,7 +163,7 @@ static void http_rest_with_url(void)
esp_http_client_set_post_field(client, post_data, strlen(post_data));
err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -172,7 +175,7 @@ static void http_rest_with_url(void)
esp_http_client_set_method(client, HTTP_METHOD_PUT);
err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP PUT Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP PUT Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -185,7 +188,7 @@ static void http_rest_with_url(void)
esp_http_client_set_post_field(client, NULL, 0);
err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP PATCH Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP PATCH Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -197,7 +200,7 @@ static void http_rest_with_url(void)
esp_http_client_set_method(client, HTTP_METHOD_DELETE);
err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP DELETE Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP DELETE Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -209,7 +212,7 @@ static void http_rest_with_url(void)
esp_http_client_set_method(client, HTTP_METHOD_HEAD);
err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP HEAD Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP HEAD Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -232,7 +235,7 @@ static void http_rest_with_hostname_path(void)
// GET
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -246,7 +249,7 @@ static void http_rest_with_hostname_path(void)
esp_http_client_set_post_field(client, post_data, strlen(post_data));
err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -258,7 +261,7 @@ static void http_rest_with_hostname_path(void)
esp_http_client_set_method(client, HTTP_METHOD_PUT);
err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP PUT Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP PUT Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -271,7 +274,7 @@ static void http_rest_with_hostname_path(void)
esp_http_client_set_post_field(client, NULL, 0);
err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP PATCH Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP PATCH Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -283,7 +286,7 @@ static void http_rest_with_hostname_path(void)
esp_http_client_set_method(client, HTTP_METHOD_DELETE);
err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP DELETE Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP DELETE Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -295,7 +298,7 @@ static void http_rest_with_hostname_path(void)
esp_http_client_set_method(client, HTTP_METHOD_HEAD);
err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP HEAD Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP HEAD Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -325,7 +328,7 @@ static void http_auth_basic(void)
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP Basic Auth Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP Basic Auth Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -344,7 +347,7 @@ static void http_auth_basic_redirect(void)
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP Basic Auth redirect Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP Basic Auth redirect Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -365,7 +368,7 @@ static void http_auth_digest(void)
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP Digest Auth Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP Digest Auth Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -387,7 +390,7 @@ static void https_with_url(void)
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -410,7 +413,7 @@ static void https_with_hostname_path(void)
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -429,7 +432,7 @@ static void http_relative_redirect(void)
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP Relative path redirect Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP Relative path redirect Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -448,7 +451,7 @@ static void http_absolute_redirect(void)
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP Absolute path redirect Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP Absolute path redirect Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -468,7 +471,7 @@ static void http_absolute_redirect_manual(void)
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP Absolute path redirect (manual) Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP Absolute path redirect (manual) Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -488,7 +491,7 @@ static void http_redirect_to_https(void)
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP redirect to HTTPS Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP redirect to HTTPS Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -508,7 +511,7 @@ static void http_download_chunk(void)
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP chunk encoding Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP chunk encoding Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -544,7 +547,7 @@ static void http_perform_as_stream_reader(void)
buffer[read_len] = 0;
ESP_LOGD(TAG, "read_len = %d", read_len);
}
ESP_LOGI(TAG, "HTTP Stream reader Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP Stream reader Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
esp_http_client_close(client);
@@ -576,7 +579,7 @@ static void https_async(void)
}
}
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -595,7 +598,7 @@ static void https_with_invalid_url(void)
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -631,7 +634,7 @@ static void http_native_request(void)
} else {
int data_read = esp_http_client_read_response(client, output_buffer, MAX_HTTP_OUTPUT_BUFFER);
if (data_read >= 0) {
ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
ESP_LOG_BUFFER_HEX(TAG, output_buffer, data_read);
@@ -661,7 +664,7 @@ static void http_native_request(void)
} else {
int data_read = esp_http_client_read_response(client, output_buffer, MAX_HTTP_OUTPUT_BUFFER);
if (data_read >= 0) {
ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
ESP_LOG_BUFFER_HEX(TAG, output_buffer, strlen(output_buffer));
@@ -687,7 +690,7 @@ static void http_partial_download(void)
esp_http_client_set_header(client, "Range", "bytes=10-");
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -698,7 +701,7 @@ static void http_partial_download(void)
esp_http_client_set_header(client, "Range", "bytes=-10");
err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -709,7 +712,7 @@ static void http_partial_download(void)
esp_http_client_set_header(client, "Range", "bytes=11-20");
err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP Status = %d, content_length = %lld",
ESP_LOGI(TAG, "HTTP Status = %d, content_length = %"PRIu64,
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
@@ -749,7 +752,9 @@ static void http_test_task(void *pvParameters)
#endif
ESP_LOGI(TAG, "Finish http example");
#if !CONFIG_IDF_TARGET_LINUX
vTaskDelete(NULL);
#endif
}
void app_main(void)
@@ -760,6 +765,7 @@ void app_main(void)
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
@@ -770,5 +776,9 @@ void app_main(void)
ESP_ERROR_CHECK(example_connect());
ESP_LOGI(TAG, "Connected to AP, begin http example");
#if CONFIG_IDF_TARGET_LINUX
http_test_task(NULL);
#else
xTaskCreate(&http_test_task, "http_test_task", 8192, NULL, 5, NULL);
#endif
}

View File

@@ -0,0 +1,2 @@
idf_component_register(SRCS esp_stubs.c
INCLUDE_DIRS "include")

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -29,6 +29,11 @@ esp_err_t nvs_flash_init(void)
return ESP_OK;
}
esp_err_t nvs_flash_erase(void)
{
return ESP_OK;
}
int main()
{
app_main();

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/

View File

@@ -0,0 +1,14 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "esp_err.h"
#define ESP_ERR_NVS_BASE 0x1100 /*!< Starting number of error codes */
#define ESP_ERR_NVS_NO_FREE_PAGES (ESP_ERR_NVS_BASE + 0x0d) /*!< NVS partition doesn't contain any empty pages. This may happen if NVS partition was truncated. Erase the whole partition and call nvs_flash_init again. */
#define ESP_ERR_NVS_NEW_VERSION_FOUND (ESP_ERR_NVS_BASE + 0x10) /*!< NVS partition contains data in new format and cannot be recognized by this version of code */
esp_err_t nvs_flash_init(void);
esp_err_t nvs_flash_erase(void);

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/

View File

@@ -3,7 +3,8 @@
cmake_minimum_required(VERSION 3.16)
if(${IDF_TARGET} STREQUAL "linux")
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/freertos/")
set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/freertos/"
"$ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs")
set(COMPONENTS main)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
else()

View File

@@ -1,6 +0,0 @@
if(${IDF_TARGET} STREQUAL "linux")
idf_component_register(SRCS
esp_stubs/esp_stubs.c
INCLUDE_DIRS . include/stubs
REQUIRES main)
endif()

View File

@@ -1,8 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "esp_err.h"
esp_err_t nvs_flash_init(void);