Hi,
I’m running OTA over cellular MQTT. In order to save power I cycle between a low power sleep state and an active state. When going to sleep, the OTA task is suspended, the MQTT connection with the broker is disconnected and then the modem is turned off. Here’s a log snippet of this happening when there are no problems:
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:2014] Received: 0 Queued: 0 Processed: 0 Dropped: 0
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:2014] Received: 0 Queued: 0 Processed: 0 Dropped: 0
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:2014] Received: 0 Queued: 0 Processed: 0 Dropped: 0
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:2014] Received: 0 Queued: 0 Processed: 0 Dropped: 0
{"id":"ID-00009-00037-015-P0N261Z","spd":0.0,"odo":0.0,"vb":0.000,"vg":3.543,"pwr":0.0,"cap":0.0,"cnt":327.0,"lat":51.410743713378906,"lon":5.401909351348877}
[INFO] [MQTT] [core_mqtt_agent_command_functions.c:76] Publishing message to iot/ID-00009-00037-015-P0N261Z.
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:1679] Sent PUBLISH packet to topic iot/ID-00009-00037-015-P0N261Z.
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:2014] Received: 0 Queued: 0 Processed: 0 Dropped: 0
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:2014] Received: 0 Queued: 0 Processed: 0 Dropped: 0
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:2014] Received: 0 Queued: 0 Processed: 0 Dropped: 0
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:2014] Received: 0 Queued: 0 Processed: 0 Dropped: 0
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:2014] Received: 0 Queued: 0 Processed: 0 Dropped: 0
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:2014] Received: 0 Queued: 0 Processed: 0 Dropped: 0
Bike state transition: [LOWPOWERAWAKE] --> [LOWPOWERSLEEP]
Cellular state transition: [CONNECTED] --> [TURNINGOFF]
[WARN] [OTA] [ota_os_freertos.c:310] OTA Timer handle NULL for Timerid=0, can't stop.
[INFO] [OTA] [ota.c:1350] OTA Agent is suspended.
[INFO] [OTA] [ota.c:2846] Current State=[Suspended], Event=[Suspend], New state=[Suspended]
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:2149] Suspended OTA agent successfully.
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:1533] Disconnecting the MQTT connection with a32g9qwxlmbo20-ats.iot.eu-central-1.amazonaws.com.
[INFO] [MQTT] [core_mqtt.c:2158] Disconnected from the broker.
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:1363] Disconnecting TLS connection.
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:1858] MQTTAgent task deleted...
CellularDevice_PowerOff +
CellularDevice_PowerOff -
Cellular state transition: [TURNINGOFF] --> [OFF]
Going to sleep...
Occasionally however it might happen that during an attempt to disconnect from the MQTT broker the cellular library reports that there is a data timeout. When this happens, this triggers a series of events that eventually cause a configassert to trigger in vPortFree(). Here is a log event of this happening:
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:2014] Received: 0 Queued: 0 Processed: 0 Dropped: 0
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:2014] Received: 0 Queued: 0 Processed: 0 Dropped: 0
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:2014] Received: 0 Queued: 0 Processed: 0 Dropped: 0
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:2014] Received: 0 Queued: 0 Processed: 0 Dropped: 0
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:2014] Received: 0 Queued: 0 Processed: 0 Dropped: 0
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:2014] Received: 0 Queued: 0 Processed: 0 Dropped: 0
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:2014] Received: 0 Queued: 0 Processed: 0 Dropped: 0
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:2014] Received: 0 Queued: 0 Processed: 0 Dropped: 0
bike timer 2 callback
Bike state transition: [LOWPOWERAWAKE] --> [LOWPOWERSLEEP]
Cellular state transition: [CONNECTED] --> [TURNINGOFF]
[WARN] [OTA] [ota_os_freertos.c:310] OTA Timer handle NULL for Timerid=0, can't stop.
[INFO] [OTA] [ota.c:1350] OTA Agent is suspended.
[INFO] [OTA] [ota.c:2846] Current State=[Suspended], Event=[Suspend], New state=[Suspended]
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:2149] Suspended OTA agent successfully.
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:1533] Disconnecting the MQTT connection with a32g9qwxlmbo20-ats.iot.eu-central-1.amazonaws.com.
[ERROR] [CellularLib] [cellular_pkthandler.c:335] pkt_recv status=1, data sending timed out
[ERROR] [CellularLib] [cellular_r4_api.c:748] Cellular_SocketSend: Data send fail, PktRet: 1
[ERROR] [TlsTransport] [using_mbedtls.c:840] Failed to send data: mbedTLSError= <No-High-Level-Code> : ERROR - Generic error.
[ERROR] [MQTT] [core_mqtt.c:625] Transport send failed. Error code=-1.
[ERROR] [MQTT] [core_mqtt.c:2146] Transport send failed for DISCONNECT packet.
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:1363] Disconnecting TLS connection.
[ERROR] [MQTT] [core_mqtt_agent.c:1022] MQTT operation failed with status MQTTSendFailed
[WARN] [OTA] [ota_os_freertos.c:310] OTA Timer handle NULL for Timerid=0, can't stop.
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:1836] Suspended OTA agent.
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:1837] MQTT Agent disconnecting...
[INFO] [OTADemo] [OtaOverMqttDemoExample.c:1363] Disconnecting TLS connection.
[ERROR] [CellularLib] [cellular_pkthandler.c:335] pkt_recv status=1, data sending timed out
[ERROR] [CellularLib] [cellular_r4_api.c:748] Cellular_SocketSend: Data send fail, PktRet: 1
[ERROR] [TlsTransport] [using_mbedtls.c:742] (Network connection 0x20033bf8) Failed to send TLS close-notify: mbedTLSError= <No-High-Level-Code> : ERROR - Generic error.
[WARN] [CellularLib] [cellular_pktio.c:367] Modem return ERROR: line AT+USOWR=0,31, cmd : +CME ERROR: Operation not allowed, respPrefix NULL, status: 0
[WARN] [CellularLib] [cellular_pkthandler.c:247] Modem returns error in sending AT command AT+USOWR=0,31, pktStatus 2.
[ERROR] [CellularLib] [cellular_r4_api.c:748] Cellular_SocketSend: Data send fail, PktRet: 2
[ERROR] [CellularLib] [cellular_common.c:487] _Cellular_TranslatePktStatus: Status 2
[ERROR] [TlsTransport] [using_mbedtls.c:742] (Network connection 0x20033bf8) Failed to send TLS close-notify: mbedTLSError= <No-High-Level-Code> : ERROR - Generic error.
This is the section in vPortFree that the programs ends up in when this happens:
/* Check the block is actually allocated. */|
configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 );|
It seems that when prvDisconnectFromMQTTBroker() is called and the MQTTAgent_Disconnect() call inside fails, it continues anyway and calls prvSocketDisconnect() after that. In parallel, inside the MQTTAgentTask, the MQTTAgent_CommandLoop exits due to the error and then in turn another call prvSocketDisconnect() is being made. That is how it is implemented, seems wrong to me.
I do not know what the best way would be to handle such a condition. Hoping that someone here can point me to the solution.