ESP32-C3在MQTT访问时出现“transport_base: Poll timeout or error”问题的分析(1)

笔者最近在测试时,突然遇到了以下错误:

网上看过一些帖子,要么就是只提出遇到了相同问题,但没有解答。如:transport_base: Poll timeout or error, errno=Connection already in progress - ESP32 Forum

要么就是和本问题类似,但不完全相同的问题。如:

TRANSPORT_BASE: poll_read select error 113, errno = Software caused connection abort, fd = 54: cannot recover from this - ESP32 Forum

要么就是虽然给出了一定的分析和一些建议的解决方法,但都不适合当前所遇问题,并且也没有更深层面的分析。如:

wifi:bcn_timout,ap_probe_send_start when using esp_http_client to make post requests (IDFGH-7547) · Issue #9108 · espressif/esp-idf · GitHub

咨询乐鑫的技术支持,至今没有反馈……

既然没有更好的办法,那么就只能自力更生。深入到代码,对此问题进行跟踪和分析。看看到底是Wi-Fi模组自身的性能问题,还是自己的代码逻辑问题。

首先,要找到错误提示出自于哪个文件的哪个函数中。在ESP-IDF的工程源码(注意:不是新建工程的,要ESP-IDF的安装路径或者组件库路径中查找,如:C:\Espressif\frameworks\esp-idf-v5.2.1)。

经过搜索,最终定位到是在components\components\tcp_transport\transport_ssl.c的ssl_write函数中。代码如下:

static int ssl_write(esp_transport_handle_t t, const char *buffer, int len, int timeout_ms)
{
    int poll;
    transport_esp_tls_t *ssl = ssl_get_context_data(t);

    if ((poll = esp_transport_poll_write(t, timeout_ms)) <= 0) {
        ESP_LOGW(TAG, "Poll timeout or error, errno=%s, fd=%d, timeout_ms=%d", strerror(errno), ssl->sockfd, timeout_ms);
        return poll;
    }
    int ret = esp_tls_conn_write(ssl->tls, (const unsigned char *) buffer, len);
    if (ret < 0) {
        ESP_LOGE(TAG, "esp_tls_conn_write error, errno=%s", strerror(errno));
        esp_tls_error_handle_t esp_tls_error_handle;
        if (esp_tls_get_error_handle(ssl->tls, &esp_tls_error_handle) == ESP_OK) {
            esp_transport_set_errors(t, esp_tls_error_handle);
        } else {
            ESP_LOGE(TAG, "Error in obtaining the error handle");
        }
    }
    return ret;
}

实际上在components\components\tcp_transport\transport_ssl.c文件中还有一处相同打印,在tcp_write函数中,该函数代码如下:

static int tcp_write(esp_transport_handle_t t, const char *buffer, int len, int timeout_ms)
{
    int poll;
    transport_esp_tls_t *ssl = ssl_get_context_data(t);

    if ((poll = esp_transport_poll_write(t, timeout_ms)) <= 0) {
        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);
    if (ret < 0) {
        ESP_LOGE(TAG, "tcp_write error, errno=%s", strerror(errno));
        esp_transport_capture_errno(t, errno);
    }
    return ret;
}

可以看到,两个函数(ssl_write和tcp_write)还是比较相似的,都是先调用esp_transport_poll_write函数进行判断,而后一个调用esp_tls_conn_write函数,另一个调用(经典的)send函数。由于笔者的MQTT是MQTTs即带证书认证的,因此应该走的是ssl_write函数,后文书也会重点围绕ssl_write函数展开分析和讲解。

对于ssl_write函数及其相关上下文的解析,请看下回。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝天居士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值