]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_network.c
Remove the FreeRTOS-IoT-Libraries from FreeRTOS-Plus as it was an old copy with a...
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-IoT-Libraries / c_sdk / standard / mqtt / src / iot_mqtt_network.c
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_network.c b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_network.c
deleted file mode 100644 (file)
index 42843d2..0000000
+++ /dev/null
@@ -1,986 +0,0 @@
-/*\r
- * Amazon FreeRTOS MQTT V2.0.0\r
- * Copyright (C) 2018 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
- *\r
- * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
- * this software and associated documentation files (the "Software"), to deal in\r
- * the Software without restriction, including without limitation the rights to\r
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
- * the Software, and to permit persons to whom the Software is furnished to do so,\r
- * subject to the following conditions:\r
- *\r
- * The above copyright notice and this permission notice shall be included in all\r
- * copies or substantial portions of the Software.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
- *\r
- * http://aws.amazon.com/freertos\r
- * http://www.FreeRTOS.org\r
- */\r
-\r
-/**\r
- * @file iot_mqtt_network.c\r
- * @brief Implements functions involving transport layer connections.\r
- */\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* Standard includes. */\r
-#include <string.h>\r
-\r
-/* Error handling include. */\r
-#include "private/iot_error.h"\r
-\r
-/* MQTT internal include. */\r
-#include "private/iot_mqtt_internal.h"\r
-\r
-/* Platform layer includes. */\r
-#include "platform/iot_threads.h"\r
-\r
-/* Atomics include. */\r
-#include "iot_atomic.h"\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/**\r
- * @brief Check if an incoming packet type is valid.\r
- *\r
- * @param[in] packetType The packet type to check.\r
- *\r
- * @return `true` if the packet type is valid; `false` otherwise.\r
- */\r
-static bool _incomingPacketValid( uint8_t packetType );\r
-\r
-/**\r
- * @brief Get an incoming MQTT packet from the network.\r
- *\r
- * @param[in] pNetworkConnection Network connection to use for receive, which\r
- * may be different from the network connection associated with the MQTT connection.\r
- * @param[in] pMqttConnection The associated MQTT connection.\r
- * @param[out] pIncomingPacket Output parameter for the incoming packet.\r
- *\r
- * @return #IOT_MQTT_SUCCESS, #IOT_MQTT_NO_MEMORY or #IOT_MQTT_BAD_RESPONSE.\r
- */\r
-static IotMqttError_t _getIncomingPacket( void * pNetworkConnection,\r
-                                          const _mqttConnection_t * pMqttConnection,\r
-                                          _mqttPacket_t * pIncomingPacket );\r
-\r
-/**\r
- * @brief Deserialize a packet received from the network.\r
- *\r
- * @param[in] pMqttConnection The associated MQTT connection.\r
- * @param[in] pIncomingPacket The packet received from the network.\r
- *\r
- * @return #IOT_MQTT_SUCCESS, #IOT_MQTT_NO_MEMORY, #IOT_MQTT_NETWORK_ERROR,\r
- * #IOT_MQTT_SCHEDULING_ERROR, #IOT_MQTT_BAD_RESPONSE, or #IOT_MQTT_SERVER_REFUSED.\r
- */\r
-static IotMqttError_t _deserializeIncomingPacket( _mqttConnection_t * pMqttConnection,\r
-                                                  _mqttPacket_t * pIncomingPacket );\r
-\r
-/**\r
- * @brief Send a PUBACK for a received QoS 1 PUBLISH packet.\r
- *\r
- * @param[in] pMqttConnection Which connection the PUBACK should be sent over.\r
- * @param[in] packetIdentifier Which packet identifier to include in PUBACK.\r
- */\r
-static void _sendPuback( _mqttConnection_t * pMqttConnection,\r
-                         uint16_t packetIdentifier );\r
-\r
-/**\r
- * @brief Flush a packet from the stream of incoming data.\r
- *\r
- * This function is called when memory for a packet cannot be allocated. The\r
- * packet is flushed from the stream of incoming data so that the next packet\r
- * may be read.\r
- *\r
- * @param[in] pNetworkConnection Network connection to use for receive, which\r
- * may be different from the network connection associated with the MQTT connection.\r
- * @param[in] pMqttConnection The associated MQTT connection.\r
- * @param[in] length The length of the packet to flush.\r
- */\r
-static void _flushPacket( void * pNetworkConnection,\r
-                          const _mqttConnection_t * pMqttConnection,\r
-                          size_t length );\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static bool _incomingPacketValid( uint8_t packetType )\r
-{\r
-    bool status = true;\r
-\r
-    /* Check packet type. Mask out lower bits to ignore flags. */\r
-    switch( packetType & 0xf0 )\r
-    {\r
-        /* Valid incoming packet types. */\r
-        case MQTT_PACKET_TYPE_CONNACK:\r
-        case MQTT_PACKET_TYPE_PUBLISH:\r
-        case MQTT_PACKET_TYPE_PUBACK:\r
-        case MQTT_PACKET_TYPE_SUBACK:\r
-        case MQTT_PACKET_TYPE_UNSUBACK:\r
-        case MQTT_PACKET_TYPE_PINGRESP:\r
-            break;\r
-\r
-        /* Any other packet type is invalid. */\r
-        default:\r
-            status = false;\r
-            break;\r
-    }\r
-\r
-    return status;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static IotMqttError_t _getIncomingPacket( void * pNetworkConnection,\r
-                                          const _mqttConnection_t * pMqttConnection,\r
-                                          _mqttPacket_t * pIncomingPacket )\r
-{\r
-    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
-    size_t dataBytesRead = 0;\r
-\r
-    /* Default functions for retrieving packet type and length. */\r
-    uint8_t ( * getPacketType )( void *,\r
-                                 const IotNetworkInterface_t * ) = _IotMqtt_GetPacketType;\r
-    size_t ( * getRemainingLength )( void *,\r
-                                     const IotNetworkInterface_t * ) = _IotMqtt_GetRemainingLength;\r
-\r
-    /* No buffer for remaining data should be allocated. */\r
-    IotMqtt_Assert( pIncomingPacket->pRemainingData == NULL );\r
-    IotMqtt_Assert( pIncomingPacket->remainingLength == 0 );\r
-\r
-    /* Choose packet type and length functions. */\r
-    #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-        if( pMqttConnection->pSerializer != NULL )\r
-        {\r
-            if( pMqttConnection->pSerializer->getPacketType != NULL )\r
-            {\r
-                getPacketType = pMqttConnection->pSerializer->getPacketType;\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-\r
-            if( pMqttConnection->pSerializer->getRemainingLength != NULL )\r
-            {\r
-                getRemainingLength = pMqttConnection->pSerializer->getRemainingLength;\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */\r
-\r
-    /* Read the packet type, which is the first byte available. */\r
-    pIncomingPacket->type = getPacketType( pNetworkConnection,\r
-                                           pMqttConnection->pNetworkInterface );\r
-\r
-    /* Check that the incoming packet type is valid. */\r
-    if( _incomingPacketValid( pIncomingPacket->type ) == false )\r
-    {\r
-        IotLogError( "(MQTT connection %p) Unknown packet type %02x received.",\r
-                     pMqttConnection,\r
-                     pIncomingPacket->type );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Read the remaining length. */\r
-    pIncomingPacket->remainingLength = getRemainingLength( pNetworkConnection,\r
-                                                           pMqttConnection->pNetworkInterface );\r
-\r
-    if( pIncomingPacket->remainingLength == MQTT_REMAINING_LENGTH_INVALID )\r
-    {\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Allocate a buffer for the remaining data and read the data. */\r
-    if( pIncomingPacket->remainingLength > 0 )\r
-    {\r
-        pIncomingPacket->pRemainingData = IotMqtt_MallocMessage( pIncomingPacket->remainingLength );\r
-\r
-        if( pIncomingPacket->pRemainingData == NULL )\r
-        {\r
-            IotLogError( "(MQTT connection %p) Failed to allocate buffer of length "\r
-                         "%lu for incoming packet type %lu.",\r
-                         pMqttConnection,\r
-                         ( unsigned long ) pIncomingPacket->remainingLength,\r
-                         ( unsigned long ) pIncomingPacket->type );\r
-\r
-            _flushPacket( pNetworkConnection, pMqttConnection, pIncomingPacket->remainingLength );\r
-\r
-            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        dataBytesRead = pMqttConnection->pNetworkInterface->receive( pNetworkConnection,\r
-                                                                     pIncomingPacket->pRemainingData,\r
-                                                                     pIncomingPacket->remainingLength );\r
-\r
-        if( dataBytesRead != pIncomingPacket->remainingLength )\r
-        {\r
-            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Clean up on error. */\r
-    IOT_FUNCTION_CLEANUP_BEGIN();\r
-\r
-    if( status != IOT_MQTT_SUCCESS )\r
-    {\r
-        if( pIncomingPacket->pRemainingData != NULL )\r
-        {\r
-            IotMqtt_FreeMessage( pIncomingPacket->pRemainingData );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    IOT_FUNCTION_CLEANUP_END();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static IotMqttError_t _deserializeIncomingPacket( _mqttConnection_t * pMqttConnection,\r
-                                                  _mqttPacket_t * pIncomingPacket )\r
-{\r
-    IotMqttError_t status = IOT_MQTT_STATUS_PENDING;\r
-    _mqttOperation_t * pOperation = NULL;\r
-\r
-    /* Deserializer function. */\r
-    IotMqttError_t ( * deserialize )( _mqttPacket_t * ) = NULL;\r
-\r
-    /* A buffer for remaining data must be allocated if remaining length is not 0. */\r
-    IotMqtt_Assert( ( pIncomingPacket->remainingLength > 0 ) ==\r
-                    ( pIncomingPacket->pRemainingData != NULL ) );\r
-\r
-    /* Only valid packets should be given to this function. */\r
-    IotMqtt_Assert( _incomingPacketValid( pIncomingPacket->type ) == true );\r
-\r
-    /* Mask out the low bits of packet type to ignore flags. */\r
-    switch( ( pIncomingPacket->type & 0xf0 ) )\r
-    {\r
-        case MQTT_PACKET_TYPE_CONNACK:\r
-            IotLogDebug( "(MQTT connection %p) CONNACK in data stream.", pMqttConnection );\r
-\r
-            /* Choose CONNACK deserializer. */\r
-            deserialize = _IotMqtt_DeserializeConnack;\r
-\r
-            #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-                if( pMqttConnection->pSerializer != NULL )\r
-                {\r
-                    if( pMqttConnection->pSerializer->deserialize.connack != NULL )\r
-                    {\r
-                        deserialize = pMqttConnection->pSerializer->deserialize.connack;\r
-                    }\r
-                    else\r
-                    {\r
-                        EMPTY_ELSE_MARKER;\r
-                    }\r
-                }\r
-                else\r
-                {\r
-                    EMPTY_ELSE_MARKER;\r
-                }\r
-            #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */\r
-\r
-            /* Deserialize CONNACK and notify of result. */\r
-            status = deserialize( pIncomingPacket );\r
-            pOperation = _IotMqtt_FindOperation( pMqttConnection,\r
-                                                 IOT_MQTT_CONNECT,\r
-                                                 NULL );\r
-\r
-            if( pOperation != NULL )\r
-            {\r
-                pOperation->u.operation.status = status;\r
-                _IotMqtt_Notify( pOperation );\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-\r
-            break;\r
-\r
-        case MQTT_PACKET_TYPE_PUBLISH:\r
-            IotLogDebug( "(MQTT connection %p) PUBLISH in data stream.", pMqttConnection );\r
-\r
-            /* Allocate memory to handle the incoming PUBLISH. */\r
-            pOperation = IotMqtt_MallocOperation( sizeof( _mqttOperation_t ) );\r
-\r
-            if( pOperation == NULL )\r
-            {\r
-                IotLogWarn( "Failed to allocate memory for incoming PUBLISH." );\r
-                status = IOT_MQTT_NO_MEMORY;\r
-\r
-                break;\r
-            }\r
-            else\r
-            {\r
-                /* Set the members of the incoming PUBLISH operation. */\r
-                ( void ) memset( pOperation, 0x00, sizeof( _mqttOperation_t ) );\r
-                pOperation->incomingPublish = true;\r
-                pOperation->pMqttConnection = pMqttConnection;\r
-                pIncomingPacket->u.pIncomingPublish = pOperation;\r
-            }\r
-\r
-            /* Choose a PUBLISH deserializer. */\r
-            deserialize = _IotMqtt_DeserializePublish;\r
-\r
-            #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-                if( pMqttConnection->pSerializer != NULL )\r
-                {\r
-                    if( pMqttConnection->pSerializer->deserialize.publish != NULL )\r
-                    {\r
-                        deserialize = pMqttConnection->pSerializer->deserialize.publish;\r
-                    }\r
-                    else\r
-                    {\r
-                        EMPTY_ELSE_MARKER;\r
-                    }\r
-                }\r
-                else\r
-                {\r
-                    EMPTY_ELSE_MARKER;\r
-                }\r
-            #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */\r
-\r
-            /* Deserialize incoming PUBLISH. */\r
-            status = deserialize( pIncomingPacket );\r
-\r
-            if( status == IOT_MQTT_SUCCESS )\r
-            {\r
-                /* Send a PUBACK for QoS 1 PUBLISH. */\r
-                if( pOperation->u.publish.publishInfo.qos == IOT_MQTT_QOS_1 )\r
-                {\r
-                    _sendPuback( pMqttConnection, pIncomingPacket->packetIdentifier );\r
-                }\r
-                else\r
-                {\r
-                    EMPTY_ELSE_MARKER;\r
-                }\r
-\r
-                /* Transfer ownership of the received MQTT packet to the PUBLISH operation. */\r
-                pOperation->u.publish.pReceivedData = pIncomingPacket->pRemainingData;\r
-                pIncomingPacket->pRemainingData = NULL;\r
-\r
-                /* Add the PUBLISH to the list of operations pending processing. */\r
-                IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
-                IotListDouble_InsertHead( &( pMqttConnection->pendingProcessing ),\r
-                                          &( pOperation->link ) );\r
-                IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
-\r
-                /* Increment the MQTT connection reference count before scheduling an\r
-                 * incoming PUBLISH. */\r
-                if( _IotMqtt_IncrementConnectionReferences( pMqttConnection ) == true )\r
-                {\r
-                    /* Schedule PUBLISH for callback invocation. */\r
-                    status = _IotMqtt_ScheduleOperation( pOperation, _IotMqtt_ProcessIncomingPublish, 0 );\r
-                }\r
-                else\r
-                {\r
-                    status = IOT_MQTT_NETWORK_ERROR;\r
-                }\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-\r
-            /* Free PUBLISH operation on error. */\r
-            if( status != IOT_MQTT_SUCCESS )\r
-            {\r
-                /* Check ownership of the received MQTT packet. */\r
-                if( pOperation->u.publish.pReceivedData != NULL )\r
-                {\r
-                    /* Retrieve the pointer MQTT packet pointer so it may be freed later. */\r
-                    IotMqtt_Assert( pIncomingPacket->pRemainingData == NULL );\r
-                    pIncomingPacket->pRemainingData = ( uint8_t * ) pOperation->u.publish.pReceivedData;\r
-                }\r
-                else\r
-                {\r
-                    EMPTY_ELSE_MARKER;\r
-                }\r
-\r
-                /* Remove operation from pending processing list. */\r
-                IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
-\r
-                if( IotLink_IsLinked( &( pOperation->link ) ) == true )\r
-                {\r
-                    IotListDouble_Remove( &( pOperation->link ) );\r
-                }\r
-                else\r
-                {\r
-                    EMPTY_ELSE_MARKER;\r
-                }\r
-\r
-                IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
-\r
-                IotMqtt_Assert( pOperation != NULL );\r
-                IotMqtt_FreeOperation( pOperation );\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-\r
-            break;\r
-\r
-        case MQTT_PACKET_TYPE_PUBACK:\r
-            IotLogDebug( "(MQTT connection %p) PUBACK in data stream.", pMqttConnection );\r
-\r
-            /* Choose PUBACK deserializer. */\r
-            deserialize = _IotMqtt_DeserializePuback;\r
-\r
-            #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-                if( pMqttConnection->pSerializer != NULL )\r
-                {\r
-                    if( pMqttConnection->pSerializer->deserialize.puback != NULL )\r
-                    {\r
-                        deserialize = pMqttConnection->pSerializer->deserialize.puback;\r
-                    }\r
-                    else\r
-                    {\r
-                        EMPTY_ELSE_MARKER;\r
-                    }\r
-                }\r
-                else\r
-                {\r
-                    EMPTY_ELSE_MARKER;\r
-                }\r
-            #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */\r
-\r
-            /* Deserialize PUBACK and notify of result. */\r
-            status = deserialize( pIncomingPacket );\r
-            pOperation = _IotMqtt_FindOperation( pMqttConnection,\r
-                                                 IOT_MQTT_PUBLISH_TO_SERVER,\r
-                                                 &( pIncomingPacket->packetIdentifier ) );\r
-\r
-            if( pOperation != NULL )\r
-            {\r
-                pOperation->u.operation.status = status;\r
-                _IotMqtt_Notify( pOperation );\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-\r
-            break;\r
-\r
-        case MQTT_PACKET_TYPE_SUBACK:\r
-            IotLogDebug( "(MQTT connection %p) SUBACK in data stream.", pMqttConnection );\r
-\r
-            /* Choose SUBACK deserializer. */\r
-            deserialize = _IotMqtt_DeserializeSuback;\r
-\r
-            #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-                if( pMqttConnection->pSerializer != NULL )\r
-                {\r
-                    if( pMqttConnection->pSerializer->deserialize.suback != NULL )\r
-                    {\r
-                        deserialize = pMqttConnection->pSerializer->deserialize.suback;\r
-                    }\r
-                    else\r
-                    {\r
-                        EMPTY_ELSE_MARKER;\r
-                    }\r
-                }\r
-                else\r
-                {\r
-                    EMPTY_ELSE_MARKER;\r
-                }\r
-            #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */\r
-\r
-            /* Deserialize SUBACK and notify of result. */\r
-            pIncomingPacket->u.pMqttConnection = pMqttConnection;\r
-            status = deserialize( pIncomingPacket );\r
-            pOperation = _IotMqtt_FindOperation( pMqttConnection,\r
-                                                 IOT_MQTT_SUBSCRIBE,\r
-                                                 &( pIncomingPacket->packetIdentifier ) );\r
-\r
-            if( pOperation != NULL )\r
-            {\r
-                pOperation->u.operation.status = status;\r
-                _IotMqtt_Notify( pOperation );\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-\r
-            break;\r
-\r
-        case MQTT_PACKET_TYPE_UNSUBACK:\r
-            IotLogDebug( "(MQTT connection %p) UNSUBACK in data stream.", pMqttConnection );\r
-\r
-            /* Choose UNSUBACK deserializer. */\r
-            deserialize = _IotMqtt_DeserializeUnsuback;\r
-\r
-            #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-                if( pMqttConnection->pSerializer != NULL )\r
-                {\r
-                    if( pMqttConnection->pSerializer->deserialize.unsuback != NULL )\r
-                    {\r
-                        deserialize = pMqttConnection->pSerializer->deserialize.unsuback;\r
-                    }\r
-                    else\r
-                    {\r
-                        EMPTY_ELSE_MARKER;\r
-                    }\r
-                }\r
-                else\r
-                {\r
-                    EMPTY_ELSE_MARKER;\r
-                }\r
-            #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */\r
-\r
-            /* Deserialize UNSUBACK and notify of result. */\r
-            status = deserialize( pIncomingPacket );\r
-            pOperation = _IotMqtt_FindOperation( pMqttConnection,\r
-                                                 IOT_MQTT_UNSUBSCRIBE,\r
-                                                 &( pIncomingPacket->packetIdentifier ) );\r
-\r
-            if( pOperation != NULL )\r
-            {\r
-                pOperation->u.operation.status = status;\r
-                _IotMqtt_Notify( pOperation );\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-\r
-            break;\r
-\r
-        default:\r
-            /* The only remaining valid type is PINGRESP. */\r
-            IotMqtt_Assert( ( pIncomingPacket->type & 0xf0 ) == MQTT_PACKET_TYPE_PINGRESP );\r
-            IotLogDebug( "(MQTT connection %p) PINGRESP in data stream.", pMqttConnection );\r
-\r
-            /* Choose PINGRESP deserializer. */\r
-            deserialize = _IotMqtt_DeserializePingresp;\r
-\r
-            #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-                if( pMqttConnection->pSerializer != NULL )\r
-                {\r
-                    if( pMqttConnection->pSerializer->deserialize.pingresp != NULL )\r
-                    {\r
-                        deserialize = pMqttConnection->pSerializer->deserialize.pingresp;\r
-                    }\r
-                    else\r
-                    {\r
-                        EMPTY_ELSE_MARKER;\r
-                    }\r
-                }\r
-                else\r
-                {\r
-                    EMPTY_ELSE_MARKER;\r
-                }\r
-            #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */\r
-\r
-            /* Deserialize PINGRESP. */\r
-            status = deserialize( pIncomingPacket );\r
-\r
-            if( status == IOT_MQTT_SUCCESS )\r
-            {\r
-                if( Atomic_CompareAndSwap_u32( &( pMqttConnection->pingreq.u.operation.periodic.ping.failure ),\r
-                                               0,\r
-                                               1 ) == 1 )\r
-                {\r
-                    IotLogDebug( "(MQTT connection %p) PINGRESP successfully parsed.",\r
-                                 pMqttConnection );\r
-                }\r
-                else\r
-                {\r
-                    IotLogWarn( "(MQTT connection %p) Unexpected PINGRESP received.",\r
-                                pMqttConnection );\r
-                }\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-\r
-            break;\r
-    }\r
-\r
-    if( status != IOT_MQTT_SUCCESS )\r
-    {\r
-        IotLogError( "(MQTT connection %p) Packet parser status %s.",\r
-                     pMqttConnection,\r
-                     IotMqtt_strerror( status ) );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    return status;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static void _sendPuback( _mqttConnection_t * pMqttConnection,\r
-                         uint16_t packetIdentifier )\r
-{\r
-    IotMqttError_t status = IOT_MQTT_STATUS_PENDING;\r
-    _mqttOperation_t * pPubackOperation = NULL;\r
-\r
-    /* Default PUBACK serializer function. */\r
-    IotMqttError_t ( * serializePuback )( uint16_t,\r
-                                          uint8_t **,\r
-                                          size_t * ) = _IotMqtt_SerializePuback;\r
-\r
-    IotLogDebug( "(MQTT connection %p) Sending PUBACK for received PUBLISH %hu.",\r
-                 pMqttConnection,\r
-                 packetIdentifier );\r
-\r
-    /* Choose PUBACK serializer and free packet functions. */\r
-    #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-        if( pMqttConnection->pSerializer != NULL )\r
-        {\r
-            if( pMqttConnection->pSerializer->serialize.puback != NULL )\r
-            {\r
-                serializePuback = pMqttConnection->pSerializer->serialize.puback;\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */\r
-\r
-    /* Create a PUBACK operation. */\r
-    status = _IotMqtt_CreateOperation( pMqttConnection,\r
-                                       0,\r
-                                       NULL,\r
-                                       &pPubackOperation );\r
-\r
-    if( status != IOT_MQTT_SUCCESS )\r
-    {\r
-        IOT_GOTO_CLEANUP();\r
-    }\r
-\r
-    /* Set the operation type. */\r
-    pPubackOperation->u.operation.type = IOT_MQTT_PUBACK;\r
-\r
-    /* Generate a PUBACK packet from the packet identifier. */\r
-    status = serializePuback( packetIdentifier,\r
-                              &( pPubackOperation->u.operation.pMqttPacket ),\r
-                              &( pPubackOperation->u.operation.packetSize ) );\r
-\r
-    if( status != IOT_MQTT_SUCCESS )\r
-    {\r
-        IOT_GOTO_CLEANUP();\r
-    }\r
-\r
-    /* Add the PUBACK operation to the send queue for network transmission. */\r
-    status = _IotMqtt_ScheduleOperation( pPubackOperation,\r
-                                         _IotMqtt_ProcessSend,\r
-                                         0 );\r
-\r
-    if( status != IOT_MQTT_SUCCESS )\r
-    {\r
-        IotLogError( "(MQTT connection %p) Failed to enqueue PUBACK for sending.",\r
-                     pMqttConnection );\r
-\r
-        IOT_GOTO_CLEANUP();\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Clean up on error. */\r
-    IOT_FUNCTION_CLEANUP_BEGIN();\r
-\r
-    if( status != IOT_MQTT_SUCCESS )\r
-    {\r
-        if( pPubackOperation != NULL )\r
-        {\r
-            _IotMqtt_DestroyOperation( pPubackOperation );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static void _flushPacket( void * pNetworkConnection,\r
-                          const _mqttConnection_t * pMqttConnection,\r
-                          size_t length )\r
-{\r
-    size_t bytesFlushed = 0;\r
-    uint8_t receivedByte = 0;\r
-\r
-    for( bytesFlushed = 0; bytesFlushed < length; bytesFlushed++ )\r
-    {\r
-        ( void ) _IotMqtt_GetNextByte( pNetworkConnection,\r
-                                       pMqttConnection->pNetworkInterface,\r
-                                       &receivedByte );\r
-    }\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-bool _IotMqtt_GetNextByte( void * pNetworkConnection,\r
-                           const IotNetworkInterface_t * pNetworkInterface,\r
-                           uint8_t * pIncomingByte )\r
-{\r
-    bool status = false;\r
-    uint8_t incomingByte = 0;\r
-    size_t bytesReceived = 0;\r
-\r
-    /* Attempt to read 1 byte. */\r
-    bytesReceived = pNetworkInterface->receive( pNetworkConnection,\r
-                                                &incomingByte,\r
-                                                1 );\r
-\r
-    /* Set the output parameter and return success if 1 byte was read. */\r
-    if( bytesReceived == 1 )\r
-    {\r
-        *pIncomingByte = incomingByte;\r
-        status = true;\r
-    }\r
-    else\r
-    {\r
-        /* Network receive must return 0 on failure. */\r
-        IotMqtt_Assert( bytesReceived == 0 );\r
-    }\r
-\r
-    return status;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void _IotMqtt_CloseNetworkConnection( IotMqttDisconnectReason_t disconnectReason,\r
-                                      _mqttConnection_t * pMqttConnection )\r
-{\r
-    IotTaskPoolError_t taskPoolStatus = IOT_TASKPOOL_SUCCESS;\r
-    IotNetworkError_t closeStatus = IOT_NETWORK_SUCCESS;\r
-    IotMqttCallbackParam_t callbackParam = { .u.message = { 0 } };\r
-    void * pNetworkConnection = NULL, * pDisconnectCallbackContext = NULL;\r
-\r
-    /* Disconnect callback function. */\r
-    void ( * disconnectCallback )( void *,\r
-                                   IotMqttCallbackParam_t * ) = NULL;\r
-\r
-    /* Network close function. */\r
-    IotNetworkError_t ( * closeConnection) ( void * ) = NULL;\r
-\r
-    /* Default free packet function. */\r
-    void ( * freePacket )( uint8_t * ) = _IotMqtt_FreePacket;\r
-\r
-    /* Mark the MQTT connection as disconnected and the keep-alive as failed. */\r
-    IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
-    pMqttConnection->disconnected = true;\r
-\r
-    if( pMqttConnection->pingreq.u.operation.periodic.ping.keepAliveMs != 0 )\r
-    {\r
-        /* Keep-alive must have a PINGREQ allocated. */\r
-        IotMqtt_Assert( pMqttConnection->pingreq.u.operation.pMqttPacket != NULL );\r
-        IotMqtt_Assert( pMqttConnection->pingreq.u.operation.packetSize != 0 );\r
-\r
-        /* PINGREQ provides a reference to the connection, so reference count must\r
-         * be nonzero. */\r
-        IotMqtt_Assert( pMqttConnection->references > 0 );\r
-\r
-        /* Attempt to cancel the keep-alive job. */\r
-        taskPoolStatus = IotTaskPool_TryCancel( IOT_SYSTEM_TASKPOOL,\r
-                                                pMqttConnection->pingreq.job,\r
-                                                NULL );\r
-\r
-        /* If the keep-alive job was not canceled, it must be already executing.\r
-         * Any other return value is invalid. */\r
-        IotMqtt_Assert( ( taskPoolStatus == IOT_TASKPOOL_SUCCESS ) ||\r
-                        ( taskPoolStatus == IOT_TASKPOOL_CANCEL_FAILED ) );\r
-\r
-        /* Clean up keep-alive if its job was successfully canceled. Otherwise,\r
-         * the executing keep-alive job will clean up itself. */\r
-        if( taskPoolStatus == IOT_TASKPOOL_SUCCESS )\r
-        {\r
-            /* Choose a function to free the packet. */\r
-            #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-                if( pMqttConnection->pSerializer != NULL )\r
-                {\r
-                    if( pMqttConnection->pSerializer->freePacket != NULL )\r
-                    {\r
-                        freePacket = pMqttConnection->pSerializer->freePacket;\r
-                    }\r
-                }\r
-            #endif\r
-\r
-            freePacket( pMqttConnection->pingreq.u.operation.pMqttPacket );\r
-\r
-            /* Clear data about the keep-alive. */\r
-            pMqttConnection->pingreq.u.operation.periodic.ping.keepAliveMs = 0;\r
-            pMqttConnection->pingreq.u.operation.pMqttPacket = NULL;\r
-            pMqttConnection->pingreq.u.operation.packetSize = 0;\r
-\r
-            /* Keep-alive is cleaned up; decrement reference count. Since this\r
-             * function must be followed with a call to DISCONNECT, a check to\r
-             * destroy the connection is not done here. */\r
-            pMqttConnection->references--;\r
-\r
-            IotLogDebug( "(MQTT connection %p) Keep-alive job canceled and cleaned up.",\r
-                         pMqttConnection );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Copy the function pointers and contexts, as the MQTT connection may be\r
-     * modified after the mutex is released. */\r
-    disconnectCallback = pMqttConnection->disconnectCallback.function;\r
-    pDisconnectCallbackContext = pMqttConnection->disconnectCallback.pCallbackContext;\r
-\r
-    closeConnection = pMqttConnection->pNetworkInterface->close;\r
-    pNetworkConnection = pMqttConnection->pNetworkConnection;\r
-\r
-    IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
-\r
-    /* Close the network connection. */\r
-    if( closeConnection != NULL )\r
-    {\r
-        closeStatus = closeConnection( pNetworkConnection );\r
-\r
-        if( closeStatus == IOT_NETWORK_SUCCESS )\r
-        {\r
-            IotLogInfo( "(MQTT connection %p) Network connection closed.", pMqttConnection );\r
-        }\r
-        else\r
-        {\r
-            IotLogWarn( "(MQTT connection %p) Failed to close network connection, error %d.",\r
-                        pMqttConnection,\r
-                        closeStatus );\r
-        }\r
-    }\r
-    else\r
-    {\r
-        IotLogWarn( "(MQTT connection %p) No network close function was set. Network connection"\r
-                    " not closed.", pMqttConnection );\r
-    }\r
-\r
-    /* Invoke the disconnect callback. */\r
-    if( disconnectCallback != NULL )\r
-    {\r
-        /* Set the members of the callback parameter. */\r
-        callbackParam.mqttConnection = pMqttConnection;\r
-        callbackParam.u.disconnectReason = disconnectReason;\r
-\r
-        disconnectCallback( pDisconnectCallbackContext,\r
-                            &callbackParam );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void IotMqtt_ReceiveCallback( void * pNetworkConnection,\r
-                              void * pReceiveContext )\r
-{\r
-    IotMqttError_t status = IOT_MQTT_SUCCESS;\r
-    _mqttPacket_t incomingPacket = { .u.pMqttConnection = NULL };\r
-\r
-    /* Cast context to correct type. */\r
-    _mqttConnection_t * pMqttConnection = ( _mqttConnection_t * ) pReceiveContext;\r
-\r
-    /* Read an MQTT packet from the network. */\r
-    status = _getIncomingPacket( pNetworkConnection,\r
-                                 pMqttConnection,\r
-                                 &incomingPacket );\r
-\r
-    if( status == IOT_MQTT_SUCCESS )\r
-    {\r
-        /* Deserialize the received packet. */\r
-        status = _deserializeIncomingPacket( pMqttConnection,\r
-                                             &incomingPacket );\r
-\r
-        /* Free any buffers allocated for the MQTT packet. */\r
-        if( incomingPacket.pRemainingData != NULL )\r
-        {\r
-            IotMqtt_FreeMessage( incomingPacket.pRemainingData );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Close the network connection on a bad response. */\r
-    if( status == IOT_MQTT_BAD_RESPONSE )\r
-    {\r
-        IotLogError( "(MQTT connection %p) Error processing incoming data. Closing connection.",\r
-                     pMqttConnection );\r
-\r
-        _IotMqtt_CloseNetworkConnection( IOT_MQTT_BAD_PACKET_RECEIVED,\r
-                                         pMqttConnection );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r