mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/support_transport_keepalive_v3.3' into 'release/v3.3'
Feature/support transport keepalive v3.3 [backport v3.3] See merge request espressif/esp-idf!12154
This commit is contained in:
commit
c3678c5378
@ -82,6 +82,34 @@ static void ms_to_timeval(int timeout_ms, struct timeval *tv)
|
||||
tv->tv_usec = (timeout_ms % 1000) * 1000;
|
||||
}
|
||||
|
||||
static int esp_tls_tcp_enable_keep_alive(int fd, tls_keep_alive_cfg_t *cfg)
|
||||
{
|
||||
int keep_alive_enable = 1;
|
||||
int keep_alive_idle = cfg->keep_alive_idle;
|
||||
int keep_alive_interval = cfg->keep_alive_interval;
|
||||
int keep_alive_count = cfg->keep_alive_count;
|
||||
|
||||
ESP_LOGD(TAG, "Enable TCP keep alive. idle: %d, interval: %d, count: %d", keep_alive_idle, keep_alive_interval, keep_alive_count);
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keep_alive_enable, sizeof(keep_alive_enable)) != 0) {
|
||||
ESP_LOGE(TAG, "Fail to setsockopt SO_KEEPALIVE");
|
||||
return -1;
|
||||
}
|
||||
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &keep_alive_idle, sizeof(keep_alive_idle)) != 0) {
|
||||
ESP_LOGE(TAG, "Fail to setsockopt TCP_KEEPIDLE");
|
||||
return -1;
|
||||
}
|
||||
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &keep_alive_interval, sizeof(keep_alive_interval)) != 0) {
|
||||
ESP_LOGE(TAG, "Fail to setsockopt TCP_KEEPINTVL");
|
||||
return -1;
|
||||
}
|
||||
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &keep_alive_count, sizeof(keep_alive_count)) != 0) {
|
||||
ESP_LOGE(TAG, "Fail to setsockopt TCP_KEEPCNT");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int esp_tcp_connect(const char *host, int hostlen, int port, int *sockfd, const esp_tls_cfg_t *cfg)
|
||||
{
|
||||
int ret = -1;
|
||||
@ -117,6 +145,12 @@ static int esp_tcp_connect(const char *host, int hostlen, int port, int *sockfd,
|
||||
ms_to_timeval(cfg->timeout_ms, &tv);
|
||||
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
||||
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
|
||||
if (cfg->keep_alive_cfg && cfg->keep_alive_cfg->keep_alive_enable) {
|
||||
if (esp_tls_tcp_enable_keep_alive(fd, cfg->keep_alive_cfg) < 0) {
|
||||
ESP_LOGE(TAG, "Error setting keep-alive");
|
||||
goto err_freesocket;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cfg->non_block) {
|
||||
int flags = fcntl(fd, F_GETFL, 0);
|
||||
|
@ -43,6 +43,16 @@ typedef enum esp_tls_conn_state {
|
||||
ESP_TLS_DONE,
|
||||
} esp_tls_conn_state_t;
|
||||
|
||||
/**
|
||||
* @brief Keep alive parameters structure
|
||||
*/
|
||||
typedef struct tls_keep_alive_cfg {
|
||||
bool keep_alive_enable; /*!< Enable keep-alive timeout */
|
||||
int keep_alive_idle; /*!< Keep-alive idle time (second) */
|
||||
int keep_alive_interval; /*!< Keep-alive interval time (second) */
|
||||
int keep_alive_count; /*!< Keep-alive packet retry send count */
|
||||
} tls_keep_alive_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief ESP-TLS configuration parameters
|
||||
*/
|
||||
@ -93,6 +103,8 @@ typedef struct esp_tls_cfg {
|
||||
If NULL, server certificate CN must match hostname. */
|
||||
|
||||
bool skip_common_name; /*!< Skip any validation of server certificate CN field */
|
||||
|
||||
tls_keep_alive_cfg_t *keep_alive_cfg; /*!< Enable TCP keep-alive timeout for SSL connection */
|
||||
} esp_tls_cfg_t;
|
||||
|
||||
/**
|
||||
|
@ -118,6 +118,7 @@ struct esp_http_client {
|
||||
bool first_line_prepared;
|
||||
int header_index;
|
||||
bool is_async;
|
||||
esp_transport_keep_alive_t keep_alive_cfg;
|
||||
};
|
||||
|
||||
typedef struct esp_http_client esp_http_client_t;
|
||||
@ -138,6 +139,9 @@ static const char *DEFAULT_HTTP_PROTOCOL = "HTTP/1.1";
|
||||
static const char *DEFAULT_HTTP_PATH = "/";
|
||||
static int DEFAULT_MAX_REDIRECT = 10;
|
||||
static int DEFAULT_TIMEOUT_MS = 5000;
|
||||
static const int DEFAULT_KEEP_ALIVE_IDLE = 5;
|
||||
static const int DEFAULT_KEEP_ALIVE_INTERVAL= 5;
|
||||
static const int DEFAULT_KEEP_ALIVE_COUNT= 3;
|
||||
|
||||
static const char *HTTP_METHOD_MAPPING[] = {
|
||||
"GET",
|
||||
@ -480,7 +484,7 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co
|
||||
{
|
||||
|
||||
esp_http_client_handle_t client;
|
||||
esp_transport_handle_t tcp;
|
||||
esp_transport_handle_t tcp = NULL;
|
||||
bool _success;
|
||||
|
||||
_success = (
|
||||
@ -511,8 +515,15 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co
|
||||
ESP_LOGE(TAG, "Error initialize transport");
|
||||
goto error;
|
||||
}
|
||||
if (config->keep_alive_enable == true) {
|
||||
client->keep_alive_cfg.keep_alive_enable = true;
|
||||
client->keep_alive_cfg.keep_alive_idle = (config->keep_alive_idle == 0) ? DEFAULT_KEEP_ALIVE_IDLE : config->keep_alive_idle;
|
||||
client->keep_alive_cfg.keep_alive_interval = (config->keep_alive_interval == 0) ? DEFAULT_KEEP_ALIVE_INTERVAL : config->keep_alive_interval;
|
||||
client->keep_alive_cfg.keep_alive_count = (config->keep_alive_count == 0) ? DEFAULT_KEEP_ALIVE_COUNT : config->keep_alive_count;
|
||||
esp_transport_tcp_set_keep_alive(tcp, &client->keep_alive_cfg);
|
||||
}
|
||||
#ifdef CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS
|
||||
esp_transport_handle_t ssl;
|
||||
esp_transport_handle_t ssl = NULL;
|
||||
_success = (
|
||||
(ssl = esp_transport_ssl_init()) &&
|
||||
(esp_transport_set_default_port(ssl, DEFAULT_HTTPS_PORT) == ESP_OK) &&
|
||||
@ -541,6 +552,10 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co
|
||||
if (config->skip_cert_common_name_check) {
|
||||
esp_transport_ssl_skip_common_name_check(ssl);
|
||||
}
|
||||
|
||||
if (config->keep_alive_enable == true) {
|
||||
esp_transport_ssl_set_keep_alive(ssl, &client->keep_alive_cfg);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_set_config(client, config) != ESP_OK) {
|
||||
|
@ -120,6 +120,10 @@ typedef struct {
|
||||
bool is_async; /*!< Set asynchronous mode, only supported with HTTPS for now */
|
||||
bool use_global_ca_store; /*!< Use a global ca_store for all the connections in which this bool is set. */
|
||||
bool skip_cert_common_name_check; /*!< Skip any validation of server certificate CN field */
|
||||
bool keep_alive_enable; /*!< Enable keep-alive timeout */
|
||||
int keep_alive_idle; /*!< Keep-alive idle time. Default is 5 (second) */
|
||||
int keep_alive_interval; /*!< Keep-alive interval time. Default is 5 (second) */
|
||||
int keep_alive_count; /*!< Keep-alive packet retry send count. Default is 3 counts */
|
||||
} esp_http_client_config_t;
|
||||
|
||||
/**
|
||||
|
@ -39,6 +39,9 @@ static const char *TAG = "WEBSOCKET_CLIENT";
|
||||
#define WEBSOCKET_NETWORK_TIMEOUT_MS (10*1000)
|
||||
#define WEBSOCKET_PING_TIMEOUT_MS (10*1000)
|
||||
#define WEBSOCKET_EVENT_QUEUE_SIZE (1)
|
||||
#define WEBSOCKET_KEEP_ALIVE_IDLE (5)
|
||||
#define WEBSOCKET_KEEP_ALIVE_INTERVAL (5)
|
||||
#define WEBSOCKET_KEEP_ALIVE_COUNT (3)
|
||||
|
||||
#define ESP_WS_CLIENT_MEM_CHECK(TAG, a, action) if (!(a)) { \
|
||||
ESP_LOGE(TAG,"%s:%d (%s): %s", __FILE__, __LINE__, __FUNCTION__, "Memory exhausted"); \
|
||||
@ -104,6 +107,7 @@ struct esp_websocket_client {
|
||||
ws_transport_opcodes_t last_opcode;
|
||||
int payload_len;
|
||||
int payload_offset;
|
||||
esp_transport_keep_alive_t keep_alive_cfg;
|
||||
};
|
||||
|
||||
static uint64_t _tick_get_ms(void)
|
||||
@ -280,6 +284,13 @@ esp_websocket_client_handle_t esp_websocket_client_init(const esp_websocket_clie
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (config->keep_alive_enable == true) {
|
||||
client->keep_alive_cfg.keep_alive_enable = true;
|
||||
client->keep_alive_cfg.keep_alive_idle = (config->keep_alive_idle == 0) ? WEBSOCKET_KEEP_ALIVE_IDLE : config->keep_alive_idle;
|
||||
client->keep_alive_cfg.keep_alive_interval = (config->keep_alive_interval == 0) ? WEBSOCKET_KEEP_ALIVE_INTERVAL : config->keep_alive_interval;
|
||||
client->keep_alive_cfg.keep_alive_count = (config->keep_alive_count == 0) ? WEBSOCKET_KEEP_ALIVE_COUNT : config->keep_alive_count;
|
||||
}
|
||||
|
||||
client->lock = xSemaphoreCreateRecursiveMutex();
|
||||
ESP_WS_CLIENT_MEM_CHECK(TAG, client->lock, goto _websocket_init_fail);
|
||||
|
||||
@ -293,6 +304,7 @@ esp_websocket_client_handle_t esp_websocket_client_init(const esp_websocket_clie
|
||||
ESP_WS_CLIENT_MEM_CHECK(TAG, tcp, goto _websocket_init_fail);
|
||||
|
||||
esp_transport_set_default_port(tcp, WEBSOCKET_TCP_DEFAULT_PORT);
|
||||
esp_transport_tcp_set_keep_alive(tcp, &client->keep_alive_cfg);
|
||||
esp_transport_list_add(client->transport_list, tcp, "_tcp"); // need to save to transport list, for cleanup
|
||||
|
||||
|
||||
@ -313,6 +325,7 @@ esp_websocket_client_handle_t esp_websocket_client_init(const esp_websocket_clie
|
||||
if (config->cert_pem) {
|
||||
esp_transport_ssl_set_cert_data(ssl, config->cert_pem, strlen(config->cert_pem));
|
||||
}
|
||||
esp_transport_ssl_set_keep_alive(ssl, &client->keep_alive_cfg);
|
||||
esp_transport_list_add(client->transport_list, ssl, "_ssl"); // need to save to transport list, for cleanup
|
||||
|
||||
esp_transport_handle_t wss = esp_transport_ws_init(ssl);
|
||||
|
@ -86,6 +86,10 @@ typedef struct {
|
||||
char *user_agent; /*!< Websocket user-agent */
|
||||
char *headers; /*!< Websocket additional headers */
|
||||
int pingpong_timeout_sec; /*!< Period before connection is aborted due to no PONGs received, disabled if value is 0 */
|
||||
bool keep_alive_enable; /*!< Enable keep-alive timeout */
|
||||
int keep_alive_idle; /*!< Keep-alive idle time. Default is 5 (second) */
|
||||
int keep_alive_interval; /*!< Keep-alive interval time. Default is 5 (second) */
|
||||
int keep_alive_count; /*!< Keep-alive packet retry send count. Default is 3 counts */
|
||||
} esp_websocket_client_config_t;
|
||||
|
||||
/**
|
||||
|
@ -16,11 +16,21 @@
|
||||
#define _ESP_TRANSPORT_H_
|
||||
|
||||
#include <esp_err.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Keep alive parameters structure
|
||||
*/
|
||||
typedef struct esp_transport_keepalive {
|
||||
bool keep_alive_enable; /*!< Enable keep-alive timeout */
|
||||
int keep_alive_idle; /*!< Keep-alive idle time (second) */
|
||||
int keep_alive_interval; /*!< Keep-alive interval time (second) */
|
||||
int keep_alive_count; /*!< Keep-alive packet retry send count */
|
||||
} esp_transport_keep_alive_t;
|
||||
|
||||
typedef struct esp_transport_list_t* esp_transport_list_handle_t;
|
||||
typedef struct esp_transport_item_t* esp_transport_handle_t;
|
||||
@ -298,6 +308,22 @@ esp_err_t esp_transport_set_async_connect_func(esp_transport_handle_t t, connect
|
||||
*/
|
||||
esp_err_t esp_transport_set_parent_transport_func(esp_transport_handle_t t, payload_transfer_func _parent_transport);
|
||||
|
||||
/**
|
||||
* @brief Set keep-alive configuration
|
||||
*
|
||||
* @param[in] t The transport handle
|
||||
* @param[in] keep_alive_cfg The keep-alive config
|
||||
*/
|
||||
void esp_transport_set_keep_alive(esp_transport_handle_t t, esp_transport_keep_alive_t *keep_alive_cfg);
|
||||
|
||||
/**
|
||||
* @brief Get keep-alive config of this transport
|
||||
*
|
||||
* @param[in] t The transport handle
|
||||
*
|
||||
* @return The keep-alive configuration
|
||||
*/
|
||||
void *esp_transport_get_keep_alive(esp_transport_handle_t t);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -78,6 +78,14 @@ void esp_transport_ssl_set_client_key_data(esp_transport_handle_t t, const char
|
||||
*/
|
||||
void esp_transport_ssl_skip_common_name_check(esp_transport_handle_t t);
|
||||
|
||||
/**
|
||||
* @brief Set keep-alive status in current ssl context
|
||||
*
|
||||
* @param[in] t ssl transport
|
||||
* @param[in] keep_alive_cfg The handle for keep-alive configuration
|
||||
*/
|
||||
void esp_transport_ssl_set_keep_alive(esp_transport_handle_t t, esp_transport_keep_alive_t *keep_alive_cfg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -21,6 +21,14 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Set TCP keep-alive configuration
|
||||
*
|
||||
* @param[in] t The transport handle
|
||||
* @param[in] keep_alive_cfg The keep-alive config
|
||||
*/
|
||||
void esp_transport_tcp_set_keep_alive(esp_transport_handle_t t, esp_transport_keep_alive_t *keep_alive_cfg);
|
||||
|
||||
/**
|
||||
* @brief Create TCP transport, the transport handle must be release esp_transport_destroy callback
|
||||
*
|
||||
|
@ -42,7 +42,7 @@ struct esp_transport_item_t {
|
||||
trans_func _destroy; /*!< Destroy and free transport */
|
||||
connect_async_func _connect_async; /*!< non-blocking connect function of this transport */
|
||||
payload_transfer_func _parent_transfer; /*!< Function returning underlying transport layer */
|
||||
|
||||
esp_transport_keep_alive_t *keep_alive_cfg; /*!< TCP keep-alive config */
|
||||
STAILQ_ENTRY(esp_transport_item_t) next;
|
||||
};
|
||||
|
||||
@ -277,3 +277,18 @@ esp_err_t esp_transport_set_parent_transport_func(esp_transport_handle_t t, payl
|
||||
t->_parent_transfer = _parent_transport;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void esp_transport_set_keep_alive(esp_transport_handle_t t, esp_transport_keep_alive_t *keep_alive_cfg)
|
||||
{
|
||||
if (t && keep_alive_cfg) {
|
||||
t->keep_alive_cfg = keep_alive_cfg;
|
||||
}
|
||||
}
|
||||
|
||||
void *esp_transport_get_keep_alive(esp_transport_handle_t t)
|
||||
{
|
||||
if (t) {
|
||||
return t->keep_alive_cfg;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -227,6 +227,14 @@ void esp_transport_ssl_skip_common_name_check(esp_transport_handle_t t)
|
||||
}
|
||||
}
|
||||
|
||||
void esp_transport_ssl_set_keep_alive(esp_transport_handle_t t, esp_transport_keep_alive_t *keep_alive_cfg)
|
||||
{
|
||||
transport_ssl_t *ssl = esp_transport_get_context_data(t);
|
||||
if (t && ssl) {
|
||||
ssl->cfg.keep_alive_cfg = (tls_keep_alive_cfg_t *)keep_alive_cfg;
|
||||
}
|
||||
}
|
||||
|
||||
esp_transport_handle_t esp_transport_ssl_init()
|
||||
{
|
||||
esp_transport_handle_t t = esp_transport_init();
|
||||
|
@ -51,11 +51,40 @@ static int resolve_dns(const char *host, struct sockaddr_in *ip) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static int tcp_enable_keep_alive(int fd, esp_transport_keep_alive_t *keep_alive_cfg)
|
||||
{
|
||||
int keep_alive_enable = 1;
|
||||
int keep_alive_idle = keep_alive_cfg->keep_alive_idle;
|
||||
int keep_alive_interval = keep_alive_cfg->keep_alive_interval;
|
||||
int keep_alive_count = keep_alive_cfg->keep_alive_count;
|
||||
|
||||
ESP_LOGD(TAG, "Enable TCP keep alive. idle: %d, interval: %d, count: %d", keep_alive_idle, keep_alive_interval, keep_alive_count);
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keep_alive_enable, sizeof(keep_alive_enable)) != 0) {
|
||||
ESP_LOGE(TAG, "Fail to setsockopt SO_KEEPALIVE");
|
||||
return -1;
|
||||
}
|
||||
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &keep_alive_idle, sizeof(keep_alive_idle)) != 0) {
|
||||
ESP_LOGE(TAG, "Fail to setsockopt TCP_KEEPIDLE");
|
||||
return -1;
|
||||
}
|
||||
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &keep_alive_interval, sizeof(keep_alive_interval)) != 0) {
|
||||
ESP_LOGE(TAG, "Fail to setsockopt TCP_KEEPINTVL");
|
||||
return -1;
|
||||
}
|
||||
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &keep_alive_count, sizeof(keep_alive_count)) != 0) {
|
||||
ESP_LOGE(TAG, "Fail to setsockopt TCP_KEEPCNT");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tcp_connect(esp_transport_handle_t t, const char *host, int port, int timeout_ms)
|
||||
{
|
||||
struct sockaddr_in remote_ip;
|
||||
struct timeval tv;
|
||||
transport_tcp_t *tcp = esp_transport_get_context_data(t);
|
||||
esp_transport_keep_alive_t *keep_alive_cfg = esp_transport_get_keep_alive(t);
|
||||
|
||||
bzero(&remote_ip, sizeof(struct sockaddr_in));
|
||||
|
||||
@ -80,7 +109,15 @@ static int tcp_connect(esp_transport_handle_t t, const char *host, int port, int
|
||||
|
||||
setsockopt(tcp->sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
||||
setsockopt(tcp->sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
|
||||
|
||||
// Set socket keep-alive option
|
||||
if (keep_alive_cfg && keep_alive_cfg->keep_alive_enable) {
|
||||
if (tcp_enable_keep_alive(tcp->sock, keep_alive_cfg) < 0) {
|
||||
ESP_LOGE(TAG, "Error to set tcp [socket=%d] keep-alive", tcp->sock);
|
||||
close(tcp->sock);
|
||||
tcp->sock = -1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ESP_LOGD(TAG, "[sock=%d],connecting to server IP:%s,Port:%d...",
|
||||
tcp->sock, ipaddr_ntoa((const ip_addr_t*)&remote_ip.sin_addr.s_addr), port);
|
||||
if (connect(tcp->sock, (struct sockaddr *)(&remote_ip), sizeof(struct sockaddr)) != 0) {
|
||||
@ -180,6 +217,11 @@ static esp_err_t tcp_destroy(esp_transport_handle_t t)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void esp_transport_tcp_set_keep_alive(esp_transport_handle_t t, esp_transport_keep_alive_t *keep_alive_cfg)
|
||||
{
|
||||
esp_transport_set_keep_alive(t, keep_alive_cfg);
|
||||
}
|
||||
|
||||
esp_transport_handle_t esp_transport_tcp_init()
|
||||
{
|
||||
esp_transport_handle_t t = esp_transport_init();
|
||||
|
@ -138,6 +138,7 @@ void advanced_ota_example_task(void * pvParameter)
|
||||
.url = CONFIG_FIRMWARE_UPGRADE_URL,
|
||||
.cert_pem = (char *)server_cert_pem_start,
|
||||
.timeout_ms = CONFIG_EXAMPLE_OTA_RECV_TIMEOUT,
|
||||
.keep_alive_enable = true,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL_FROM_STDIN
|
||||
|
@ -182,6 +182,7 @@ static void ota_example_task(void *pvParameter)
|
||||
.url = EXAMPLE_SERVER_URL,
|
||||
.cert_pem = (char *)server_cert_pem_start,
|
||||
.timeout_ms = CONFIG_EXAMPLE_OTA_RECV_TIMEOUT,
|
||||
.keep_alive_enable = true,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL_FROM_STDIN
|
||||
|
@ -145,6 +145,7 @@ void simple_ota_example_task(void * pvParameter)
|
||||
.url = CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL,
|
||||
.cert_pem = (char *)server_cert_pem_start,
|
||||
.event_handler = _http_event_handler,
|
||||
.keep_alive_enable = true,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL_FROM_STDIN
|
||||
|
Loading…
Reference in New Issue
Block a user