mirror of
https://github.com/FreeRTOS/coreMQTT
synced 2025-05-13 21:59:40 +08:00

<!--- Title --> Description ----------- <!--- Describe your changes in detail. --> This PR enables the coreMQTT library to resend unacked publishes on an unclean session connection. Following is a brief summary of changes: 1. Add a new API `MQTT_InitRetransmits` that will initialise the context to handle publish retransmits on an unclean session connection 2. Add signatures of callback function pointers that users will define in order to: a. copy and store outgoing publishes b. retrieve copied publish on an unclean session connection to resend c. clear a copied publish when a `PUBACK`/`PUBREC` is received d. clear all copied publishes on a clean session connection 3. Update the API's to check if callback's are defined and implement resend publishes as required. Following are the specifics of the changes: 1. Add 3 new MQTTStatus_t values: MQTTPublishStoreFailed, MQTTPublishRetrieveFailed and MQTTPublishClearAllFailed 2. Update `MQTTContext_t` to hold the callback function pointers a. `MQTTRetransmitStorePacket storeFunction` b. `MQTTRetransmitRetrievePacket retrieveFunction` c. `MQTTRetransmitClearPacket clearFunction` d. `MQTTRetransmitClearAllPackets clearAllFunction` 3. Update the `MQTT_Status_strerror` function to handle the new `MQTTStatus_t` values 4. Add a new API function `MQTT_InitRetransmits` that will initialise the new callback functions in the `MQTTContext_t` 5. Add this API to the core_mqtt.h file to make it available to users 6. Modify `MQTT_Publish` a. copy the outgoing publish packet in form of an array of `TransportOutVector_t` if the callback if defined b. if copy fails then bubble up corresponding error status code 7. Modify `MQTT_ReceiveLoop` a. on receiving a `PUBACK`/`PUBREC` clear the copy of that particular publish after the state of the publish record has been successfully updated, if the callback if defined 8. Modify `MQTT_Connect` a. on a clean session clear all the copies of publishes stored if the callback is defined b. if clear all fails then bubble up corresponding error status code c. on an unclean session get the packetID of the unacked publishes and retrieve the copies of those if the callback is defined d. if retrieve fails then bubble up corresponding error status code Approaches Taken --------------- - To let user know about the changes we have made we will add them to a changelog and have a minor version bump - To be in line with the zero copy principle in our library we chose to provide and retrieve the publish packets for storing and resending in form of an array of `TransportOutVector_t` - Code is written in a way that on receiving a `PUBACK`/`PUBREC` the copy will be cleared after the state of the publish record is changed so that if state update fails the copy won't be cleared. Otherwise if the state does not change and the copy is cleared then when a connection is made with an unclean session there will be a retrieve fail as the system is in an inconsistent state. - We are storing the copies of the publishes with the Duplicate flag set this is because on retrieving the packet we will get it in the form of a `TransportOutVector_t` that holds the data in a `const` pointer which cannot be changed after retrieving. Pending Tasks --------------- - [ ] Changelog - [ ] Minor version bump - [x] Doxygen example for the new API - [x] Better API Names - [x] Unit Test Updates - [x] CBMC Proof --------- Co-authored-by: Dakshit Babbar <dakshba@amazon.com> Co-authored-by: GitHub Action <action@github.com> Co-authored-by: AniruddhaKanhere <60444055+AniruddhaKanhere@users.noreply.github.com>