MQTTAgent_Ping handling

Does the MQTT agent responsible for sending keep alive pings internally or this is the agent user responsibility?

I’m not sure it has been tested yet but the intent is for that to be the responsibility of the agent.

I did not find it in the code, maybe I missied it, appriciate if you can point me to how can I activate it.

Currently, as a walkaround, I created a timer in the connection manager (in prvConnectAndCreateDemoTasks) and from the time callback I’m calling MQTTAgent_Ping(mqttexampleMQTT_CONTEXT_HANDLE, NULL, NULL, 50) and this is working fine and the MQTT connection preserved up for as long as I run.

Thank you Eyal for pointing it. Yes, it is not done currently but as Richard mentioned, that is the intent and we will update the agent to handle PINGs automatically.

For now, the workaround you have is the right thing to do. You should reset this timer everytime you send something out as PINGs are only needed when the connection is idle.

Thanks again.

Hi @EyalG,

This is not necessary as the MQTT Agent already handles pings. After each MQTT operation, the agent calls MQTT_ProcessLoop() for every active connection, which will send a pingreq if enough time has elapsed. You do not need to configure anything for this as it cannot actually be disabled.

Thanks

Thank you for this reply but the reason I initially asked this question was because PINGs was not sent (or at least not in the right time gaps) in my app and the connection was closed by the host as of that.

Can you please point me to where in the agent this is done? And if you say that there is no need to define anything then how does that PING mechanism in the agent works with the keep alive interval?

Thanks

Hi @EyalG,

After each command, the agent calls the process loop for every active connection. If a command has not been received for some wait time, then an empty command will be passed to that function and the process loop should still execute. If no packet is received and the client has not sent a packet in the keep alive interval, it should send a ping request. The keep alive interval is set in the connection information that is passed to the agent.

If your app is not sending pings when idle, I can guess there’s an issue with inaccurate timestamps, or the process loop is not executing in time. Enabling debug logs for both the agent and coreMQTT might help to trace the issue. Additionally, I would try reducing the block time for the command queue, as decreasing it will cause the process loop to execute more frequently.

Also, do you happen to be using Visual Studio? The timestamps on the Windows simulator are known to be unreliable for MQTT keep alive.

Hello Muneeb,

Yes, I’m working under VS as well as on the HW, I tried to do what you suggested and run on VS with DEBUG level log, I blocked my PING timer so I do not send PING by myself and I let the agent handle it.

This is my log:

After I publish something to the shadow I get this:

13682 13423 [ConnectManager] [INFO] [SHADOW] [shadow_task.c:802] Received response from the device shadow. Previously published update with clientToken=13268 has been accepted.
13683 13423 [ConnectManager] [DEBUG] [MQTT] [core_mqtt.c:645] BytesSent=4, BytesRemaining=0
13684 13423 [ConnectManager] [DEBUG] [MQTT] [core_mqtt.c:666] Successfully sent packet at time 13031.
13685 13423 [ConnectManager] [DEBUG] [MQTT] [core_mqtt_serializer.c:2386] No data was received from the transport.
13686 14423 [ConnectManager] [DEBUG] [MQTT] [core_mqtt_serializer.c:2386] No data was received from the transport.
13687 15423 [ConnectManager] [DEBUG] [MQTT] [core_mqtt_serializer.c:2386] No data was received from the transport.
13688 16423 [ConnectManager] [DEBUG] [MQTT] [core_mqtt_serializer.c:2386] No data was received from the transport.
13689 17423 [ConnectManager] [DEBUG] [MQTT] [core_mqtt_serializer.c:2386] No data was received from the transport.

Now, this is going on for 60 sec almost (it start at 13423 ) until I get this:

13732 60423 [ConnectManager] [DEBUG] [MQTT] [core_mqtt_serializer.c:2386] No data was received from the transport.
13733 61423 [ConnectManager] [DEBUG] [MQTT] [core_mqtt_serializer.c:2386] No data was received from the transport.
13734 62423 [ConnectManager] [DEBUG] [MQTT] [core_mqtt_serializer.c:2386] No data was received from the transport.
13735 62782 [ConnectManager] [ERROR] [TlsTransport] [using_mbedtls.c:780] Failed to read data: mbedTLSError= SSL - The peer notified us that the connection is going to be closed :
.
13736 62782 [ConnectManager] [ERROR] [MQTT] [core_mqtt_serializer.c:2396] A single byte was not read from the transport: transportStatus=-30848.
13737 62782 [ConnectManager] [ERROR] [MQTT] [core_mqtt.c:1320] Receiving incoming packet length failed. Status=MQTTRecvFailed
13738 62782 [ConnectManager] [ERROR] [MQTT] [core_mqtt.c:2192] Exiting process loop due to failure: ErrorStatus=MQTTRecvFailed
13739 62782 [ConnectManager] [ERROR] [MQTT] [freertos_mqtt_agent.c:1460] MQTT operation failed with status MQTTRecvFailed

13740 62782 [ConnectManager] [INFO] [MQTTApp] [connection_manager.c:535] Disconnecting TLS connection.

13741 62782 [ConnectManager] [INFO] [MQTTApp] [connection_manager.c:470] Creating a TLS connection to [MyEndPointPrefix].iot.us-east-1.amazonaws.com:8883.
13742 62837 [ConnectManager] DNS[0x7295]: The answer to ‘[MyEndPointPrefix].amazonaws.com’ (A.B.C.D) will be stored
[DEBUG] [MQTT] [core_mqtt_serializer.c:459] 13743 63317 [ConnectManager] Encoded size for length 93 is 1 bytes.
13744 63317 [ConnectManager] [DEBUG] [MQTT] [core_mqtt_serializer.c:1593] CONNECT packet remaining length=93 and packet size=95.
13745 63317 [ConnectManager] [DEBUG] [MQTT] [core_mqtt.c:1782] CONNECT packet size is 95 and remaining length is 93.
13746 63317 [ConnectManager] [DEBUG] [MQTT] [core_mqtt_serializer.c:459] Encoded size for length 93 is 1 bytes.
13747 63317 [ConnectManager] [DEBUG] [MQTT] [core_mqtt_serializer.c:1492] Length of serialized CONNECT packet is 95.
13748 63317 [ConnectManager] [DEBUG] [MQTT] [core_mqtt.c:645] BytesSent=95, BytesRemaining=0
13749 63317 [ConnectManager] [DEBUG] [MQTT] [core_mqtt.c:666] Successfully sent packet at time 62925.
13750 63317 [ConnectManager] [DEBUG] [MQTT] [core_mqtt.c:1807] Sent 95 bytes of CONNECT packet.
13751 63317 [ConnectManager] [DEBUG] [MQTT] [core_mqtt_serializer.c:2386] No data was received from the transport.
13752 63317 [ConnectManager] [DEBUG] [MQTT] [core_mqtt_serializer.c:2386] No data was received from the transport.

Hi @EyalG,

This is likely to be the issue. The timer on the Windows simulator is imprecise and known to have longer delays than real-time (see “Simulating the tick interrupt” here). As such, the keep alive mechanism is unreliable when using Visual Studio, though it should still work on your hardware.

Of course, you’re free to still keep sending pings from a timer anyway, but it shouldn’t be necessary on your board.