From a643f7fc43a52a50526b1fbb86761b38c4de239c Mon Sep 17 00:00:00 2001 From: AniruddhaKanhere <60444055+AniruddhaKanhere@users.noreply.github.com> Date: Tue, 22 Oct 2024 02:28:55 +0000 Subject: [PATCH] Add opaque struct and functions to serialize it. --- .github/.cSpellWords.txt | 2 + source/core_mqtt.c | 105 +++--- source/include/core_mqtt.h | 78 ++--- source/include/core_mqtt_serializer.h | 14 +- test/unit-test/core_mqtt_utest.c | 446 +++++++++++++++++--------- 5 files changed, 377 insertions(+), 268 deletions(-) diff --git a/.github/.cSpellWords.txt b/.github/.cSpellWords.txt index d2ba4f17..71edb870 100644 --- a/.github/.cSpellWords.txt +++ b/.github/.cSpellWords.txt @@ -20,6 +20,7 @@ DLIBRARY DNDEBUG DUNITTEST DUNITY +getbytesinmqttvec getpacketid isystem lcov @@ -34,6 +35,7 @@ NONDET pylint pytest pyyaml +serializemqttvec sinclude UNACKED unpadded diff --git a/source/core_mqtt.c b/source/core_mqtt.c index 55afe35d..3ec78bbb 100644 --- a/source/core_mqtt.c +++ b/source/core_mqtt.c @@ -92,7 +92,7 @@ struct MQTTVec { - TransportOutVector_t pVector; /**< Pointer to transport vector. USER SHOULD NOT ACCESS THIS DIRECTLY - IT IS AN INTERNAL DETAIL AND CAN CHANGE. */ + TransportOutVector_t pVector; /**< Pointer to transport vector. USER SHOULD NOT ACCESS THIS DIRECTLY - IT IS AN INTERNAL DETAIL AND CAN CHANGE. */ }; /*-----------------------------------------------------------*/ @@ -450,8 +450,7 @@ static MQTTStatus_t handleUncleanSessionResumption( MQTTContext_t * pContext ); * * @param[in] pContext Initialized MQTT context. * - * @return #MQTTPublishClearAllFailed if clearing all the copied publishes fails; - * #MQTTSuccess otherwise. + * @return #MQTTSuccess always otherwise. */ static MQTTStatus_t handleCleanSession( MQTTContext_t * pContext ); @@ -1608,10 +1607,9 @@ static MQTTStatus_t handlePublishAcks( MQTTContext_t * pContext, if( ( ackType == MQTTPuback ) || ( ackType == MQTTPubrec ) ) { if( ( status == MQTTSuccess ) && - ( pContext->clearFunction != NULL ) && - ( pContext->clearFunction( pContext, packetIdentifier ) != true ) ) + ( pContext->clearFunction != NULL ) ) { - LogWarn( ( "Failed to clear copied publish on receiving an ack.\n" ) ); + pContext->clearFunction( pContext, packetIdentifier ); } } @@ -2222,10 +2220,14 @@ static MQTTStatus_t sendPublishWithoutCopy( MQTTContext_t * pContext, /* store a copy of the publish for retransmission purposes */ if( ( pPublishInfo->qos > MQTTQoS0 ) && - ( pContext->storeFunction != NULL ) && - ( pContext->storeFunction( pContext, packetId, pIoVector, ioVectorLength ) != true ) ) + ( pContext->storeFunction != NULL ) ) { - status = MQTTPublishStoreFailed; + MQTTVec_t * pMqttVec = ( MQTTVec_t * ) pIoVector; + + if( pContext->storeFunction( pContext, packetId, pMqttVec, ioVectorLength ) != true ) + { + status = MQTTPublishStoreFailed; + } } /* change the value of the dup flag to its original, if it was changed */ @@ -2524,9 +2526,8 @@ static MQTTStatus_t handleUncleanSessionResumption( MQTTContext_t * pContext ) MQTTStateCursor_t cursor = MQTT_STATE_CURSOR_INITIALIZER; uint16_t packetId = MQTT_PACKET_ID_INVALID; MQTTPublishState_t state = MQTTStateNull; - TransportOutVector_t * pIoVec, * pIoVectIterator; - size_t ioVecCount; size_t totalMessageLength; + uint8_t * pMqttPacket; assert( pContext != NULL ); @@ -2547,42 +2548,31 @@ static MQTTStatus_t handleUncleanSessionResumption( MQTTContext_t * pContext ) { cursor = MQTT_STATE_CURSOR_INITIALIZER; - packetId = MQTT_PublishToResend( pContext, &cursor ); - - if( ( packetId != MQTT_PACKET_ID_INVALID ) && - ( pContext->retrieveFunction( pContext, packetId, &pIoVec, &ioVecCount ) != true ) ) - { - status = MQTTPublishRetrieveFailed; - } - /* Resend all the PUBLISH for which PUBACK/PUBREC is not received * after session is reestablished. */ - while( ( packetId != MQTT_PACKET_ID_INVALID ) && - ( status == MQTTSuccess ) ) + do { - totalMessageLength = 0; - - for( pIoVectIterator = pIoVec; pIoVectIterator <= &( pIoVec[ ioVecCount - 1U ] ); pIoVectIterator++ ) - { - totalMessageLength += pIoVectIterator->iov_len; - } - - MQTT_PRE_STATE_UPDATE_HOOK( pContext ); + packetId = MQTT_PublishToResend( pContext, &cursor ); - if( sendMessageVector( pContext, pIoVec, ioVecCount ) != ( int32_t ) totalMessageLength ) + if( packetId != MQTT_PACKET_ID_INVALID ) { - status = MQTTSendFailed; - } + if( pContext->retrieveFunction( pContext, packetId, &pMqttPacket, &totalMessageLength ) != true ) + { + status = MQTTPublishRetrieveFailed; + break; + } - MQTT_POST_STATE_UPDATE_HOOK( pContext ); + MQTT_PRE_STATE_UPDATE_HOOK( pContext ); - packetId = MQTT_PublishToResend( pContext, &cursor ); + if( sendBuffer( pContext, pMqttPacket, totalMessageLength ) != ( int32_t ) totalMessageLength ) + { + status = MQTTSendFailed; + } - if( pContext->retrieveFunction( pContext, packetId, &pIoVec, &ioVecCount ) != true ) - { - status = MQTTPublishRetrieveFailed; + MQTT_POST_STATE_UPDATE_HOOK( pContext ); } - } + } while( ( packetId != MQTT_PACKET_ID_INVALID ) && + ( status == MQTTSuccess ) ); } return status; @@ -2591,6 +2581,8 @@ static MQTTStatus_t handleUncleanSessionResumption( MQTTContext_t * pContext ) static MQTTStatus_t handleCleanSession( MQTTContext_t * pContext ) { MQTTStatus_t status = MQTTSuccess; + MQTTStateCursor_t cursor = MQTT_STATE_CURSOR_INITIALIZER; + uint16_t packetId = MQTT_PACKET_ID_INVALID; assert( pContext != NULL ); @@ -2598,6 +2590,24 @@ static MQTTStatus_t handleCleanSession( MQTTContext_t * pContext ) pContext->index = 0; ( void ) memset( pContext->networkBuffer.pBuffer, 0, pContext->networkBuffer.size ); + if( pContext->clearFunction != NULL ) + { + cursor = MQTT_STATE_CURSOR_INITIALIZER; + + /* Resend all the PUBLISH for which PUBACK/PUBREC is not received + * after session is reestablished. */ + do + { + packetId = MQTT_PublishToResend( pContext, &cursor ); + + if( packetId != MQTT_PACKET_ID_INVALID ) + { + pContext->clearFunction( pContext, packetId ); + } + } while( ( packetId != MQTT_PACKET_ID_INVALID ) && + ( status == MQTTSuccess ) ); + } + if( pContext->outgoingPublishRecordMaxCount > 0U ) { /* Clear any existing records if a new session is established. */ @@ -2613,12 +2623,6 @@ static MQTTStatus_t handleCleanSession( MQTTContext_t * pContext ) pContext->incomingPublishRecordMaxCount * sizeof( *pContext->incomingPublishRecords ) ); } - if( ( pContext->clearAllFunction != NULL ) && - ( pContext->clearAllFunction( pContext ) != true ) ) - { - status = MQTTPublishClearAllFailed; - } - return status; } @@ -2787,8 +2791,7 @@ MQTTStatus_t MQTT_InitStatefulQoS( MQTTContext_t * pContext, MQTTStatus_t MQTT_InitRetransmits( MQTTContext_t * pContext, MQTTStorePacketForRetransmit storeFunction, MQTTRetrievePacketForRetransmit retrieveFunction, - MQTTClearPacketForRetransmit clearFunction, - MQTTClearAllPacketsForRetransmit clearAllFunction ) + MQTTClearPacketForRetransmit clearFunction ) { MQTTStatus_t status = MQTTSuccess; @@ -2813,17 +2816,11 @@ MQTTStatus_t MQTT_InitRetransmits( MQTTContext_t * pContext, LogError( ( "Invalid parameter: clearFunction is NULL" ) ); status = MQTTBadParameter; } - else if( clearAllFunction == NULL ) - { - LogError( ( "Invalid parameter: clearAllFunction is NULL" ) ); - status = MQTTBadParameter; - } else { pContext->storeFunction = storeFunction; pContext->retrieveFunction = retrieveFunction; pContext->clearFunction = clearFunction; - pContext->clearAllFunction = clearAllFunction; } return status; @@ -3718,10 +3715,6 @@ const char * MQTT_Status_strerror( MQTTStatus_t status ) str = "MQTTPublishRetrieveFailed"; break; - case MQTTPublishClearAllFailed: - str = "MQTTPublishClearAllFailed"; - break; - default: str = "Invalid MQTT Status code"; break; diff --git a/source/include/core_mqtt.h b/source/include/core_mqtt.h index eef73276..8d4fc288 100644 --- a/source/include/core_mqtt.h +++ b/source/include/core_mqtt.h @@ -64,6 +64,12 @@ struct MQTTPubAckInfo; struct MQTTContext; struct MQTTDeserializedInfo; +/** + * @ingroup mqtt_struct_types + * @brief An opaque structure provided by the library to the #MQTTStorePacketForRetransmit function when using #MQTTStorePacketForRetransmit. + */ +typedef struct MQTTVec MQTTVec_t; + /** * @ingroup mqtt_callback_types * @brief Application provided function to query the time elapsed since a given @@ -107,16 +113,18 @@ typedef void (* MQTTEventCallback_t )( struct MQTTContext * pContext, * * @param[in] pContext Initialised MQTT Context. * @param[in] packetId Outgoing publish packet identifier. - * @param[in] pIoVec Pointer to the outgoing publish packet in form of array of Tansport Vectors. - * @param[in] ioVecCount Number of transport vectors in the pIoVec array. + * @param[in] pMqttVec Pointer to the opaque mqtt vector structure. Users should use MQTT_SerializeMQTTVec + * and MQTT_GetBytesInMQTTVec functions to get the memory required and to serialize the + * MQTTVec_t in the provided memory respectively. + * @param[in] mqttVecCount Number of transport vectors in the pIoVec array. * * @return True if the copy is successful else false. */ /* @[define_mqtt_retransmitstorepacket] */ typedef bool ( * MQTTStorePacketForRetransmit)( struct MQTTContext * pContext, uint16_t packetId, - TransportOutVector_t * pIoVec, - size_t ioVecCount ); + MQTTVec_t * pMqttVec, + size_t mqttVecCount ); /* @[define_mqtt_retransmitstorepacket] */ /** @@ -125,16 +133,19 @@ typedef bool ( * MQTTStorePacketForRetransmit)( struct MQTTContext * pContext, * * @param[in] pContext Initialised MQTT Context. * @param[in] packetId Copied publish packet identifier. - * @param[out] pIoVec Output parameter to store the pointer to the copied publish packet form of array of Tansport Vectors. - * @param[out] ioVecCount Output parameter to store the number of transport vectors in the pIoVec array. + * @param[out] pSerializedMqttVec Output parameter to store the pointer to the serialized MQTTVec_t + * using MQTT_SerializeMQTTVec. + * @param[out] pSerializedMqttVecLen Output parameter to return the number of bytes used to store the + * MQTTVec_t. This value should be the same as the one received from MQTT_GetBytesInMQTTVec + * when storing the packet. * * @return True if the retreive is successful else false. */ /* @[define_mqtt_retransmitretrievepacket] */ typedef bool ( * MQTTRetrievePacketForRetransmit)( struct MQTTContext * pContext, uint16_t packetId, - TransportOutVector_t ** pIoVec, - size_t * ioVecCount ); + uint8_t ** pSerializedMqttVec, + size_t * pSerializedMqttVecLen ); /* @[define_mqtt_retransmitretrievepacket] */ /** @@ -147,22 +158,10 @@ typedef bool ( * MQTTRetrievePacketForRetransmit)( struct MQTTContext * pContext * @return True if the clear is successful else false. */ /* @[define_mqtt_retransmitclearpacket] */ -typedef bool (* MQTTClearPacketForRetransmit)( struct MQTTContext * pContext, +typedef void (* MQTTClearPacketForRetransmit)( struct MQTTContext * pContext, uint16_t packetId ); /* @[define_mqtt_retransmitclearpacket] */ -/** - * @brief User defined callback used to clear all copied publish packets. Used to - * when connecting with a clean session. - * - * @param[in] pContext Initialised MQTT Context. - * - * @return True if the clear all is successful else false. - */ -/* @[define_mqtt_retransmitclearallpackets] */ -typedef bool (* MQTTClearAllPacketsForRetransmit)( struct MQTTContext * pContext ); -/* @[define_mqtt_retransmitclearallpackets] */ - /** * @ingroup mqtt_enum_types * @brief Values indicating if an MQTT connection exists. @@ -324,11 +323,6 @@ typedef struct MQTTContext * @brief User defined API used to clear a particular copied publish packet. */ MQTTClearPacketForRetransmit clearFunction; - - /** - * @brief User defined API used to clear all copied publish packets. - */ - MQTTClearAllPacketsForRetransmit clearAllFunction; } MQTTContext_t; /** @@ -343,12 +337,6 @@ typedef struct MQTTDeserializedInfo MQTTStatus_t deserializationResult; /**< @brief Return code of deserialization. */ } MQTTDeserializedInfo_t; -/** - * @ingroup mqtt_struct_types - * @brief An opaque structure provided by the library to the #MQTTStorePacketForRetransmit function when using #MQTTStorePacketForRetransmit. - */ -typedef struct MQTTVec MQTTVec_t; - /** * @brief Initialize an MQTT context. * @@ -512,7 +500,6 @@ MQTTStatus_t MQTT_InitStatefulQoS( MQTTContext_t * pContext, * @param[in] storeFunction User defined API used to store outgoing publishes. * @param[in] retrieveFunction User defined API used to retreive a copied publish for resend operation. * @param[in] clearFunction User defined API used to clear a particular copied publish packet. - * @param[in] clearAllFunction User defined API used to clear a particular copied publish packet. * * @return #MQTTBadParameter if invalid parameters are passed; * #MQTTSuccess otherwise. @@ -535,7 +522,7 @@ MQTTStatus_t MQTT_InitStatefulQoS( MQTTContext_t * pContext, * // User defined callback used to store outgoing publishes * bool publishStoreCallback(struct MQTTContext* pContext, * uint16_t packetId, - * TransportOutVector_t* pIoVec, + * MQTTVec_t* pIoVec, * size_t ioVecCount); * // User defined callback used to retreive a copied publish for resend operation * bool publishRetrieveCallback(struct MQTTContext* pContext, @@ -594,8 +581,7 @@ MQTTStatus_t MQTT_InitStatefulQoS( MQTTContext_t * pContext, MQTTStatus_t MQTT_InitRetransmits( MQTTContext_t * pContext, MQTTStorePacketForRetransmit storeFunction, MQTTRetrievePacketForRetransmit retrieveFunction, - MQTTClearPacketForRetransmit clearFunction, - MQTTClearAllPacketsForRetransmit clearAllFunction ); + MQTTClearPacketForRetransmit clearFunction ); /* @[declare_mqtt_initretransmits] */ /** @@ -657,10 +643,8 @@ MQTTStatus_t MQTT_CheckConnectStatus( MQTTContext_t * pContext ); * #MQTTStatusConnected if the connection is already established * #MQTTStatusDisconnectPending if the user is expected to call MQTT_Disconnect * before calling any other API - * MQTTPublishClearAllFailed if on a clean session connection, clearing all the - * previously copied publishes fails * MQTTPublishRetrieveFailed if on an unclean session connection, the copied - * publishes are not retrieved successfuly for retransmission + * publishes are not retrieved successfully for retransmission * #MQTTSuccess otherwise. * * @note This API may spend more time than provided in the timeoutMS parameters in @@ -1247,12 +1231,12 @@ const char * MQTT_Status_strerror( MQTTStatus_t status ); /* @[declare_mqtt_status_strerror] */ /** - * @brief Get the bytes in an array of #MQTTVec_t which can store the whole array as a an MQTT packet when calling MQTT_SerializeMQTTVec( void * pAllocatedMem, MQTTVec_t *pVec, size_t len ) function. + * @brief Get the bytes in an array of #MQTTVec which can store the whole array as a an MQTT packet when calling MQTT_SerializeMQTTVec( void * pAllocatedMem, MQTTVec_t *pVec, size_t len ) function. * - * @param[in] pVec The #MQTTVec_t array. - * @param[in] len The length of the #MQTTVec_t array. + * @param[in] pVec The #MQTTVec array. + * @param[in] len The length of the #MQTTVec array. * - * @return The bytes in the provided MQTTVec_t array which can then be used to set aside memory to be used with MQTT_SerializeMQTTVec( void * pAllocatedMem, MQTTVec_t *pVec, size_t len ) function. + * @return The bytes in the provided #MQTTVec array which can then be used to set aside memory to be used with MQTT_SerializeMQTTVec( void * pAllocatedMem, MQTTVec_t *pVec, size_t len ) function. */ /* @[declare_mqtt_getbytesinmqttvec] */ size_t MQTT_GetBytesInMQTTVec( MQTTVec_t * pVec, @@ -1260,11 +1244,11 @@ size_t MQTT_GetBytesInMQTTVec( MQTTVec_t * pVec, /* @[declare_mqtt_getbytesinmqttvec] */ /** - * @brief Serialize the bytes in an array of #MQTTVec_t in the provided \p pAllocatedMem + * @brief Serialize the bytes in an array of #MQTTVec in the provided \p pAllocatedMem * - * @param[in] pAllocatedMem Memory in which to serialize the data in the #MQTTVec_t array. It must be of size provided by MQTT_GetBytesInMQTTVec( MQTTVec_t *pVec, size_t len ). - * @param[in] pVec The #MQTTVec_t array. - * @param[in] len The length of the #MQTTVec_t array. + * @param[in] pAllocatedMem Memory in which to serialize the data in the #MQTTVec array. It must be of size provided by MQTT_GetBytesInMQTTVec( MQTTVec_t *pVec, size_t len ). + * @param[in] pVec The #MQTTVec array. + * @param[in] len The length of the #MQTTVec array. */ /* @[declare_mqtt_serializemqttvec] */ void MQTT_SerializeMQTTVec( uint8_t * pAllocatedMem, diff --git a/source/include/core_mqtt_serializer.h b/source/include/core_mqtt_serializer.h index 6429d7b6..92c3ceea 100644 --- a/source/include/core_mqtt_serializer.h +++ b/source/include/core_mqtt_serializer.h @@ -99,15 +99,13 @@ typedef enum MQTTStatus MQTTNeedMoreBytes, /**< MQTT_ProcessLoop/MQTT_ReceiveLoop has received incomplete data; it should be called again (probably after a delay). */ - MQTTStatusConnected, /**< MQTT connection is established with the broker */ - MQTTStatusNotConnected, /**< MQTT connection is not established with the broker */ - MQTTStatusDisconnectPending, /**< Transport Interface has failed and MQTT connection needs to be closed */ + MQTTStatusConnected, /**< MQTT connection is established with the broker. */ + MQTTStatusNotConnected, /**< MQTT connection is not established with the broker. */ + MQTTStatusDisconnectPending, /**< Transport Interface has failed and MQTT connection needs to be closed. */ MQTTPublishStoreFailed, /**< User provided API to store a copy of outgoing publish for retransmission purposes, - has failed */ - MQTTPublishRetrieveFailed, /**< User provided API to retrieve the copy of a publish while reconnecting - with an unclean session has failed */ - MQTTPublishClearAllFailed /**< User provided API to clear all the copies of publishes while connecting with a clean - session has failed */ + has failed. */ + MQTTPublishRetrieveFailed /**< User provided API to retrieve the copy of a publish while reconnecting + with an unclean session has failed. */ } MQTTStatus_t; /** diff --git a/test/unit-test/core_mqtt_utest.c b/test/unit-test/core_mqtt_utest.c index 0f7f1442..51f13e78 100644 --- a/test/unit-test/core_mqtt_utest.c +++ b/test/unit-test/core_mqtt_utest.c @@ -211,7 +211,7 @@ static uint8_t mqttBuffer[ MQTT_TEST_BUFFER_LENGTH ] = { 0 }; /** * @brief A static buffer used by the MQTT library for storing publishes for retransmiting purpose. */ -static TransportOutVector_t * publishCopyBuffer = NULL; +static uint8_t * publishCopyBuffer = NULL; /** * @brief Size of the publishCopyBuffer array @@ -418,13 +418,13 @@ static int32_t transportWritevSuccess( NetworkContext_t * pNetworkContext, */ bool publishStoreCallbackSuccess( struct MQTTContext * pContext, uint16_t packetId, - TransportOutVector_t * pIoVec, - size_t ioVecCount ) + MQTTVec_t * pMqttVec, + size_t mqttVecLen ) { ( void ) pContext; ( void ) packetId; - ( void ) pIoVec; - ( void ) ioVecCount; + ( void ) pMqttVec; + ( void ) mqttVecLen; return true; } @@ -441,13 +441,13 @@ bool publishStoreCallbackSuccess( struct MQTTContext * pContext, */ bool publishStoreCallbackFailed( struct MQTTContext * pContext, uint16_t packetId, - TransportOutVector_t * pIoVec, - size_t ioVecCount ) + MQTTVec_t * pMqttVec, + size_t mqttVecLen ) { ( void ) pContext; ( void ) packetId; - ( void ) pIoVec; - ( void ) ioVecCount; + ( void ) pMqttVec; + ( void ) mqttVecLen; return false; } @@ -464,14 +464,14 @@ bool publishStoreCallbackFailed( struct MQTTContext * pContext, */ bool publishRetrieveCallbackSuccess( struct MQTTContext * pContext, uint16_t packetId, - TransportOutVector_t ** pIoVec, - size_t * ioVecCount ) + uint8_t ** pPacket, + size_t * pPacketSize ) { ( void ) pContext; ( void ) packetId; - *pIoVec = publishCopyBuffer; - *ioVecCount = publishCopyBufferSize; + *pPacket = publishCopyBuffer; + *pPacketSize = publishCopyBufferSize; return true; } @@ -488,8 +488,8 @@ bool publishRetrieveCallbackSuccess( struct MQTTContext * pContext, */ bool publishRetrieveCallbackSuccessThenFail( struct MQTTContext * pContext, uint16_t packetId, - TransportOutVector_t ** pIoVec, - size_t * ioVecCount ) + uint8_t ** pPacket, + size_t * pPacketSize ) { ( void ) pContext; ( void ) packetId; @@ -497,15 +497,17 @@ bool publishRetrieveCallbackSuccessThenFail( struct MQTTContext * pContext, bool ret = true; static int count = 0; - *pIoVec = publishCopyBuffer; - *ioVecCount = publishCopyBufferSize; + *pPacket = publishCopyBuffer; + *pPacketSize = publishCopyBufferSize; - if( count++ ) + if( count != 0 ) { count = 0; ret = false; } + count++; + return ret; } @@ -521,78 +523,32 @@ bool publishRetrieveCallbackSuccessThenFail( struct MQTTContext * pContext, */ bool publishRetrieveCallbackFailed( struct MQTTContext * pContext, uint16_t packetId, - TransportOutVector_t ** pIoVec, - size_t * ioVecCount ) + uint8_t ** pPacket, + size_t * pPacketSize ) { ( void ) pContext; ( void ) packetId; - ( void ) pIoVec; - ( void ) ioVecCount; + ( void ) pPacket; + ( void ) pPacketSize; return false; } /** - * @brief Mocked successful publish clear function. + * @brief Mocked publish clear function. * * @param[in] pContext initialised mqtt context. * @param[in] packetId packet id * * @return true if clear is successful else false */ -bool publishClearCallbackSuccess( struct MQTTContext * pContext, - uint16_t packetId ) +void publishClearCallback( struct MQTTContext * pContext, + uint16_t packetId ) { ( void ) pContext; ( void ) packetId; - - return true; -} - -/** - * @brief Mocked failed publish clear function. - * - * @param[in] pContext initialised mqtt context. - * @param[in] packetId packet id - * - * @return true if clear is successful else false - */ -bool publishClearCallbackFailed( struct MQTTContext * pContext, - uint16_t packetId ) -{ - ( void ) pContext; - ( void ) packetId; - - return false; } -/** - * @brief Mocked successful publish clear all function. - * - * @param[in] pContext initialised mqtt context. - * - * @return true if clear all is successful else false - */ -bool publishClearAllCallbackSuccess( struct MQTTContext * pContext ) -{ - ( void ) pContext; - - return true; -} - -/** - * @brief Mocked failed publish clear all function. - * - * @param[in] pContext initialised mqtt context. - * - * @return true if clear all is successful else false - */ -bool publishClearAllCallbackFailed( struct MQTTContext * pContext ) -{ - ( void ) pContext; - - return false; -} static void verifyEncodedTopicString( TransportOutVector_t * pIoVectorIterator, char * pTopicFilter, @@ -1441,31 +1397,21 @@ void test_MQTT_InitRetransmits_Invalid_Params( void ) /* Check that MQTTBadParameter is returned if any NULL parameters are passed. */ mqttStatus = MQTT_InitRetransmits( NULL, publishStoreCallbackSuccess, publishRetrieveCallbackSuccess, - publishClearCallbackSuccess, - publishClearAllCallbackSuccess ); + publishClearCallback ); TEST_ASSERT_EQUAL( MQTTBadParameter, mqttStatus ); mqttStatus = MQTT_InitRetransmits( &context, NULL, publishRetrieveCallbackSuccess, - publishClearCallbackSuccess, - publishClearAllCallbackSuccess ); + publishClearCallback ); TEST_ASSERT_EQUAL( MQTTBadParameter, mqttStatus ); mqttStatus = MQTT_InitRetransmits( &context, publishStoreCallbackSuccess, NULL, - publishClearCallbackSuccess, - publishClearAllCallbackSuccess ); + publishClearCallback ); TEST_ASSERT_EQUAL( MQTTBadParameter, mqttStatus ); mqttStatus = MQTT_InitRetransmits( &context, publishStoreCallbackSuccess, publishRetrieveCallbackSuccess, - NULL, - publishClearAllCallbackSuccess ); - TEST_ASSERT_EQUAL( MQTTBadParameter, mqttStatus ); - - mqttStatus = MQTT_InitRetransmits( &context, publishStoreCallbackSuccess, - publishRetrieveCallbackSuccess, - publishClearCallbackSuccess, NULL ); TEST_ASSERT_EQUAL( MQTTBadParameter, mqttStatus ); } @@ -2379,21 +2325,12 @@ void test_MQTT_Connect_resendUnAckedPublishes( void ) TransportInterface_t transport = { 0 }; MQTTFixedBuffer_t networkBuffer = { 0 }; MQTTPacketInfo_t incomingPacket = { 0 }; - uint16_t packetIdentifier = 1; - /* MQTTPublishState_t pubRelState = MQTTPubRelSend; */ MQTTPubAckInfo_t incomingRecords = { 0 }; MQTTPubAckInfo_t outgoingRecords = { 0 }; - /* MQTTPublishState_t expectedState = { 0 }; */ - TransportOutVector_t localPublishCopyBuffer[ 4 ] = { 0 }; - - /* dummy values for the stored publish packet */ - localPublishCopyBuffer[ 0 ].iov_len = 7; - localPublishCopyBuffer[ 1 ].iov_len = 7; - localPublishCopyBuffer[ 2 ].iov_len = 7; - localPublishCopyBuffer[ 3 ].iov_len = 7; + uint8_t * localPublishCopyBuffer = ( uint8_t * ) "Hello world!"; publishCopyBuffer = localPublishCopyBuffer; - publishCopyBufferSize = 4; + publishCopyBufferSize = sizeof( "Hello world!" ); setupTransportInterface( &transport ); setupNetworkBuffer( &networkBuffer ); @@ -2408,8 +2345,7 @@ void test_MQTT_Connect_resendUnAckedPublishes( void ) MQTT_InitRetransmits( &mqttContext, publishStoreCallbackSuccess, publishRetrieveCallbackSuccess, - publishClearCallbackSuccess, - publishClearAllCallbackSuccess ); + publishClearCallback ); MQTT_SerializeConnect_IgnoreAndReturn( MQTTSuccess ); MQTT_GetConnectPacketSize_IgnoreAndReturn( MQTTSuccess ); @@ -2425,32 +2361,53 @@ void test_MQTT_Connect_resendUnAckedPublishes( void ) sessionPresent = false; MQTT_DeserializeAck_ExpectAnyArgsAndReturn( MQTTSuccess ); MQTT_DeserializeAck_ReturnThruPtr_pSessionPresent( &sessionPresent ); + + MQTT_PublishToResend_ExpectAnyArgsAndReturn( 1 ); + MQTT_PublishToResend_ExpectAnyArgsAndReturn( MQTT_PACKET_TYPE_INVALID ); MQTT_SerializeConnectFixedHeader_Stub( MQTT_SerializeConnectFixedHeader_cb ); status = MQTT_Connect( &mqttContext, &connectInfo, NULL, timeout, &sessionPresentResult ); TEST_ASSERT_EQUAL_INT( MQTTSuccess, status ); TEST_ASSERT_EQUAL_INT( MQTTConnected, mqttContext.connectStatus ); TEST_ASSERT_EQUAL_INT( connectInfo.keepAliveSeconds, mqttContext.keepAliveIntervalSec ); TEST_ASSERT_FALSE( sessionPresentResult ); - mqttContext.connectStatus = MQTTNotConnected; +} - /* Test 2. Connecting with a clean session. Clear all callback fails */ - /* successful receive CONNACK packet. */ - incomingPacket.type = MQTT_PACKET_TYPE_CONNACK; - incomingPacket.remainingLength = 2; - MQTT_GetIncomingPacketTypeAndLength_ExpectAnyArgsAndReturn( MQTTSuccess ); - MQTT_GetIncomingPacketTypeAndLength_ReturnThruPtr_pIncomingPacket( &incomingPacket ); - /* Return with a session present flag. */ - sessionPresent = false; - MQTT_DeserializeAck_ExpectAnyArgsAndReturn( MQTTSuccess ); - MQTT_DeserializeAck_ReturnThruPtr_pSessionPresent( &sessionPresent ); - MQTT_SerializeConnectFixedHeader_Stub( MQTT_SerializeConnectFixedHeader_cb ); - mqttContext.clearAllFunction = publishClearAllCallbackFailed; - status = MQTT_Connect( &mqttContext, &connectInfo, NULL, timeout, &sessionPresentResult ); - TEST_ASSERT_EQUAL_INT( MQTTPublishClearAllFailed, status ); - TEST_ASSERT_EQUAL_INT( MQTTNotConnected, mqttContext.connectStatus ); - TEST_ASSERT_EQUAL_INT( connectInfo.keepAliveSeconds, mqttContext.keepAliveIntervalSec ); - TEST_ASSERT_FALSE( sessionPresentResult ); - mqttContext.clearAllFunction = publishClearAllCallbackSuccess; +void test_MQTT_Connect_resendUnAckedPublishes2( void ) +{ + MQTTContext_t mqttContext = { 0 }; + MQTTConnectInfo_t connectInfo = { 0 }; + uint32_t timeout = 2; + bool sessionPresent, sessionPresentResult; + MQTTStatus_t status; + TransportInterface_t transport = { 0 }; + MQTTFixedBuffer_t networkBuffer = { 0 }; + MQTTPacketInfo_t incomingPacket = { 0 }; + MQTTPubAckInfo_t incomingRecords = { 0 }; + MQTTPubAckInfo_t outgoingRecords = { 0 }; + uint8_t * localPublishCopyBuffer = ( uint8_t * ) "Hello world!"; + + publishCopyBuffer = localPublishCopyBuffer; + publishCopyBufferSize = sizeof( "Hello world!" ); + + setupTransportInterface( &transport ); + setupNetworkBuffer( &networkBuffer ); + + memset( &mqttContext, 0x0, sizeof( mqttContext ) ); + memset( &connectInfo, 0x00, sizeof( connectInfo ) ); + MQTT_Init( &mqttContext, &transport, getTime, eventCallback, &networkBuffer ); + + MQTT_InitStatefulQoS( &mqttContext, + &outgoingRecords, 4, + &incomingRecords, 4 ); + + MQTT_InitRetransmits( &mqttContext, publishStoreCallbackSuccess, + publishRetrieveCallbackSuccess, + publishClearCallback ); + + MQTT_SerializeConnect_IgnoreAndReturn( MQTTSuccess ); + MQTT_GetConnectPacketSize_IgnoreAndReturn( MQTTSuccess ); + connectInfo.keepAliveSeconds = MQTT_SAMPLE_KEEPALIVE_INTERVAL_S; + mqttContext.clearFunction = publishClearCallback; /* Test 3. No publishes to resend reestablishing a session. */ /* successful receive CONNACK packet. */ @@ -2472,22 +2429,105 @@ void test_MQTT_Connect_resendUnAckedPublishes( void ) TEST_ASSERT_EQUAL_INT( MQTTConnected, mqttContext.connectStatus ); TEST_ASSERT_EQUAL_INT( connectInfo.keepAliveSeconds, mqttContext.keepAliveIntervalSec ); TEST_ASSERT_TRUE( sessionPresentResult ); +} + +void test_MQTT_Connect_resendUnAckedPublishes3( void ) +{ + MQTTContext_t mqttContext = { 0 }; + MQTTConnectInfo_t connectInfo = { 0 }; + uint32_t timeout = 2; + bool sessionPresent, sessionPresentResult; + MQTTStatus_t status; + TransportInterface_t transport = { 0 }; + MQTTFixedBuffer_t networkBuffer = { 0 }; + MQTTPacketInfo_t incomingPacket = { 0 }; + uint16_t packetIdentifier = 1; + /* MQTTPublishState_t pubRelState = MQTTPubRelSend; */ + MQTTPubAckInfo_t incomingRecords = { 0 }; + MQTTPubAckInfo_t outgoingRecords = { 0 }; + /* MQTTPublishState_t expectedState = { 0 }; */ + uint8_t * localPublishCopyBuffer = ( uint8_t * ) "Hello world!"; + + publishCopyBuffer = localPublishCopyBuffer; + publishCopyBufferSize = sizeof( "Hello world!" ); + + setupTransportInterface( &transport ); + setupNetworkBuffer( &networkBuffer ); + memset( &mqttContext, 0x0, sizeof( mqttContext ) ); + memset( &connectInfo, 0x00, sizeof( connectInfo ) ); + MQTT_Init( &mqttContext, &transport, getTime, eventCallback, &networkBuffer ); + + MQTT_InitStatefulQoS( &mqttContext, + &outgoingRecords, 4, + &incomingRecords, 4 ); + + MQTT_InitRetransmits( &mqttContext, publishStoreCallbackSuccess, + publishRetrieveCallbackSuccess, + publishClearCallback ); + + MQTT_SerializeConnect_IgnoreAndReturn( MQTTSuccess ); + MQTT_GetConnectPacketSize_IgnoreAndReturn( MQTTSuccess ); + connectInfo.keepAliveSeconds = MQTT_SAMPLE_KEEPALIVE_INTERVAL_S; /* Test 4. One publish packet found to resend, but retrieve failed. */ sessionPresentResult = false; mqttContext.connectStatus = MQTTNotConnected; mqttContext.keepAliveIntervalSec = 0; + incomingPacket.type = MQTT_PACKET_TYPE_CONNACK; + incomingPacket.remainingLength = 2; + sessionPresent = true; MQTT_GetIncomingPacketTypeAndLength_ExpectAnyArgsAndReturn( MQTTSuccess ); MQTT_GetIncomingPacketTypeAndLength_ReturnThruPtr_pIncomingPacket( &incomingPacket ); MQTT_DeserializeAck_ExpectAnyArgsAndReturn( MQTTSuccess ); MQTT_DeserializeAck_ReturnThruPtr_pSessionPresent( &sessionPresent ); MQTT_PubrelToResend_ExpectAnyArgsAndReturn( MQTT_PACKET_TYPE_INVALID ); MQTT_PublishToResend_ExpectAnyArgsAndReturn( packetIdentifier ); + MQTT_SerializeConnectFixedHeader_Stub( MQTT_SerializeConnectFixedHeader_cb ); mqttContext.retrieveFunction = publishRetrieveCallbackFailed; status = MQTT_Connect( &mqttContext, &connectInfo, NULL, timeout, &sessionPresentResult ); TEST_ASSERT_EQUAL_INT( MQTTPublishRetrieveFailed, status ); TEST_ASSERT_EQUAL_INT( MQTTDisconnectPending, mqttContext.connectStatus ); TEST_ASSERT_TRUE( sessionPresentResult ); +} + +void test_MQTT_Connect_resendUnAckedPublishes4( void ) +{ + MQTTContext_t mqttContext = { 0 }; + MQTTConnectInfo_t connectInfo = { 0 }; + uint32_t timeout = 2; + bool sessionPresent, sessionPresentResult; + MQTTStatus_t status; + TransportInterface_t transport = { 0 }; + MQTTFixedBuffer_t networkBuffer = { 0 }; + MQTTPacketInfo_t incomingPacket = { 0 }; + uint16_t packetIdentifier = 1; + /* MQTTPublishState_t pubRelState = MQTTPubRelSend; */ + MQTTPubAckInfo_t incomingRecords = { 0 }; + MQTTPubAckInfo_t outgoingRecords = { 0 }; + /* MQTTPublishState_t expectedState = { 0 }; */ + uint8_t * localPublishCopyBuffer = ( uint8_t * ) "Hello world!"; + + publishCopyBuffer = localPublishCopyBuffer; + publishCopyBufferSize = sizeof( "Hello world!" ); + + setupTransportInterface( &transport ); + setupNetworkBuffer( &networkBuffer ); + + memset( &mqttContext, 0x0, sizeof( mqttContext ) ); + memset( &connectInfo, 0x00, sizeof( connectInfo ) ); + MQTT_Init( &mqttContext, &transport, getTime, eventCallback, &networkBuffer ); + + MQTT_InitStatefulQoS( &mqttContext, + &outgoingRecords, 4, + &incomingRecords, 4 ); + + MQTT_InitRetransmits( &mqttContext, publishStoreCallbackSuccess, + publishRetrieveCallbackSuccess, + publishClearCallback ); + + MQTT_SerializeConnect_IgnoreAndReturn( MQTTSuccess ); + MQTT_GetConnectPacketSize_IgnoreAndReturn( MQTTSuccess ); + connectInfo.keepAliveSeconds = MQTT_SAMPLE_KEEPALIVE_INTERVAL_S; mqttContext.retrieveFunction = publishRetrieveCallbackSuccess; /* Test 5. One publish packet found to resend, but Transport Send failed. */ @@ -2496,21 +2536,65 @@ void test_MQTT_Connect_resendUnAckedPublishes( void ) mqttContext.keepAliveIntervalSec = 0; mqttContext.transportInterface.writev = NULL; mqttContext.transportInterface.send = transportSendSucceedThenFailAfterConnect; + incomingPacket.type = MQTT_PACKET_TYPE_CONNACK; + incomingPacket.remainingLength = 2; + sessionPresent = true; MQTT_GetIncomingPacketTypeAndLength_ExpectAnyArgsAndReturn( MQTTSuccess ); MQTT_GetIncomingPacketTypeAndLength_ReturnThruPtr_pIncomingPacket( &incomingPacket ); MQTT_DeserializeAck_ExpectAnyArgsAndReturn( MQTTSuccess ); MQTT_DeserializeAck_ReturnThruPtr_pSessionPresent( &sessionPresent ); MQTT_PubrelToResend_ExpectAnyArgsAndReturn( MQTT_PACKET_TYPE_INVALID ); MQTT_PublishToResend_ExpectAnyArgsAndReturn( packetIdentifier ); - MQTT_PublishToResend_ExpectAnyArgsAndReturn( MQTT_PACKET_TYPE_INVALID ); + MQTT_SerializeConnectFixedHeader_Stub( MQTT_SerializeConnectFixedHeader_cb ); status = MQTT_Connect( &mqttContext, &connectInfo, NULL, timeout, &sessionPresentResult ); TEST_ASSERT_EQUAL_INT( MQTTSendFailed, status ); TEST_ASSERT_EQUAL_INT( MQTTDisconnectPending, mqttContext.connectStatus ); TEST_ASSERT_TRUE( sessionPresentResult ); +} + +void test_MQTT_Connect_resendUnAckedPublishes5( void ) +{ + MQTTContext_t mqttContext = { 0 }; + MQTTConnectInfo_t connectInfo = { 0 }; + uint32_t timeout = 2; + bool sessionPresent; + MQTTStatus_t status; + TransportInterface_t transport = { 0 }; + MQTTFixedBuffer_t networkBuffer = { 0 }; + MQTTPacketInfo_t incomingPacket = { 0 }; + uint16_t packetIdentifier = 1; + MQTTPubAckInfo_t incomingRecords = { 0 }; + MQTTPubAckInfo_t outgoingRecords = { 0 }; + uint8_t * localPublishCopyBuffer = ( uint8_t * ) "Hello world!"; + + publishCopyBuffer = localPublishCopyBuffer; + publishCopyBufferSize = sizeof( "Hello world!" ); + + setupTransportInterface( &transport ); + setupNetworkBuffer( &networkBuffer ); + + memset( &mqttContext, 0x0, sizeof( mqttContext ) ); + memset( &connectInfo, 0x00, sizeof( connectInfo ) ); + MQTT_Init( &mqttContext, &transport, getTime, eventCallback, &networkBuffer ); + + MQTT_InitStatefulQoS( &mqttContext, + &outgoingRecords, 4, + &incomingRecords, 4 ); + + MQTT_InitRetransmits( &mqttContext, publishStoreCallbackSuccess, + publishRetrieveCallbackSuccess, + publishClearCallback ); + + MQTT_SerializeConnect_IgnoreAndReturn( MQTTSuccess ); + MQTT_GetConnectPacketSize_IgnoreAndReturn( MQTTSuccess ); + connectInfo.keepAliveSeconds = MQTT_SAMPLE_KEEPALIVE_INTERVAL_S; mqttContext.transportInterface.send = transportSendSuccess; /* Test 6. One publish packet found to resend, Sent successfully. */ mqttContext.connectStatus = MQTTNotConnected; + incomingPacket.type = MQTT_PACKET_TYPE_CONNACK; + incomingPacket.remainingLength = 2; + sessionPresent = true; MQTT_GetIncomingPacketTypeAndLength_ExpectAnyArgsAndReturn( MQTTSuccess ); MQTT_GetIncomingPacketTypeAndLength_ReturnThruPtr_pIncomingPacket( &incomingPacket ); MQTT_DeserializeAck_ExpectAnyArgsAndReturn( MQTTSuccess ); @@ -2518,16 +2602,56 @@ void test_MQTT_Connect_resendUnAckedPublishes( void ) MQTT_PubrelToResend_ExpectAnyArgsAndReturn( MQTT_PACKET_TYPE_INVALID ); MQTT_PublishToResend_ExpectAnyArgsAndReturn( packetIdentifier ); MQTT_PublishToResend_ExpectAnyArgsAndReturn( MQTT_PACKET_TYPE_INVALID ); + MQTT_SerializeConnectFixedHeader_Stub( MQTT_SerializeConnectFixedHeader_cb ); /* Query for any remaining packets pending to ack. */ status = MQTT_Connect( &mqttContext, &connectInfo, NULL, timeout, &sessionPresent ); TEST_ASSERT_EQUAL_INT( MQTTSuccess, status ); TEST_ASSERT_EQUAL_INT( MQTTConnected, mqttContext.connectStatus ); TEST_ASSERT_EQUAL_INT( connectInfo.keepAliveSeconds, mqttContext.keepAliveIntervalSec ); +} + +void test_MQTT_Connect_resendUnAckedPublishes6( void ) +{ + MQTTContext_t mqttContext = { 0 }; + MQTTConnectInfo_t connectInfo = { 0 }; + uint32_t timeout = 2; + bool sessionPresent; + MQTTStatus_t status; + TransportInterface_t transport = { 0 }; + MQTTFixedBuffer_t networkBuffer = { 0 }; + MQTTPacketInfo_t incomingPacket = { 0 }; + uint16_t packetIdentifier = 1; + MQTTPubAckInfo_t incomingRecords = { 0 }; + MQTTPubAckInfo_t outgoingRecords = { 0 }; + uint8_t * localPublishCopyBuffer = ( uint8_t * ) "Hello world!"; + + publishCopyBuffer = localPublishCopyBuffer; + publishCopyBufferSize = sizeof( "Hello world!" ); + + setupTransportInterface( &transport ); + setupNetworkBuffer( &networkBuffer ); + + MQTT_Init( &mqttContext, &transport, getTime, eventCallback, &networkBuffer ); + + MQTT_InitStatefulQoS( &mqttContext, + &outgoingRecords, 4, + &incomingRecords, 4 ); + + MQTT_InitRetransmits( &mqttContext, publishStoreCallbackSuccess, + publishRetrieveCallbackSuccessThenFail, + publishClearCallback ); + + MQTT_SerializeConnect_IgnoreAndReturn( MQTTSuccess ); + MQTT_GetConnectPacketSize_IgnoreAndReturn( MQTTSuccess ); + connectInfo.keepAliveSeconds = MQTT_SAMPLE_KEEPALIVE_INTERVAL_S; /* Test 7. Two publish packets found to resend. Sent successfully * for first and failed for second. */ mqttContext.keepAliveIntervalSec = 0; mqttContext.connectStatus = MQTTNotConnected; + sessionPresent = true; + incomingPacket.type = MQTT_PACKET_TYPE_CONNACK; + incomingPacket.remainingLength = 2; MQTT_GetIncomingPacketTypeAndLength_ExpectAnyArgsAndReturn( MQTTSuccess ); MQTT_GetIncomingPacketTypeAndLength_ReturnThruPtr_pIncomingPacket( &incomingPacket ); MQTT_DeserializeAck_ExpectAnyArgsAndReturn( MQTTSuccess ); @@ -2537,37 +2661,10 @@ void test_MQTT_Connect_resendUnAckedPublishes( void ) MQTT_PublishToResend_ExpectAnyArgsAndReturn( packetIdentifier ); /* Second packet. */ MQTT_PublishToResend_ExpectAnyArgsAndReturn( packetIdentifier + 1 ); - mqttContext.retrieveFunction = publishRetrieveCallbackSuccessThenFail; + MQTT_SerializeConnectFixedHeader_Stub( MQTT_SerializeConnectFixedHeader_cb ); status = MQTT_Connect( &mqttContext, &connectInfo, NULL, timeout, &sessionPresent ); TEST_ASSERT_EQUAL_INT( MQTTPublishRetrieveFailed, status ); TEST_ASSERT_EQUAL_INT( MQTTDisconnectPending, mqttContext.connectStatus ); - mqttContext.retrieveFunction = publishRetrieveCallbackSuccess; - - /* / * Test 6. Two packets found in ack pending state. Sent PUBREL successfully */ - /* * for first and failed for second. * / */ - /* mqttContext.connectStatus = MQTTNotConnected; */ - /* MQTT_GetIncomingPacketTypeAndLength_ExpectAnyArgsAndReturn( MQTTSuccess ); */ - /* MQTT_GetIncomingPacketTypeAndLength_ReturnThruPtr_pIncomingPacket( &incomingPacket ); */ - /* MQTT_DeserializeAck_ExpectAnyArgsAndReturn( MQTTSuccess ); */ - /* MQTT_DeserializeAck_ReturnThruPtr_pSessionPresent( &sessionPresent ); */ - /* / * First packet. * / */ - /* MQTT_PubrelToResend_ExpectAnyArgsAndReturn( packetIdentifier ); */ - /* MQTT_PubrelToResend_ReturnThruPtr_pState( &pubRelState ); */ - /* / * Serialize Ack successful. * / */ - /* MQTT_SerializeAck_ExpectAnyArgsAndReturn( MQTTSuccess ); */ - /* MQTT_UpdateStateAck_ExpectAnyArgsAndReturn( MQTTSuccess ); */ - /* / * Second packet. * / */ - /* MQTT_PubrelToResend_ExpectAnyArgsAndReturn( packetIdentifier + 1 ); */ - /* MQTT_PubrelToResend_ReturnThruPtr_pState( &pubRelState ); */ - /* / * Serialize Ack successful. * / */ - /* MQTT_SerializeAck_ExpectAnyArgsAndReturn( MQTTSuccess ); */ - /* MQTT_UpdateStateAck_ExpectAnyArgsAndReturn( MQTTSuccess ); */ - /* / * Query for any remaining packets pending to ack. * / */ - /* MQTT_PubrelToResend_ExpectAnyArgsAndReturn( MQTT_PACKET_ID_INVALID ); */ - /* status = MQTT_Connect( &mqttContext, &connectInfo, NULL, timeout, &sessionPresent ); */ - /* TEST_ASSERT_EQUAL_INT( MQTTSuccess, status ); */ - /* TEST_ASSERT_EQUAL_INT( MQTTConnected, mqttContext.connectStatus ); */ - /* TEST_ASSERT_EQUAL_INT( connectInfo.keepAliveSeconds, mqttContext.keepAliveIntervalSec ); */ } /** @@ -3035,8 +3132,7 @@ void test_MQTT_Publish_Storing_Publish_Success( void ) MQTT_InitRetransmits( &mqttContext, publishStoreCallbackSuccess, publishRetrieveCallbackSuccess, - publishClearCallbackSuccess, - publishClearAllCallbackSuccess ); + publishClearCallback ); mqttContext.connectStatus = MQTTConnected; @@ -3087,8 +3183,7 @@ void test_MQTT_Publish_Storing_Publish_Failed( void ) MQTT_InitRetransmits( &mqttContext, publishStoreCallbackFailed, publishRetrieveCallbackSuccess, - publishClearCallbackSuccess, - publishClearAllCallbackSuccess ); + publishClearCallback ); mqttContext.connectStatus = MQTTConnected; @@ -4704,8 +4799,7 @@ void test_MQTT_ProcessLoop_handleIncomingAck_Clear_Publish_Copies( void ) mqttStatus = MQTT_InitRetransmits( &context, publishStoreCallbackSuccess, publishRetrieveCallbackSuccess, - publishClearCallbackSuccess, - publishClearAllCallbackSuccess ); + publishClearCallback ); context.connectStatus = MQTTConnected; @@ -4729,7 +4823,7 @@ void test_MQTT_ProcessLoop_handleIncomingAck_Clear_Publish_Copies( void ) expectParams.stateAfterSerialize = MQTTPubCompPending; expectProcessLoopCalls( &context, &expectParams ); - context.clearFunction = publishClearCallbackFailed; + context.clearFunction = publishClearCallback; /* Mock the receiving of a PUBACK packet type and expect the appropriate * calls made from the process loop. */ @@ -7086,11 +7180,7 @@ void test_MQTT_Status_strerror( void ) str = MQTT_Status_strerror( status ); TEST_ASSERT_EQUAL_STRING( "MQTTPublishRetrieveFailed", str ); - status = MQTTPublishClearAllFailed; - str = MQTT_Status_strerror( status ); - TEST_ASSERT_EQUAL_STRING( "MQTTPublishClearAllFailed", str ); - - status = MQTTPublishClearAllFailed + 1; + status = MQTTPublishRetrieveFailed + 1; str = MQTT_Status_strerror( status ); TEST_ASSERT_EQUAL_STRING( "Invalid MQTT Status code", str ); } @@ -7242,3 +7332,45 @@ void test_MQTT_InitStatefulQoS_callback_is_null( void ) TEST_ASSERT_EQUAL( MQTTBadParameter, mqttStatus ); } /* ========================================================================== */ + +void test_MQTT_GetBytesInMQTTVec( void ) +{ + TransportOutVector_t pTransportArray[ 10 ] = + { + { .iov_base = NULL, .iov_len = 1 }, + { .iov_base = NULL, .iov_len = 2 }, + { .iov_base = NULL, .iov_len = 3 }, + { .iov_base = NULL, .iov_len = 4 }, + { .iov_base = NULL, .iov_len = 5 }, + { .iov_base = NULL, .iov_len = 6 }, + { .iov_base = NULL, .iov_len = 7 }, + { .iov_base = NULL, .iov_len = 8 }, + { .iov_base = NULL, .iov_len = 9 }, + { .iov_base = NULL, .iov_len = 10 }, + }; + + size_t ret = MQTT_GetBytesInMQTTVec( ( MQTTVec_t * ) pTransportArray, 10 ); + + TEST_ASSERT_EQUAL( 55, ret ); +} +/* ========================================================================== */ + +void test_MQTT_SerializeMQTTVec( void ) +{ + TransportOutVector_t pTransportArray[ 10 ] = + { + { .iov_base = "This ", .iov_len = strlen( "This " ) }, + { .iov_base = "is ", .iov_len = strlen( "is " ) }, + { .iov_base = "a ", .iov_len = strlen( "a " ) }, + { .iov_base = "coreMQTT ", .iov_len = strlen( "coreMQTT " ) }, + { .iov_base = "unit-test ", .iov_len = strlen( "unit-test " ) }, + { .iov_base = "string.", .iov_len = strlen( "string." ) } + }; + + uint8_t array[ 50 ] = { 0 }; + + MQTT_SerializeMQTTVec( array, ( MQTTVec_t * ) pTransportArray, 6 ); + + TEST_ASSERT_EQUAL_MEMORY( "This is a coreMQTT unit-test string.", array, strlen( "This is a coreMQTT unit-test string." ) ); + TEST_ASSERT_EQUAL_MEMORY( "\0\0\0\0\0\0\0\0\0\0\0\0\0", &array[ 37 ], 13 ); +}