forked from espressif/esp-idf
Compare commits
21 Commits
v6.0-beta1
...
fixes
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37cd2e2b48 | ||
| c6d093b1a1 | |||
| 688c818c2f | |||
| c9281dc1e3 | |||
| a4f4040ef0 | |||
| fdb3a300b3 | |||
| d0cba05798 | |||
| f34b2966d9 | |||
| 11769a9eb7 | |||
| c9dcfbace5 | |||
|
|
2d0af32c8f | ||
| 1c715e372a | |||
| b76c9b20de | |||
|
|
888952efaa | ||
| 86e4391bde | |||
| 6846f9846c | |||
| 55092b1409 | |||
| 0e63b97662 | |||
| cc60dc1410 | |||
| 74cf5f130a | |||
| c740d3179b |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -56,7 +56,8 @@
|
||||
|
||||
[submodule "components/mqtt/esp-mqtt"]
|
||||
path = components/mqtt/esp-mqtt
|
||||
url = ../../espressif/esp-mqtt.git
|
||||
# url = ../../espressif/esp-mqtt.git
|
||||
url = ../../0xFEEDC0DE64/esp-mqtt.git
|
||||
|
||||
[submodule "components/protobuf-c/protobuf-c"]
|
||||
path = components/protobuf-c/protobuf-c
|
||||
|
||||
@@ -333,7 +333,10 @@ endforeach()
|
||||
# Only run validation for the main project, not subprojects like bootloader
|
||||
idf_build_get_property(bootloader_build BOOTLOADER_BUILD)
|
||||
idf_build_get_property(esp_tee_build ESP_TEE_BUILD)
|
||||
if(NOT bootloader_build AND NOT esp_tee_build)
|
||||
if((NOT DEFINED ENV{ESP_IDF_DISABLE_COMPONENT_VALIDATION}
|
||||
OR "$ENV{ESP_IDF_DISABLE_COMPONENT_VALIDATION}" STREQUAL ""
|
||||
OR "$ENV{ESP_IDF_DISABLE_COMPONENT_VALIDATION}" STREQUAL "0")
|
||||
AND NOT bootloader_build AND NOT esp_tee_build)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/tools/cmake/component_validation.cmake")
|
||||
__component_validation_run_checks()
|
||||
endif()
|
||||
|
||||
@@ -717,7 +717,25 @@ static void load_image(const esp_image_metadata_t *image_data)
|
||||
*/
|
||||
ESP_LOGI(TAG, "Checking flash encryption...");
|
||||
bool flash_encryption_enabled = esp_flash_encrypt_state();
|
||||
if (!flash_encryption_enabled) {
|
||||
if (flash_encryption_enabled) {
|
||||
#if BOOTLOADER_BUILD
|
||||
/* Ensure security eFuses are burnt */
|
||||
esp_efuse_batch_write_begin();
|
||||
esp_err_t err = esp_flash_encryption_enable_secure_features();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error setting security eFuses (err=0x%x).", err);
|
||||
esp_efuse_batch_write_cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
err = esp_efuse_batch_write_commit();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error programming security eFuses (err=0x%x).", err);
|
||||
return;
|
||||
}
|
||||
ESP_LOGI(TAG, "Security eFuses are burnt");
|
||||
#endif // BOOTLOADER_BUILD
|
||||
} else {
|
||||
#ifdef CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED
|
||||
ESP_LOGE(TAG, "flash encryption is not enabled, and SECURE_FLASH_REQUIRE_ALREADY_ENABLED is set, refusing to boot.");
|
||||
return;
|
||||
|
||||
@@ -129,7 +129,7 @@ static ssize_t tcp_read(esp_tls_t *tls, char *data, size_t datalen)
|
||||
|
||||
static ssize_t tcp_write(esp_tls_t *tls, const char *data, size_t datalen)
|
||||
{
|
||||
return send(tls->sockfd, data, datalen, 0);
|
||||
return send(tls->sockfd, data, datalen, MSG_MORE);
|
||||
}
|
||||
|
||||
ssize_t esp_tls_conn_read(esp_tls_t *tls, void *data, size_t datalen)
|
||||
|
||||
@@ -297,6 +297,9 @@ typedef struct esp_tls_cfg_server {
|
||||
unsigned int cacert_pem_bytes; /*!< Size of client CA certificate legacy name */
|
||||
};
|
||||
|
||||
bool cacert_authmode_optional; /*!< Enable this option to set the authmode
|
||||
to OPTIONAL (only useful when cacert is set) */
|
||||
|
||||
union {
|
||||
const unsigned char *servercert_buf; /*!< Server certificate in a buffer
|
||||
This buffer should be NULL terminated */
|
||||
|
||||
@@ -757,6 +757,8 @@ static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls)
|
||||
if (esp_ret != ESP_OK) {
|
||||
return esp_ret;
|
||||
}
|
||||
if (cfg->cacert_authmode_optional)
|
||||
mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
|
||||
} else {
|
||||
#ifdef CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL
|
||||
mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
|
||||
|
||||
@@ -1314,6 +1314,51 @@ esp_err_t i2c_master_transmit_receive(i2c_master_dev_handle_t i2c_dev, const uin
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t i2c_master_multi_buffer_transmit_receive(i2c_master_dev_handle_t i2c_dev, i2c_master_transmit_multi_buffer_info_t *buffer_info_array, size_t array_size, uint8_t *read_buffer, size_t read_size, int xfer_timeout_ms)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(i2c_dev != NULL, ESP_ERR_INVALID_ARG, TAG, "i2c handle not initialized");
|
||||
ESP_RETURN_ON_FALSE(array_size <= (SOC_I2C_CMD_REG_NUM - 2 - 3), ESP_ERR_INVALID_ARG, TAG, "i2c command list cannot contain so many commands");
|
||||
ESP_RETURN_ON_FALSE(buffer_info_array != NULL, ESP_ERR_INVALID_ARG, TAG, "buffer info array is empty");
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
size_t op_index = 0;
|
||||
i2c_operation_t i2c_ops[SOC_I2C_CMD_REG_NUM] = {};
|
||||
i2c_ops[op_index++].hw_cmd.op_code = I2C_LL_CMD_RESTART;
|
||||
int i;
|
||||
for (i = 0; i < array_size; i++) {
|
||||
if (buffer_info_array[i].buffer_size == 0) {
|
||||
continue;
|
||||
}
|
||||
i2c_ops[op_index].hw_cmd.ack_en = i2c_dev->ack_check_disable ? false : true;
|
||||
i2c_ops[op_index].hw_cmd.op_code = I2C_LL_CMD_WRITE;
|
||||
i2c_ops[op_index].data = (uint8_t*)buffer_info_array[i].write_buffer;
|
||||
i2c_ops[op_index].total_bytes = buffer_info_array[i].buffer_size;
|
||||
i2c_ops[op_index].bytes_used = 0;
|
||||
op_index++;
|
||||
}
|
||||
|
||||
i2c_ops[op_index++].hw_cmd.op_code = I2C_LL_CMD_RESTART;
|
||||
|
||||
i2c_ops[op_index].hw_cmd.op_code = I2C_LL_CMD_READ;
|
||||
i2c_ops[op_index].hw_cmd.ack_val = I2C_ACK_VAL;
|
||||
i2c_ops[op_index].data = read_buffer;
|
||||
i2c_ops[op_index++].total_bytes = read_size - 1;
|
||||
|
||||
i2c_ops[op_index].hw_cmd.op_code = I2C_LL_CMD_READ;
|
||||
i2c_ops[op_index].hw_cmd.ack_val = I2C_NACK_VAL;
|
||||
i2c_ops[op_index].data = (read_buffer + read_size - 1);
|
||||
i2c_ops[op_index++].total_bytes = 1;
|
||||
|
||||
i2c_ops[op_index++].hw_cmd.op_code = I2C_LL_CMD_STOP;
|
||||
|
||||
if (i2c_dev->master_bus->async_trans == false) {
|
||||
ret = s_i2c_synchronous_transaction(i2c_dev, i2c_ops, op_index, xfer_timeout_ms);
|
||||
} else {
|
||||
ret = s_i2c_asynchronous_transaction(i2c_dev, i2c_ops, op_index, xfer_timeout_ms);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t i2c_master_receive(i2c_master_dev_handle_t i2c_dev, uint8_t *read_buffer, size_t read_size, int xfer_timeout_ms)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(i2c_dev != NULL, ESP_ERR_INVALID_ARG, TAG, "i2c handle not initialized");
|
||||
|
||||
@@ -214,6 +214,29 @@ esp_err_t i2c_master_multi_buffer_transmit(i2c_master_dev_handle_t i2c_dev, i2c_
|
||||
*/
|
||||
esp_err_t i2c_master_transmit_receive(i2c_master_dev_handle_t i2c_dev, const uint8_t *write_buffer, size_t write_size, uint8_t *read_buffer, size_t read_size, int xfer_timeout_ms);
|
||||
|
||||
/**
|
||||
* @brief Perform a multi-write-read transaction on the I2C bus.
|
||||
* This function transmits multiple buffers of data and then reads.
|
||||
* The transaction will be undergoing until it finishes or it reaches
|
||||
* the timeout provided.
|
||||
*
|
||||
* @note If a callback was registered with `i2c_master_register_event_callbacks`, the transaction will be asynchronous, and thus, this function will return directly, without blocking.
|
||||
* You will get finish information from callback. Besides, data buffer should always be completely prepared when callback is registered, otherwise, the data will get corrupt.
|
||||
*
|
||||
* @param[in] i2c_dev I2C master device handle that created by `i2c_master_bus_add_device`.
|
||||
* @param[in] buffer_info_array Pointer to buffer information array.
|
||||
* @param[in] array_size size of buffer information array.
|
||||
* @param[out] read_buffer Data bytes received from i2c bus.
|
||||
* @param[in] read_size Size, in bytes, of the read buffer.
|
||||
* @param[in] xfer_timeout_ms Wait timeout, in ms. Note: -1 means wait forever.
|
||||
* @return
|
||||
* - ESP_OK: I2C master transmit-receive success.
|
||||
* - ESP_ERR_INVALID_RESPONSE: I2C master transmit-receive receives NACK.
|
||||
* - ESP_ERR_INVALID_ARG: I2C master transmit parameter invalid.
|
||||
* - ESP_ERR_TIMEOUT: Operation timeout(larger than xfer_timeout_ms) because the bus is busy or hardware crash.
|
||||
*/
|
||||
esp_err_t i2c_master_multi_buffer_transmit_receive(i2c_master_dev_handle_t i2c_dev, i2c_master_transmit_multi_buffer_info_t *buffer_info_array, size_t array_size, uint8_t *read_buffer, size_t read_size, int xfer_timeout_ms);
|
||||
|
||||
/**
|
||||
* @brief Perform a read transaction on the I2C bus.
|
||||
* The transaction will be undergoing until it finishes or it reaches
|
||||
|
||||
@@ -407,6 +407,9 @@ int spi_get_freq_limit(bool gpio_is_used, int input_delay_ns);
|
||||
*/
|
||||
esp_err_t spi_bus_get_max_transaction_len(spi_host_device_t host_id, size_t *max_bytes);
|
||||
|
||||
intr_handle_t spi_bus_get_intr(spi_host_device_t host);
|
||||
void spi_dma_reset_start(spi_device_handle_t handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -726,6 +726,22 @@ static void SPI_MASTER_ISR_ATTR spi_bus_intr_disable(void *host)
|
||||
#define spi_dma_start(chan, addr) gdma_start(chan, (intptr_t)(addr))
|
||||
#endif
|
||||
|
||||
void SPI_MASTER_ISR_ATTR spi_dma_reset_start(spi_device_handle_t handle){
|
||||
spi_host_t *host = handle->host;
|
||||
spi_hal_context_t *hal = &(host->hal);
|
||||
|
||||
const spi_dma_ctx_t *dma_ctx = host->dma_ctx;
|
||||
|
||||
spi_dma_reset(dma_ctx->rx_dma_chan);
|
||||
spi_hal_hw_prepare_rx(hal->hw);
|
||||
spi_dma_start(dma_ctx->rx_dma_chan, dma_ctx->dmadesc_rx);
|
||||
|
||||
|
||||
spi_dma_reset(dma_ctx->tx_dma_chan);
|
||||
spi_hal_hw_prepare_tx(hal->hw);
|
||||
spi_dma_start(dma_ctx->tx_dma_chan, dma_ctx->dmadesc_tx);
|
||||
}
|
||||
|
||||
static void SPI_MASTER_ISR_ATTR s_spi_dma_prepare_data(spi_host_t *host, spi_hal_context_t *hal, const spi_hal_dev_config_t *dev, const spi_hal_trans_config_t *trans)
|
||||
{
|
||||
const spi_dma_ctx_t *dma_ctx = host->dma_ctx;
|
||||
@@ -1518,6 +1534,10 @@ esp_err_t spi_bus_get_max_transaction_len(spi_host_device_t host_id, size_t *max
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
intr_handle_t spi_bus_get_intr(spi_host_device_t host) {
|
||||
return bus_driver_ctx[host]->intr;
|
||||
}
|
||||
|
||||
#if SOC_SPI_SCT_SUPPORTED
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
|
||||
@@ -576,6 +576,7 @@ int uart_write_bytes_with_break(uart_port_t uart_num, const void* src, size_t si
|
||||
|
||||
/**
|
||||
* @brief UART read bytes from UART buffer
|
||||
* Blocks until the buffer to fill is filled completely or timeout is expired
|
||||
*
|
||||
* @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
|
||||
* @param buf pointer to the buffer.
|
||||
@@ -588,6 +589,21 @@ int uart_write_bytes_with_break(uart_port_t uart_num, const void* src, size_t si
|
||||
*/
|
||||
int uart_read_bytes(uart_port_t uart_num, void* buf, uint32_t length, TickType_t ticks_to_wait);
|
||||
|
||||
/**
|
||||
* @brief UART read bytes from UART buffer
|
||||
* Blocks until there is at least something to read (might be smaller than length!) or timeout is expired
|
||||
*
|
||||
* @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
|
||||
* @param buf pointer to the buffer.
|
||||
* @param length data length
|
||||
* @param ticks_to_wait sTimeout, count in RTOS ticks
|
||||
*
|
||||
* @return
|
||||
* - (-1) Error
|
||||
* - OTHERS (>=0) The number of bytes read from UART buffer
|
||||
*/
|
||||
int uart_read_some_bytes(uart_port_t uart_num, void* buf, uint32_t length, TickType_t ticks_to_wait);
|
||||
|
||||
/**
|
||||
* @brief Alias of uart_flush_input.
|
||||
* UART ring buffer flush. This will discard all data in the UART RX buffer.
|
||||
|
||||
@@ -1731,6 +1731,34 @@ int uart_read_bytes(uart_port_t uart_num, void *buf, uint32_t length, TickType_t
|
||||
return copy_len;
|
||||
}
|
||||
|
||||
int uart_read_some_bytes(uart_port_t uart_num, void *buf, uint32_t length, TickType_t ticks_to_wait)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), (-1), UART_TAG, "uart_num error");
|
||||
ESP_RETURN_ON_FALSE((buf), (-1), UART_TAG, "uart data null");
|
||||
ESP_RETURN_ON_FALSE((p_uart_obj[uart_num]), (-1), UART_TAG, "uart driver error");
|
||||
uint8_t *data = NULL;
|
||||
size_t size = 0;
|
||||
if (xSemaphoreTake(p_uart_obj[uart_num]->rx_mux, (TickType_t)ticks_to_wait) != pdTRUE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
data = (uint8_t *) xRingbufferReceiveUpTo(p_uart_obj[uart_num]->rx_ring_buf, &size, (TickType_t) ticks_to_wait, length);
|
||||
if (!data) {
|
||||
xSemaphoreGive(p_uart_obj[uart_num]->rx_mux);
|
||||
return 0;
|
||||
}
|
||||
memcpy((uint8_t *)buf, data, size);
|
||||
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
|
||||
p_uart_obj[uart_num]->rx_buffered_len -= size;
|
||||
uart_pattern_queue_update(uart_num, size);
|
||||
UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
|
||||
vRingbufferReturnItem(p_uart_obj[uart_num]->rx_ring_buf, data);
|
||||
uart_check_buf_full(uart_num);
|
||||
|
||||
xSemaphoreGive(p_uart_obj[uart_num]->rx_mux);
|
||||
return size;
|
||||
}
|
||||
|
||||
esp_err_t uart_get_buffered_data_len(uart_port_t uart_num, size_t *size)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error");
|
||||
|
||||
@@ -302,7 +302,8 @@ static int http_on_header_value(http_parser *parser, const char *at, size_t leng
|
||||
} else if (strcasecmp(client->current_header_key, "Transfer-Encoding") == 0
|
||||
&& memcmp(at, "chunked", length) == 0) {
|
||||
client->response->is_chunked = true;
|
||||
} else if (strcasecmp(client->current_header_key, "WWW-Authenticate") == 0) {
|
||||
} else if (strcasecmp(client->current_header_key, "WWW-Authenticate") == 0 ||
|
||||
strcasecmp(client->current_header_key, "X-WWW-Authenticate") == 0) {
|
||||
HTTP_RET_ON_FALSE_DBG(http_utils_append_string(&client->auth_header, at, length), -1, TAG, "Failed to append string");
|
||||
}
|
||||
HTTP_RET_ON_FALSE_DBG(http_utils_append_string(&client->current_header_value, at, length), -1, TAG, "Failed to append string");
|
||||
@@ -1421,7 +1422,7 @@ int esp_http_client_read(esp_http_client_handle_t client, char *buffer, int len)
|
||||
esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
|
||||
{
|
||||
esp_err_t err = ESP_FAIL;
|
||||
do {
|
||||
//do {
|
||||
if (client->process_again) {
|
||||
esp_http_client_prepare(client);
|
||||
}
|
||||
@@ -1561,7 +1562,9 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} while (client->process_again && err == ESP_OK);
|
||||
//} while (client->process_again && err == ESP_OK);
|
||||
if (client->process_again && err == ESP_OK)
|
||||
return ESP_ERR_HTTP_EAGAIN;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ int httpd_send(httpd_req_t *r, const char *buf, size_t buf_len)
|
||||
}
|
||||
|
||||
struct httpd_req_aux *ra = r->aux;
|
||||
int ret = ra->sd->send_fn(ra->sd->handle, ra->sd->fd, buf, buf_len, 0);
|
||||
int ret = ra->sd->send_fn(ra->sd->handle, ra->sd->fd, buf, buf_len, MSG_MORE);
|
||||
if (ret < 0) {
|
||||
ESP_LOGD(TAG, LOG_FMT("error in send_fn"));
|
||||
return ret;
|
||||
@@ -71,7 +71,7 @@ static esp_err_t httpd_send_all(httpd_req_t *r, const char *buf, size_t buf_len)
|
||||
int ret;
|
||||
|
||||
while (buf_len > 0) {
|
||||
ret = ra->sd->send_fn(ra->sd->handle, ra->sd->fd, buf, buf_len, 0);
|
||||
ret = ra->sd->send_fn(ra->sd->handle, ra->sd->fd, buf, buf_len, MSG_MORE);
|
||||
if (ret < 0) {
|
||||
ESP_LOGD(TAG, LOG_FMT("error in send_fn"));
|
||||
return ESP_FAIL;
|
||||
|
||||
@@ -303,10 +303,31 @@ esp_err_t httpd_uri(struct httpd_data *hd)
|
||||
|
||||
/* If URI with method not found, respond with error code */
|
||||
if (uri == NULL) {
|
||||
|
||||
switch (err) {
|
||||
case HTTPD_404_NOT_FOUND:
|
||||
ESP_LOGW(TAG, LOG_FMT("URI '%s' not found"), req->uri);
|
||||
{
|
||||
char ipstr[INET6_ADDRSTRLEN] = "UNKNOWN";
|
||||
|
||||
const int sockfd = httpd_req_to_sockfd(req);
|
||||
|
||||
if (sockfd < 0)
|
||||
ESP_LOGW(TAG, "httpd_req_to_sockfd() failed with %i", sockfd);
|
||||
else
|
||||
{
|
||||
struct sockaddr_in6 addr; // esp_http_server uses IPv6 addressing
|
||||
socklen_t addr_size = sizeof(addr);
|
||||
const int result = getpeername(sockfd, (struct sockaddr *)&addr, &addr_size);
|
||||
|
||||
if (result < 0)
|
||||
ESP_LOGW(TAG, "getpeername() failed with %i", result);
|
||||
else
|
||||
inet_ntop(AF_INET, &addr.sin6_addr.un.u32_addr[3], ipstr, sizeof(ipstr));
|
||||
}
|
||||
|
||||
ESP_LOGW(TAG, LOG_FMT("URI '%s' not found for %s"), req->uri, ipstr);
|
||||
return httpd_req_handle_err(req, HTTPD_404_NOT_FOUND);
|
||||
}
|
||||
case HTTPD_405_METHOD_NOT_ALLOWED:
|
||||
ESP_LOGW(TAG, LOG_FMT("Method '%d' not allowed for URI '%s'"),
|
||||
req->method, req->uri);
|
||||
|
||||
@@ -445,14 +445,14 @@ esp_err_t httpd_ws_send_frame_async(httpd_handle_t hd, int fd, httpd_ws_frame_t
|
||||
}
|
||||
|
||||
/* Send off header */
|
||||
if (sess->send_fn(hd, fd, (const char *)header_buf, tx_len, 0) < 0) {
|
||||
if (sess->send_fn(hd, fd, (const char *)header_buf, tx_len, MSG_MORE) < 0) {
|
||||
ESP_LOGW(TAG, LOG_FMT("Failed to send WS header"));
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
/* Send off payload */
|
||||
if(frame->len > 0 && frame->payload != NULL) {
|
||||
if (sess->send_fn(hd, fd, (const char *)frame->payload, frame->len, 0) < 0) {
|
||||
if (sess->send_fn(hd, fd, (const char *)frame->payload, frame->len, MSG_MORE) < 0) {
|
||||
ESP_LOGW(TAG, LOG_FMT("Failed to send WS payload"));
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
@@ -135,6 +135,13 @@ static esp_err_t _http_handle_response_code(esp_https_ota_t *https_ota_handle, i
|
||||
} else if (status_code >= HttpStatus_InternalError) {
|
||||
ESP_LOGE(TAG, "Server error (%d)", status_code);
|
||||
return ESP_FAIL;
|
||||
} else if (https_ota_handle->binary_file_len > 0
|
||||
#if CONFIG_ESP_HTTPS_OTA_ENABLE_PARTIAL_DOWNLOAD
|
||||
&& !https_ota_handle->partial_http_download
|
||||
#endif
|
||||
&& status_code != HttpStatus_PartialContent) {
|
||||
ESP_LOGE(TAG, "Requested range header ignored by server");
|
||||
return ESP_ERR_HTTP_RANGE_NOT_SATISFIABLE;
|
||||
}
|
||||
|
||||
char upgrade_data_buf[256];
|
||||
|
||||
@@ -91,6 +91,9 @@ struct httpd_ssl_config {
|
||||
/** CA certificate byte length */
|
||||
size_t cacert_len;
|
||||
|
||||
/** CA certificate verification optional */
|
||||
bool cacert_authmode_optional;
|
||||
|
||||
/** Private key */
|
||||
const uint8_t *prvtkey_pem;
|
||||
|
||||
|
||||
@@ -278,6 +278,7 @@ static esp_err_t create_secure_context(const struct httpd_ssl_config *config, ht
|
||||
cfg->userdata = config->ssl_userdata;
|
||||
cfg->alpn_protos = config->alpn_protos;
|
||||
cfg->tls_handshake_timeout_ms = config->tls_handshake_timeout_ms;
|
||||
cfg->cacert_authmode_optional = config->cacert_authmode_optional;
|
||||
|
||||
cfg->tls_version = config->tls_version;
|
||||
cfg->ciphersuites_list = config->ciphersuites_list;
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#ifndef _ESP_NETIF_PPP_H_
|
||||
#define _ESP_NETIF_PPP_H_
|
||||
|
||||
#include "esp_netif_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -72,7 +72,7 @@ typedef struct {
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*/
|
||||
esp_err_t esp_phy_set_ant_gpio(esp_phy_ant_gpio_config_t *config);
|
||||
esp_err_t esp_phy_set_ant_gpio(const esp_phy_ant_gpio_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Get current antenna GPIO configuration
|
||||
|
||||
@@ -177,7 +177,7 @@ static void phy_ant_set_gpio_output(uint32_t io_num)
|
||||
gpio_config(&io_conf);
|
||||
}
|
||||
|
||||
esp_err_t esp_phy_set_ant_gpio(esp_phy_ant_gpio_config_t *config)
|
||||
esp_err_t esp_phy_set_ant_gpio(const esp_phy_ant_gpio_config_t *config)
|
||||
{
|
||||
if (config == NULL) {
|
||||
ESP_LOGE(TAG, "Invalid configuration");
|
||||
|
||||
@@ -18,6 +18,9 @@ extern "C" {
|
||||
#include "esp_err.h"
|
||||
#include "esp_cpu.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
/*
|
||||
* @brief Structure used for backtracing
|
||||
*
|
||||
@@ -129,6 +132,8 @@ esp_err_t esp_backtrace_print(int depth);
|
||||
*/
|
||||
esp_err_t esp_backtrace_print_all_tasks(int depth);
|
||||
|
||||
esp_err_t esp_backtrace_print_task(TaskHandle_t pxTask, int depth, bool panic);
|
||||
|
||||
/**
|
||||
* @brief Set a watchpoint to break/panic when a certain memory range is accessed.
|
||||
* Superseded by esp_cpu_set_watchpoint in esp_cpu.h.
|
||||
|
||||
@@ -250,3 +250,70 @@ ipc_err:
|
||||
malloc_err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_backtrace_print_task(TaskHandle_t pxTask, int depth, bool panic)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
TaskSnapshot_t task_snapshot;
|
||||
cur_task_backtrace_ctrl_t ctrl = {0};
|
||||
|
||||
// Suspend the scheduler to prevent task switching
|
||||
vTaskSuspend(pxTask);
|
||||
|
||||
/*
|
||||
Initialize backtracing for this core:
|
||||
|
||||
- Flush current core's register windows back onto current task's stack using esp_backtrace_get_start()
|
||||
- Get starting frame for backtracing (starting frame is the caller of this function) using esp_backtrace_get_start()
|
||||
- Save the starting frame details into the control block
|
||||
*/
|
||||
BaseType_t core_id = xPortGetCoreID(); // Get core ID now that task switching is disabled
|
||||
ctrl.cur_tasks[core_id].task_hdl = xTaskGetCurrentTaskHandle();
|
||||
esp_backtrace_get_start(&ctrl.cur_tasks[core_id].starting_pc,
|
||||
&ctrl.cur_tasks[core_id].starting_sp,
|
||||
&ctrl.cur_tasks[core_id].next_pc);
|
||||
|
||||
vTaskGetSnapshot(pxTask, &task_snapshot);
|
||||
|
||||
// Print the backtrace of the task
|
||||
bool cur_running = false;
|
||||
TaskHandle_t task_hdl = (TaskHandle_t) task_snapshot.pxTCB;
|
||||
esp_backtrace_frame_t stk_frame = {0};
|
||||
|
||||
// Check if the task is one of the currently running tasks
|
||||
for (BaseType_t core_id = 0; core_id < configNUMBER_OF_CORES; core_id++) {
|
||||
if (task_hdl == ctrl.cur_tasks[core_id].task_hdl) {
|
||||
cur_running = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Initialize the starting backtrace frame of the task
|
||||
if (cur_running) {
|
||||
/*
|
||||
Setting the starting backtrace frame for currently running tasks is different. We cannot
|
||||
use the current frame of each running task as the starting frame (due to the possibility
|
||||
of the SP changing). Thus, each currently running task will have initialized their callers
|
||||
as the starting frame for backtracing, which is saved inside the
|
||||
cur_task_backtrace_ctrl_t block.
|
||||
*/
|
||||
stk_frame.pc = ctrl.cur_tasks[core_id].starting_pc;
|
||||
stk_frame.sp = ctrl.cur_tasks[core_id].starting_sp;
|
||||
stk_frame.next_pc = ctrl.cur_tasks[core_id].next_pc;
|
||||
} else {
|
||||
// Set the starting backtrace frame using the task's saved stack pointer
|
||||
XtExcFrame* exc_frame = (XtExcFrame*) task_snapshot.pxTopOfStack;
|
||||
stk_frame.pc = exc_frame->pc;
|
||||
stk_frame.sp = exc_frame->a1;
|
||||
stk_frame.next_pc = exc_frame->a0;
|
||||
}
|
||||
// Print backtrace
|
||||
esp_err_t bt_ret = esp_backtrace_print_from_frame(depth, &stk_frame, panic);
|
||||
if (bt_ret != ESP_OK) {
|
||||
ret = bt_ret;
|
||||
}
|
||||
|
||||
// Resume the scheduler to allow task switching again
|
||||
vTaskResume(pxTask);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -819,7 +819,10 @@ esp_err_t esp_task_wdt_print_triggered_tasks(task_wdt_msg_handler msg_handler, v
|
||||
msg_handler(opaque, name);
|
||||
msg_handler(opaque, cpu);
|
||||
}
|
||||
|
||||
esp_backtrace_print_task(entry->task_handle, 100, true);
|
||||
}
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ extern "C" {
|
||||
#include "core_dump_checksum.h"
|
||||
|
||||
#if CONFIG_ESP_COREDUMP_LOGS
|
||||
#define ESP_COREDUMP_LOG( level, format, ... ) if (LOG_LOCAL_LEVEL >= level) { esp_rom_printf((format), esp_log_early_timestamp(), (const char *)TAG, ##__VA_ARGS__); }
|
||||
#define ESP_COREDUMP_LOG( level, format, ... ) if (LOG_LOCAL_LEVEL >= level) { esp_rom_printf(format, esp_log_early_timestamp(), (const char *)TAG, ##__VA_ARGS__); }
|
||||
#else
|
||||
#define ESP_COREDUMP_LOG( level, format, ... ) // dummy define doing nothing
|
||||
#endif
|
||||
|
||||
@@ -11,8 +11,12 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/** @cond */
|
||||
|
||||
#define ESP_LOG_STRINGIFY2(x) #x
|
||||
#define ESP_LOG_STRINGIFY(x) ESP_LOG_STRINGIFY2(x)
|
||||
|
||||
// For backward compatibility (these macros are not used in the log v2).
|
||||
#define LOG_FORMAT(letter, format) LOG_COLOR_ ## letter #letter " (%" PRIu32 ") %s: " format LOG_RESET_COLOR "\n"
|
||||
#define LOG_FORMAT(letter, format) LOG_COLOR_ ## letter #letter " %s:" ESP_LOG_STRINGIFY(__LINE__) " (%" PRIu32 ") %s: " format LOG_RESET_COLOR "\n", (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__)
|
||||
#define _ESP_LOG_DRAM_LOG_FORMAT(letter, format) DRAM_STR(#letter " %s: " format "\n")
|
||||
#define LOG_SYSTEM_TIME_FORMAT(letter, format) LOG_COLOR_ ## letter #letter " (%s) %s: " format LOG_RESET_COLOR "\n"
|
||||
/** @endcond */
|
||||
|
||||
Submodule components/mqtt/esp-mqtt updated: 6af4446a48...0089418a77
@@ -11,7 +11,7 @@ extern "C" {
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct emac_ext_dev_s {
|
||||
typedef volatile struct emac_ext_dev_s {
|
||||
volatile union {
|
||||
struct {
|
||||
uint32_t div_num : 4;
|
||||
|
||||
@@ -17,6 +17,11 @@ extern "C" {
|
||||
// Features supported
|
||||
#define ESP_TRANSPORT_WS_STORE_RESPONSE_HEADERS 1
|
||||
|
||||
// this define will also be used for optimized websocket sends with the
|
||||
// optimized version to prepend the required space for the websocket
|
||||
// header
|
||||
#define MAX_WEBSOCKET_HEADER_SIZE 16
|
||||
|
||||
typedef enum ws_transport_opcodes {
|
||||
WS_TRANSPORT_OPCODES_CONT = 0x00,
|
||||
WS_TRANSPORT_OPCODES_TEXT = 0x01,
|
||||
@@ -174,6 +179,37 @@ esp_err_t esp_transport_ws_set_config(esp_transport_handle_t t, const esp_transp
|
||||
*/
|
||||
int esp_transport_ws_send_raw(esp_transport_handle_t t, ws_transport_opcodes_t opcode, const char *b, int len, int timeout_ms);
|
||||
|
||||
/**
|
||||
* @brief Sends websocket raw message with custom opcode and payload in a optimized way
|
||||
*
|
||||
* This method is similar to esp_transport_ws_send_raw(), but
|
||||
* it assumes, that the first MAX_WEBSOCKET_HEADER_SIZE bytes
|
||||
* of the buffer should not be sent and should rather be used
|
||||
* for the required websocket header itself. This is done to
|
||||
* have a single TCP packet for header and payload and to avoid
|
||||
* copying and allocating additional resources. The first
|
||||
* MAX_WEBSOCKET_HEADER_SIZE bytes should not be initialized in
|
||||
* any specific way, and the return value (length) will also
|
||||
* include the MAX_WEBSOCKET_HEADER_SIZE byte extra buffer.
|
||||
*
|
||||
* Note that generic esp_transport_write for ws handle sends
|
||||
* binary massages by default if size is > 0 and
|
||||
* ping message if message size is set to 0.
|
||||
* This API is provided to support explicit messages with arbitrary opcode,
|
||||
* should it be PING, PONG or TEXT message with arbitrary data.
|
||||
*
|
||||
* @param[in] t Websocket transport handle
|
||||
* @param[in] opcode ws operation code
|
||||
* @param[in] buffer The buffer
|
||||
* @param[in] len The length
|
||||
* @param[in] timeout_ms The timeout milliseconds (-1 indicates block forever)
|
||||
*
|
||||
* @return
|
||||
* - Number of bytes was written
|
||||
* - (-1) if there are any errors, should check errno
|
||||
*/
|
||||
int esp_transport_ws_send_raw_optimized(esp_transport_handle_t t, ws_transport_opcodes_t opcode, const char *b, int len, int timeout_ms);
|
||||
|
||||
/**
|
||||
* @brief Returns websocket fin flag for last received data
|
||||
*
|
||||
|
||||
@@ -249,7 +249,7 @@ static int tcp_write(esp_transport_handle_t t, const char *buffer, int len, int
|
||||
ESP_LOGW(TAG, "Poll timeout or error, errno=%s, fd=%d, timeout_ms=%d", strerror(errno), ssl->sockfd, timeout_ms);
|
||||
return poll;
|
||||
}
|
||||
int ret = send(ssl->sockfd, (const unsigned char *) buffer, len, 0);
|
||||
int ret = send(ssl->sockfd, (const unsigned char *) buffer, len, MSG_MORE);
|
||||
if (ret < 0) {
|
||||
ESP_LOGE(TAG, "tcp_write error, errno=%s", strerror(errno));
|
||||
esp_transport_capture_errno(t, errno);
|
||||
|
||||
@@ -469,6 +469,92 @@ static int _ws_write(esp_transport_handle_t t, int opcode, int mask_flag, const
|
||||
return ret;
|
||||
}
|
||||
|
||||
// This method is similar to _ws_write() but it assumes, that the first 16 bytes of the buffer should not be sent and
|
||||
// should rather be used for the required websocket header itself. This is done to have a single TCP packet for header
|
||||
// and payload and to avoid copying and allocating additional resources. The first 16 bytes should not be initialized
|
||||
// in any specific way, and the return value (length) will also include the 16 byte extra buffer.
|
||||
static int _ws_write_optimized(esp_transport_handle_t t, int opcode, int mask_flag, const char *b, int len, int timeout_ms)
|
||||
{
|
||||
assert(len >= MAX_WEBSOCKET_HEADER_SIZE);
|
||||
|
||||
transport_ws_t *ws = esp_transport_get_context_data(t);
|
||||
char *buffer = (char *)b;
|
||||
char *ws_header;
|
||||
// char *mask;
|
||||
int header_len = 0; //, i;
|
||||
|
||||
int poll_write;
|
||||
if ((poll_write = esp_transport_poll_write(ws->parent, timeout_ms)) <= 0) {
|
||||
ESP_LOGE(TAG, "Error transport_poll_write %i", poll_write);
|
||||
return poll_write;
|
||||
}
|
||||
|
||||
int len2 = len - MAX_WEBSOCKET_HEADER_SIZE;
|
||||
if (len2 <= 125) {
|
||||
ws_header = buffer+MAX_WEBSOCKET_HEADER_SIZE-2-4;
|
||||
ws_header[header_len++] = opcode;
|
||||
ws_header[header_len++] = (uint8_t)(len2 | mask_flag);
|
||||
} else if (len2 < 65536) {
|
||||
ws_header = buffer+MAX_WEBSOCKET_HEADER_SIZE-4-4;
|
||||
ws_header[header_len++] = opcode;
|
||||
ws_header[header_len++] = WS_SIZE16 | mask_flag;
|
||||
ws_header[header_len++] = (uint8_t)(len2 >> 8);
|
||||
ws_header[header_len++] = (uint8_t)(len2 & 0xFF);
|
||||
} else {
|
||||
ws_header = buffer+MAX_WEBSOCKET_HEADER_SIZE-10-4;
|
||||
ws_header[header_len++] = opcode;
|
||||
ws_header[header_len++] = WS_SIZE64 | mask_flag;
|
||||
/* Support maximum 4 bytes length */
|
||||
ws_header[header_len++] = 0; //(uint8_t)((len >> 56) & 0xFF);
|
||||
ws_header[header_len++] = 0; //(uint8_t)((len >> 48) & 0xFF);
|
||||
ws_header[header_len++] = 0; //(uint8_t)((len >> 40) & 0xFF);
|
||||
ws_header[header_len++] = 0; //(uint8_t)((len >> 32) & 0xFF);
|
||||
ws_header[header_len++] = (uint8_t)((len2 >> 24) & 0xFF);
|
||||
ws_header[header_len++] = (uint8_t)((len2 >> 16) & 0xFF);
|
||||
ws_header[header_len++] = (uint8_t)((len2 >> 8) & 0xFF);
|
||||
ws_header[header_len++] = (uint8_t)((len2 >> 0) & 0xFF);
|
||||
}
|
||||
|
||||
if (mask_flag) {
|
||||
ws_header[header_len++] = 0;
|
||||
ws_header[header_len++] = 0;
|
||||
ws_header[header_len++] = 0;
|
||||
ws_header[header_len++] = 0;
|
||||
// mask = &ws_header[header_len];
|
||||
// mask = 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 = MAX_WEBSOCKET_HEADER_SIZE; i < len; ++i) {
|
||||
// buffer[i] = (buffer[i] ^ mask[i % 4]);
|
||||
// }
|
||||
}
|
||||
|
||||
// if (esp_transport_write(ws->parent, ws_header, len - MAX_WEBSOCKET_HEADER_SIZE + header_len, timeout_ms) != header_len) {
|
||||
// ESP_LOGE(TAG, "Error write header");
|
||||
// return -1;
|
||||
// }
|
||||
// if (len == 0) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
int ret = esp_transport_write(ws->parent, ws_header, len - MAX_WEBSOCKET_HEADER_SIZE + header_len, timeout_ms);
|
||||
// ESP_LOGI(TAG, "len=%d header_len=%d total_size=%d sent=%d", len, header_len, len - MAX_WEBSOCKET_HEADER_SIZE + header_len, ret);
|
||||
// in case of masked transport we have to revert back to the original data, as ws layer
|
||||
// does not create its own copy of data to be sent
|
||||
if (mask_flag) {
|
||||
// mask = &ws_header[header_len - 4];
|
||||
// for (i = 0; i < len; ++i) {
|
||||
// buffer[i] = (buffer[i] ^ mask[i % 4]);
|
||||
// }
|
||||
}
|
||||
return ret + (ws_header - buffer);
|
||||
}
|
||||
|
||||
int esp_transport_ws_send_raw(esp_transport_handle_t t, ws_transport_opcodes_t opcode, const char *b, int len, int timeout_ms)
|
||||
{
|
||||
uint8_t op_code = ws_get_bin_opcode(opcode);
|
||||
@@ -480,6 +566,17 @@ int esp_transport_ws_send_raw(esp_transport_handle_t t, ws_transport_opcodes_t o
|
||||
return _ws_write(t, op_code, WS_MASK, b, len, timeout_ms);
|
||||
}
|
||||
|
||||
int esp_transport_ws_send_raw_optimized(esp_transport_handle_t t, ws_transport_opcodes_t opcode, const char *b, int len, int timeout_ms)
|
||||
{
|
||||
uint8_t op_code = ws_get_bin_opcode(opcode);
|
||||
if (t == NULL) {
|
||||
ESP_LOGE(TAG, "Transport must be a valid ws handle");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
ESP_LOGD(TAG, "Sending raw ws message with opcode %d", op_code);
|
||||
return _ws_write_optimized(t, op_code, WS_MASK, b, len, timeout_ms);
|
||||
}
|
||||
|
||||
static int ws_write(esp_transport_handle_t t, const char *b, int len, int timeout_ms)
|
||||
{
|
||||
if (len == 0) {
|
||||
|
||||
Reference in New Issue
Block a user