summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMuneeb Ahmed <54290492+muneebahmed10@users.noreply.github.com>2020-06-22 14:24:32 -0700
committerGitHub <noreply@github.com>2020-06-22 14:24:32 -0700
commit1f46e79f02bacf72a677b90073f0a5b9dba5094a (patch)
tree897e495c32625a4a0c2440f81b4dc28dbc39fcf2
parent1c7c31e7a6a0868efe8ff7e5af261adaf2e8e35d (diff)
downloadfreertos-git-1f46e79f02bacf72a677b90073f0a5b9dba5094a.tar.gz
Sync Keep Alive fix from C-SDK (#100)
-rwxr-xr-xFreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_operation.c46
-rwxr-xr-xFreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_validate.c21
2 files changed, 67 insertions, 0 deletions
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_operation.c b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_operation.c
index fe2edd002..986441d43 100755
--- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_operation.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_operation.c
@@ -886,8 +886,54 @@ void _IotMqtt_ProcessKeepAlive( taskPoolJob_t * pKeepAliveJob,
IotLogDebug( "(MQTT connection %p) PINGRESP was received.", pMqttConnection );
/* PINGRESP was received. Schedule the next PINGREQ transmission. */
+
+ /* This function is called for two purposes:
+ *
+ * 1. To send a PINGREQ.
+ * 2. To check that the corresponding PINGRESP is received within
+ * IOT_MQTT_RESPONSE_WAIT_MS.
+ *
+ * The way it differentiates between the two is by checking
+ * ping.nextPeriodMs in pPingreqOperation->u.operation.periodic:
+ *
+ * If ping.nextPeriodMs is set to ping.keepAliveMs,
+ * the invocation is for sending PINGREQ.
+ * Otherwise, the invocation is for checking that PINGRESP is received
+ * within IOT_MQTT_RESPONSE_WAIT_MS.
+ *
+ * Therefore, it is necessary to set ping.nextPeriodMs
+ * to ping.keepAliveMs to ensure that PINGREQ is sent in
+ * the next invocation. But we must ensure that the next time to send
+ * PINGREQ is calculated from the moment last PINGREQ was sent and NOT
+ * when we checked for PINGRESP. As a result we need to schedule the next
+ * invocation at ping.keepAliveMs - IOT_MQTT_RESPONSE_WAIT_MS.
+ * The following diagram also explains it:
+ *
+ * WaitMS KeepAliveMS - WaitMS
+ * <-------->|<-------------------->
+ * ---------------------------------
+ * ^ ^ ^
+ * | | |
+ * PINGREQ PINGRESP PINGREQ
+ * (Call 1) (Call 2) (Call 3)
+ * <------------------------------->
+ * KeepAliveMS
+ * WaitMS = IOT_MQTT_RESPONSE_WAIT_MS.
+ * KeepAliveMS = pPingreqOperation->u.operation.periodic.ping.keepAliveMs.
+ * Call 1 - First PINGREQ is sent.
+ * Call 2 - PINGRESP is checked after IOT_MQTT_RESPONSE_WAIT_MS.
+ * Call 3 - Next PINGREQ is sent. Time difference between Call 2 and
+ * Call 3 is KeepAliveMS - WaitMS, while time difference between Call 1
+ * and Call 3 is KeepAliveMS. */
pPingreqOperation->u.operation.periodic.ping.nextPeriodMs =
pPingreqOperation->u.operation.periodic.ping.keepAliveMs;
+
+ IotMqtt_Assert( pPingreqOperation->u.operation.periodic.ping.keepAliveMs
+ > IOT_MQTT_RESPONSE_WAIT_MS );
+
+ /* Subtract time taken for PINGRESP check. */
+ scheduleDelay = pPingreqOperation->u.operation.periodic.ping.keepAliveMs
+ - IOT_MQTT_RESPONSE_WAIT_MS;
}
else
{
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_validate.c b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_validate.c
index 26381594f..cdcca62f0 100755
--- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_validate.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_validate.c
@@ -595,6 +595,27 @@ bool _IotMqtt_ValidateConnect( const IotMqttConnectInfo_t * pConnectInfo )
if( status == true )
{
+ /* Check that keep alive is not too short. */
+ if( pConnectInfo->keepAliveSeconds != 0U )
+ {
+ /* After sending a PINGREQ, we wait for IOT_MQTT_RESPONSE_WAIT_MS to
+ * receive the corresponding PINGRESP. If the PINGRESP is received within
+ * IOT_MQTT_RESPONSE_WAIT_MS, we schedule another job to send PINGREQ.
+ * If the IOT_MQTT_RESPONSE_WAIT_MS is longer than keep alive interval,
+ * we will fail to send PINGRESP on time. */
+ if( ( pConnectInfo->keepAliveSeconds * 1000U ) <= IOT_MQTT_RESPONSE_WAIT_MS )
+ {
+ IotLogError( "Keep alive interval %u ms must be longer than response wait time %u ms.",
+ pConnectInfo->keepAliveSeconds * 1000U,
+ IOT_MQTT_RESPONSE_WAIT_MS );
+
+ status = false;
+ }
+ }
+ }
+
+ if( status == true )
+ {
/* If will info is provided, check that it is valid. */
if( pConnectInfo->pWillInfo != NULL )
{