I am collecting data that I push to Microsoft IoT Hub thru MQTT. My code runs on an ESP32-based custom PCB.
Everything sounds good (I get the data on the cloud), but after some duration (usually after 5 to 15 minutes), I get the following error:
E (200965) TRANS_SSL: ssl_poll_write select error 113, errno = Software caused connection abort, fd = 57
As per my understanding, this tells me it was not able to get an acknowledgment from the recipient, right?
My logs are as follows:
b6611|—| IoT: MQTT: event MQTT_EVENT_PUBLISHED (activity: 24)
b6611|—| IoT: MQTT: event MQTT_EVENT_PUBLISHED (activity: 25)
b6611|—| IoT: ==MQTT==: connected
(2)b6611|—| IoT: WiFi connected
b6611|—| IoT: SAS token not expired
b6611|—| IoT: MQTT connected
b6611|—| IoT: MQTT: event MQTT_EVENT_PUBLISHED (activity: 26)
E (200965) TRANS_SSL: ssl_poll_write select error 113, errno = Software caused connection abort, fd = 57
b6611|—| IoT: MQTT: event MQTT_EVENT_ERROR
E (200970) MQTT_CLIENT: Error write data or timeout, written len = -1, errno=0
E (200977) MQTT_CLIENT: Error to resend data
b6611|—| IoT: MQTT: event MQTT_EVENT_DISCONNECTED
b6611|—| IoT: ==MQTT==: disconnected!
(0)b6611|—| IoT: WiFi no longer connected, establishing connection…
My code's as follows:
int Iot :: initializeMqttClient() {
stateMqttClientOk = false;
if (!isConnectedToIp()) return 2;
log("Init MQTT client");
#if SUPPORT_IOT_DPS
#else
if (sasToken->Generate(SAS_TOKEN_DURATION_IN_MINUTES) != 0) {
error("Failed generating SAS token");
return 1;
}
else {
success("Successfully generated SAS token from %s", sasToken->moduleName());
}
#endif
mqttConnectionState = IOT_MQTT_CONNECTING;
// == If a client is already there, destroy it before creating a new one
if (mqtt_client) {
log("MQTT client already exists, remove it for a brand new one");
(void)esp_mqtt_client_destroy(mqtt_client);
}
// == Create a new mqtt client
esp_mqtt_client_config_t mqtt_config;
memset(&mqtt_config, 0, sizeof(mqtt_config));
mqtt_config.uri = mqtt_broker_uri;
mqtt_config.port = mqtt_port;
mqtt_config.client_id = mqtt_client_id;
mqtt_config.username = mqtt_username;
az_span t = sasToken->get();
#if LOG_LEVEL >= LOG_LEVEL_DEBUG
log("SAS token: sasToken is %p", sasToken);
log("SAS token: sasToken->get() is %p", t);
#endif
mqtt_config.password = (const char*)az_span_ptr(t);
// == Removed 30s period heartbeat down to 120s (default)
//mqtt_config.keepalive = 30;
mqtt_config.disable_clean_session = 0;
mqtt_config.disable_auto_reconnect = false;
mqtt_config.event_handle = mqtt_event_handler;
mqtt_config.user_context = NULL;
//== Removed the certificate as it makes MQTT crash with the following:
// E (21414) TRANS_SSL: ssl_poll_read select error 113, errno = Software caused connection abort, fd = 54
// E (21416) MQTT_CLIENT: Poll read error: 0, aborting connection
//mqtt_config.cert_pem = (const char*)ca_pem;
mqtt_client = esp_mqtt_client_init(&mqtt_config);
if (mqtt_client == NULL) {
error("Failed creating mqtt client");
return 1;
}
else {
success("Successfully create MQTT client, now let's start it");
}
I tried to comment out the two lines without any noticeable improvement, as follows:
// == Removed this by Sdl on Thursday October 13th 2022 3:15pm
//mqtt_config.disable_clean_session = 0;
//mqtt_config.disable_auto_reconnect = false;
There is probably something wrong with my config code. Any idea?
Also, it would probably be interesting to unmount the MQTT and mount it back again in order to continue doing the collection. But how can this be done?
[UPDATE]
The SAS is checked on a regular basis (and will be updated if expired). But in my case it did not expire (You can see the line the SAS did not expire in the provided logs).
What I should mention is that after a lost of connection (typically between 5 to 15 minutes), MQTT some time manages to reconnect and then succeeds to send a few messages before losing the connection again.