diff --git a/components/esp-tls/esp_tls.c b/components/esp-tls/esp_tls.c index 44b1b16710..33f3a0e1a0 100644 --- a/components/esp-tls/esp_tls.c +++ b/components/esp-tls/esp_tls.c @@ -32,6 +32,8 @@ static const char *TAG = "esp-tls"; #define ESP_LOGE(TAG, ...) printf(__VA_ARGS__); #endif +#define DEFAULT_TIMEOUT_MS -1 + static struct addrinfo *resolve_host_name(const char *host, size_t hostlen) { struct addrinfo hints; @@ -74,7 +76,13 @@ static ssize_t tls_read(esp_tls_t *tls, char *data, size_t datalen) return ret; } -static int esp_tcp_connect(const char *host, int hostlen, int port) +static void ms_to_timeval(int timeout_ms, struct timeval *tv) +{ + tv->tv_sec = timeout_ms / 1000; + tv->tv_usec = (timeout_ms % 1000) * 1000; +} + +static int esp_tcp_connect(const char *host, int hostlen, int port, int timeout_ms) { struct addrinfo *res = resolve_host_name(host, hostlen); if (!res) { @@ -103,6 +111,12 @@ static int esp_tcp_connect(const char *host, int hostlen, int port) goto err_freesocket; } + if (timeout_ms >= 0) { + struct timeval tv; + ms_to_timeval(timeout_ms, &tv); + setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + } + ret = connect(fd, addr_ptr, res->ai_addrlen); if (ret < 0) { ESP_LOGE(TAG, "Failed to connnect to host (errno %d)", errno); @@ -266,7 +280,13 @@ static ssize_t tls_write(esp_tls_t *tls, const char *data, size_t datalen) */ esp_tls_t *esp_tls_conn_new(const char *hostname, int hostlen, int port, const esp_tls_cfg_t *cfg) { - int sockfd = esp_tcp_connect(hostname, hostlen, port); + int sockfd; + if (cfg) { + sockfd = esp_tcp_connect(hostname, hostlen, port, cfg->timeout_ms); + } else { + sockfd = esp_tcp_connect(hostname, hostlen, port, DEFAULT_TIMEOUT_MS); + } + if (sockfd < 0) { return NULL; } @@ -324,3 +344,12 @@ esp_tls_t *esp_tls_conn_http_new(const char *url, const esp_tls_cfg_t *cfg) return esp_tls_conn_new(&url[u.field_data[UF_HOST].off], u.field_data[UF_HOST].len, get_port(url, &u), cfg); } + +size_t esp_tls_get_bytes_avail(esp_tls_t *tls) +{ + if (!tls) { + ESP_LOGE(TAG, "empty arg passed to esp_tls_get_bytes_avail()"); + return ESP_FAIL; + } + return mbedtls_ssl_get_bytes_avail(&tls->ssl); +} \ No newline at end of file diff --git a/components/esp-tls/esp_tls.h b/components/esp-tls/esp_tls.h index 92b0734ebe..d5975dc198 100644 --- a/components/esp-tls/esp_tls.h +++ b/components/esp-tls/esp_tls.h @@ -18,7 +18,6 @@ #include #include - #include "mbedtls/platform.h" #include "mbedtls/net_sockets.h" #include "mbedtls/esp_debug.h" @@ -48,12 +47,14 @@ typedef struct esp_tls_cfg { const unsigned char *cacert_pem_buf; /*!< Certificate Authority's certificate in a buffer */ - const unsigned int cacert_pem_bytes; /*!< Size of Certificate Authority certificate + unsigned int cacert_pem_bytes; /*!< Size of Certificate Authority certificate pointed to by cacert_pem_buf */ bool non_block; /*!< Configure non-blocking mode. If set to true the underneath socket will be configured in non blocking mode after tls session is established */ + + int timeout_ms; /*!< Network timeout in milliseconds */ } esp_tls_cfg_t; /** @@ -165,6 +166,21 @@ static inline ssize_t esp_tls_conn_read(esp_tls_t *tls, void *data, size_t data */ void esp_tls_conn_delete(esp_tls_t *tls); +/** + * @brief Return the number of application data bytes remaining to be + * read from the current record + * + * This API is a wrapper over mbedtls's mbedtls_ssl_get_bytes_avail() API. + * + * @param[in] tls pointer to esp-tls as esp-tls handle. + * + * @return + * - -1 in case of invalid arg + * - bytes available in the application data + * record read buffer + */ +size_t esp_tls_get_bytes_avail(esp_tls_t *tls); + #ifdef __cplusplus } #endif